4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: YoungHun Kim <yh8004.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "muse_server_private.h"
24 #include <system_info.h>
25 #include <runtime_info.h>
27 #define MUSE_STORAGE_EXTERNAL_FEATURE "http://tizen.org/feature/storage.external"
29 enum muse_poweroff_type {
30 MUSE_POWER_OFF_NONE = 0,
32 MUSE_POWER_OFF_DIRECT,
33 MUSE_POWER_OFF_RESTART,
36 #ifdef MUSE_USE_POWER_OFF_STATE_CHANGE
37 static int _ms_system_subscribe_poweroff_state_change(ms_system_t *system);
38 static void _ms_system_unsubscribe_poweroff_state_change(void);
39 static void _ms_poweroff_state_changed_cb(GDBusConnection *con, const gchar *sender_name, const gchar *object_path,
40 const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data);
43 #ifdef MUSE_USE_EXTERNAL_STORAGE_STATE_CHANGE
44 static int _ms_system_subscribe_external_storage_state_change(ms_system_t *system);
45 static void _ms_system_unsubscribe_external_storage_state_change(void);
46 static void _ms_external_storage_state_changed_cb(int storage_id, storage_dev_e dev, storage_state_e state, const char *fstype,
47 const char *fsuuid, const char *mount_path, bool primary, int flags, void *user_data);
50 #ifdef MUSE_USE_RM_READY
51 static int _ms_system_subscribe_resource_manager_state_change(ms_system_t *system);
52 static void _ms_system_unsubscribe_resource_manager_state_change(void);
53 static void _ms_resource_manager_owner_name_changed_cb(GDBusConnection *con, const gchar *sender_name, const gchar *object_path,
54 const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data);
57 #ifdef MUSE_USE_POWER_OFF_STATE_CHANGE
58 static int _ms_system_subscribe_poweroff_state_change(ms_system_t *system)
62 muse_return_val_if_fail(system, MM_ERROR_INVALID_ARGUMENT);
64 muse_return_val_if_fail(system->connection, MM_ERROR_UNKNOWN);
66 system->muse_poweroff_id = g_dbus_connection_signal_subscribe(system->connection, NULL,
67 MS_POWER_DBUS_INTERFACE, MS_POWER_DBUS_MSG, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
68 _ms_poweroff_state_changed_cb, NULL, NULL);
75 static void _ms_system_unsubscribe_poweroff_state_change(void)
77 ms_system_t *system = NULL;
79 muse_return_if_fail(ms_get_instance());
81 system = ms_get_instance()->system;
82 muse_return_if_fail(system);
83 muse_return_if_fail(system->connection);
85 g_dbus_connection_signal_unsubscribe(system->connection, system->muse_poweroff_id);
88 static void _ms_poweroff_state_changed_cb(GDBusConnection *con, const gchar *sender_name, const gchar *object_path,
89 const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data)
93 ms_cmd_dispatcher_info_t dispatch;
94 ms_system_t *system = NULL;
95 ms_connection_t *connection = NULL;
97 LOGE("received power off signal");
99 muse_return_if_fail(ms_get_instance());
100 muse_return_if_fail(object_path);
101 muse_return_if_fail(signal_name);
102 muse_return_if_fail(parameters);
104 system = ms_get_instance()->system;
105 muse_return_if_fail(system);
107 connection = ms_get_instance()->connection;
108 muse_return_if_fail(connection);
110 if (g_strcmp0(object_path, MS_POWER_DBUS_PATH) || g_strcmp0(signal_name, MS_POWER_DBUS_MSG)) {
111 LOGE("object_path : %s signal_name : %s", object_path, signal_name);
115 g_variant_get(parameters, "(i)", &val_int);
117 LOGE("POWER OFF TYPE = %d", val_int);
119 /* muse has to restart when MUSE_POWER_OFF_DIRECT and MUSE_POWER_OFF_RESTART */
120 muse_return_if_fail(val_int > MUSE_POWER_OFF_POPUP);
122 _ms_system_unsubscribe_poweroff_state_change();
124 g_mutex_lock(&system->lock);
126 ms_connection_lock(connection);
128 queue = connection->instance_queue;
130 dispatch.cmd = MUSE_MODULE_COMMAND_SHUTDOWN;
132 g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
134 ms_connection_unlock(connection);
136 g_mutex_unlock(&system->lock);
142 #ifdef MUSE_USE_EXTERNAL_STORAGE_STATE_CHANGE
143 static int _ms_system_subscribe_external_storage_state_change(ms_system_t *system)
147 int ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, _ms_external_storage_state_changed_cb, system);
149 if (ret != STORAGE_ERROR_NONE) {
150 LOGE("[0x%x] failed to register storage changed callback", ret);
156 return MM_ERROR_NONE;
159 static void _ms_system_unsubscribe_external_storage_state_change(void)
161 int ret = storage_unset_changed_cb(STORAGE_TYPE_EXTERNAL, _ms_external_storage_state_changed_cb);
162 if (ret != STORAGE_ERROR_NONE)
163 LOGE("[0x%x] failed to unregister storage changed callback", ret);
166 static void _ms_external_storage_state_changed_cb(int storage_id, storage_dev_e dev, storage_state_e state, const char *fstype,
167 const char *fsuuid, const char *mount_path, bool primary, int flags, void *user_data)
170 ms_cmd_dispatcher_info_t dispatch;
171 ms_system_t *system = (ms_system_t *)user_data;
172 ms_connection_t *connection = NULL;
174 muse_return_if_fail(system);
175 muse_return_if_fail(ms_get_instance());
177 connection = ms_get_instance()->connection;
178 muse_return_if_fail(connection);
181 case STORAGE_STATE_UNMOUNTABLE:
182 LOGI("[%d] [%s] STORAGE_STATE_UNMOUNTABLE", state, mount_path);
184 case STORAGE_STATE_REMOVED:
185 LOGI("[%d] [%s] STORAGE_STATE_REMOVED", state, mount_path);
187 case STORAGE_STATE_MOUNTED:
188 LOGI("[%d] [%s] STORAGE_STATE_MOUNTED", state, mount_path);
190 case STORAGE_STATE_MOUNTED_READ_ONLY:
191 LOGI("[%d] [%s] STORAGE_STATE_MOUNTED_READ_ONLY", state, mount_path);
197 g_mutex_lock(&system->lock);
199 ms_connection_lock(connection);
201 queue = connection->instance_queue;
203 dispatch.cmd = MUSE_MODULE_COMMAND_EXTERNAL_STORAGE_STATE_CHANGED;
205 dispatch.storage.id = storage_id;
206 dispatch.storage.state = state;
207 dispatch.storage.path = mount_path;
209 g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
211 ms_connection_unlock(connection);
213 g_mutex_unlock(&system->lock);
217 #ifdef MUSE_USE_RM_READY
218 static int _ms_system_subscribe_resource_manager_state_change(ms_system_t *system)
222 muse_return_val_if_fail(system, MM_ERROR_INVALID_ARGUMENT);
224 muse_return_val_if_fail(system->connection, MM_ERROR_UNKNOWN);
226 system->muse_rm_id = g_dbus_connection_signal_subscribe(system->connection, MS_DBUS_SERVICE,
227 MS_DBUS_INTERFACE, MS_RM_DBUS_MSG, NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
228 _ms_resource_manager_owner_name_changed_cb, NULL, NULL);
231 return MM_ERROR_NONE;
234 static void _ms_system_unsubscribe_resource_manager_state_change(void)
236 ms_system_t *system = NULL;
238 muse_return_if_fail(ms_get_instance());
240 system = ms_get_instance()->system;
242 muse_return_if_fail(system);
243 muse_return_if_fail(system->connection);
245 g_dbus_connection_signal_unsubscribe(system->connection, system->muse_rm_id);
248 static void _ms_resource_manager_owner_name_changed_cb(GDBusConnection *con, const gchar *sender_name, const gchar *object_path,
249 const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data)
252 ms_cmd_dispatcher_info_t dispatch;
253 ms_system_t *system = NULL;
254 ms_connection_t *connection = NULL;
255 gchar *owner_name = NULL;
256 gchar *old_owner = NULL;
257 gchar *new_owner = NULL;
259 muse_return_if_fail(ms_get_instance());
260 muse_return_if_fail(object_path);
261 muse_return_if_fail(signal_name);
262 muse_return_if_fail(parameters);
264 system = ms_get_instance()->system;
265 muse_return_if_fail(system);
267 connection = ms_get_instance()->connection;
268 muse_return_if_fail(connection);
270 if (g_strcmp0(object_path, MS_DBUS_PATH) || g_strcmp0(signal_name, MS_RM_DBUS_MSG))
273 g_variant_get(parameters, "(sss)", &owner_name, &old_owner, &new_owner);
275 if (g_strcmp0(owner_name, MS_RM_DBUS_SENDER) || *new_owner == '\0')
278 g_mutex_lock(&system->lock);
280 ms_connection_lock(connection);
282 queue = connection->instance_queue;
284 dispatch.cmd = MUSE_MODULE_COMMAND_RESOURCE_MANAGER_SHUTDOWN;
286 g_queue_foreach(queue, ms_cmd_dispatch_foreach_func, (gpointer)&dispatch);
287 LOGE("resource manager shutdown");
289 ms_connection_unlock(connection);
291 g_mutex_unlock(&system->lock);
299 void ms_system_init(ms_system_t *system)
301 GError *error = NULL;
303 muse_return_if_fail(system);
307 system->connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
308 if (!system->connection) {
310 LOGE("fail to get gdbus connection (%s)", error->message);
315 system->platform_info_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
316 muse_return_if_fail(system->platform_info_table);
318 g_mutex_init(&system->lock);
323 void ms_system_deinit(ms_system_t *system)
325 muse_return_if_fail(system);
326 #ifdef MUSE_USE_POWER_OFF_STATE_CHANGE
327 _ms_system_unsubscribe_poweroff_state_change();
329 #ifdef MUSE_USE_EXTERNAL_STORAGE_STATE_CHANGE
330 _ms_system_unsubscribe_external_storage_state_change();
332 #ifdef MUSE_USE_RM_READY
333 _ms_system_unsubscribe_resource_manager_state_change();
335 if (system->connection)
336 g_object_unref(system->connection);
338 g_mutex_clear(&system->lock);
340 g_hash_table_destroy(system->platform_info_table);
345 int ms_system_get_platform_info(const char *key, bool *value)
347 int ret = MM_ERROR_NONE;
349 ms_system_t *system = NULL;
351 muse_return_val_if_fail(ms_get_instance(), MM_ERROR_UNKNOWN);
353 system = ms_get_instance()->system;
355 muse_return_val_if_fail(system, MM_ERROR_INVALID_ARGUMENT);
356 muse_return_val_if_fail(key, MM_ERROR_INVALID_ARGUMENT);
357 muse_return_val_if_fail(value, MM_ERROR_INVALID_ARGUMENT);
359 g_mutex_lock(&system->lock);
361 if (g_hash_table_lookup_extended(system->platform_info_table, key, NULL, &orig_value)) {
362 *value = GPOINTER_TO_INT(orig_value);
364 ret = system_info_get_platform_bool(key, value);
366 case SYSTEM_INFO_ERROR_NONE: /* Successful */
367 g_hash_table_insert(system->platform_info_table, g_strdup(key), GINT_TO_POINTER(*value));
370 case SYSTEM_INFO_ERROR_INVALID_PARAMETER: /* Cannot find the key in the model config file */
371 ret = MM_ERROR_COMMON_ATTR_NOT_EXIST;
373 case SYSTEM_INFO_ERROR_IO_ERROR: /* An input/output error occurred while reading the value from the model config file */
374 ret = MM_ERROR_UNKNOWN;
376 case SYSTEM_INFO_ERROR_PERMISSION_DENIED: /* No permission to use the API */
377 ret = MM_ERROR_COMMON_INVALID_PERMISSION;
380 LOGE("system_info_get_platform_bool returns 0x%x", ret);
381 ret = MM_ERROR_UNKNOWN;
386 g_mutex_unlock(&system->lock);
391 void ms_system_subscribe_external_event(ms_system_t *system)
393 #ifdef MUSE_USE_EXTERNAL_STORAGE_STATE_CHANGE
394 int ret = MM_ERROR_NONE;
395 bool is_external_storage_enabled = false;
397 muse_return_if_fail(system);
399 #ifdef MUSE_USE_POWER_OFF_STATE_CHANGE
400 if (_ms_system_subscribe_poweroff_state_change(system) != MM_ERROR_NONE)
401 LOGE("Fail to subscribe poweroff state change");
404 #ifdef MUSE_USE_EXTERNAL_STORAGE_STATE_CHANGE
405 /* external storage feature is supported as of tizen_5.5 */
406 ret = system_info_get_platform_bool(MUSE_STORAGE_EXTERNAL_FEATURE, &is_external_storage_enabled);
408 if (ret != MM_ERROR_NONE) /* get the value of mused.conf until tizen_5.0 */
409 is_external_storage_enabled = (bool)ms_config_is_external_storage_enabled();
411 if (is_external_storage_enabled == true && _ms_system_subscribe_external_storage_state_change(system) != MM_ERROR_NONE)
412 LOGE("Fail to subscribe external storage state change");
415 #ifdef MUSE_USE_RM_READY
416 if (_ms_system_subscribe_resource_manager_state_change(system) != MM_ERROR_NONE)
417 LOGE("Fail to subscribe resource manager state change");
421 int ms_system_get_memory_usage(int pid)
424 process_memory_info_s *info = NULL;
425 int ret = runtime_info_get_process_memory_info(&pid, 1, &info);
427 if (MM_ERROR_NONE == ret && info)
428 used_pss = info->pss;
430 LOGE("Fail to get process (%d) memory %s", pid, get_error_message(ret));
437 gboolean ms_system_get_gdbus(GDBusConnection **connection)
441 ms_system_t *system = NULL;
443 muse_return_val_if_fail(ms_get_instance(), FALSE);
445 system = ms_get_instance()->system;
446 muse_return_val_if_fail(system, FALSE);
447 muse_return_val_if_fail(system->connection, FALSE);
449 *connection = system->connection;