27e8d7b2f28f5e2cd7a6c765237e2a5e2684712d
[platform/core/multimedia/mm-resource-manager.git] / src / daemon / mm_resource_manager_daemon_dbus.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
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 "daemon/mm_resource_manager_daemon_dbus.h"
18 #include "common/mm_resource_manager_dbus.h"
19 #include "daemon/mm_resource_manager_daemon_priv.h"
20 #include "common/mm_resource_manager_utils.h"
21 #include "daemon/mm_resource_manager_daemon_conf.h"
22
23
24
25 static MMResourceManager *interface;
26
27 extern int notify_fd[2];
28
29 static void __gv2c_array(GVariantIter *gv, mm_resource_manager_dmn_res_request_s **c);
30 static gboolean on_get_conf(MMResourceManager *interface,
31                 GDBusMethodInvocation *invocation, gpointer user_data);
32 static gboolean on_create_handle(MMResourceManager *interface,
33                 GDBusMethodInvocation *invocation, const gint app_class,
34                 gpointer user_data);
35 static gboolean on_destroy_handle(MMResourceManager *interface,
36                 GDBusMethodInvocation *invocation, const guint64 id, gpointer user_data);
37 static gboolean on_commit_handle(MMResourceManager *interface,
38                 GDBusMethodInvocation *invocation, const guint64 id,
39                 GVariant *release, GVariant *acquire, gpointer user_data);
40 static void on_bus_acquired(GDBusConnection *connection, const gchar *name,
41                 gpointer user_data);
42
43
44
45 int _mmrm_dmn_dbus_init()
46 {
47         interface = mmresource_manager_skeleton_new();
48         MM_RM_RETVM_IF(interface == NULL,
49                         MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION,
50                         "Interface cannot be created");
51         g_bus_own_name(G_BUS_TYPE_SYSTEM, RMD_GDBUS_NAME,
52                         G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, NULL, NULL, NULL,
53                         NULL);
54         return MM_RESOURCE_MANAGER_ERROR_NONE;
55 }
56
57 int _mmrm_dmn_dbus_deinit()
58 {
59         MM_RM_RETVM_IF(interface == NULL,
60                         MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Interface is NULL");
61         g_object_unref(interface);
62         interface = NULL;
63         return MM_RESOURCE_MANAGER_ERROR_NONE;
64 }
65
66 int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume,
67                 mm_resource_manager_condition_volume_a **cond_volume)
68 {
69         mm_resource_manager_conf_s *conf;
70
71         conf = mm_resource_manager_get_conf();
72
73         MM_RM_RETVM_IF(conf == NULL,
74                         MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION,
75                         "mm_resource_manager_conf is NULL");
76
77         *max_volume = conf->max_volume;
78         *cond_volume = &conf->condition_volume;
79
80         return MM_RESOURCE_MANAGER_ERROR_NONE;
81 }
82
83 int _mmrm_dmn_dbus_create(mm_resource_manager_app_class_e app_class,
84                 mm_resource_manager_id *id)
85 {
86         return _mmrm_dmn_create(app_class, id);
87 }
88
89 int _mmrm_dmn_dbus_destroy(mm_resource_manager_id id)
90 {
91         return _mmrm_dmn_destroy(id);
92 }
93
94 int _mmrm_dmn_dbus_commit(mm_resource_manager_id id, GVariantIter *release,
95                 GVariantIter *acquire, gboolean **priority_error)
96 {
97         int i;
98         int ret;
99         mm_resource_manager_dmn_res_request_s *release_requests = NULL,
100                         *acquire_requests = NULL;
101
102         MM_RM_DEBUG("Commit release request of %"G_GSIZE_FORMAT" items",
103                         g_variant_iter_n_children(release));
104         __gv2c_array(release, &release_requests);
105
106         MM_RM_DEBUG("Commit acquire request of %"G_GSIZE_FORMAT" items",
107                         g_variant_iter_n_children(acquire));
108         __gv2c_array(acquire, &acquire_requests);
109
110         *priority_error = (gboolean *) g_malloc0_n(
111                         g_variant_iter_n_children(acquire), sizeof(**priority_error));
112
113         ret = _mmrm_dmn_commit(id, release_requests, acquire_requests);
114
115         for (i = 0; acquire_requests[i].type != MM_RESOURCE_MANAGER_NO_RES; i++)
116                 (*priority_error)[i] = acquire_requests[i].priority_error;
117
118         g_free(release_requests);
119         g_free(acquire_requests);
120
121         return ret;
122 }
123
124 int _mmrm_dmn_dbus_release_callback(mm_resource_manager_id id,
125                 mm_resource_manager_res_type_e type,
126                 mm_resource_manager_res_volume volume)
127 {
128         mmresource_manager_emit_release_callback(interface, id, type, volume);
129         return MM_RESOURCE_MANAGER_ERROR_NONE;
130 }
131
132 int _mmrm_dmn_dbus_status_callback(mm_resource_manager_status_e status)
133 {
134         MM_RM_DEBUG("Emitting %d status", status);
135         mmresource_manager_emit_status_callback(interface, status);
136         return MM_RESOURCE_MANAGER_ERROR_NONE;
137 }
138
139 void _mmrm_dmn_notify_fork_done(void)
140 {
141         /* Send "string" through the output side of pipe */
142         MM_RM_RETM_IF(write(notify_fd[1], MSG_DONE, strlen(MSG_DONE) + 1) < 0,
143                 "Failed to notify parent process that child initialization is done");
144
145         MM_RM_DEBUG("[%d] Notify parent process that child initialization is done", notify_fd[1]);
146         close(notify_fd[0]);
147         close(notify_fd[1]);
148 }
149
150 static void __gv2c_array(GVariantIter *gv, mm_resource_manager_dmn_res_request_s **c)
151 {
152         int i;
153         mm_resource_manager_dmn_res_request_s *rs;
154
155         rs = (mm_resource_manager_dmn_res_request_s *)
156                         g_malloc0_n(g_variant_iter_n_children(gv), sizeof(*rs));
157         for (i = 0; g_variant_iter_next(gv, "(ii)", &rs[i].type, &rs[i].volume); i++)
158                 MM_RM_DEBUG("(type,vol) = (%d,%d)", rs[i].type, rs[i].volume);
159
160         *c = rs;
161 }
162
163 static gboolean on_get_conf(MMResourceManager *interface,
164                 GDBusMethodInvocation *invocation, gpointer user_data)
165 {
166         int i, j;
167         gint error = 0;
168         mm_resource_manager_res_volume *max_volume = NULL;
169         mm_resource_manager_condition_volume_a *cond_volume = NULL;
170         GVariantBuilder *res_type_builder;
171         GVariantBuilder *res_cond_builder;
172         GVariant *res_type_conf;
173         GVariant *res_cond_conf;
174
175         error = _mmrm_dmn_dbus_get_conf(&max_volume, &cond_volume);
176
177         res_type_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
178         for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++)
179                 g_variant_builder_add_value(res_type_builder, g_variant_new("i", max_volume[i]));
180
181         res_type_conf = g_variant_builder_end(res_type_builder);
182         g_variant_builder_unref(res_type_builder);
183
184         res_type_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
185         for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
186                 res_cond_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
187                 for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++)
188                         g_variant_builder_add_value(res_cond_builder, g_variant_new("i", cond_volume[i][j]));
189
190                 g_variant_builder_add_value(res_type_builder, g_variant_builder_end(res_cond_builder));
191                 g_variant_builder_unref(res_cond_builder);
192         }
193         res_cond_conf = g_variant_builder_end(res_type_builder);
194         g_variant_builder_unref(res_type_builder);
195
196         mmresource_manager_complete_conf(interface, invocation, error, res_type_conf, res_cond_conf);
197
198         return TRUE;
199 }
200
201 static gboolean on_create_handle(MMResourceManager *interface,
202                 GDBusMethodInvocation *invocation, const gint app_class,
203                 gpointer user_data)
204 {
205         guint64 id = 0;
206         gint error = 0;
207
208         error = _mmrm_dmn_dbus_create(app_class, &id);
209
210         MM_RM_DEBUG("Receive create message for RM");
211
212         mmresource_manager_complete_create(interface, invocation, id, error);
213
214         return TRUE;
215 }
216
217 static gboolean on_destroy_handle(MMResourceManager *interface,
218                 GDBusMethodInvocation *invocation, const guint64 id, gpointer user_data)
219 {
220         gint error = 0;
221
222         MM_RM_DEBUG("Receive destroy message for RM");
223         error = _mmrm_dmn_dbus_destroy(id);
224
225         mmresource_manager_complete_destroy(interface, invocation, error);
226         return TRUE;
227 }
228
229 static gboolean on_commit_handle(MMResourceManager *interface,
230                 GDBusMethodInvocation *invocation, const guint64 id,
231                 GVariant *release, GVariant *acquire, gpointer user_data)
232 {
233         gint error = 0;
234         gboolean *flags;
235         GVariantBuilder *flags_builder;
236         GVariant *not_acquired_flags;
237         GVariantIter *release_array;
238         GVariantIter *acquire_array;
239         gsize acquire_len;
240         gint i;
241
242         MM_RM_DEBUG("Receive commit message");
243
244         release_array = g_variant_iter_new(release);
245         acquire_array = g_variant_iter_new(acquire);
246         acquire_len = g_variant_iter_n_children(acquire_array);
247
248         error = _mmrm_dmn_dbus_commit(id, release_array, acquire_array, &flags);
249
250         flags_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
251         for (i = 0; i < acquire_len; i++)
252                 g_variant_builder_add_value(flags_builder, g_variant_new("b", flags[i]));
253         not_acquired_flags = g_variant_builder_end(flags_builder);
254         mmresource_manager_complete_commit(interface, invocation, error, not_acquired_flags);
255
256         g_free(flags);
257         g_variant_builder_unref(flags_builder);
258         g_variant_iter_free(release_array);
259         g_variant_iter_free(acquire_array);
260
261         return TRUE;
262 }
263
264 static void on_bus_acquired(GDBusConnection *connection, const gchar *name,
265                 gpointer user_data)
266 {
267         GError* error = NULL;
268         MM_RM_DEBUG("name of bus = %s, userID = %d", name, getuid());
269
270         g_signal_connect(interface, "handle-conf", G_CALLBACK(on_get_conf), NULL);
271         g_signal_connect(interface, "handle-create", G_CALLBACK(on_create_handle), NULL);
272         g_signal_connect(interface, "handle-destroy", G_CALLBACK(on_destroy_handle), NULL);
273         g_signal_connect(interface, "handle-commit", G_CALLBACK(on_commit_handle), NULL);
274
275         if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(interface),
276                         connection, RMD_GDBUS_PATH, &error)) {
277                 MM_RM_ERROR("failed to export interface. msg : %s", error->message);
278                 g_error_free(error);
279         }
280 }