api/libmm-glib/cli: add AudioPort and AudioFormat properties to the Call object
This commit is contained in:
@@ -145,6 +145,12 @@ mmcli_call_shutdown (void)
|
||||
static void
|
||||
print_call_info (MMCall *call)
|
||||
{
|
||||
const gchar *audio_port;
|
||||
MMCallAudioFormat *audio_format;
|
||||
|
||||
audio_port = mm_call_get_audio_port (call);
|
||||
audio_format = mm_call_peek_audio_format (call);
|
||||
|
||||
/* Not the best thing to do, as we may be doing _get() calls twice, but
|
||||
* easiest to maintain */
|
||||
#undef VALIDATE
|
||||
@@ -161,6 +167,23 @@ print_call_info (MMCall *call)
|
||||
if (mm_call_get_state_reason(call) != MM_CALL_STATE_REASON_UNKNOWN)
|
||||
g_print (" | state reason: '%s'\n",
|
||||
mm_call_state_reason_get_string(mm_call_get_state_reason (call)));
|
||||
|
||||
if (audio_port)
|
||||
g_print (" | audio port: '%s'\n", VALIDATE (audio_port));
|
||||
|
||||
if (audio_format) {
|
||||
guint rate = mm_call_audio_format_get_rate (audio_format);
|
||||
gchar *rate_str = rate ? g_strdup_printf ("%u", rate) : NULL;
|
||||
|
||||
g_print (" -------------------------\n"
|
||||
" Audio Format | encoding: '%s'\n"
|
||||
" | resolution: '%s'\n"
|
||||
" | rate: '%s'\n",
|
||||
VALIDATE (mm_call_audio_format_get_encoding (audio_format)),
|
||||
VALIDATE (mm_call_audio_format_get_resolution (audio_format)),
|
||||
VALIDATE (rate_str));
|
||||
g_free (rate_str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1257,6 +1257,10 @@ mm_call_dup_number
|
||||
mm_call_get_direction
|
||||
mm_call_get_state
|
||||
mm_call_get_state_reason
|
||||
mm_call_get_audio_port
|
||||
mm_call_dup_audio_port
|
||||
mm_call_get_audio_format
|
||||
mm_call_peek_audio_format
|
||||
<SUBSECTION Methods>
|
||||
mm_call_start
|
||||
mm_call_start_finish
|
||||
@@ -1341,6 +1345,34 @@ MM_TYPE_PCO
|
||||
mm_pco_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>mm-call-audio-format</FILE>
|
||||
<TITLE>MMCallAudioFormat</TITLE>
|
||||
MMCallAudioFormat
|
||||
<SUBSECTION Getters>
|
||||
mm_call_audio_format_get_encoding
|
||||
mm_call_audio_format_get_resolution
|
||||
mm_call_audio_format_get_rate
|
||||
<SUBSECTION Private>
|
||||
mm_call_audio_format_get_dictionary
|
||||
mm_call_audio_format_new
|
||||
mm_call_audio_format_new_from_dictionary
|
||||
mm_call_audio_format_set_encoding
|
||||
mm_call_audio_format_set_resolution
|
||||
mm_call_audio_format_set_rate
|
||||
mm_call_audio_format_dup
|
||||
<SUBSECTION Standard>
|
||||
MMCallAudioFormatClass
|
||||
MMCallAudioFormatPrivate
|
||||
MM_CALL_AUDIO_FORMAT
|
||||
MM_CALL_AUDIO_FORMAT_CLASS
|
||||
MM_CALL_AUDIO_FORMAT_GET_CLASS
|
||||
MM_IS_CALL_AUDIO_FORMAT
|
||||
MM_IS_CALL_AUDIO_FORMAT_CLASS
|
||||
MM_TYPE_CALL_AUDIO_FORMAT
|
||||
mm_call_audio_format_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>mm-enums-types</FILE>
|
||||
<TITLE>Flags and Enumerations</TITLE>
|
||||
|
@@ -111,5 +111,44 @@
|
||||
The remote phone number.
|
||||
-->
|
||||
<property name="Number" type="s" access="read" />
|
||||
|
||||
<!--
|
||||
AudioPort:
|
||||
|
||||
If call audio is routed via the host, the name of the kernel device that
|
||||
provides the audio. For example, with certain Huawei USB modems, this
|
||||
property might be "ttyUSB2" indicating audio is available via ttyUSB2 in
|
||||
the format described by the AudioFormat property.
|
||||
-->
|
||||
<property name="AudioPort" type="s" access="read" />
|
||||
|
||||
<!--
|
||||
AudioFormat:
|
||||
|
||||
If call audio is routed via the host, a description of the audio format
|
||||
supported by the audio port.
|
||||
|
||||
This property may include the following items:
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>"encoding"</literal></term>
|
||||
<listitem>
|
||||
The audio encoding format. For example, "pcm" for PCM audio.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>"resolution"</literal></term>
|
||||
<listitem>
|
||||
The sampling precision and its encoding format. For example,
|
||||
"s16le" for signed 16-bit little-endian samples.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>"rate"</literal></term>
|
||||
<listitem>
|
||||
The sampling rate as an unsigned integer. For example, 8000 for
|
||||
8000hz.
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
-->
|
||||
<property name="AudioFormat" type="a{sv}" access="read" />
|
||||
</interface>
|
||||
</node>
|
||||
|
@@ -85,6 +85,8 @@ libmm_glib_la_SOURCES = \
|
||||
mm-kernel-event-properties.c \
|
||||
mm-pco.h \
|
||||
mm-pco.c \
|
||||
mm-call-audio-format.h \
|
||||
mm-call-audio-format.c \
|
||||
$(NULL)
|
||||
|
||||
libmm_glib_la_CPPFLAGS = \
|
||||
@@ -155,6 +157,7 @@ include_HEADERS = \
|
||||
mm-signal.h \
|
||||
mm-kernel-event-properties.h \
|
||||
mm-pco.h \
|
||||
mm-call-audio-format.h \
|
||||
$(NULL)
|
||||
|
||||
CLEANFILES =
|
||||
|
276
libmm-glib/mm-call-audio-format.c
Normal file
276
libmm-glib/mm-call-audio-format.c
Normal file
@@ -0,0 +1,276 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mm-errors-types.h"
|
||||
#include "mm-call-audio-format.h"
|
||||
|
||||
/**
|
||||
* SECTION: mm-call-audio-format
|
||||
* @title: MMCallAudioFormat
|
||||
* @short_description: Helper object to handle voice call audio formats.
|
||||
*
|
||||
* The #MMCallAudioFormat is an object handling the voice call audio format
|
||||
* which describes how to send/receive voice call audio from the host.
|
||||
*
|
||||
* This object is retrieved with either mm_call_get_audio_format() or
|
||||
* mm_call_peek_audio_format().
|
||||
*/
|
||||
|
||||
G_DEFINE_TYPE (MMCallAudioFormat, mm_call_audio_format, G_TYPE_OBJECT)
|
||||
|
||||
#define PROPERTY_ENCODING "encoding"
|
||||
#define PROPERTY_RESOLUTION "resolution"
|
||||
#define PROPERTY_RATE "rate"
|
||||
|
||||
struct _MMCallAudioFormatPrivate {
|
||||
gchar *encoding;
|
||||
gchar *resolution;
|
||||
guint rate;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_audio_format_get_encoding:
|
||||
* @self: a #MMCallAudioFormat.
|
||||
*
|
||||
* Gets the encoding of the audio format. For example, "pcm" for PCM-encoded
|
||||
* audio.
|
||||
*
|
||||
* Returns: a string with the encoding, or #NULL if unknown. Do not free the returned value, it is owned by @self.
|
||||
*/
|
||||
const gchar *
|
||||
mm_call_audio_format_get_encoding (MMCallAudioFormat *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), NULL);
|
||||
|
||||
return self->priv->encoding;
|
||||
}
|
||||
|
||||
void
|
||||
mm_call_audio_format_set_encoding (MMCallAudioFormat *self,
|
||||
const gchar *encoding)
|
||||
{
|
||||
g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self));
|
||||
|
||||
g_free (self->priv->encoding);
|
||||
self->priv->encoding = g_strdup (encoding);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_audio_format_get_resolution:
|
||||
* @self: a #MMCallAudioFormat.
|
||||
*
|
||||
* Gets the resolution of the audio format. For example, "s16le" for signed
|
||||
* 16-bit little-endian audio sampling resolution.
|
||||
*
|
||||
* Returns: a string with the resolution, or #NULL if unknown. Do not free the returned value, it is owned by @self.
|
||||
*/
|
||||
const gchar *
|
||||
mm_call_audio_format_get_resolution (MMCallAudioFormat *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), NULL);
|
||||
|
||||
return self->priv->resolution;
|
||||
}
|
||||
|
||||
void
|
||||
mm_call_audio_format_set_resolution (MMCallAudioFormat *self,
|
||||
const gchar *resolution)
|
||||
{
|
||||
g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self));
|
||||
|
||||
g_free (self->priv->resolution);
|
||||
self->priv->resolution = g_strdup (resolution);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_audio_format_get_rate:
|
||||
* @self: a #MMCallAudioFormat.
|
||||
*
|
||||
* Gets the sampling rate of the audio format. For example, 8000 for an 8000hz
|
||||
* sampling rate.
|
||||
*
|
||||
* Returns: the sampling rate, or 0 if unknown.
|
||||
*/
|
||||
guint
|
||||
mm_call_audio_format_get_rate (MMCallAudioFormat *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (self), 0);
|
||||
|
||||
return self->priv->rate;
|
||||
}
|
||||
|
||||
void
|
||||
mm_call_audio_format_set_rate (MMCallAudioFormat *self,
|
||||
guint rate)
|
||||
{
|
||||
g_return_if_fail (MM_IS_CALL_AUDIO_FORMAT (self));
|
||||
|
||||
self->priv->rate = rate;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
GVariant *
|
||||
mm_call_audio_format_get_dictionary (MMCallAudioFormat *self)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
|
||||
/* We do allow NULL */
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
if (self) {
|
||||
if (self->priv->encoding)
|
||||
g_variant_builder_add (&builder,
|
||||
"{sv}",
|
||||
PROPERTY_ENCODING,
|
||||
g_variant_new_string (self->priv->encoding));
|
||||
|
||||
if (self->priv->resolution)
|
||||
g_variant_builder_add (&builder,
|
||||
"{sv}",
|
||||
PROPERTY_RESOLUTION,
|
||||
g_variant_new_string (self->priv->resolution));
|
||||
|
||||
if (self->priv->rate)
|
||||
g_variant_builder_add (&builder,
|
||||
"{sv}",
|
||||
PROPERTY_RATE,
|
||||
g_variant_new_uint32 (self->priv->rate));
|
||||
}
|
||||
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMCallAudioFormat *
|
||||
mm_call_audio_format_new_from_dictionary (GVariant *dictionary,
|
||||
GError **error)
|
||||
{
|
||||
GVariantIter iter;
|
||||
gchar *key;
|
||||
GVariant *value;
|
||||
MMCallAudioFormat *self;
|
||||
|
||||
self = mm_call_audio_format_new ();
|
||||
if (!dictionary)
|
||||
return self;
|
||||
|
||||
if (!g_variant_is_of_type (dictionary, G_VARIANT_TYPE ("a{sv}"))) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_INVALID_ARGS,
|
||||
"Cannot create call audio format from dictionary: "
|
||||
"invalid variant type received");
|
||||
g_object_unref (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_iter_init (&iter, dictionary);
|
||||
while (g_variant_iter_next (&iter, "{sv}", &key, &value)) {
|
||||
if (g_str_equal (key, PROPERTY_ENCODING))
|
||||
mm_call_audio_format_set_encoding (
|
||||
self,
|
||||
g_variant_get_string (value, NULL));
|
||||
else if (g_str_equal (key, PROPERTY_RESOLUTION))
|
||||
mm_call_audio_format_set_resolution (
|
||||
self,
|
||||
g_variant_get_string (value, NULL));
|
||||
else if (g_str_equal (key, PROPERTY_RATE))
|
||||
mm_call_audio_format_set_rate (
|
||||
self,
|
||||
g_variant_get_uint32 (value));
|
||||
|
||||
g_free (key);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_audio_format_dup:
|
||||
* @orig: a #MMCallAudioFormat
|
||||
*
|
||||
* Creates a copy of @orig.
|
||||
*
|
||||
* Returns: (transfer full): a newly created #MMCallAudioFormat
|
||||
*/
|
||||
MMCallAudioFormat *
|
||||
mm_call_audio_format_dup (MMCallAudioFormat *orig)
|
||||
{
|
||||
GVariant *dict;
|
||||
MMCallAudioFormat *copy;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (MM_IS_CALL_AUDIO_FORMAT (orig), NULL);
|
||||
|
||||
dict = mm_call_audio_format_get_dictionary (orig);
|
||||
copy = mm_call_audio_format_new_from_dictionary (dict, &error);
|
||||
g_assert_no_error (error);
|
||||
g_variant_unref (dict);
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMCallAudioFormat *
|
||||
mm_call_audio_format_new (void)
|
||||
{
|
||||
return (MM_CALL_AUDIO_FORMAT (
|
||||
g_object_new (MM_TYPE_CALL_AUDIO_FORMAT, NULL)));
|
||||
}
|
||||
|
||||
static void
|
||||
mm_call_audio_format_init (MMCallAudioFormat *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
|
||||
MM_TYPE_CALL_AUDIO_FORMAT,
|
||||
MMCallAudioFormatPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
MMCallAudioFormat *self = MM_CALL_AUDIO_FORMAT (object);
|
||||
|
||||
g_free (self->priv->encoding);
|
||||
g_free (self->priv->resolution);
|
||||
|
||||
G_OBJECT_CLASS (mm_call_audio_format_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_call_audio_format_class_init (MMCallAudioFormatClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (MMCallAudioFormatPrivate));
|
||||
|
||||
object_class->finalize = finalize;
|
||||
}
|
88
libmm-glib/mm-call-audio-format.h
Normal file
88
libmm-glib/mm-call-audio-format.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2017 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef MM_CALL_AUDIO_FORMAT_H
|
||||
#define MM_CALL_AUDIO_FORMAT_H
|
||||
|
||||
#if !defined (__LIBMM_GLIB_H_INSIDE__) && !defined (LIBMM_GLIB_COMPILATION)
|
||||
#error "Only <libmm-glib.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <ModemManager.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define MM_TYPE_CALL_AUDIO_FORMAT (mm_call_audio_format_get_type ())
|
||||
#define MM_CALL_AUDIO_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormat))
|
||||
#define MM_CALL_AUDIO_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormatClass))
|
||||
#define MM_IS_CALL_AUDIO_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_CALL_AUDIO_FORMAT))
|
||||
#define MM_IS_CALL_AUDIO_FORMAT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_CALL_AUDIO_FORMAT))
|
||||
#define MM_CALL_AUDIO_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_CALL_AUDIO_FORMAT, MMCallAudioFormatClass))
|
||||
|
||||
typedef struct _MMCallAudioFormat MMCallAudioFormat;
|
||||
typedef struct _MMCallAudioFormatClass MMCallAudioFormatClass;
|
||||
typedef struct _MMCallAudioFormatPrivate MMCallAudioFormatPrivate;
|
||||
|
||||
/**
|
||||
* MMCallAudioFormat:
|
||||
*
|
||||
* The #MMCallAudioFormat structure contains private data and should
|
||||
* only be accessed using the provided API.
|
||||
*/
|
||||
struct _MMCallAudioFormat {
|
||||
/*< private >*/
|
||||
GObject parent;
|
||||
MMCallAudioFormatPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MMCallAudioFormatClass {
|
||||
/*< private >*/
|
||||
GObjectClass parent;
|
||||
};
|
||||
|
||||
GType mm_call_audio_format_get_type (void);
|
||||
|
||||
const gchar *mm_call_audio_format_get_encoding (MMCallAudioFormat *self);
|
||||
const gchar *mm_call_audio_format_get_resolution (MMCallAudioFormat *self);
|
||||
guint mm_call_audio_format_get_rate (MMCallAudioFormat *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* ModemManager/libmm-glib/mmcli specific methods */
|
||||
|
||||
#if defined (_LIBMM_INSIDE_MM) || \
|
||||
defined (_LIBMM_INSIDE_MMCLI) || \
|
||||
defined (LIBMM_GLIB_COMPILATION)
|
||||
|
||||
MMCallAudioFormat *mm_call_audio_format_new (void);
|
||||
MMCallAudioFormat *mm_call_audio_format_new_from_dictionary (GVariant *dictionary,
|
||||
GError **error);
|
||||
|
||||
MMCallAudioFormat *mm_call_audio_format_dup (MMCallAudioFormat *orig);
|
||||
|
||||
void mm_call_audio_format_set_encoding (MMCallAudioFormat *self,
|
||||
const gchar *encoding);
|
||||
void mm_call_audio_format_set_resolution (MMCallAudioFormat *self,
|
||||
const gchar *resolution);
|
||||
void mm_call_audio_format_set_rate (MMCallAudioFormat *self,
|
||||
guint rate);
|
||||
|
||||
GVariant *mm_call_audio_format_get_dictionary (MMCallAudioFormat *self);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* MM_CALL_AUDIO_FORMAT_H */
|
@@ -36,6 +36,13 @@
|
||||
|
||||
G_DEFINE_TYPE (MMCall, mm_call, MM_GDBUS_TYPE_CALL_PROXY)
|
||||
|
||||
struct _MMCallPrivate {
|
||||
/* Audio Format */
|
||||
GMutex audio_format_mutex;
|
||||
guint audio_format_id;
|
||||
MMCallAudioFormat *audio_format;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -176,6 +183,156 @@ mm_call_get_state_reason (MMCall *self)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_get_audio_port:
|
||||
* @self: A #MMCall.
|
||||
*
|
||||
* Gets the kernel device used for audio (if any).
|
||||
*
|
||||
* Returns: (transfer none): The audio port, or %NULL if call audio is not
|
||||
* routed via the host or couldn't be retrieved.
|
||||
*/
|
||||
const gchar *
|
||||
mm_call_get_audio_port (MMCall *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL (self), NULL);
|
||||
|
||||
RETURN_NON_EMPTY_CONSTANT_STRING (
|
||||
mm_gdbus_call_get_audio_port (MM_GDBUS_CALL (self)));
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_call_dup_audio_port:
|
||||
* @self: A #MMCall.
|
||||
*
|
||||
* Gets the kernel device used for audio (if any).
|
||||
*
|
||||
* Returns: (transfer full): The audio port, or %NULL if call audio is not
|
||||
* routed via the host or couldn't be retrieved.
|
||||
*/
|
||||
gchar *
|
||||
mm_call_dup_audio_port (MMCall *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL (self), NULL);
|
||||
|
||||
RETURN_NON_EMPTY_STRING (
|
||||
mm_gdbus_call_dup_audio_port (MM_GDBUS_CALL (self)));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
audio_format_updated (MMCall *self,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
g_mutex_lock (&self->priv->audio_format_mutex);
|
||||
{
|
||||
GVariant *dictionary;
|
||||
|
||||
g_clear_object (&self->priv->audio_format);
|
||||
|
||||
/* TODO: update existing object instead of re-creating? */
|
||||
dictionary = mm_gdbus_call_get_audio_format (MM_GDBUS_CALL (self));
|
||||
if (dictionary) {
|
||||
GError *error = NULL;
|
||||
|
||||
self->priv->audio_format = mm_call_audio_format_new_from_dictionary (dictionary, &error);
|
||||
if (error) {
|
||||
g_warning ("Invalid audio format update received: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
}
|
||||
g_mutex_unlock (&self->priv->audio_format_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_internal_audio_format (MMCall *self,
|
||||
MMCallAudioFormat **dup)
|
||||
{
|
||||
g_mutex_lock (&self->priv->audio_format_mutex);
|
||||
{
|
||||
/* If this is the first time ever asking for the object, setup the
|
||||
* update listener and the initial object, if any. */
|
||||
if (!self->priv->audio_format_id) {
|
||||
GVariant *dictionary;
|
||||
|
||||
dictionary = mm_gdbus_call_dup_audio_format (MM_GDBUS_CALL (self));
|
||||
if (dictionary) {
|
||||
GError *error = NULL;
|
||||
|
||||
self->priv->audio_format = mm_call_audio_format_new_from_dictionary (dictionary, &error);
|
||||
if (error) {
|
||||
g_warning ("Invalid initial audio format: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_variant_unref (dictionary);
|
||||
}
|
||||
|
||||
/* No need to clear this signal connection when freeing self */
|
||||
self->priv->audio_format_id =
|
||||
g_signal_connect (self,
|
||||
"notify::audio-format",
|
||||
G_CALLBACK (audio_format_updated),
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (dup && self->priv->audio_format)
|
||||
*dup = g_object_ref (self->priv->audio_format);
|
||||
}
|
||||
g_mutex_unlock (&self->priv->audio_format_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_call_get_audio_format:
|
||||
* @self: A #MMCall.
|
||||
*
|
||||
* Gets a #MMCallAudioFormat object specifying the audio format used by the
|
||||
* audio port if call audio is routed via the host.
|
||||
*
|
||||
* <warning>The values reported by @self are not updated when the values in the
|
||||
* interface change. Instead, the client is expected to call
|
||||
* mm_call_get_audio_format() again to get a new #MMCallAudioFormat with the
|
||||
* new values.</warning>
|
||||
*
|
||||
* Returns: (transfer full): A #MMCallAudioFormat that must be freed with g_object_unref() or %NULL if unknown.
|
||||
*/
|
||||
MMCallAudioFormat *
|
||||
mm_call_get_audio_format (MMCall *self)
|
||||
{
|
||||
MMCallAudioFormat *format = NULL;
|
||||
|
||||
g_return_val_if_fail (MM_IS_CALL (self), NULL);
|
||||
|
||||
ensure_internal_audio_format (self, &format);
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* mm_call_peek_audio_format:
|
||||
* @self: A #MMCall.
|
||||
*
|
||||
* Gets a #MMCallAudioFormat object specifying the audio format used by the
|
||||
* audio port if call audio is routed via the host.
|
||||
*
|
||||
* <warning>The returned value is only valid until the property changes so
|
||||
* it is only safe to use this function on the thread where
|
||||
* @self was constructed. Use mm_call_get_audio_format() if on another
|
||||
* thread.</warning>
|
||||
*
|
||||
* Returns: (transfer none): A #MMCallAudioFormat. Do not free the returned value, it belongs to @self.
|
||||
*/
|
||||
MMCallAudioFormat *
|
||||
mm_call_peek_audio_format (MMCall *self)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_CALL (self), NULL);
|
||||
|
||||
ensure_internal_audio_format (self, NULL);
|
||||
return self->priv->audio_format;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* mm_call_start_finish:
|
||||
* @self: A #MMCall.
|
||||
@@ -500,9 +657,40 @@ mm_call_send_dtmf_sync (MMCall *self,
|
||||
static void
|
||||
mm_call_init (MMCall *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
MM_TYPE_CALL,
|
||||
MMCallPrivate);
|
||||
g_mutex_init (&self->priv->audio_format_mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
MMCall *self = MM_CALL (object);
|
||||
|
||||
g_mutex_clear (&self->priv->audio_format_mutex);
|
||||
|
||||
G_OBJECT_CLASS (mm_call_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
MMCall *self = MM_CALL (object);
|
||||
|
||||
g_clear_object (&self->priv->audio_format);
|
||||
|
||||
G_OBJECT_CLASS (mm_call_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_call_class_init (MMCallClass *call_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (call_class);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (MMCallPrivate));
|
||||
|
||||
/* Virtual methods */
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#include <ModemManager.h>
|
||||
|
||||
#include "mm-gdbus-call.h"
|
||||
#include "mm-call-properties.h"
|
||||
#include "mm-call-audio-format.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -39,6 +39,7 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct _MMCall MMCall;
|
||||
typedef struct _MMCallClass MMCallClass;
|
||||
typedef struct _MMCallPrivate MMCallPrivate;
|
||||
|
||||
/**
|
||||
* MMCall:
|
||||
@@ -49,7 +50,7 @@ typedef struct _MMCallClass MMCallClass;
|
||||
struct _MMCall {
|
||||
/*< private >*/
|
||||
MmGdbusCallProxy parent;
|
||||
gpointer unused;
|
||||
MMCallPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MMCallClass {
|
||||
@@ -71,6 +72,11 @@ MMCallStateReason mm_call_get_state_reason (MMCall *self);
|
||||
|
||||
MMCallDirection mm_call_get_direction (MMCall *self);
|
||||
|
||||
const gchar *mm_call_get_audio_port (MMCall *self);
|
||||
gchar *mm_call_dup_audio_port (MMCall *self);
|
||||
|
||||
MMCallAudioFormat *mm_call_get_audio_format (MMCall *self);
|
||||
MMCallAudioFormat *mm_call_peek_audio_format(MMCall *self);
|
||||
|
||||
|
||||
void mm_call_start (MMCall *self,
|
||||
|
@@ -724,6 +724,21 @@ mm_base_call_received_dtmf (MMBaseCall *self,
|
||||
mm_gdbus_call_emit_dtmf_received (MM_GDBUS_CALL (self), dtmf);
|
||||
}
|
||||
|
||||
void
|
||||
mm_base_call_set_audio_port (MMBaseCall *self, const gchar *port)
|
||||
{
|
||||
mm_gdbus_call_set_audio_port (MM_GDBUS_CALL (self), port);
|
||||
}
|
||||
|
||||
void
|
||||
mm_base_call_set_audio_format (MMBaseCall *self,
|
||||
MMCallAudioFormat *audio_format)
|
||||
{
|
||||
mm_gdbus_call_set_audio_format (
|
||||
MM_GDBUS_CALL (self),
|
||||
mm_call_audio_format_get_dictionary (audio_format));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Start the CALL */
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <libmm-glib.h>
|
||||
|
||||
#include "mm-base-modem.h"
|
||||
#include "mm-call-audio-format.h"
|
||||
|
||||
#define MM_TYPE_BASE_CALL (mm_base_call_get_type ())
|
||||
#define MM_BASE_CALL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BASE_CALL, MMBaseCall))
|
||||
@@ -104,6 +105,11 @@ void mm_base_call_change_state (MMBaseCall *self,
|
||||
MMCallState new_state,
|
||||
MMCallStateReason reason);
|
||||
|
||||
void mm_base_call_set_audio_port (MMBaseCall *self,
|
||||
const gchar *port);
|
||||
void mm_base_call_set_audio_format (MMBaseCall *self,
|
||||
MMCallAudioFormat *audio_format);
|
||||
|
||||
void mm_base_call_received_dtmf (MMBaseCall *self,
|
||||
const gchar *dtmf);
|
||||
|
||||
|
Reference in New Issue
Block a user