/** * Remove an activity cb from the list of monitored processes * and the callback itself * * @param owner The D-Bus owner of the callback */ static void remove_activity_cb(const gchar *owner) { GSList *tmp = activity_callbacks; /* Remove the name monitor for the activity callback * and the activity callback itself */ (void)mce_dbus_owner_monitor_remove(owner, &activity_cb_monitor_list); while (tmp != NULL) { activity_cb_t *cb; cb = tmp->data; /* Is this the matching sender? */ if (!strcmp(cb->owner, owner)) { g_free(cb->owner); g_free(cb->service); g_free(cb->path); g_free(cb->interface); g_free(cb->method_name); g_free(cb); activity_callbacks = g_slist_remove(activity_callbacks, cb); break; } tmp = g_slist_next(tmp); }; }
/** * D-Bus callback for the ALS disabling method call * * @param msg The D-Bus message * @return TRUE */ static gboolean als_disable_req_dbus_cb(DBusMessage *const msg) { const char *sender; gssize retval; if( !(sender = dbus_message_get_sender(msg)) ) goto EXIT; mce_log(LL_DEBUG, "Received ALS disable request from %s", sender); retval = mce_dbus_owner_monitor_remove(sender, &ext_als_enablers); if (retval == -1) { mce_log(LL_INFO, "Failed to remove name owner monitoring" " for `%s'",sender); goto EXIT; } rethink_als_status(); EXIT: if( !dbus_message_get_no_reply(msg) ) { DBusMessage *reply = dbus_new_method_reply(msg); dbus_send_message(reply), reply = 0; } return TRUE; }
/** * D-Bus callback for the alarm dialog status signal * * @param msg The D-Bus message * @return TRUE on success, FALSE on failure */ static gboolean alarm_dialog_status_dbus_cb(DBusMessage *const msg) { alarm_ui_state_t alarm_ui_state = MCE_ALARM_UI_INVALID_INT32; gboolean status = FALSE; const gchar *sender = dbus_message_get_sender(msg); DBusError error; dbus_int32_t dialog_status; /* Register error channel */ dbus_error_init(&error); mce_log(LL_DEVEL, "Received alarm dialog status signal from %s", mce_dbus_get_name_owner_ident(sender)); if (dbus_message_get_args(msg, &error, DBUS_TYPE_INT32, &dialog_status, DBUS_TYPE_INVALID) == FALSE) { // XXX: should we return an error instead? mce_log(LL_CRIT, "Failed to get argument from %s.%s: %s", VISUAL_REMINDERS_SIGNAL_IF, VISUAL_REMINDER_STATUS_SIG, error.message); dbus_error_free(&error); goto EXIT; } /* Convert alarm dialog status to to MCE alarm ui enum */ switch (dialog_status) { case VISUAL_REMINDER_ON_SCREEN: setup_alarm_dbus_monitor(sender); alarm_ui_state = MCE_ALARM_UI_RINGING_INT32; break; case VISUAL_REMINDER_ON_SCREEN_NO_SOUND: setup_alarm_dbus_monitor(sender); alarm_ui_state = MCE_ALARM_UI_VISIBLE_INT32; break; case VISUAL_REMINDER_NOT_ON_SCREEN: mce_dbus_owner_monitor_remove(sender, &alarm_owner_monitor_list); alarm_ui_state = MCE_ALARM_UI_OFF_INT32; break; default: mce_log(LL_ERR, "Received invalid alarm dialog status; " "defaulting to OFF"); alarm_ui_state = MCE_ALARM_UI_OFF_INT32; break; } alarm_sync_state_to_datapipe(alarm_ui_state); status = TRUE; EXIT: return status; }
/** * Alarm D-Bus service monitor callback. * * @param msg The D-Bus message * @return TRUE on success, FALSE on failure */ static gboolean alarm_owner_monitor_dbus_cb(DBusMessage *const msg) { gboolean status = FALSE; const gchar *old_name; const gchar *new_name; const gchar *service; gssize retval; DBusError error; /* Register error channel */ dbus_error_init(&error); /* Extract result */ if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &old_name, DBUS_TYPE_STRING, &new_name, DBUS_TYPE_INVALID) == FALSE) { mce_log(LL_ERR, "Failed to get argument from %s.%s; %s", "org.freedesktop.DBus", "NameOwnerChanged", error.message); dbus_error_free(&error); goto EXIT; } retval = mce_dbus_owner_monitor_remove(service, &alarm_owner_monitor_list); if (retval == 0) { /* We didn't get alarm off from the same service before it * unregistered (e.g. due crash), turn alarm state off so at * least powerkey works again. */ mce_log(LL_DEBUG, "visual reminder service died, " "turning off alarm state"); alarm_sync_state_to_datapipe(MCE_ALARM_UI_OFF_INT32); } status = TRUE; EXIT: return status; }
/** * Remove an activity cb from the list of monitored processes * and the callback itself * * @param owner The D-Bus owner of the callback */ static void mia_activity_action_remove(const char *owner) { /* Remove D-Bus name owner monitor */ mce_dbus_owner_monitor_remove(owner, &activity_action_owners); /* Remove the activity callback itself */ for( GSList *now = activity_action_list; now; now = now->next ) { mia_action_t *cb = now->data; if( strcmp(cb->owner, owner) ) continue; activity_action_list = g_slist_remove(activity_action_list, cb); mia_action_delete(cb); break; }; }
/** * D-Bus callback used for monitoring the process that requested * the call state; if that process exits, immediately * restore the call state to "none" and call type to "normal" * * @param msg The D-Bus message * @return TRUE on success, FALSE on failure */ static gboolean call_state_owner_monitor_dbus_cb(DBusMessage *const msg) { gboolean status = FALSE; const gchar *old_name; const gchar *new_name; const gchar *service; DBusError error; /* Register error channel */ dbus_error_init(&error); /* Extract result */ if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &old_name, DBUS_TYPE_STRING, &new_name, DBUS_TYPE_INVALID) == FALSE) { mce_log(LL_ERR, "Failed to get argument from %s.%s; %s", "org.freedesktop.DBus", "NameOwnerChanged", error.message); dbus_error_free(&error); goto EXIT; } /* Remove the name monitor for the call state requester */ if (mce_dbus_owner_monitor_remove(service, &call_state_monitor_list) == 0) { simulated.state = CALL_STATE_NONE; simulated.type = NORMAL_CALL; call_state_rethink_schedule(); } status = TRUE; EXIT: return status; }
/** * D-Bus callback used for reference counting ALS enabling; * if the requesting process exits, immediately decrease the refcount * * @param msg The D-Bus message * @return TRUE */ static gboolean als_owner_monitor_dbus_cb(DBusMessage *const msg) { const gchar *old_name = 0; const gchar *new_name = 0; const gchar *service = 0; DBusError error = DBUS_ERROR_INIT; gssize retval; if( !dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &old_name, DBUS_TYPE_STRING, &new_name, DBUS_TYPE_INVALID) ) { mce_log(LL_ERR, "Failed to get argument from %s.%s; %s: %s", "org.freedesktop.DBus", "NameOwnerChanged", error.name, error.message); goto EXIT; } /* Remove the name monitor for the ALS owner */ retval = mce_dbus_owner_monitor_remove(service, &ext_als_enablers); if (retval == -1) { mce_log(LL_WARN, "Failed to remove name owner monitoring" " for `%s'", service); goto EXIT; } rethink_als_status(); EXIT: dbus_error_free(&error); return TRUE; }
/** Install/remove alarm queue D-Bus name owner monitor * * @param sender Private D-Bus name to monitor * @param monitor true/false to start/stop monitoring */ static void queue_monitor_setup(const char *sender, bool monitor) { if( monitor ) { gssize cnt = mce_dbus_owner_monitor_add(sender, queue_owner_monitor_dbus_cb, &queue_owner_monitor_list, ALARM_MAX_MONITORED); if( cnt != -1 ) { /* A owner monitor was added/renewed */ mce_log(LL_DEVEL, "monitoring dbus name: %s", sender); mce_wakelock_obtain(ALARM_IMMINENT_WAKELOCK_NAME, ALARM_IMMINENT_TIMEOUT_MS); } } else { gssize cnt = mce_dbus_owner_monitor_remove(sender, &queue_owner_monitor_list); if( cnt == 0 ) { /* The last monitor was removed */ mce_log(LL_DEVEL, "all dbus name monitors removed"); mce_wakelock_release(ALARM_IMMINENT_WAKELOCK_NAME); } } }
/** * D-Bus callback for the call state change request method call * * @param msg The D-Bus message * @return TRUE on success, FALSE on failure */ static gboolean change_call_state_dbus_cb(DBusMessage *const msg) { gboolean status = FALSE; const char *state = 0; const char *type = 0; const gchar *sender = dbus_message_get_sender(msg); call_state_t call_state = CALL_STATE_NONE; call_type_t call_type = NORMAL_CALL; DBusMessage *reply = NULL; DBusError error = DBUS_ERROR_INIT; dbus_bool_t changed = false; mce_log(LL_DEBUG, "Received set call state request"); if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &state, DBUS_TYPE_STRING, &type, DBUS_TYPE_INVALID) == FALSE) { // XXX: return an error! mce_log(LL_CRIT, "Failed to get argument from %s.%s: %s", MCE_REQUEST_IF, MCE_CALL_STATE_CHANGE_REQ, error.message); dbus_error_free(&error); goto EXIT; } /* Convert call state to enum */ call_state = call_state_parse(state); if (call_state == MCE_INVALID_TRANSLATION) { mce_log(LL_DEBUG, "Invalid call state received; request ignored"); goto EXIT; } /* Convert call type to enum */ call_type = call_type_parse(type); if (call_type == MCE_INVALID_TRANSLATION) { mce_log(LL_DEBUG, "Invalid call type received; request ignored"); goto EXIT; } /* reject no-call emergency calls ... */ if( call_state == CALL_STATE_NONE ) call_type = NORMAL_CALL; /* If call state isn't monitored or if the request comes from * the owner of the current state, then some additional changes * are ok */ if( call_state_monitor_list && !mce_dbus_is_owner_monitored(sender, call_state_monitor_list) ) { mce_log(LL_DEBUG, "Call state already has owner; ignoring request"); goto EXIT; } /* Only transitions to/from "none" are allowed, * and from "ringing" to "active", * to avoid race conditions; except when new tuple * is active:emergency */ if( call_state == CALL_STATE_ACTIVE && simulated.state != CALL_STATE_RINGING && call_type != EMERGENCY_CALL ) { mce_log(LL_INFO, "Call state change vetoed. Requested: %i:%i " "(current: %i:%i)", call_state, call_type, simulated.state, simulated.type); goto EXIT; } if( call_state != CALL_STATE_NONE && mce_dbus_owner_monitor_add(sender, call_state_owner_monitor_dbus_cb, &call_state_monitor_list, 1) != -1 ) { simulated.state = call_state; simulated.type = call_type; } else { mce_dbus_owner_monitor_remove(sender, &call_state_monitor_list); simulated.state = CALL_STATE_NONE; simulated.type = NORMAL_CALL; } changed = call_state_rethink_forced(); EXIT: /* Setup the reply */ reply = dbus_new_method_reply(msg); /* Append the result */ if (dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &changed, DBUS_TYPE_INVALID) == FALSE) { mce_log(LL_CRIT, "Failed to append reply arguments to D-Bus " "message for %s.%s", MCE_REQUEST_IF, MCE_CALL_STATE_CHANGE_REQ); dbus_message_unref(reply); } else { /* Send the message */ status = dbus_send_message(reply); } return status; }