2 * Copyright (c) 2017 - 2021 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/socket.h>
20 #include <sys/types.h>
27 #include "aul-internal.hh"
28 #include "debug-port-internal.hh"
29 #include "exception-internal.hh"
30 #include "include/rpc-port-internal.h"
31 #include "log-private.hh"
32 #include "proxy-internal.hh"
33 #include "request-internal.hh"
34 #include "response-internal.hh"
36 #define EILLEGALACCESS 127
42 constexpr const char kPortTypeMain[] = "main";
43 constexpr const char kPortTypeDelegate[] = "delegate";
44 constexpr const char kDPrefix[] = "d::";
45 constexpr const char kUdPrefix[] = "ud::";
47 std::string GenInstance() {
51 uuid_unparse(u, uuid);
52 return std::string(uuid) + "@" + Aul::GetAppId(getpid());
55 int SendRequest(ClientSocket* client, const Request& request) {
56 tizen_base::Parcel parcel;
57 parcel.WriteParcelable(const_cast<Request&>(request));
58 size_t size = parcel.GetDataSize();
59 int ret = client->Send(reinterpret_cast<void*>(&size), sizeof(size));
61 _E("Send() is failed. error(%d)", ret); // LCOV_EXCL_LINE
62 return -1; // LCOV_EXCL_LINE
65 ret = client->Send(parcel.GetData(), size);
67 _E("Send() is failed. error(%d)", ret); // LCOV_EXCL_LINE
68 return -1; // LCOV_EXCL_LINE
74 int ReceiveResponse(ClientSocket* client, Response** response) {
75 int flags = fcntl(client->GetFd(), F_GETFL, 0);
76 fcntl(client->GetFd(), F_SETFL, flags & ~O_NONBLOCK);
79 int ret = client->Receive(reinterpret_cast<void*>(&size), sizeof(size));
82 _E("Receive() is failed. error(%d)", ret);
83 fcntl(client->GetFd(), F_SETFL, flags);
88 uint8_t* buf = static_cast<uint8_t*>(malloc(size));
92 fcntl(client->GetFd(), F_SETFL, flags);
97 ret = client->Receive(buf, size);
100 _E("Receive() is failed. error(%d)", ret);
102 fcntl(client->GetFd(), F_SETFL, flags);
107 tizen_base::Parcel parcel(buf, size, false);
108 *response = new (std::nothrow) Response();
109 if (*response == nullptr) {
112 fcntl(client->GetFd(), F_SETFL, flags);
117 parcel.ReadParcelable(*response);
118 fcntl(client->GetFd(), F_SETFL, flags);
122 bool IsDaemon(const std::string& name) {
123 if (name.compare(0, strlen(kDPrefix), kDPrefix) == 0) return true;
125 if (name.compare(0, strlen(kUdPrefix), kUdPrefix) == 0) return true;
133 _D("Proxy::Proxy()");
137 std::lock_guard<std::recursive_mutex> lock(GetMutex());
138 _D("Proxy::~Proxy()");
139 if (main_port_.get() != nullptr)
140 DebugPort::RemoveSession(main_port_->GetFd()); // LCOV_EXCL_LINE
148 int Proxy::MainPortConnect(const std::string& instance, bool sync) {
149 std::lock_guard<std::recursive_mutex> lock(GetMutex());
151 main_client_.reset(Client::Create(this, port_path_));
152 if (main_client_.get() == nullptr)
153 return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
155 Request request(instance.c_str(), kPortTypeMain);
156 int ret = SendRequest(main_client_.get(), request);
157 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
159 main_client_->SetNonblock();
161 Response* response = nullptr;
162 ret = ReceiveResponse(main_client_.get(), &response);
163 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
165 std::unique_ptr<Response> response_auto(response);
166 if (response->GetResult() != 0) {
167 _E("Permission denied"); // LCOV_EXCL_LINE
168 return RPC_PORT_ERROR_PERMISSION_DENIED; // LCOV_EXCL_LINE
171 fds_[0] = main_client_->RemoveFd();
173 ret = main_client_->Watch();
174 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
177 return RPC_PORT_ERROR_NONE;
180 int Proxy::DelegatePortConnect(const std::string& instance, bool sync) {
181 std::lock_guard<std::recursive_mutex> lock(GetMutex());
183 delegate_client_.reset(Client::Create(this, port_path_));
184 if (delegate_client_.get() == nullptr)
185 return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
187 Request request(instance.c_str(), kPortTypeDelegate);
188 int ret = SendRequest(delegate_client_.get(), request);
189 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
191 delegate_client_->SetNonblock();
193 Response* response = nullptr;
194 ret = ReceiveResponse(delegate_client_.get(), &response);
195 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
197 std::unique_ptr<Response> response_auto(response);
198 if (response->GetResult() != 0) {
199 _E("Permission denied"); // LCOV_EXCL_LINE
200 return RPC_PORT_ERROR_PERMISSION_DENIED; // LCOV_EXCL_LINE
203 fds_[1] = delegate_client_->RemoveFd();
205 ret = delegate_client_->Watch();
206 if (ret != 0) return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
209 return RPC_PORT_ERROR_NONE;
212 int Proxy::Connect(bool sync) {
213 std::lock_guard<std::recursive_mutex> lock(GetMutex());
214 std::string instance = GenInstance();
215 int ret = MainPortConnect(instance, sync);
216 if (ret != RPC_PORT_ERROR_NONE) return ret;
218 ret = DelegatePortConnect(instance, sync);
219 if (ret != RPC_PORT_ERROR_NONE) return ret;
222 main_port_.reset(new ProxyPort(this, fds_[0], target_appid_, false));
223 delegate_port_.reset(new ProxyPort(this, fds_[1], target_appid_));
224 DebugPort::AddSession(port_name_, target_appid_, fds_[0], fds_[1]);
225 listener_->OnConnected(target_appid_, main_port_.get());
231 int Proxy::Connect(std::string appid, std::string port_name,
232 IEventListener* listener) {
233 if (listener == nullptr)
234 return RPC_PORT_ERROR_INVALID_PARAMETER;
236 std::lock_guard<std::recursive_mutex> lock(GetMutex());
237 if (HasRequested()) {
238 _D("Already requested"); // LCOV_EXCL_LINE
239 return RPC_PORT_ERROR_INVALID_PARAMETER; // LCOV_EXCL_LINE
242 listener_ = listener;
243 target_appid_ = std::move(appid);
244 port_name_ = std::move(port_name);
245 SetRealAppId(target_appid_);
247 delegate_port_.reset();
249 Aul::GetPortPath(real_appid_, port_name_, rpc_port_get_target_uid());
253 if (!IsDaemon(real_appid_)) {
254 int ret = Aul::PrepareStub(real_appid_, port_name_,
255 rpc_port_get_target_uid());
256 if (ret != RPC_PORT_ERROR_NONE) {
263 listener_ = nullptr; // LCOV_EXCL_LINE
264 return RPC_PORT_ERROR_IO_ERROR; // LCOV_EXCL_LINE
267 return RPC_PORT_ERROR_NONE;
270 int Proxy::ConnectSync(std::string appid, std::string port_name,
271 IEventListener* listener) {
272 if (listener == nullptr)
273 return RPC_PORT_ERROR_INVALID_PARAMETER;
275 std::lock_guard<std::recursive_mutex> lock(GetMutex());
276 if (HasRequested()) {
277 _D("Already requested");
278 return RPC_PORT_ERROR_INVALID_PARAMETER;
281 listener_ = listener;
282 target_appid_ = std::move(appid);
283 port_name_ = std::move(port_name);
284 SetRealAppId(target_appid_);
286 Aul::GetPortPath(real_appid_, port_name_, rpc_port_get_target_uid());
288 if (!IsDaemon(real_appid_)) {
289 int ret = Aul::PrepareStub(real_appid_, port_name_,
290 rpc_port_get_target_uid());
291 if (ret != RPC_PORT_ERROR_NONE) {
297 if (!WaitUntilPortCreation())
298 return RPC_PORT_ERROR_IO_ERROR;
300 int ret = Connect(true);
301 if (ret != RPC_PORT_ERROR_NONE) {
308 return RPC_PORT_ERROR_NONE;
311 bool Proxy::WaitUntilPortCreation() {
312 file_monitor_.reset(new FileMonitor(port_path_));
313 int retry_count = 100;
315 if (file_monitor_->Exist()) return true;
319 } while (retry_count > 0);
321 if (!file_monitor_->Exist()) {
323 _E("port(%s) of appid(%s) is not ready",
324 port_name_.c_str(), target_appid_.c_str());
332 void Proxy::DisconnectPort() {
333 std::lock_guard<std::recursive_mutex> lock(GetMutex());
334 if (main_port_.get() != nullptr) {
335 DebugPort::RemoveSession(main_port_->GetFd());
341 std::lock_guard<std::recursive_mutex> lock(GetMutex());
343 file_monitor_.reset(new FileMonitor(port_path_, this));
344 file_monitor_->Start();
347 } catch (const Exception& e) {
348 LOGE("Exception occurs. error(%s)", e.what());
355 void Proxy::Cancel() {
356 std::lock_guard<std::recursive_mutex> lock(GetMutex());
357 file_monitor_.reset();
360 void Proxy::SetRealAppId(const std::string& alias_appid) {
361 std::lock_guard<std::recursive_mutex> lock(GetMutex());
362 if (!real_appid_.empty())
365 if (IsDaemon(alias_appid)) {
366 real_appid_ = alias_appid;
370 char* appid = nullptr;
371 int ret = aul_svc_get_appid_by_alias_appid(alias_appid.c_str(), &appid);
372 if (ret != AUL_SVC_RET_OK) {
373 real_appid_ = alias_appid;
378 std::unique_ptr<char, decltype(std::free)*> appid_ptr(appid, std::free);
379 real_appid_ = std::string(appid);
380 _W("alias_appid(%s), real_appid(%s)", alias_appid.c_str(), appid);
384 std::recursive_mutex& Proxy::GetMutex() const {
388 void Proxy::SetConnTimer() {
389 if (conn_timer_data_) {
390 _W("Already exists"); // LCOV_EXCL_START
391 return; // LCOV_EXCL_START
394 conn_timer_data_ = CreateWeakPtr();
395 if (conn_timer_data_ == nullptr) {
396 _E("Out of memory"); // LCOV_EXCL_START
397 return; // LCOV_EXCL_START
400 g_timeout_add_seconds(10, OnTimedOut, conn_timer_data_);
403 void Proxy::UnsetConnTimer() {
404 if (conn_timer_data_ == nullptr)
407 GSource* source = g_main_context_find_source_by_user_data(nullptr,
409 if (source && !g_source_is_destroyed(source))
410 g_source_destroy(source);
412 DestroyWeakPtr(conn_timer_data_);
413 conn_timer_data_ = nullptr;
416 void Proxy::SetIdler() {
418 _W("Already exists"); // LCOV_EXCL_START
419 return; // LCOV_EXCL_START
422 idler_data_ = CreateWeakPtr();
423 if (idler_data_ == nullptr) {
424 _E("Out of memory"); // LCOV_EXCL_START
425 return; // LCOV_EXCL_START
428 g_idle_add(OnIdle, idler_data_);
431 void Proxy::UnsetIdler() {
432 if (idler_data_ == nullptr)
435 GSource* source = g_main_context_find_source_by_user_data(nullptr,
437 if (source && !g_source_is_destroyed(source))
438 g_source_destroy(source);
440 DestroyWeakPtr(idler_data_);
441 idler_data_ = nullptr;
444 void Proxy::OnFileCreated(const std::string& path) {
445 _W("appid=%s, port_name=%s, port_path=%s",
446 target_appid_.c_str(), port_name_.c_str(), path.c_str());
447 std::lock_guard<std::recursive_mutex> lock(GetMutex());
450 if (listener_ == nullptr) return; // LCOV_EXCL_LINE
452 int ret = Connect(false);
453 if (ret != RPC_PORT_ERROR_NONE) {
456 auto* listener = listener_;
458 if (ret == RPC_PORT_ERROR_PERMISSION_DENIED)
459 listener->OnRejected(target_appid_, ret);
461 listener->OnDisconnected(target_appid_);
466 void Proxy::OnFileDeleted(const std::string& path) {
467 _W("appid=%s, port_name=%s, port_path=%s",
468 target_appid_.c_str(), port_name_.c_str(), path.c_str());
469 std::lock_guard<std::recursive_mutex> lock(GetMutex());
473 gboolean Proxy::OnTimedOut(gpointer user_data) {
475 auto* ptr = static_cast<std::weak_ptr<Proxy>*>(user_data);
476 auto proxy = ptr->lock();
477 if (proxy == nullptr) {
478 _E("Proxy is nullptr"); // LCOV_EXCL_LINE
479 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
482 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
483 if (proxy->conn_timer_data_ == nullptr) {
484 _E("Invalid context. proxy(%p)", proxy.get()); // LCOV_EXCL_LINE
485 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
489 proxy->main_client_.reset();
490 proxy->delegate_client_.reset();
491 DestroyWeakPtr(proxy->conn_timer_data_);
492 proxy->conn_timer_data_ = nullptr;
494 auto* listener = proxy->listener_;
495 if (listener == nullptr) {
496 _E("Invalid context"); // LCOV_EXCL_LINE
497 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
500 proxy->listener_ = nullptr;
501 listener->OnRejected(proxy->target_appid_, RPC_PORT_ERROR_IO_ERROR);
502 return G_SOURCE_REMOVE;
505 gboolean Proxy::OnIdle(gpointer user_data) {
506 auto* ptr = static_cast<std::weak_ptr<Proxy>*>(user_data);
507 auto proxy = ptr->lock();
508 if (proxy == nullptr) {
509 _E("Proxy is nullptr"); // LCOV_EXCL_LINE
510 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
513 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
514 if (proxy->idler_data_ == nullptr) {
515 _E("Invalid context. proxy(%p)", proxy.get()); // LCOV_EXCL_LINE
516 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
519 DestroyWeakPtr(proxy->idler_data_);
520 proxy->idler_data_ = nullptr;
522 if (proxy->file_monitor_->Exist()) {
523 proxy->OnFileCreated(proxy->port_path_);
525 proxy->OnFileDeleted(proxy->port_path_);
528 return G_SOURCE_REMOVE;
531 Proxy::ProxyPort::ProxyPort(Proxy* parent, int fd, const std::string& id,
533 : Port(fd, id), parent_(parent) {
537 Proxy::ProxyPort::~ProxyPort() {
538 if (disconn_source_ > 0)
539 g_source_remove(disconn_source_);
542 g_source_remove(source_);
544 if (channel_ != nullptr)
545 g_io_channel_unref(channel_);
548 int Proxy::ProxyPort::Watch(bool receive) {
549 channel_ = g_io_channel_unix_new(GetFd());
550 if (channel_ == nullptr) {
551 _E("g_io_channel_unix_new() is failed"); // LCOV_EXCL_LINE
552 return -1; // LCOV_EXCL_LINE
555 disconn_source_ = g_io_add_watch(channel_,
556 static_cast<GIOCondition>(G_IO_ERR | G_IO_HUP | G_IO_NVAL),
557 Proxy::ProxyPort::OnSocketDisconnected, parent_);
558 if (disconn_source_ == 0) {
559 _E("g_io_add_watch() is failed"); // LCOV_EXCL_LINE
560 return -1; // LCOV_EXCL_LINE
566 source_ = g_io_add_watch(channel_, static_cast<GIOCondition>(G_IO_IN),
567 Proxy::ProxyPort::OnDataReceived, parent_);
569 _E("g_io_add_watch() is failed"); // LCOV_EXCL_LINE
570 return -1; // LCOV_EXCL_LINE
576 void Proxy::ProxyPort::SetDisconnectedSource(guint source_id) {
577 disconn_source_ = source_id;
580 void Proxy::ProxyPort::SetSource(guint source_id) {
584 gboolean Proxy::ProxyPort::OnSocketDisconnected(GIOChannel* channel,
585 GIOCondition cond, gpointer user_data) {
586 auto* proxy = static_cast<Proxy*>(user_data);
587 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
588 auto* listener = proxy->listener_;
589 if (listener == nullptr) {
590 _E("Invalid context"); // LCOV_EXCL_LINE
591 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
594 int fd = g_io_channel_unix_get_fd(channel);
595 _W("Socket was disconnected. fd(%d)", fd);
596 if (proxy->main_port_.get() != nullptr &&
597 proxy->main_port_->GetFd() == fd) {
598 proxy->main_port_->SetDisconnectedSource(0);
599 } else if (proxy->delegate_port_.get() != nullptr &&
600 proxy->delegate_port_->GetFd() == fd) {
601 proxy->delegate_port_->SetDisconnectedSource(0);
604 proxy->main_port_.reset();
605 proxy->delegate_port_.reset();
606 proxy->listener_ = nullptr;
607 listener->OnDisconnected(proxy->target_appid_);
608 DebugPort::RemoveSession(fd);
609 return G_SOURCE_REMOVE;
612 gboolean Proxy::ProxyPort::OnDataReceived(GIOChannel* channel,
613 GIOCondition cond, gpointer user_data) {
614 auto* proxy = static_cast<Proxy*>(user_data);
615 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
616 auto* listener = proxy->listener_;
617 if (listener == nullptr) {
618 _E("Invalid context"); // LCOV_EXCL_LINE
619 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
622 int fd = g_io_channel_unix_get_fd(channel);
623 if (proxy->delegate_port_->GetFd() == fd) {
625 if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
626 _W("Socket was disconnected by stub. fd(%d)", fd);
627 proxy->listener_ = nullptr;
628 proxy->delegate_port_->SetSource(0);
629 if (proxy->main_port_.get() != nullptr) {
630 DebugPort::RemoveSession(proxy->main_port_->GetFd());
631 proxy->main_port_.reset();
633 proxy->delegate_port_.reset();
634 listener->OnDisconnected(proxy->target_appid_);
635 return G_SOURCE_REMOVE;
638 listener->OnReceived(proxy->target_appid_);
641 return G_SOURCE_CONTINUE;
644 Proxy::Client::Client(Proxy* parent) : parent_(parent) {
647 Proxy::Client::~Client() {
649 g_io_channel_unref(channel_);
651 if (disconn_source_ > 0)
652 g_source_remove(disconn_source_);
655 g_source_remove(source_);
658 Proxy::Client* Proxy::Client::Create(Proxy* parent,
659 const std::string& endpoint) {
660 std::unique_ptr<Proxy::Client> client;
662 client.reset(new (std::nothrow) Proxy::Client(parent));
663 } catch (const Exception& e) {
664 _E("Exception(%s) occurs", e.what()); // LCOV_EXCL_LINE
665 return nullptr; // LCOV_EXCL_LINE
671 ret = client->Connect(endpoint);
674 } else if (ret < 0) {
676 _D("Connect() is failed");
681 } while (retry_count > 0);
684 _E("Connect() is failed"); // LCOV_EXCL_LINE
685 return nullptr; // LCOV_EXCL_LINE
689 client->SetReceiveTimeout(5000);
690 } catch (const Exception& e) {
691 _E("Exception occurs. error(%s)", e.what()); // LCOV_EXCL_LINE
692 return nullptr; // LCOV_EXCL_LINE
695 _W("endpoint(%s), fd(%d)", endpoint.c_str(), client->GetFd());
696 return client.release();
699 int Proxy::Client::Watch() {
700 channel_ = g_io_channel_unix_new(GetFd());
701 if (channel_ == nullptr) {
702 _E("g_io_channel_unix_new() is failed"); // LCOV_EXCL_LINE
703 return -1; // LCOV_EXCL_LINE
706 source_ = g_io_add_watch(channel_, static_cast<GIOCondition>(G_IO_IN),
707 Proxy::Client::OnResponseReceived, parent_);
709 _E("g_io_add_watch() is failed"); // LCOV_EXCL_LINE
710 return -1; // LCOV_EXCL_LINE
713 disconn_source_ = g_io_add_watch(channel_,
714 static_cast<GIOCondition>(G_IO_ERR | G_IO_HUP | G_IO_NVAL),
715 Proxy::Client::OnSocketDisconnected, parent_);
716 if (disconn_source_ == 0) {
717 _E("g_io_add_watch() is failed"); // LCOV_EXCL_LINE
718 return -1; // LCOV_EXCL_LINE
725 void Proxy::Client::SetDisconnectedSource(guint source) {
726 disconn_source_ = source;
730 void Proxy::Client::SetSource(guint source) {
735 gboolean Proxy::Client::OnSocketDisconnected(GIOChannel* channel,
736 GIOCondition cond, gpointer user_data) {
737 auto* proxy = static_cast<Proxy*>(user_data);
738 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
739 proxy->UnsetConnTimer();
740 auto* listener = proxy->listener_;
741 if (listener == nullptr) {
742 _E("Invalid context");
743 return G_SOURCE_REMOVE;
746 int fd = g_io_channel_unix_get_fd(channel);
747 _W("Socket was disconnected. fd(%d)", fd);
748 if (proxy->main_client_.get() != nullptr &&
749 proxy->main_client_->GetFd() == fd) {
750 proxy->main_client_->SetDisconnectedSource(0);
751 } else if (proxy->delegate_client_.get() != nullptr &&
752 proxy->delegate_client_->GetFd() == fd) {
753 proxy->delegate_client_->SetDisconnectedSource(0);
756 proxy->main_client_.reset();
757 proxy->delegate_client_.reset();
758 proxy->listener_ = nullptr;
759 listener->OnDisconnected(proxy->target_appid_);
760 return G_SOURCE_REMOVE;
764 gboolean Proxy::Client::OnResponseReceived(GIOChannel* channel,
765 GIOCondition cond, gpointer user_data) {
766 auto* proxy = static_cast<Proxy*>(user_data);
767 std::lock_guard<std::recursive_mutex> lock(proxy->GetMutex());
768 proxy->UnsetConnTimer();
769 auto* listener = proxy->listener_;
770 if (listener == nullptr) {
771 _E("Invalid context"); // LCOV_EXCL_LINE
772 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
775 bool is_delegate = false;
776 std::unique_ptr<Client> client;
777 int fd = g_io_channel_unix_get_fd(channel);
778 if (proxy->main_client_.get() != nullptr &&
779 proxy->main_client_->GetFd() == fd) {
780 client.reset(proxy->main_client_.release());
781 } else if (proxy->delegate_client_.get() != nullptr &&
782 proxy->delegate_client_->GetFd() == fd) {
783 client.reset(proxy->delegate_client_.release());
787 if (client.get() == nullptr) {
788 _E("Unknown fd(%d)", fd); // LCOV_EXCL_LINE
789 return G_SOURCE_REMOVE; // LCOV_EXCL_LINE
792 client->SetSource(0);
794 Response* response = nullptr;
795 int ret = ReceiveResponse(client.get(), &response);
798 proxy->listener_ = nullptr;
799 proxy->main_client_.reset();
800 proxy->delegate_client_.reset();
801 listener->OnRejected(proxy->target_appid_, RPC_PORT_ERROR_IO_ERROR);
802 return G_SOURCE_REMOVE;
806 std::unique_ptr<Response> response_auto(response);
807 if (response->GetResult() != 0) {
808 _E("Permission denied");
809 proxy->listener_ = nullptr;
810 proxy->main_client_.reset();
811 proxy->delegate_client_.reset();
812 listener->OnRejected(proxy->target_appid_,
813 RPC_PORT_ERROR_PERMISSION_DENIED);
814 return G_SOURCE_REMOVE;
817 client->SetNonblock();
818 int client_fd = client->RemoveFd();
820 _W("[DELEGATE] Result received");
821 proxy->fds_[1] = client_fd;
822 proxy->delegate_port_.reset(
823 new ProxyPort(proxy, proxy->fds_[1], proxy->target_appid_));
825 _W("[MAIN] Result received");
826 proxy->fds_[0] = client_fd;
827 proxy->main_port_.reset(
828 new ProxyPort(proxy, proxy->fds_[0], proxy->target_appid_, false));
831 if (proxy->main_port_.get() != nullptr &&
832 proxy->delegate_port_.get() != nullptr) {
833 _W("target_appid(%s), port_name(%s), main_fd(%d), delegate_fd(%d)",
834 proxy->target_appid_.c_str(), proxy->port_name_.c_str(),
835 proxy->fds_[0], proxy->fds_[1]);
837 DebugPort::AddSession(proxy->port_name_, proxy->target_appid_,
838 proxy->fds_[0], proxy->fds_[1]);
839 listener->OnConnected(proxy->target_appid_, proxy->main_port_.get());
842 return G_SOURCE_REMOVE;
845 std::shared_ptr<Proxy> Proxy::GetSharedPtr() {
846 return shared_from_this();
849 gpointer Proxy::CreateWeakPtr() {
850 auto* ptr = new (std::nothrow) std::weak_ptr<Proxy>(GetSharedPtr());
851 return static_cast<gpointer>(ptr);
854 void Proxy::DestroyWeakPtr(gpointer data) {
855 auto* ptr = static_cast<std::weak_ptr<Proxy>*>(data);
859 bool Proxy::HasRequested() const {
860 return listener_ != nullptr &&
861 (!main_port_ || !delegate_port_ || main_port_->GetFd() > 0);
864 } // namespace internal
865 } // namespace rpc_port