Separate benchmark tool from rpc-port
[platform/core/appfw/rpc-port.git] / benchmark / server / dbus / main.cc
1 /*
2  * Copyright (c) 2024 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <glib.h>
18 #include <gio/gio.h>
19
20 #include <string_view>
21 #include <string>
22
23 #include "log-private.hh"
24
25 namespace {
26
27 constexpr const char BUS_NAME[] = "tizen.appfw.rpcport.benchmark.dbus";
28 constexpr const char OBJECT_PATH[] = "/tizen/appfw/rpcport/benchmark/dbus";
29
30 constexpr const char INTROSPECTION_XML[] = R"__dbus(
31 <node>
32   <interface name='tizen.appfw.rpcport.benchmark.dbus'>
33     <method name='Test'>
34       <arg type='s' name='data' direction='in'/>
35       <arg type='i' name='ret' direction='out'/>
36     </method>
37     <method name='Start'>
38       <arg type='i' name='caller_pid' direction='in'/>
39       <arg type='i' name='ret' direction='out'/>
40     </method>
41     <method name='Stop'>
42       <arg type='i' name='caller_pid' direction='in'/>
43       <arg type='i' name='ret' direction='out'/>
44     </method>
45   </interface>
46 </node>
47 )__dbus";
48
49 class MainLoop {
50  public:
51   MainLoop() {
52     loop_ = g_main_loop_new(nullptr, FALSE);
53   }
54
55   ~MainLoop() {
56     g_main_loop_unref(loop_);
57     if (introspection_data_)
58       g_dbus_node_info_unref(introspection_data_);
59   }
60
61   int OnTest(std::string data) {
62     return 0;
63   }
64
65   void OnBusAcquired(GDBusConnection* connection, const gchar* name) {
66     _I("bus acquired(%s)", name);
67
68     static const GDBusInterfaceVTable interface_vtable = {
69       [](GDBusConnection *connection,
70           const gchar *sender, const gchar *object_path,
71           const gchar *interface_name, const gchar *method_name,
72           GVariant *parameters, GDBusMethodInvocation *invocation,
73           gpointer user_data) {
74         if (std::string_view(method_name) == "Test") {
75           char* data = nullptr;
76           g_variant_get(parameters, "(&s)", &data);
77           auto* obj = static_cast<MainLoop*>(user_data);
78           int ret = obj->OnTest(data);
79
80           GVariant* param = g_variant_new("(i)", ret);
81           g_dbus_method_invocation_return_value(invocation, param);
82         } else if (std::string_view(method_name) == "Stop") {
83           gint caller_pid = -1;
84           g_variant_get(parameters, "(i)", &caller_pid);
85           _D("Stop request received from caller(%d)", caller_pid);
86           auto* main_loop = static_cast<MainLoop*>(user_data);
87           int ret = main_loop->SetTermTimer();
88
89           GVariant* param = g_variant_new("(i)", ret);
90           g_dbus_method_invocation_return_value(invocation, param);
91         } else if (std::string_view(method_name) == "Start") {
92           gint caller_pid = -1;
93           g_variant_get(parameters, "(i)", &caller_pid);
94           _D("Start request received from caller(%d)", caller_pid);
95           auto* main_loop = static_cast<MainLoop*>(user_data);
96           int ret = main_loop->UnsetTermTimer();
97
98           GVariant* param = g_variant_new("(i)", ret);
99           g_dbus_method_invocation_return_value(invocation, param);
100         }
101       },
102       nullptr,
103       nullptr
104     };
105
106     GError* error = nullptr;
107     guint reg_id = g_dbus_connection_register_object(connection,
108         OBJECT_PATH,
109         introspection_data_->interfaces[0],
110         &interface_vtable,
111         this, nullptr, &error);
112     if (reg_id == 0) {
113       _E("g_dbus_connection_register_object error(%s)",
114           error ? error->message : "");
115       g_error_free(error);
116     }
117   }
118
119   void Run() {
120     GError* error = nullptr;
121     introspection_data_ = g_dbus_node_info_new_for_xml(INTROSPECTION_XML,
122         &error);
123     if (!introspection_data_) {
124       _E("g_dbus_node_info_new_for_xml error(%s)", error ? error->message : "");
125       g_error_free(error);
126       return;
127     }
128
129     guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
130         BUS_NAME,
131         G_BUS_NAME_OWNER_FLAGS_NONE,
132         [](GDBusConnection* connection, const gchar* name,
133             gpointer user_data) {
134           auto* obj = static_cast<MainLoop*>(user_data);
135           obj->OnBusAcquired(connection, name);
136         },
137         [](GDBusConnection* connection,
138             const gchar* name, gpointer user_data) {
139           _I("name acquired(%s)", name);
140         },
141         [](GDBusConnection* connection,
142             const gchar* name, gpointer user_data) {
143           _I("name lost(%s)", name);
144         },
145         this, nullptr);
146     if (!owner_id) {
147       _E("g_bus_own_name error");
148       g_dbus_node_info_unref(introspection_data_);
149       return;
150     }
151
152     g_main_loop_run(loop_);
153   }
154
155   void Quit() {
156     g_main_loop_quit(loop_);
157   }
158
159   int SetTermTimer() {
160     if (timer_) return 0;
161
162     timer_ = g_timeout_add(
163         5000, [](gpointer user_data) {
164           auto* main_loop = static_cast<MainLoop*>(user_data);
165           main_loop->Quit();
166           main_loop->timer_ = 0;
167           return G_SOURCE_REMOVE;
168         }, this);
169
170     return 0;
171   }
172
173   int UnsetTermTimer() {
174     if (timer_) {
175       g_source_remove(timer_);
176       timer_ = 0;
177     }
178
179     return 0;
180   }
181
182  private:
183   GMainLoop* loop_ = nullptr;
184   GDBusNodeInfo* introspection_data_ = nullptr;
185   guint timer_ = 0;
186 };
187
188 }  // namespace
189
190 int main(int argc, char** argv) {
191   MainLoop loop;
192   loop.Run();
193   return 0;
194 }