Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright © 2018 Endless Mobile, Inc.
4 : : *
5 : : * This library is free software; you can redistribute it and/or
6 : : * modify it under the terms of the GNU Lesser General Public
7 : : * License as published by the Free Software Foundation; either
8 : : * version 2.1 of the License, or (at your option) any later version.
9 : : *
10 : : * This library is distributed in the hope that it will be useful,
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : : * Lesser General Public License for more details.
14 : : *
15 : : * You should have received a copy of the GNU Lesser General Public
16 : : * License along with this library; if not, write to the Free Software
17 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : : *
19 : : * Authors:
20 : : * - Philip Withnall <withnall@endlessm.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <glib.h>
26 : : #include <glib-object.h>
27 : : #include <glib/gi18n-lib.h>
28 : : #include <gio/gio.h>
29 : : #include <libmogwai-schedule/connection-monitor.h>
30 : :
31 : :
32 : : /**
33 : : * mws_metered_combine_pessimistic:
34 : : * @a: a metered status
35 : : * @b: another metered status
36 : : *
37 : : * Combine two #MwsMetered values pessimistically, returning the one
38 : : * which more conservatively estimates the metered status of a connection. For
39 : : * example, if the two values were %MWS_METERED_GUESS_NO and
40 : : * %MWS_METERED_GUESS_YES, the returned value would be %MWS_METERED_GUESS_YES.
41 : : *
42 : : * The return value is guaranteed to either be @a or @b.
43 : : *
44 : : * Returns: pessimistic choice between @a and @b
45 : : * Since: 0.1.0
46 : : */
47 : : MwsMetered
48 : 0 : mws_metered_combine_pessimistic (MwsMetered a,
49 : : MwsMetered b)
50 : : {
51 [ # # ]: 0 : if (a == b)
52 : 0 : return a;
53 [ # # ]: 0 : if (a == MWS_METERED_UNKNOWN)
54 : 0 : return b;
55 [ # # ]: 0 : if (b == MWS_METERED_UNKNOWN)
56 : 0 : return a;
57 : :
58 [ # # # # ]: 0 : if (a == MWS_METERED_YES || b == MWS_METERED_YES)
59 : 0 : return MWS_METERED_YES;
60 [ # # # # ]: 0 : if (a == MWS_METERED_GUESS_YES || b == MWS_METERED_GUESS_YES)
61 : 0 : return MWS_METERED_GUESS_YES;
62 [ # # # # ]: 0 : if (a == MWS_METERED_GUESS_NO || b == MWS_METERED_GUESS_NO)
63 : 0 : return MWS_METERED_GUESS_NO;
64 : :
65 : 0 : return MWS_METERED_NO;
66 : : }
67 : :
68 : : /**
69 : : * mws_metered_to_string:
70 : : * @metered: a metered status
71 : : *
72 : : * Return a string form of the @metered status. This is intended for use in
73 : : * debug output, and is not translated, stable, or user-friendly.
74 : : *
75 : : * Returns: metered status string
76 : : * Since: 0.1.0
77 : : */
78 : : const gchar *
79 : 167 : mws_metered_to_string (MwsMetered metered)
80 : : {
81 [ - + + + : 167 : switch (metered)
- - ]
82 : : {
83 : 0 : case MWS_METERED_UNKNOWN:
84 : 0 : return "unknown";
85 : 31 : case MWS_METERED_YES:
86 : 31 : return "yes";
87 : 132 : case MWS_METERED_NO:
88 : 132 : return "no";
89 : 4 : case MWS_METERED_GUESS_YES:
90 : 4 : return "guess-yes";
91 : 0 : case MWS_METERED_GUESS_NO:
92 : 0 : return "guess-no";
93 : 0 : default:
94 : 0 : g_assert_not_reached ();
95 : : }
96 : : }
97 : :
98 : : /**
99 : : * mws_connection_details_clear:
100 : : * @details: (transfer full): a #MwsConnectionDetails
101 : : *
102 : : * Free any allocated memory in the given @details instance (but don’t free the
103 : : * @details itself), and reset the instance to neutral default values.
104 : : *
105 : : * This should be used with stack-allocated #MwsConnectionDetails.
106 : : *
107 : : * Since: 0.1.0
108 : : */
109 : : void
110 : 307 : mws_connection_details_clear (MwsConnectionDetails *details)
111 : : {
112 : 307 : details->metered = MWS_METERED_UNKNOWN;
113 : 307 : details->allow_downloads_when_metered = FALSE;
114 : 307 : details->allow_downloads = TRUE;
115 [ + + ]: 307 : g_clear_object (&details->tariff);
116 : 307 : }
117 : :
118 : : /**
119 : : * MwsConnectionMonitor:
120 : : *
121 : : * A connection monitor is an abstraction over the OS’s network interface,
122 : : * making the set of active network connections, and some of their details,
123 : : * available to the scheduler to use in scheduling decisions.
124 : : *
125 : : * The default implementation for production use is #MwsConnectionMonitorNm,
126 : : * which uses NetworkManager to get connection information. Unit tests will use
127 : : * a different implementation, allowing them to provide fake data to the
128 : : * scheduler easily.
129 : : *
130 : : * Each implementation of #MwsConnectionMonitor can define its own format for
131 : : * IDs, but all IDs must be non-%NULL, non-empty, and valid UTF-8.
132 : : *
133 : : * Since: 0.1.0
134 : : */
135 : :
136 [ + + + - : 975 : G_DEFINE_INTERFACE (MwsConnectionMonitor, mws_connection_monitor, G_TYPE_OBJECT)
+ + ]
137 : :
138 : : static void
139 : 2 : mws_connection_monitor_default_init (MwsConnectionMonitorInterface *iface)
140 : : {
141 : : /**
142 : : * MwsConnectionMonitor::connections-changed:
143 : : * @self: a #MwsConnectionMonitor
144 : : * @added_connections: (element-type utf8) (nullable): potentially empty or
145 : : * %NULL array of connection IDs which have been added (a %NULL array is
146 : : * equivalent to an empty one)
147 : : * @removed_connections: (element-type utf8) (nullable): potentially empty or
148 : : * %NULL array of connection IDs which have been removed (a %NULL array is
149 : : * equivalent to an empty one)
150 : : *
151 : : * Emitted when the set of active connections has changed. The details of
152 : : * new or changed connections can be queried using
153 : : * mws_connection_monitor_get_connection_details().
154 : : *
155 : : * If a connection is listed in one of the two arrays, it will not be listed
156 : : * in the other. There will be one connection listed in at least one of the
157 : : * arrays.
158 : : *
159 : : * Since: 0.1.0
160 : : */
161 : 2 : g_signal_new ("connections-changed", G_TYPE_FROM_INTERFACE (iface),
162 : : G_SIGNAL_RUN_LAST,
163 : : 0, NULL, NULL, NULL,
164 : : G_TYPE_NONE, 2,
165 : : G_TYPE_PTR_ARRAY,
166 : : G_TYPE_PTR_ARRAY);
167 : :
168 : : /**
169 : : * MwsConnectionMonitor::connection-details-changed:
170 : : * @self: a #MwsConnectionMonitor
171 : : * @connection_id: ID of the connection whose details have changed
172 : : *
173 : : * Emitted when the details of a connection have changed, to prompt
174 : : * subscribers to re-query the connection’s details using
175 : : * mws_connection_monitor_get_connection_details().
176 : : *
177 : : * There is no guarantee that the connection details have actually changed if
178 : : * this signal is emitted.
179 : : *
180 : : * Since: 0.1.0
181 : : */
182 : 2 : g_signal_new ("connection-details-changed", G_TYPE_FROM_INTERFACE (iface),
183 : : G_SIGNAL_RUN_LAST,
184 : : 0, NULL, NULL, NULL,
185 : : G_TYPE_NONE, 1,
186 : : G_TYPE_STRING);
187 : 2 : }
188 : :
189 : : /**
190 : : * mws_connection_monitor_get_connection_ids:
191 : : * @self: a #MwsConnectionMonitor
192 : : *
193 : : * Get the IDs of the currently active network connections on this system.
194 : : * The returned array may be empty, but is guaranteed to be non-%NULL.
195 : : *
196 : : * Returns: (transfer none) (array zero-terminated=1): IDs of the active
197 : : * connections (may be empty)
198 : : * Since: 0.1.0
199 : : */
200 : : const gchar * const *
201 : 235 : mws_connection_monitor_get_connection_ids (MwsConnectionMonitor *self)
202 : : {
203 [ - + ]: 235 : g_return_val_if_fail (MWS_IS_CONNECTION_MONITOR (self), NULL);
204 : :
205 : 235 : MwsConnectionMonitorInterface *iface = MWS_CONNECTION_MONITOR_GET_IFACE (self);
206 [ - + ]: 235 : g_assert (iface->get_connection_ids != NULL);
207 : 235 : const gchar * const *ids = iface->get_connection_ids (self);
208 : :
209 [ - + ]: 235 : g_return_val_if_fail (ids != NULL, NULL);
210 : :
211 : 235 : return ids;
212 : : }
213 : :
214 : : /**
215 : : * mws_connection_monitor_get_connection_details:
216 : : * @self: a #MwsConnectionMonitor
217 : : * @id: ID of the connection to get details for
218 : : * @out_details: (out caller-allocates) (optional): pointer to a
219 : : * #MwsConnectionDetails to fill in, or %NULL to not receive the information
220 : : *
221 : : * Get the current details of the active connection with the given @id. If
222 : : * @out_details is %NULL, this can be used to check whether a given @id is
223 : : * valid.
224 : : *
225 : : * The populated @out_details may contain heap-allocated memory, ownership of
226 : : * which is transferred to the caller. Call mws_connection_details_clear() to
227 : : * free it afterwards.
228 : : *
229 : : * Returns: %TRUE if @id is valid and @out_details has been filled (if provided);
230 : : * %FALSE otherwise
231 : : * Since: 0.1.0
232 : : */
233 : : gboolean
234 : 202 : mws_connection_monitor_get_connection_details (MwsConnectionMonitor *self,
235 : : const gchar *id,
236 : : MwsConnectionDetails *out_details)
237 : : {
238 [ - + ]: 202 : g_return_val_if_fail (MWS_IS_CONNECTION_MONITOR (self), FALSE);
239 [ - + ]: 202 : g_return_val_if_fail (id != NULL, FALSE);
240 : :
241 : 202 : MwsConnectionMonitorInterface *iface = MWS_CONNECTION_MONITOR_GET_IFACE (self);
242 [ - + ]: 202 : g_assert (iface->get_connection_details != NULL);
243 : 202 : return iface->get_connection_details (self, id, out_details);
244 : : }
|