2 * Copyright © 2010 Codethink Limited
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
19 * Author: Ryan Lortie <desrt@desrt.ca>
24 #include "gpermission.h"
28 #include "gasyncresult.h"
29 #include "gsimpleasyncresult.h"
36 * @short_description: An object representing the permission
37 * to perform a certain action
40 * A #GPermission represents the status of the caller's permission to
41 * perform a certain action.
43 * You can query if the action is currently allowed and if it is
44 * possible to acquire the permission so that the action will be allowed
47 * There is also an API to actually acquire the permission and one to
50 * As an example, a #GPermission might represent the ability for the
51 * user to write to a #GSettings object. This #GPermission object could
52 * then be used to decide if it is appropriate to show a "Click here to
53 * unlock" button in a dialog and to provide the mechanism to invoke
54 * when that button is clicked.
60 * #GPermission is an opaque data structure and can only be accessed
61 * using the following functions.
64 struct _GPermissionPrivate
78 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GPermission, g_permission, G_TYPE_OBJECT)
81 * g_permission_acquire:
82 * @permission: a #GPermission instance
83 * @cancellable: (allow-none): a #GCancellable, or %NULL
84 * @error: a pointer to a %NULL #GError, or %NULL
86 * Attempts to acquire the permission represented by @permission.
88 * The precise method by which this happens depends on the permission
89 * and the underlying authentication mechanism. A simple example is
90 * that a dialog may appear asking the user to enter their password.
92 * You should check with g_permission_get_can_acquire() before calling
95 * If the permission is acquired then %TRUE is returned. Otherwise,
96 * %FALSE is returned and @error is set appropriately.
98 * This call is blocking, likely for a very long time (in the case that
99 * user interaction is required). See g_permission_acquire_async() for
100 * the non-blocking version.
102 * Returns: %TRUE if the permission was successfully acquired
107 g_permission_acquire (GPermission *permission,
108 GCancellable *cancellable,
111 return G_PERMISSION_GET_CLASS (permission)
112 ->acquire (permission, cancellable, error);
116 * g_permission_acquire_async:
117 * @permission: a #GPermission instance
118 * @cancellable: (allow-none): a #GCancellable, or %NULL
119 * @callback: the #GAsyncReadyCallback to call when done
120 * @user_data: the user data to pass to @callback
122 * Attempts to acquire the permission represented by @permission.
124 * This is the first half of the asynchronous version of
125 * g_permission_acquire().
130 g_permission_acquire_async (GPermission *permission,
131 GCancellable *cancellable,
132 GAsyncReadyCallback callback,
135 G_PERMISSION_GET_CLASS (permission)
136 ->acquire_async (permission, cancellable, callback, user_data);
140 * g_permission_acquire_finish:
141 * @permission: a #GPermission instance
142 * @result: the #GAsyncResult given to the #GAsyncReadyCallback
143 * @error: a pointer to a %NULL #GError, or %NULL
145 * Collects the result of attempting to acquire the permission
146 * represented by @permission.
148 * This is the second half of the asynchronous version of
149 * g_permission_acquire().
151 * Returns: %TRUE if the permission was successfully acquired
156 g_permission_acquire_finish (GPermission *permission,
157 GAsyncResult *result,
160 return G_PERMISSION_GET_CLASS (permission)
161 ->acquire_finish (permission, result, error);
165 * g_permission_release:
166 * @permission: a #GPermission instance
167 * @cancellable: (allow-none): a #GCancellable, or %NULL
168 * @error: a pointer to a %NULL #GError, or %NULL
170 * Attempts to release the permission represented by @permission.
172 * The precise method by which this happens depends on the permission
173 * and the underlying authentication mechanism. In most cases the
174 * permission will be dropped immediately without further action.
176 * You should check with g_permission_get_can_release() before calling
179 * If the permission is released then %TRUE is returned. Otherwise,
180 * %FALSE is returned and @error is set appropriately.
182 * This call is blocking, likely for a very long time (in the case that
183 * user interaction is required). See g_permission_release_async() for
184 * the non-blocking version.
186 * Returns: %TRUE if the permission was successfully released
191 g_permission_release (GPermission *permission,
192 GCancellable *cancellable,
195 return G_PERMISSION_GET_CLASS (permission)
196 ->release (permission, cancellable, error);
200 * g_permission_release_async:
201 * @permission: a #GPermission instance
202 * @cancellable: (allow-none): a #GCancellable, or %NULL
203 * @callback: the #GAsyncReadyCallback to call when done
204 * @user_data: the user data to pass to @callback
206 * Attempts to release the permission represented by @permission.
208 * This is the first half of the asynchronous version of
209 * g_permission_release().
214 g_permission_release_async (GPermission *permission,
215 GCancellable *cancellable,
216 GAsyncReadyCallback callback,
219 G_PERMISSION_GET_CLASS (permission)
220 ->release_async (permission, cancellable, callback, user_data);
224 * g_permission_release_finish:
225 * @permission: a #GPermission instance
226 * @result: the #GAsyncResult given to the #GAsyncReadyCallback
227 * @error: a pointer to a %NULL #GError, or %NULL
229 * Collects the result of attempting to release the permission
230 * represented by @permission.
232 * This is the second half of the asynchronous version of
233 * g_permission_release().
235 * Returns: %TRUE if the permission was successfully released
240 g_permission_release_finish (GPermission *permission,
241 GAsyncResult *result,
244 return G_PERMISSION_GET_CLASS (permission)
245 ->release_finish (permission, result, error);
249 * g_permission_get_allowed:
250 * @permission: a #GPermission instance
252 * Gets the value of the 'allowed' property. This property is %TRUE if
253 * the caller currently has permission to perform the action that
254 * @permission represents the permission to perform.
256 * Returns: the value of the 'allowed' property
261 g_permission_get_allowed (GPermission *permission)
263 return permission->priv->allowed;
267 * g_permission_get_can_acquire:
268 * @permission: a #GPermission instance
270 * Gets the value of the 'can-acquire' property. This property is %TRUE
271 * if it is generally possible to acquire the permission by calling
272 * g_permission_acquire().
274 * Returns: the value of the 'can-acquire' property
279 g_permission_get_can_acquire (GPermission *permission)
281 return permission->priv->can_acquire;
285 * g_permission_get_can_release:
286 * @permission: a #GPermission instance
288 * Gets the value of the 'can-release' property. This property is %TRUE
289 * if it is generally possible to release the permission by calling
290 * g_permission_release().
292 * Returns: the value of the 'can-release' property
297 g_permission_get_can_release (GPermission *permission)
299 return permission->priv->can_release;
303 * g_permission_impl_update:
304 * @permission: a #GPermission instance
305 * @allowed: the new value for the 'allowed' property
306 * @can_acquire: the new value for the 'can-acquire' property
307 * @can_release: the new value for the 'can-release' property
309 * This function is called by the #GPermission implementation to update
310 * the properties of the permission. You should never call this
311 * function except from a #GPermission implementation.
313 * GObject notify signals are generated, as appropriate.
318 g_permission_impl_update (GPermission *permission,
320 gboolean can_acquire,
321 gboolean can_release)
323 GObject *object = G_OBJECT (permission);
325 g_object_freeze_notify (object);
327 allowed = allowed != FALSE;
328 if (allowed != permission->priv->allowed)
330 permission->priv->allowed = allowed;
331 g_object_notify (object, "allowed");
334 can_acquire = can_acquire != FALSE;
335 if (can_acquire != permission->priv->can_acquire)
337 permission->priv->can_acquire = can_acquire;
338 g_object_notify (object, "can-acquire");
341 can_release = can_release != FALSE;
342 if (can_release != permission->priv->can_release)
344 permission->priv->can_release = can_release;
345 g_object_notify (object, "can-release");
348 g_object_thaw_notify (object);
352 g_permission_get_property (GObject *object, guint prop_id,
353 GValue *value, GParamSpec *pspec)
355 GPermission *permission = G_PERMISSION (object);
360 g_value_set_boolean (value, permission->priv->allowed);
363 case PROP_CAN_ACQUIRE:
364 g_value_set_boolean (value, permission->priv->can_acquire);
367 case PROP_CAN_RELEASE:
368 g_value_set_boolean (value, permission->priv->can_release);
372 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
377 g_permission_init (GPermission *permission)
379 permission->priv = g_permission_get_instance_private (permission);
383 acquire_or_release (GPermission *permission,
384 GCancellable *cancellable,
387 g_set_error_literal (error,
388 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
389 "Can't acquire or release permission");
394 acquire_or_release_async (GPermission *permission,
395 GCancellable *cancellable,
396 GAsyncReadyCallback callback,
399 g_simple_async_report_error_in_idle (G_OBJECT (permission),
401 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
402 "Can't acquire or release permission");
406 acquire_or_release_finish (GPermission *permission,
407 GAsyncResult *result,
410 g_async_result_legacy_propagate_error (result, error);
415 g_permission_class_init (GPermissionClass *class)
417 GObjectClass *object_class = G_OBJECT_CLASS (class);
419 object_class->get_property = g_permission_get_property;
421 class->acquire = acquire_or_release;
422 class->release = acquire_or_release;
423 class->acquire_async = acquire_or_release_async;
424 class->release_async = acquire_or_release_async;
425 class->acquire_finish = acquire_or_release_finish;
426 class->release_finish = acquire_or_release_finish;
429 * GPermission:allowed:
431 * %TRUE if the caller currently has permission to perform the action that
432 * @permission represents the permission to perform.
434 g_object_class_install_property (object_class, PROP_ALLOWED,
435 g_param_spec_boolean ("allowed",
437 P_("If the caller is allowed to perform the action"),
439 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
442 * GPermission:can-acquire:
444 * %TRUE if it is generally possible to acquire the permission by calling
445 * g_permission_acquire().
447 g_object_class_install_property (object_class, PROP_CAN_ACQUIRE,
448 g_param_spec_boolean ("can-acquire",
450 P_("If calling g_permission_acquire() makes sense"),
452 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
455 * GPermission:can-release:
457 * %TRUE if it is generally possible to release the permission by calling
458 * g_permission_release().
460 g_object_class_install_property (object_class, PROP_CAN_RELEASE,
461 g_param_spec_boolean ("can-release",
463 P_("If calling g_permission_release() makes sense"),
465 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));