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, see <http://www.gnu.org/licenses/>.
17 * Author: Ryan Lortie <desrt@desrt.ca>
22 #include "gpermission.h"
26 #include "gasyncresult.h"
27 #include "gsimpleasyncresult.h"
34 * @short_description: An object representing the permission
35 * to perform a certain action
38 * A #GPermission represents the status of the caller's permission to
39 * perform a certain action.
41 * You can query if the action is currently allowed and if it is
42 * possible to acquire the permission so that the action will be allowed
45 * There is also an API to actually acquire the permission and one to
48 * As an example, a #GPermission might represent the ability for the
49 * user to write to a #GSettings object. This #GPermission object could
50 * then be used to decide if it is appropriate to show a "Click here to
51 * unlock" button in a dialog and to provide the mechanism to invoke
52 * when that button is clicked.
58 * #GPermission is an opaque data structure and can only be accessed
59 * using the following functions.
62 struct _GPermissionPrivate
76 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GPermission, g_permission, G_TYPE_OBJECT)
79 * g_permission_acquire:
80 * @permission: a #GPermission instance
81 * @cancellable: (allow-none): a #GCancellable, or %NULL
82 * @error: a pointer to a %NULL #GError, or %NULL
84 * Attempts to acquire the permission represented by @permission.
86 * The precise method by which this happens depends on the permission
87 * and the underlying authentication mechanism. A simple example is
88 * that a dialog may appear asking the user to enter their password.
90 * You should check with g_permission_get_can_acquire() before calling
93 * If the permission is acquired then %TRUE is returned. Otherwise,
94 * %FALSE is returned and @error is set appropriately.
96 * This call is blocking, likely for a very long time (in the case that
97 * user interaction is required). See g_permission_acquire_async() for
98 * the non-blocking version.
100 * Returns: %TRUE if the permission was successfully acquired
105 g_permission_acquire (GPermission *permission,
106 GCancellable *cancellable,
109 return G_PERMISSION_GET_CLASS (permission)
110 ->acquire (permission, cancellable, error);
114 * g_permission_acquire_async:
115 * @permission: a #GPermission instance
116 * @cancellable: (allow-none): a #GCancellable, or %NULL
117 * @callback: the #GAsyncReadyCallback to call when done
118 * @user_data: the user data to pass to @callback
120 * Attempts to acquire the permission represented by @permission.
122 * This is the first half of the asynchronous version of
123 * g_permission_acquire().
128 g_permission_acquire_async (GPermission *permission,
129 GCancellable *cancellable,
130 GAsyncReadyCallback callback,
133 G_PERMISSION_GET_CLASS (permission)
134 ->acquire_async (permission, cancellable, callback, user_data);
138 * g_permission_acquire_finish:
139 * @permission: a #GPermission instance
140 * @result: the #GAsyncResult given to the #GAsyncReadyCallback
141 * @error: a pointer to a %NULL #GError, or %NULL
143 * Collects the result of attempting to acquire the permission
144 * represented by @permission.
146 * This is the second half of the asynchronous version of
147 * g_permission_acquire().
149 * Returns: %TRUE if the permission was successfully acquired
154 g_permission_acquire_finish (GPermission *permission,
155 GAsyncResult *result,
158 return G_PERMISSION_GET_CLASS (permission)
159 ->acquire_finish (permission, result, error);
163 * g_permission_release:
164 * @permission: a #GPermission instance
165 * @cancellable: (allow-none): a #GCancellable, or %NULL
166 * @error: a pointer to a %NULL #GError, or %NULL
168 * Attempts to release the permission represented by @permission.
170 * The precise method by which this happens depends on the permission
171 * and the underlying authentication mechanism. In most cases the
172 * permission will be dropped immediately without further action.
174 * You should check with g_permission_get_can_release() before calling
177 * If the permission is released then %TRUE is returned. Otherwise,
178 * %FALSE is returned and @error is set appropriately.
180 * This call is blocking, likely for a very long time (in the case that
181 * user interaction is required). See g_permission_release_async() for
182 * the non-blocking version.
184 * Returns: %TRUE if the permission was successfully released
189 g_permission_release (GPermission *permission,
190 GCancellable *cancellable,
193 return G_PERMISSION_GET_CLASS (permission)
194 ->release (permission, cancellable, error);
198 * g_permission_release_async:
199 * @permission: a #GPermission instance
200 * @cancellable: (allow-none): a #GCancellable, or %NULL
201 * @callback: the #GAsyncReadyCallback to call when done
202 * @user_data: the user data to pass to @callback
204 * Attempts to release the permission represented by @permission.
206 * This is the first half of the asynchronous version of
207 * g_permission_release().
212 g_permission_release_async (GPermission *permission,
213 GCancellable *cancellable,
214 GAsyncReadyCallback callback,
217 G_PERMISSION_GET_CLASS (permission)
218 ->release_async (permission, cancellable, callback, user_data);
222 * g_permission_release_finish:
223 * @permission: a #GPermission instance
224 * @result: the #GAsyncResult given to the #GAsyncReadyCallback
225 * @error: a pointer to a %NULL #GError, or %NULL
227 * Collects the result of attempting to release the permission
228 * represented by @permission.
230 * This is the second half of the asynchronous version of
231 * g_permission_release().
233 * Returns: %TRUE if the permission was successfully released
238 g_permission_release_finish (GPermission *permission,
239 GAsyncResult *result,
242 return G_PERMISSION_GET_CLASS (permission)
243 ->release_finish (permission, result, error);
247 * g_permission_get_allowed:
248 * @permission: a #GPermission instance
250 * Gets the value of the 'allowed' property. This property is %TRUE if
251 * the caller currently has permission to perform the action that
252 * @permission represents the permission to perform.
254 * Returns: the value of the 'allowed' property
259 g_permission_get_allowed (GPermission *permission)
261 return permission->priv->allowed;
265 * g_permission_get_can_acquire:
266 * @permission: a #GPermission instance
268 * Gets the value of the 'can-acquire' property. This property is %TRUE
269 * if it is generally possible to acquire the permission by calling
270 * g_permission_acquire().
272 * Returns: the value of the 'can-acquire' property
277 g_permission_get_can_acquire (GPermission *permission)
279 return permission->priv->can_acquire;
283 * g_permission_get_can_release:
284 * @permission: a #GPermission instance
286 * Gets the value of the 'can-release' property. This property is %TRUE
287 * if it is generally possible to release the permission by calling
288 * g_permission_release().
290 * Returns: the value of the 'can-release' property
295 g_permission_get_can_release (GPermission *permission)
297 return permission->priv->can_release;
301 * g_permission_impl_update:
302 * @permission: a #GPermission instance
303 * @allowed: the new value for the 'allowed' property
304 * @can_acquire: the new value for the 'can-acquire' property
305 * @can_release: the new value for the 'can-release' property
307 * This function is called by the #GPermission implementation to update
308 * the properties of the permission. You should never call this
309 * function except from a #GPermission implementation.
311 * GObject notify signals are generated, as appropriate.
316 g_permission_impl_update (GPermission *permission,
318 gboolean can_acquire,
319 gboolean can_release)
321 GObject *object = G_OBJECT (permission);
323 g_object_freeze_notify (object);
325 allowed = allowed != FALSE;
326 if (allowed != permission->priv->allowed)
328 permission->priv->allowed = allowed;
329 g_object_notify (object, "allowed");
332 can_acquire = can_acquire != FALSE;
333 if (can_acquire != permission->priv->can_acquire)
335 permission->priv->can_acquire = can_acquire;
336 g_object_notify (object, "can-acquire");
339 can_release = can_release != FALSE;
340 if (can_release != permission->priv->can_release)
342 permission->priv->can_release = can_release;
343 g_object_notify (object, "can-release");
346 g_object_thaw_notify (object);
350 g_permission_get_property (GObject *object, guint prop_id,
351 GValue *value, GParamSpec *pspec)
353 GPermission *permission = G_PERMISSION (object);
358 g_value_set_boolean (value, permission->priv->allowed);
361 case PROP_CAN_ACQUIRE:
362 g_value_set_boolean (value, permission->priv->can_acquire);
365 case PROP_CAN_RELEASE:
366 g_value_set_boolean (value, permission->priv->can_release);
370 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
375 g_permission_init (GPermission *permission)
377 permission->priv = g_permission_get_instance_private (permission);
381 acquire_or_release (GPermission *permission,
382 GCancellable *cancellable,
385 g_set_error_literal (error,
386 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
387 "Can't acquire or release permission");
392 acquire_or_release_async (GPermission *permission,
393 GCancellable *cancellable,
394 GAsyncReadyCallback callback,
397 g_simple_async_report_error_in_idle (G_OBJECT (permission),
399 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
400 "Can't acquire or release permission");
404 acquire_or_release_finish (GPermission *permission,
405 GAsyncResult *result,
408 g_async_result_legacy_propagate_error (result, error);
413 g_permission_class_init (GPermissionClass *class)
415 GObjectClass *object_class = G_OBJECT_CLASS (class);
417 object_class->get_property = g_permission_get_property;
419 class->acquire = acquire_or_release;
420 class->release = acquire_or_release;
421 class->acquire_async = acquire_or_release_async;
422 class->release_async = acquire_or_release_async;
423 class->acquire_finish = acquire_or_release_finish;
424 class->release_finish = acquire_or_release_finish;
427 * GPermission:allowed:
429 * %TRUE if the caller currently has permission to perform the action that
430 * @permission represents the permission to perform.
432 g_object_class_install_property (object_class, PROP_ALLOWED,
433 g_param_spec_boolean ("allowed",
435 P_("If the caller is allowed to perform the action"),
437 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
440 * GPermission:can-acquire:
442 * %TRUE if it is generally possible to acquire the permission by calling
443 * g_permission_acquire().
445 g_object_class_install_property (object_class, PROP_CAN_ACQUIRE,
446 g_param_spec_boolean ("can-acquire",
448 P_("If calling g_permission_acquire() makes sense"),
450 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
453 * GPermission:can-release:
455 * %TRUE if it is generally possible to release the permission by calling
456 * g_permission_release().
458 g_object_class_install_property (object_class, PROP_CAN_RELEASE,
459 g_param_spec_boolean ("can-release",
461 P_("If calling g_permission_release() makes sense"),
463 G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));