60a2c93b27639487a2e36c6f585704e366c8ae7b
[platform/core/system/pass.git] / src / monitor / monitor.c
1 /*
2  * PASS (Power Aware System Service)
3  *
4  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <glib.h>
20
21 #include <util/device-notifier.h>
22 #include <util/log.h>
23 #include <util/devices.h>
24 #include <util/gdbus-util.h>
25 #include <monitor/monitor.h>
26
27 static struct monitor g_monitor;
28 static gboolean g_debug_mode;
29
30 static SystemPassMonitor *g_gdbus_instance;
31
32 struct monitor *monitor_get(void)
33 {
34         return &g_monitor;
35 }
36
37 gboolean monitor_get_debug_mode(void)
38 {
39         return g_debug_mode;
40 }
41
42 void monitor_set_debug_mode(gboolean on)
43 {
44         g_debug_mode = on;
45 }
46
47 static gboolean dbus_cb_monitor_set_debug(SystemPassMonitor *obj,
48                 GDBusMethodInvocation *invoc,
49                 gboolean on,
50                 gpointer user_data)
51 {
52         if (monitor_get_debug_mode() != on) {
53                 monitor_set_debug_mode(on);
54                 _I("PASS Resource Monitor debug mode is set to %s", on ? "on" : "off");
55         }
56
57         g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", 0));
58
59         return TRUE;
60 }
61
62 static struct gdbus_signal_info g_gdbus_signal_infos[] = {
63         {
64                 .handler = DBUS_MONITOR_I_SET_DEBUG_HANDLER,
65                 .cb = G_CALLBACK(dbus_cb_monitor_set_debug),
66                 .cb_data = NULL,
67                 .ret_id = 0,
68         },
69 };
70
71 static int monitor_setup(void *data, void *user_data)
72 {
73         int ret;
74
75         syscommon_resman_init_resource_drivers();
76
77         ret = request_server_init();
78         if (ret < 0) {
79                 _E("failed to initialize request server\n");
80                 return ret;
81         }
82
83         ret = monitor_thread_init(&g_monitor);
84         if (ret < 0) {
85                 _E("failed to initialize monitor thread\n");
86                 request_server_exit();
87                 return ret;
88         }
89
90         return 0;
91 }
92
93 static void monitor_init(void *data)
94 {
95         /* This is the case of daemon creation: DO NOTHING */
96 }
97
98 static void monitor_exit(void *data)
99 {
100         monitor_thread_exit(&g_monitor);
101         request_server_exit();
102         syscommon_resman_exit_resource_drivers();
103         unregister_notifier(DEVICE_NOTIFIER_INIT_DONE, monitor_setup, NULL);
104 }
105
106 static int monitor_probe(void *data)
107 {
108         int ret = 0;
109
110         g_gdbus_instance = gdbus_get_instance_monitor();
111         if (g_gdbus_instance == NULL) {
112                 _E("failed to get instance for the %s interface\n",
113                                 DBUS_MONITOR_INTERFACE);
114                 return -EINVAL;
115         }
116
117         ret = gdbus_connect_signal(g_gdbus_instance,
118                         ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos);
119         if (ret < 0) {
120                 _E("failed to register dbus methods\n");
121                 ret = -EINVAL;
122                 goto out;
123         }
124
125         ret = gdbus_export_interface(PASS_DBUS_CORE,
126                         g_gdbus_instance, DBUS_MONITOR_PATH);
127         if (ret < 0) {
128                 _E("cannot export the dbus interface '%s' at the object path '%s'\n",
129                                 DBUS_MONITOR_INTERFACE,
130                                 DBUS_MONITOR_PATH);
131                 ret = -EINVAL;
132                 goto out_disconnect;
133         }
134
135         /*
136          * Register a notifier for the booting-done event. The actual
137          * initialization of the daemon is performed by this notifier after
138          * booting is completely done.
139          */
140         ret = register_notifier(DEVICE_NOTIFIER_INIT_DONE,
141                         monitor_setup, NULL);
142         if (ret < 0) {
143                 _E("cannot register a callback function \
144                                 for the booting-done event (%d)\n", ret);
145                 goto out_disconnect;
146         }
147
148         return 0;
149
150 out_disconnect:
151         gdbus_disconnect_signal(g_gdbus_instance,
152                         ARRAY_SIZE(g_gdbus_signal_infos), g_gdbus_signal_infos);
153 out:
154         gdbus_put_instance_monitor(&g_gdbus_instance);
155
156         return ret;
157
158 }
159
160 static const struct device_ops monitor_device_ops = {
161         .name   = "monitor",
162         .probe  = monitor_probe,
163         .init   = monitor_init,
164         .exit   = monitor_exit,
165 };
166
167 DEVICE_OPS_REGISTER(&monitor_device_ops)