--- /dev/null
+/*
+ * Generated by tidlc 1.9.1.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <libgen.h>
+#include <dlog.h>
+
+#include "BenchmarkStub.h"
+
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "RPC_PORT_STUB"
+
+#ifdef _E
+#undef _E
+#endif
+
+#ifdef _W
+#undef _W
+#endif
+
+#ifdef _I
+#undef _I
+#endif
+
+#ifdef _D
+#undef _D
+#endif
+
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "1.9.1"
+#endif
+
+namespace rpc_port {
+namespace BenchmarkStub {
+
+namespace stub {
+
+Benchmark::ServiceBase::ServiceBase(std::string sender, std::string instance)
+ : sender_(std::move(sender)), instance_(std::move(instance)),
+ active_object_(new ActiveObject()) {}
+
+void Benchmark::ServiceBase::SetPort(rpc_port_h port) {
+ port_ = port;
+}
+
+void Benchmark::ServiceBase::Disconnect() {
+ int ret = rpc_port_disconnect(port_);
+ if (ret == RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect the port(%d)", ret);
+ return;
+ }
+
+ port_ = nullptr;
+}
+
+
+std::atomic<int> Benchmark::CallbackBase::seq_num_ { 0 };
+
+Benchmark::CallbackBase::CallbackBase(int delegate_id, bool once)
+ : id_(delegate_id), once_(once) {
+ seq_id_ = seq_num_++;
+}
+
+int Benchmark::CallbackBase::GetId() const {
+ return id_;
+}
+
+int Benchmark::CallbackBase::GetSeqId() const {
+ return seq_id_;
+}
+
+bool Benchmark::CallbackBase::IsOnce() const {
+ return once_;
+}
+
+std::string Benchmark::CallbackBase::GetTag() const {
+ return std::to_string(id_) + "::" + std::to_string(seq_id_);
+}
+
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const Benchmark::CallbackBase& cb) {
+ rpc_port_parcel_write_int32(h, cb.id_);
+ rpc_port_parcel_write_int32(h, cb.seq_id_);
+ rpc_port_parcel_write_bool(h, cb.once_);
+
+ return h;
+}
+
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, Benchmark::CallbackBase& cb) {
+ rpc_port_parcel_read_int32(h, &cb.id_);
+ rpc_port_parcel_read_int32(h, &cb.seq_id_);
+ rpc_port_parcel_read_bool(h, &cb.once_);
+
+ return h;
+}
+
+Benchmark::Benchmark() {
+ int r = rpc_port_stub_create(&stub_, "Benchmark");
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create stub handle");
+ throw InvalidIOException();
+ }
+ rpc_port_stub_add_connected_event_cb(stub_, OnConnectedCB, this);
+ rpc_port_stub_add_disconnected_event_cb(stub_, OnDisconnectedCB, this);
+ rpc_port_stub_add_received_event_cb(stub_, OnReceivedCB, this);
+}
+
+Benchmark::~Benchmark() {
+ for (auto& i : services_) {
+ i->OnTerminate();
+ }
+
+ if (stub_) {
+ rpc_port_stub_destroy(stub_);
+ }
+}
+
+void Benchmark::Listen(std::shared_ptr<Benchmark::ServiceBase::Factory> service_factory) {
+ service_factory_ = std::move(service_factory);
+ int r = rpc_port_stub_listen(stub_);
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to listen stub");
+ switch (r) {
+ case RPC_PORT_ERROR_INVALID_PARAMETER:
+ case RPC_PORT_ERROR_IO_ERROR:
+ throw InvalidIOException();
+ }
+ }
+}
+
+void Benchmark::OnConnectedCB(const char* sender, const char* instance, void* data) {
+ Benchmark* stub = static_cast<Benchmark*>(data);
+ auto s = stub->service_factory_->CreateService(sender, instance);
+
+ rpc_port_h port;
+ int ret = rpc_port_stub_get_port(stub->stub_, RPC_PORT_PORT_CALLBACK, instance, &port);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to get the port(%d)", ret);
+ return;
+ }
+
+ s->SetPort(port);
+ s->OnCreate();
+ stub->services_.emplace_back(std::move(s));
+}
+
+void Benchmark::OnDisconnectedCB(const char* sender, const char* instance, void *data) {
+ Benchmark* stub = static_cast<Benchmark*>(data);
+
+ for (auto& i : stub->services_) {
+ if (i->GetInstance() == instance) {
+ i->OnTerminate();
+ stub->services_.remove(i);
+ return;
+ }
+ }
+}
+
+int Benchmark::OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void *data)
+{
+ auto* cxt = static_cast<Benchmark*>(data);
+ rpc_port_parcel_h p;
+ rpc_port_parcel_h result;
+ rpc_port_parcel_h header;
+ int seq_num = -1;
+ int cmd;
+ int ret;
+ std::shared_ptr<ServiceBase> b;
+ rpc_port_h callback_port;
+
+ for (auto& i : cxt->services_) {
+ if (i->GetInstance() == instance) {
+ b = i;
+ break;
+ }
+ }
+
+ if (b.get() == nullptr) {
+ _E("Failed to find Benchmark context(%s)", instance);
+ return -1;
+ }
+
+ ret = rpc_port_stub_get_port(cxt->stub_, RPC_PORT_PORT_CALLBACK, instance,
+ &callback_port);
+ if (ret != 0) {
+ _E("Failed to get callback port");
+ }
+
+ ret = rpc_port_parcel_create_from_port(&p, port);
+ if (ret != 0) {
+ _E("Failed to create parcel from port");
+ return ret;
+ }
+
+ rpc_port_parcel_get_header(p, &header);
+ rpc_port_parcel_header_get_seq_num(header, &seq_num);
+ _W("[Sequence] %d", seq_num);
+
+ rpc_port_parcel_create(&result);
+ rpc_port_parcel_get_header(result, &header);
+ rpc_port_parcel_header_set_tag(header, TIDL_VERSION);
+ rpc_port_parcel_header_set_seq_num(header, seq_num);
+
+ rpc_port_parcel_read_int32(p, &cmd);
+
+ switch (cmd) {
+ case static_cast<int>(MethodId::Test): {
+ char* param1_raw = nullptr;
+ rpc_port_parcel_read_string(p, ¶m1_raw);
+ std::string param1(param1_raw);
+ free(param1_raw);
+ auto retVal = b->Test(param1);
+ rpc_port_parcel_write_int32(result, static_cast<int>(MethodId::__Result));
+ rpc_port_parcel_write_int32(result, retVal);
+ ret = rpc_port_parcel_send(result, port);
+ _I("Parcel send result(%d)", ret);
+ break;
+ }
+
+ default:
+ _E("Unknown command(%d)", cmd);
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+ return -1;
+ }
+
+ rpc_port_parcel_destroy(p);
+ rpc_port_parcel_destroy(result);
+
+ return ret;
+}
+
+} // namespace stub
+} // namespace BenchmarkStub
+} // namespace rpc_port
--- /dev/null
+/*
+ * Generated by tidlc 1.9.1.
+ */
+
+#pragma once
+
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <list>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+#include <deque>
+#include <thread>
+
+namespace rpc_port {
+namespace BenchmarkStub {
+
+class Bundle final {
+ public:
+ Bundle() {
+ raw_ = bundle_create();
+ }
+
+ Bundle(bundle* b) {
+ raw_ = b;
+ }
+
+ ~Bundle() {
+ if (raw_)
+ bundle_free(raw_);
+ }
+
+ Bundle(Bundle&& b) : raw_(b.raw_) {
+ b.raw_ = nullptr;
+ }
+
+ Bundle& operator = (Bundle&& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = b.raw_;
+ b.raw_ = nullptr;
+ }
+ return *this;
+ }
+
+ Bundle(const Bundle& b) : raw_(bundle_dup(b.GetHandle())) {}
+
+ Bundle& operator = (const Bundle& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = bundle_dup(b.GetHandle());
+ }
+ return *this;
+ }
+
+ bundle* GetHandle() const {
+ return raw_;
+ }
+
+ private:
+ bundle* raw_;
+};
+
+class File final {
+ public:
+ File() {
+ }
+
+ File(std::string filename) {
+ filename_ = filename;
+ }
+
+ std::string GetFileName() const {
+ return filename_;
+ }
+
+ private:
+ std::string filename_;
+};
+
+namespace stub {
+
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class InvalidCallbackException : public Exception {};
+class Job {
+ public:
+ class IEvent {
+ public:
+ virtual ~IEvent() = default;
+ virtual void Run() = 0;
+ };
+
+ Job() : handler_(nullptr) {
+ }
+
+ Job(IEvent* handler) : handler_(handler) {
+ }
+ virtual ~Job() = default;
+
+ Job(const Job& job) {
+ handler_ = job.handler_;
+ }
+
+ Job& operator = (const Job& job) {
+ if (this != &job)
+ handler_ = job.handler_;
+ return *this;
+ }
+ Job(Job&& job) noexcept {
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+ }
+
+ Job& operator = (Job&& job) noexcept {
+ if (this != &job) {
+ handler_ = job.handler_;
+ job.handler_ = nullptr;
+ }
+ return *this;
+ }
+
+ void Invoke() {
+ if (handler_)
+ handler_->Run();
+ }
+
+ private:
+ IEvent* handler_;
+};
+
+
+template <class T>
+class SharedQueue {
+ public:
+ SharedQueue() = default;
+ virtual ~SharedQueue() = default;
+
+ void Push(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_back(item);
+ cond_var_.notify_one();
+ }
+
+ void PushFront(T item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ queue_.push_front(item);
+ cond_var_.notify_one();
+ }
+
+ bool TryAndPop(T& item) {
+ std::lock_guard<std::mutex> lock(mutex_);
+ if (queue_.empty())
+ return false;
+
+ item = queue_.front();
+ queue_.pop_front();
+
+ return true;
+ }
+
+ void WaitAndPop(T& item) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ while (queue_.empty())
+ cond_var_.wait(lock);
+
+ item = queue_.front();
+ queue_.pop_front();
+ }
+
+ bool Empty() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.empty();
+ }
+
+ int Size() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ return queue_.size();
+ }
+
+ private:
+ std::deque<T> queue_;
+ mutable std::mutex mutex_;
+ std::condition_variable cond_var_;
+};
+
+class ActiveObject : public Job::IEvent {
+ public:
+ ActiveObject() {
+ thread_ = std::thread([&]{
+ do {
+ std::shared_ptr<Job> item;
+ queue_.WaitAndPop(item);
+ item->Invoke();
+ } while (!done_);
+ });
+ }
+ virtual ~ActiveObject() {
+ Quit();
+ thread_.join();
+ }
+
+ public:
+ void Send(std::shared_ptr<Job> job) {
+ queue_.Push(std::move(job));
+ }
+
+ private:
+ void Quit() {
+ Send(std::shared_ptr<Job>(new (std::nothrow) Job(this)));
+ }
+ void Run() override {
+ done_ = true;
+ }
+
+ private:
+ std::thread thread_;
+ bool done_ = false;
+ SharedQueue<std::shared_ptr<Job>> queue_;
+};
+
+
+class Benchmark final {
+ public:
+ class ServiceBase;
+
+ class CallbackBase {
+ public:
+ CallbackBase(int delegate_id, bool once);
+ virtual ~CallbackBase() = default;
+
+ int GetId() const;
+ int GetSeqId() const;
+ bool IsOnce() const;
+ std::string GetTag() const;
+
+ private:
+ friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);
+ friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);
+
+ static std::atomic<int> seq_num_;
+ int id_;
+ int seq_id_;
+ bool once_;
+ };
+
+ class ServiceBase {
+ public:
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+
+ /// <summary>
+ /// The method for making service instances
+ /// </summary>
+ /// <param name="sender">The client app ID</param>
+ /// <param name="instance">The client instance ID</param>
+ virtual std::unique_ptr<ServiceBase> CreateService(std::string sender, std::string instance) = 0;
+ };
+
+ virtual ~ServiceBase() = default;
+
+ /// <summary>
+ /// Gets client app ID
+ /// </summary>
+ const std::string& GetSender() const {
+ return sender_;
+ }
+
+ /// <summary>
+ /// Gets client instance ID
+ /// </summary>
+ const std::string& GetInstance() const {
+ return instance_;
+ }
+
+ /// <summary>
+ /// Sets the client app port
+ /// </summary>
+ /// <param name="port">The port of the client</param>
+ void SetPort(rpc_port_h port);
+
+ /// <summary>
+ /// Disconnects from the client app
+ /// </summary>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
+ /// This method will be called when the client is connected
+ /// </summary>
+ virtual void OnCreate() = 0;
+
+ /// <summary>
+ /// This method will be called when the client is disconnected
+ /// </summary>
+ virtual void OnTerminate() = 0;
+
+ void Dispatch(rpc_port_h port, rpc_port_h callback_port,
+ rpc_port_parcel_h parcel, std::shared_ptr<ServiceBase> service);
+
+ virtual int Test(std::string data) = 0;
+
+ protected:
+ ServiceBase(std::string sender, std::string instance);
+
+ private:
+ std::string sender_;
+ std::string instance_;
+ rpc_port_h port_ = nullptr;
+ std::unique_ptr<ActiveObject> active_object_;
+ };
+
+ Benchmark();
+ ~Benchmark();
+
+ /// <summary>
+ /// Listens to client apps
+ /// </summary>
+ /// <param name="service_factory">The factory object for making service instances</param>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ void Listen(std::shared_ptr<ServiceBase::Factory> service_factory);
+
+ /// <summary>
+ /// Gets service objects which are connected
+ /// </summary>
+ /// <returns>The list of service objects which are connected</returns>
+ const std::list<std::shared_ptr<ServiceBase>>& GetServices() const {
+ return services_;
+ }
+
+ private:
+ enum class MethodId : int {
+ __Result = 0,
+ __Callback = 1,
+ Test = 2,
+
+ };
+
+ enum class DelegateId : int {
+
+ };
+ static void OnConnectedCB(const char* sender, const char* instance, void* data);
+ static void OnDisconnectedCB(const char* sender, const char* instance, void* data);
+ static int OnReceivedCB(const char* sender, const char* instance, rpc_port_h port, void* data);
+
+ rpc_port_stub_h stub_ = nullptr;
+ std::shared_ptr<ServiceBase::Factory> service_factory_;
+ std::list<std::shared_ptr<ServiceBase>> services_;
+};
+} // namespace stub
+} // namespace BenchmarkStub
+} // namespace rpc_port
--- /dev/null
+/*
+ * Generated by tidlc 1.9.1.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <dlog.h>
+
+#include "BenchmarkProxy.h"
+
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "RPC_PORT_PROXY"
+
+#ifdef _E
+#undef _E
+#endif
+
+#ifdef _W
+#undef _W
+#endif
+
+#ifdef _I
+#undef _I
+#endif
+
+#ifdef _D
+#undef _D
+#endif
+
+#define _E(fmt, ...) dlog_print(DLOG_ERROR, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _W(fmt, ...) dlog_print(DLOG_WARN, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _I(fmt, ...) dlog_print(DLOG_INFO, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+#define _D(fmt, ...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s: %s(%d) > " fmt, basename(const_cast<char*>(__FILE__)), __FUNCTION__, __LINE__, ##__VA_ARGS__)
+
+#ifndef TIDL_VERSION
+#define TIDL_VERSION "1.9.1"
+#endif
+
+namespace rpc_port {
+namespace BenchmarkProxy {
+
+namespace proxy {
+
+
+std::atomic<int> Benchmark::CallbackBase::seq_num_ { 0 };
+
+Benchmark::CallbackBase::CallbackBase(int delegate_id, bool once)
+ : id_(delegate_id), once_(once) {
+ seq_id_ = seq_num_++;
+}
+
+int Benchmark::CallbackBase::GetId() const {
+ return id_;
+}
+
+int Benchmark::CallbackBase::GetSeqId() const {
+ return seq_id_;
+}
+
+bool Benchmark::CallbackBase::IsOnce() const {
+ return once_;
+}
+
+std::string Benchmark::CallbackBase::GetTag() const {
+ return std::to_string(id_) + "::" + std::to_string(seq_id_);
+}
+
+rpc_port_parcel_h operator << (rpc_port_parcel_h h, const Benchmark::CallbackBase& cb) {
+ rpc_port_parcel_write_int32(h, cb.id_);
+ rpc_port_parcel_write_int32(h, cb.seq_id_);
+ rpc_port_parcel_write_bool(h, cb.once_);
+
+ return h;
+}
+
+rpc_port_parcel_h operator >> (rpc_port_parcel_h h, Benchmark::CallbackBase& cb) {
+ rpc_port_parcel_read_int32(h, &cb.id_);
+ rpc_port_parcel_read_int32(h, &cb.seq_id_);
+ rpc_port_parcel_read_bool(h, &cb.once_);
+
+ return h;
+}
+
+Benchmark::Benchmark(IEventListener* listener, const std::string& target_appid)
+ : port_(nullptr), callback_port_(nullptr), proxy_(nullptr),
+ listener_(listener), target_appid_(target_appid) {
+ int r = rpc_port_proxy_create(&proxy_);
+
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to create proxy");
+ throw InvalidIOException();
+ }
+
+ rpc_port_proxy_add_connected_event_cb(proxy_, OnConnectedCB, this);
+ rpc_port_proxy_add_disconnected_event_cb(proxy_, OnDisconnectedCB, this);
+ rpc_port_proxy_add_rejected_event_cb(proxy_, OnRejectedCB, this);
+ rpc_port_proxy_add_received_event_cb(proxy_, OnReceivedCB, this);
+}
+
+Benchmark::~Benchmark() {
+ if (proxy_)
+ rpc_port_proxy_destroy(proxy_);
+}
+
+void Benchmark::Connect(bool sync) {
+ int ret;
+ if (sync)
+ ret = rpc_port_proxy_connect_sync(proxy_, target_appid_.c_str(), "Benchmark");
+ else
+ ret = rpc_port_proxy_connect(proxy_, target_appid_.c_str(), "Benchmark");
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to connect Benchmark");
+ switch (ret) {
+ case RPC_PORT_ERROR_INVALID_PARAMETER:
+ throw InvalidIDException();
+
+ case RPC_PORT_ERROR_IO_ERROR:
+ throw InvalidIOException();
+
+ case RPC_PORT_ERROR_PERMISSION_DENIED:
+ throw PermissionDeniedException();
+ }
+ }
+}
+
+void Benchmark::Disconnect() {
+ int ret = rpc_port_disconnect(port_);
+ if (ret != RPC_PORT_ERROR_NONE) {
+ _E("Failed to disconnect Benchmark");
+ throw InvalidIDException();
+ }
+}
+
+void Benchmark::DisposeCallback(const std::string& tag) {
+ for (auto& i : delegate_list_) {
+ if (i->GetTag() == tag) {
+ delegate_list_.remove(i);
+ return;
+ }
+ }
+}
+
+void Benchmark::ProcessReceivedEvent(rpc_port_parcel_h parcel) {
+ int id = 0;
+ int seq_id = 0;
+ bool once = false;
+
+ rpc_port_parcel_read_int32(parcel, &id);
+ rpc_port_parcel_read_int32(parcel, &seq_id);
+ rpc_port_parcel_read_bool(parcel, &once);
+
+ for (auto& i : delegate_list_) {
+ if (i->GetId() == id && i->GetSeqId() == seq_id) {
+ i->OnReceivedEvent(parcel);
+ if (i->IsOnce())
+ delegate_list_.remove(i);
+ break;
+ }
+ }
+}
+
+void Benchmark::ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port) {
+ do {
+ rpc_port_parcel_h p;
+ int ret = rpc_port_parcel_create_from_port(&p, port);
+ int cmd;
+
+ if (ret != 0)
+ break;
+ rpc_port_parcel_read_int32(p, &cmd);
+ if (cmd == static_cast<int>(MethodId::__Result)) {
+ *parcel = p;
+ return;
+ }
+
+ rpc_port_parcel_destroy(p);
+ *parcel = nullptr;
+ } while (true);
+ *parcel = nullptr;
+}
+
+void Benchmark::OnConnectedCB(const char *ep, const char *port_name, rpc_port_h port, void *data) {
+ Benchmark* l = static_cast<Benchmark*>(data);
+ rpc_port_h cb_port;
+
+ l->port_ = port;
+ rpc_port_proxy_get_port(l->proxy_, RPC_PORT_PORT_CALLBACK, &cb_port);
+ l->callback_port_ = cb_port;
+ l->listener_->OnConnected();
+}
+
+void Benchmark::OnDisconnectedCB(const char *ep, const char *port_name, void *data) {
+ Benchmark* l = static_cast<Benchmark*>(data);
+ l->delegate_list_.clear();
+ l->listener_->OnDisconnected();
+}
+
+void Benchmark::OnRejectedCB(const char *ep, const char *port_name, void *data) {
+ Benchmark* l = static_cast<Benchmark*>(data);
+ l->listener_->OnRejected();
+}
+
+void Benchmark::OnReceivedCB(const char *ep, const char *port_name, void *data) {
+ Benchmark* l = static_cast<Benchmark*>(data);
+ int cmd;
+ rpc_port_parcel_h parcel_received;
+
+ if (rpc_port_parcel_create_from_port(&parcel_received, l->callback_port_) != 0) {
+ _E("Failed to create parcel from port");
+ return;
+ }
+
+ rpc_port_parcel_read_int32(parcel_received, &cmd);
+ if (cmd != static_cast<int>(MethodId::__Callback)) {
+ rpc_port_parcel_destroy(parcel_received);
+ return;
+ }
+
+ l->ProcessReceivedEvent(parcel_received);
+ rpc_port_parcel_destroy(parcel_received);
+}
+
+
+int Benchmark::Test(std::string data) {
+ if (port_ == nullptr) {
+ _E("Not connected");
+ throw NotConnectedSocketException();
+ }
+
+ rpc_port_parcel_h p;
+ rpc_port_parcel_create(&p);
+
+ rpc_port_parcel_header_h header_;
+ rpc_port_parcel_get_header(p, &header_);
+ rpc_port_parcel_header_set_tag(header_, TIDL_VERSION);
+ int seq_num_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_);
+ _W("[Version] \"%s\", [Sequence] %d", TIDL_VERSION, seq_num_);
+ rpc_port_parcel_write_int32(p, static_cast<int>(MethodId::Test));
+ rpc_port_parcel_write_string(p, data.c_str());
+
+ std::lock_guard<std::recursive_mutex> lock(mutex_);
+
+ // Send
+ int r = rpc_port_parcel_send(p, port_);
+ if (r != RPC_PORT_ERROR_NONE) {
+ _E("Failed to send parcel. result(%d)", r);
+ rpc_port_parcel_destroy(p);
+ throw InvalidIOException();
+ }
+
+ int ret;
+ bool done_ = false;
+ do {
+ rpc_port_parcel_h parcel_received = nullptr;
+ // Receive
+ ConsumeCommand(&parcel_received, port_);
+ if (parcel_received == nullptr) {
+ _E("Invalid protocol");
+ throw InvalidProtocolException();
+ }
+
+ rpc_port_parcel_get_header(parcel_received, &header_);
+ char* tag_ = nullptr;
+ rpc_port_parcel_header_get_tag(header_, &tag_);
+ std::unique_ptr<char, decltype(std::free)*> tag_auto_(tag_, std::free);
+ if (tag_ && tag_[0] != '\0') {
+ _W("[Version] %s", tag_);
+ int seq_num_received_ = -1;
+ rpc_port_parcel_header_get_seq_num(header_, &seq_num_received_);
+ if (seq_num_received_ != seq_num_) {
+ _E("Invalid protocol. %d", seq_num_received_);
+ rpc_port_parcel_destroy(parcel_received);
+ continue;
+ }
+ }
+ done_ = true;
+
+ rpc_port_parcel_read_int32(parcel_received, &ret);
+
+ rpc_port_parcel_destroy(parcel_received);
+ } while (!done_);
+
+ rpc_port_parcel_destroy(p);
+
+ return ret;
+
+}
+} // namespace proxy
+} // namespace BenchmarkProxy
+} // namespace rpc_port
--- /dev/null
+/*
+ * Generated by tidlc 1.9.1.
+ */
+
+#pragma once
+
+#include <bundle.h>
+#include <rpc-port-parcel.h>
+#include <rpc-port.h>
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <mutex>
+#include <list>
+#include <atomic>
+
+namespace rpc_port {
+namespace BenchmarkProxy {
+class Bundle final {
+ public:
+ Bundle() {
+ raw_ = bundle_create();
+ }
+
+ Bundle(bundle* b) {
+ raw_ = b;
+ }
+
+ ~Bundle() {
+ if (raw_)
+ bundle_free(raw_);
+ }
+
+ Bundle(Bundle&& b) : raw_(b.raw_) {
+ b.raw_ = nullptr;
+ }
+
+ Bundle& operator = (Bundle&& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = b.raw_;
+ b.raw_ = nullptr;
+ }
+ return *this;
+ }
+
+ Bundle(const Bundle& b) : raw_(bundle_dup(b.GetHandle())) {}
+
+ Bundle& operator = (const Bundle& b) {
+ if (this != &b) {
+ if (raw_)
+ bundle_free(raw_);
+
+ raw_ = bundle_dup(b.GetHandle());
+ }
+ return *this;
+ }
+
+ bundle* GetHandle() const {
+ return raw_;
+ }
+
+ private:
+ bundle* raw_;
+};
+
+class File final {
+ public:
+ File() {
+ }
+
+ File(std::string filename) {
+ filename_ = filename;
+ }
+
+ std::string GetFileName() const {
+ return filename_;
+ }
+
+ private:
+ std::string filename_;
+};
+
+
+namespace proxy {
+
+class Exception {};
+class NotConnectedSocketException : public Exception {};
+class InvalidProtocolException : public Exception {};
+class InvalidIOException : public Exception {};
+class PermissionDeniedException : public Exception {};
+class InvalidIDException : public Exception {};
+
+class Benchmark {
+ public:
+
+ class CallbackBase {
+ public:
+ CallbackBase(int delegate_id, bool once);
+ virtual ~CallbackBase() = default;
+ virtual void OnReceivedEvent(rpc_port_parcel_h port) = 0;
+ int GetId() const;
+ int GetSeqId() const;
+ bool IsOnce() const;
+ std::string GetTag() const;
+
+ private:
+ friend rpc_port_parcel_h operator << (rpc_port_parcel_h h, const CallbackBase& cb);
+ friend rpc_port_parcel_h operator >> (rpc_port_parcel_h h, CallbackBase& cb);
+
+ static std::atomic<int> seq_num_;
+ int id_;
+ int seq_id_;
+ bool once_;
+ };
+
+ class IEventListener {
+ public:
+ /// <summary>
+ /// This method will be invoked when the client app is connected to the servicece app.
+ /// </summary>
+ virtual void OnConnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked after the client app was disconnected from the servicece app.
+ /// </summary>
+ virtual void OnDisconnected() = 0;
+
+ /// <summary>
+ /// This method will be invoked when the service app rejects the client app.
+ /// </summary>
+ virtual void OnRejected() = 0;
+ };
+
+ /// <summary>
+ /// Constructor for this class
+ /// </summary>
+ /// <param name="listener">The listener for events</param>
+ /// <param name="target_appid">The service app ID to connect</param>
+ Benchmark(IEventListener* listener, const std::string& target_appid);
+
+ /// <summary>
+ /// Destructor for this class
+ /// </summary>
+ virtual ~Benchmark();
+
+ /// <summary>
+ /// Connects to the service app.
+ /// </summary>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <privilege>http://tizen.org/privilege/datasharing</privilege>
+ // <param name="sync">if true, connects to the service app synchornously</param>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the appid to connect is invalid.
+ /// </exception>
+ /// <exception cref="InvalidIOException">
+ /// Thrown when internal I/O error happen.
+ /// </exception>
+ /// <exception cref="PermissionDeniedException">
+ /// Thrown when the permission is denied.
+ /// </exception>
+ /// <remark> If you want to use this method, you must add privileges.</remark>
+ void Connect(bool sync = false);
+
+ /// <summary>
+ /// Disconnects from the service app.
+ /// </summary>
+ /// <exception cref="InvalidIDException">
+ /// Thrown when the stub port is invalid.
+ /// </exception>
+ void Disconnect();
+
+ /// <summary>
+ /// Disposes delegate objects in this interface
+ /// </summary>
+ /// <param name="tag">The tag string from delegate object</param>
+ void DisposeCallback(const std::string& tag);
+
+ int Test(std::string data);
+
+ private:
+ enum class MethodId : int {
+ __Result = 0,
+ __Callback = 1,
+ Test = 2,
+
+ };
+
+ enum class DelegateId : int {
+
+ };
+ void ProcessReceivedEvent(rpc_port_parcel_h parcel);
+ void ConsumeCommand(rpc_port_parcel_h* parcel, rpc_port_h port);
+
+ static void OnConnectedCB(const char *ep, const char *port_name,
+ rpc_port_h port, void *data);
+ static void OnDisconnectedCB(const char *ep, const char *port_name,
+ void *data);
+ static void OnRejectedCB(const char *ep, const char *port_name, void *data);
+ static void OnReceivedCB(const char *ep, const char *port_name, void *data);
+
+ rpc_port_h port_;
+ rpc_port_h callback_port_;
+ rpc_port_proxy_h proxy_;
+ IEventListener* listener_;
+ std::recursive_mutex mutex_;
+ std::list<std::unique_ptr<CallbackBase>> delegate_list_;
+ std::string target_appid_;
+};
+} // namespace proxy
+} // namespace BenchmarkProxy
+} // namespace rpc_port
BuildRequires: pkgconfig(pkgmgr)
BuildRequires: pkgconfig(pkgmgr-info)
BuildRequires: pkgconfig(uuid)
-BuildRequires: tidl
%if 0%{?gcov:1}
BuildRequires: lcov
%setup -q
cp %{SOURCE1001} .
-tidlc -p -l C++ -i ./benchmark/tidl/test.tidl -o BenchmarkProxy
-mv ./BenchmarkProxy.* ./benchmark/tool/
-tidlc -s -l C++ -i ./benchmark/tidl/test.tidl -o BenchmarkStub
-mv ./BenchmarkStub.* ./benchmark/server/
-
%build
%if 0%{?gcov:1}
export CFLAGS+=" -fprofile-arcs -ftest-coverage"