LCOV - Code Coverage - Accounts/account.cpp

LCOV - code coverage report
Current view: | top level - Accounts - account.cpp (source / functions) |  |  | Hit | Total | Coverage
Test: | Code Coverage |  | Lines: | 263 | 279 | 94.3 %
Date: | 2013-04-26 |  | Functions: | 54 | 57 | 94.7 %
Legend: | Lines: hit not hit | Branches: + taken - not taken # not executed |  | Branches: | 81 | 105 | 77.1 %

               Branch data     Line data    Source code
           1                 :            : /* vi: set et sw=4 ts=4 cino=t0,(0: */
           2                 :            : /*
           3                 :            :  * This file is part of libaccounts-qt
           4                 :            :  *
           5                 :            :  * Copyright (C) 2009-2011 Nokia Corporation.
           6                 :            :  * Copyright (C) 2012-2013 Canonical Ltd.
           7                 :            :  *
           8                 :            :  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
           9                 :            :  *
          10                 :            :  * This library is free software; you can redistribute it and/or
          11                 :            :  * modify it under the terms of the GNU Lesser General Public License
          12                 :            :  * version 2.1 as published by the Free Software Foundation.
          13                 :            :  *
          14                 :            :  * This library is distributed in the hope that it will be useful, but
          15                 :            :  * WITHOUT ANY WARRANTY; without even the implied warranty of
          16                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
          17                 :            :  * Lesser General Public License for more details.
          18                 :            :  *
          19                 :            :  * You should have received a copy of the GNU Lesser General Public
          20                 :            :  * License along with this library; if not, write to the Free Software
          21                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
          22                 :            :  * 02110-1301 USA
          23                 :            :  */
          24                 :            :
          25                 :            : #include "account.h"
          26                 :            : #include "manager.h"
          27                 :            : #include "manager_p.h"
          28                 :            : #include "utils.h"
          29                 :            :
          30                 :            : #include <QPointer>
          31                 :            : #include <libaccounts-glib/ag-account.h>
          32                 :            :
          33                 :            : namespace Accounts {
          34                 :            :
          35                 :            : /*!
          36                 :            :  * @class Watch
          37                 :            :  * @headerfile account.h Accounts/Account
          38                 :            :  *
          39                 :            :  * @brief Monitors an account key or group of keys.
          40                 :            :  *
          41                 :            :  * @details A watch is created via the Account::watch method and is a simple
          42                 :            :  * object which will emit the notify() signal when the value of the key (or
          43                 :            :  * group) that it is monitoring is changed.
          44                 :            :  */
          45                 :            :
          46                 :            : /*!
          47                 :            :  * @class Account
          48                 :            :  * @headerfile account.h Accounts/Account
          49                 :            :  *
          50                 :            :  * @brief The Account class provides an interface to account settings.
          51                 :            :  *
          52                 :            :  * @details The Account class is used to access the account and service settings.
          53                 :            :  * This class has no constructor, therefore to instantiate one Account object
          54                 :            :  * one has to either use the Manager::createAccount method (to create a new
          55                 :            :  * empty account) or Manager::account (to load an existing account).
          56                 :            :  *
          57                 :            :  * @attention Do not call setParent() on an account object; the Account class
          58                 :            :  * assumes that the parent is always the Manager, and changing it will have
          59                 :            :  * unpredictable results.
          60                 :            :  *
          61                 :            :  * Most of the methods in the Account class act on the selected service: for
          62                 :            :  * example, calling setEnabled(false) on the NULL service (this is the service
          63                 :            :  * to be used for changing settings globally on the account) will disable the
          64                 :            :  * account, while the code
          65                 :            :  * \code
          66                 :            :  * account->selectService(myService);
          67                 :            :  * account->setEnabled(false);
          68                 :            :  * \endcode
          69                 :            :  * will disable the "myService" service.
          70                 :            :  *
          71                 :            :  * All changes made on an account (including deletion) are not stored until
          72                 :            :  * sync() is called.
          73                 :            :  */
          74                 :            :
          75                 :            : class Account::Private
          76                 :            : {
          77                 :            : public:
          78                 :            :     Private(Manager *manager, const QString &providerName, Account *account);
          79                 :            :     Private(Manager *manager, AgAccount *agAccount);
          80                 :            :
          81                 :         33 :     ~Private()
          82                 :         33 :     {
          83                 :         33 :         g_cancellable_cancel(m_cancellable);
          84                 :         33 :         g_object_unref(m_cancellable);
          85                 :         33 :         m_cancellable = NULL;
          86                 :         33 :     }
          87                 :            :
          88                 :            :     void init(Account *account);
          89                 :            :
          90                 :            :     QPointer<Manager> m_manager;
          91                 :            :     AgAccount *m_account;  //real account
          92                 :            :     GCancellable *m_cancellable;
          93                 :            :     QString prefix;
          94                 :            :
          95                 :            :     static void on_display_name_changed(Account *self);
          96                 :            :     static void on_enabled(Account *self, const gchar *service_name,
          97                 :            :                            gboolean enabled);
          98                 :            :     static void account_store_cb(AgAccount *account,
          99                 :            :                                  GAsyncResult *res,
         100                 :            :                                  Account *self);
         101                 :            :     static void on_deleted(Account *self);
         102                 :            : };
         103                 :            :
         104                 :            : class Watch::Private
         105                 :            : {
         106                 :            : public:
         107                 :            :     static void account_notify_cb(AgAccount *account, const gchar *key,
         108                 :            :                                   Watch *self);
         109                 :            : };
         110                 :            : } //namespace Accounts
         111                 :            :
         112                 :            :
         113                 :            : using namespace Accounts;
         114                 :            :
         115                 :          1 : static QChar slash = QChar::fromLatin1('/');
         116                 :            :
         117                 :            : /*!
         118                 :            :  * @fn Watch::notify(const char *key)
         119                 :            :  *
         120                 :            :  * Emitted when the value of the keys monitored by this watch change.
         121                 :            :  * @param key The string that was used to create this watch. Note that if
         122                 :            :  * this watch is monitor multiple keys this param only identifies their
         123                 :            :  * common prefix, and not the actual key being changed.
         124                 :            :  */
         125                 :            :
         126                 :          3 : Watch::Watch(QObject *parent):
         127                 :          3 :     QObject(parent)
         128                 :            : {
         129                 :          3 : }
         130                 :            :
         131                 :          3 : Watch::~Watch()
         132                 :            : {
         133                 :          3 :     Account *account = qobject_cast<Account *>(QObject::parent());
         134                 :            :     /* The destructor of Account deletes the child Watches before detaching
         135                 :            :      * them, so here account should always be not NULL */
         136                 :            :     Q_ASSERT(account != NULL);
         137                 :          3 :     ag_account_remove_watch(account->d->m_account, watch);
         138                 :          6 : }
         139                 :            :
         140                 :         30 : Account::Private::Private(Manager *manager, const QString &providerName,
         141                 :            :                           Account *account):
         142                 :            :     m_manager(manager),
         143                 :         30 :     m_cancellable(g_cancellable_new())
         144                 :            : {
         145                 :            :     m_account = ag_manager_create_account(manager->d->m_manager,
         146                 :         30 :                                           providerName.toUtf8().constData());
         147                 :         30 :     init(account);
         148                 :         30 : }
         149                 :            :
         150                 :          3 : Account::Private::Private(Manager *manager, AgAccount *agAccount):
         151                 :            :     m_manager(manager),
         152                 :            :     m_account(agAccount),
         153                 :          3 :     m_cancellable(g_cancellable_new())
         154                 :            : {
         155                 :          3 : }
         156                 :            :
         157                 :         33 : void Account::Private::init(Account *account)
         158                 :            : {
         159         [ +  - ]:         66 :     if (m_account == 0) return;
         160                 :            :     g_signal_connect_swapped(m_account, "display-name-changed",
         161                 :            :                              G_CALLBACK(&Private::on_display_name_changed),
         162                 :         33 :                              account);
         163                 :         33 :     g_signal_connect_swapped(m_account, "enabled",
         164                 :         33 :                              G_CALLBACK(&Private::on_enabled), account);
         165                 :         33 :     g_signal_connect_swapped(m_account, "deleted",
         166                 :         33 :                              G_CALLBACK(&Private::on_deleted), account);
         167                 :            : }
         168                 :            :
         169                 :          2 : void Account::Private::on_display_name_changed(Account *self)
         170                 :            : {
         171                 :          2 :     const gchar *name = ag_account_get_display_name(self->d->m_account);
         172                 :            :
         173                 :          2 :     Q_EMIT self->displayNameChanged(UTF8(name));
         174                 :          2 : }
         175                 :            :
         176                 :         18 : void Account::Private::on_enabled(Account *self, const gchar *service_name,
         177                 :            :                                   gboolean enabled)
         178                 :            : {
         179                 :         18 :     Q_EMIT self->enabledChanged(UTF8(service_name), enabled);
         180                 :         18 : }
         181                 :            :
         182                 :          2 : void Account::Private::on_deleted(Account *self)
         183                 :            : {
         184                 :          2 :     TRACE();
         185                 :            :
         186                 :          2 :     Q_EMIT self->removed();
         187                 :          2 : }
         188                 :            :
         189                 :            : /*!
         190                 :            :  * @fn Account::error(Accounts::Error error)
         191                 :            :  *
         192                 :            :  * Emitted when an error occurs.
         193                 :            :  */
         194                 :            :
         195                 :            : /*!
         196                 :            :  * Constructs a new Account. The account exists only in memory and is not
         197                 :            :  * visible to other applications (or Manager instances) until sync() has been
         198                 :            :  * called.
         199                 :            :  * @param manager The account manager. Do not destroy it while the account
         200                 :            :  * object is in use.
         201                 :            :  * @param providerName Name of the provider for the account.
         202                 :            :  * @param parent Parent object.
         203                 :            :  */
         204                 :         30 : Account::Account(Manager *manager, const QString &providerName,
         205                 :            :                  QObject *parent):
         206                 :            :     QObject(parent),
         207                 :         30 :     d(new Private(manager, providerName, this))
         208                 :            : {
         209                 :         30 : }
         210                 :            :
         211                 :          3 : Account::Account(Private *d, QObject *parent):
         212                 :            :     QObject(parent),
         213                 :          3 :     d(d)
         214                 :            : {
         215                 :          3 :     d->init(this);
         216                 :          3 : }
         217                 :            :
         218                 :            : /*!
         219                 :            :  * Constructs an Account object representing an account stored in the database.
         220                 :            :  * @param manager The account manager. Do not destroy it while the account
         221                 :            :  * object is in use.
         222                 :            :  * @param id The numeric identifier of the account.
         223                 :            :  * @param parent Parent object.
         224                 :            :  *
         225                 :            :  * @return A new account object, or 0 if an error occurred.
         226                 :            :  */
         227                 :          5 : Account *Account::fromId(Manager *manager, AccountId id, QObject *parent)
         228                 :            : {
         229                 :          5 :     GError *error = 0;
         230                 :            :     AgAccount *account = ag_manager_load_account(manager->d->m_manager, id,
         231                 :          5 :                                                  &error);
         232         [ +  + ]:          5 :     if (account == 0) {
         233                 :            :         Q_ASSERT(error != 0);
         234                 :          2 :         manager->d->lastError = Error(error);
         235                 :          2 :         g_error_free(error);
         236                 :            :         return 0;
         237                 :            :     }
         238                 :            :     Q_ASSERT(error == 0);
         239                 :          5 :     return new Account(new Private(manager, account), parent);
         240                 :            : }
         241                 :            :
         242                 :            : /*!
         243                 :            :  * Destroys the current account object and free all resources.
         244                 :            :  */
         245                 :         33 : Account::~Account()
         246                 :            : {
         247                 :         33 :     QObjectList list = children();
         248         [ +  + ]:         35 :     for (int i = 0; i < list.count(); i++)
         249                 :            :     {
         250                 :          2 :         QObject *o = list.at(i);
         251         [ +  - ]:          2 :         if (qobject_cast<Watch *>(o))
         252         [ +  - ]:          2 :             delete o;
         253                 :            :     }
         254                 :            :
         255                 :         33 :     g_signal_handlers_disconnect_by_func
         256                 :         33 :         (d->m_account, (void *)&Private::on_display_name_changed, this);
         257                 :         33 :     g_signal_handlers_disconnect_by_func
         258                 :         33 :         (d->m_account, (void *)&Private::on_enabled, this);
         259                 :         33 :     g_signal_handlers_disconnect_by_func
         260                 :         33 :         (d->m_account, (void *)&Private::on_deleted, this);
         261                 :         33 :     g_object_unref(d->m_account);
         262         [ +  - ]:         33 :     delete d;
         263                 :         33 :     d = 0;
         264                 :         66 : }
         265                 :            :
         266                 :            : /*!
         267                 :            :  * Returns the AccountId of this account (0 if the account has not yet been
         268                 :            :  * stored into the database).
         269                 :            :  */
         270                 :         12 : AccountId Account::id() const
         271                 :            : {
         272         [ +  - ]:         12 :     return d->m_account ? d->m_account->id : 0;
         273                 :            : }
         274                 :            :
         275                 :            : /*!
         276                 :            :  * Returns the Manager.
         277                 :            :  */
         278                 :          6 : Manager *Account::manager() const
         279                 :            : {
         280                 :          6 :     return d->m_manager;
         281                 :            : }
         282                 :            :
         283                 :            : /*!
         284                 :            :  * Checks whether the account supports the given service.
         285                 :            :  */
         286                 :          2 : bool Account::supportsService(const QString &serviceType) const
         287                 :            : {
         288                 :            :     return ag_account_supports_service(d->m_account,
         289                 :          2 :                                        serviceType.toUtf8().constData());
         290                 :            : }
         291                 :            :
         292                 :            : /*!
         293                 :            :  * Returns a list of services supported by this account. If the manager was
         294                 :            :  * constructed with given service type only the services which supports the
         295                 :            :  * service type will be returned.
         296                 :            :  *
         297                 :            :  * This is currently computed by returning all services having the same
         298                 :            :  * provider as the account.
         299                 :            :  */
         300                 :          3 : ServiceList Account::services(const QString &serviceType) const
         301                 :            : {
         302                 :            :     GList *list;
         303         [ +  + ]:          3 :     if (serviceType.isEmpty()) {
         304                 :          1 :         list = ag_account_list_services(d->m_account);
         305                 :            :     } else {
         306                 :            :         list = ag_account_list_services_by_type(d->m_account,
         307                 :          2 :             serviceType.toUtf8().constData());
         308                 :            :     }
         309                 :            :
         310                 :            :     /* convert glist -> ServiceList */
         311                 :            :     ServiceList servList;
         312                 :            :     GList *iter;
         313         [ +  + ]:          5 :     for (iter = list; iter; iter = iter->next)
         314                 :            :     {
         315                 :          2 :         AgService *service = (AgService*)iter->data;
         316                 :          2 :         servList.append(Service(service, StealReference));
         317                 :            :     }
         318                 :            :
         319                 :          3 :     g_list_free(list);
         320                 :            :
         321                 :          3 :     return servList;
         322                 :            : }
         323                 :            :
         324                 :            : /*!
         325                 :            :  * Returns a list of enabled services supported by this account. If the manager
         326                 :            :  * was constructed with given service type only the services which supports the
         327                 :            :  * service type will be returned.
         328                 :            :  */
         329                 :          2 : ServiceList Account::enabledServices() const
         330                 :            : {
         331                 :            :     GList *list;
         332                 :          2 :     list = ag_account_list_enabled_services(d->m_account);
         333                 :            :
         334                 :            :     /* convert glist -> ServiceList */
         335                 :            :     ServiceList servList;
         336                 :            :     GList *iter;
         337 [ +  - ][ +  + ]:          3 :     for (iter = list; iter; iter = g_list_next(iter))
         338                 :            :     {
         339                 :          1 :         AgService *service = (AgService*)iter->data;
         340                 :          1 :         servList.append(Service(service, StealReference));
         341                 :            :     }
         342                 :            :
         343                 :          2 :     g_list_free(list);
         344                 :            :
         345                 :          2 :     return servList;
         346                 :            : }
         347                 :            :
         348                 :            : /*!
         349                 :            :  * Checks whether the account or selected service is enabled.
         350                 :            :  *
         351                 :            :  * This method operates on the currently selected service or
         352                 :            :  * globally, if none selected.
         353                 :            :  */
         354                 :          2 : bool Account::enabled() const
         355                 :            : {
         356                 :          2 :     return ag_account_get_enabled(d->m_account);
         357                 :            : }
         358                 :            :
         359                 :            : /*!
         360                 :            :  * Enables/disables the account or selected service.
         361                 :            :  * The change will be written only when sync() is called.
         362                 :            :  *
         363                 :            :  * This method operates on the currently selected service or
         364                 :            :  * globally, if none selected.
         365                 :            :  */
         366                 :         15 : void Account::setEnabled(bool enabled)
         367                 :            : {
         368                 :         15 :     ag_account_set_enabled(d->m_account, enabled);
         369                 :         15 : }
         370                 :            :
         371                 :            : /*!
         372                 :            :  * Returns the display name of the account.
         373                 :            :  *
         374                 :            :  * This method operates on the currently selected service.
         375                 :            :  */
         376                 :          3 : QString Account::displayName() const
         377                 :            : {
         378                 :          3 :     return UTF8(ag_account_get_display_name(d->m_account));
         379                 :            : }
         380                 :            :
         381                 :            : /*!
         382                 :            :  * Changes the display name of the account.
         383                 :            :  * The change will be written only when sync() is called.
         384                 :            :  */
         385                 :          2 : void Account::setDisplayName(const QString &displayName)
         386                 :            : {
         387                 :            :     ag_account_set_display_name(d->m_account,
         388                 :          2 :                                 displayName.toUtf8().constData());
         389                 :          2 : }
         390                 :            :
         391                 :            : /*!
         392                 :            :  * Returns the name of the provider of the account.
         393                 :            :  */
         394                 :          6 : QString Account::providerName() const
         395                 :            : {
         396                 :          6 :     return UTF8(ag_account_get_provider_name(d->m_account));
         397                 :            : }
         398                 :            :
         399                 :            : /*!
         400                 :            :  * Returns the provider of the account.
         401                 :            :  */
         402                 :          1 : Provider Account::provider() const
         403                 :            : {
         404                 :          1 :     return manager()->provider(providerName());
         405                 :            : }
         406                 :            :
         407                 :            : /*!
         408                 :            :  * Select the Service for the subsequent operations.
         409                 :            :  * @param service The Service to select. If this is invalid, the global
         410                 :            :  * account settings will be selected.
         411                 :            :  */
         412                 :         19 : void Account::selectService(const Service &service)
         413                 :            : {
         414                 :            :     AgService *agService = NULL;
         415                 :            :
         416         [ +  + ]:         19 :     if (service.isValid())
         417                 :         13 :         agService = service.service();
         418                 :            :
         419                 :         19 :     ag_account_select_service(d->m_account, agService);
         420                 :         19 :     d->prefix = QString();
         421                 :         19 : }
         422                 :            :
         423                 :            : /*!
         424                 :            :  * @return The currently selected service.
         425                 :            :  */
         426                 :          3 : Service Account::selectedService() const
         427                 :            : {
         428                 :          3 :     AgService *agService = ag_account_get_selected_service(d->m_account);
         429                 :          3 :     return Service(agService);
         430                 :            : }
         431                 :            :
         432                 :            : /*!
         433                 :            :  * Returns all keys in the current group.
         434                 :            :  *
         435                 :            :  * This method operates on the currently selected service.
         436                 :            :  */
         437                 :         12 : QStringList Account::allKeys() const
         438                 :            : {
         439                 :            :     QStringList allKeys;
         440                 :            :     AgAccountSettingIter iter;
         441                 :            :     const gchar *key;
         442                 :            :     GVariant *val;
         443                 :            :
         444                 :            :     /* iterate the settings */
         445                 :         12 :     QByteArray tmp = d->prefix.toLatin1();
         446                 :         12 :     ag_account_settings_iter_init(d->m_account, &iter, tmp.constData());
         447         [ +  + ]:         71 :     while (ag_account_settings_iter_get_next(&iter, &key, &val))
         448                 :            :     {
         449                 :         59 :         allKeys.append(QString(ASCII(key)));
         450                 :            :     }
         451                 :         12 :     return allKeys;
         452                 :            : }
         453                 :            :
         454                 :            : /*!
         455                 :            :  * Enters a group. This method never fails.
         456                 :            :  * @param prefix
         457                 :            :  *
         458                 :            :  * This method operates on the currently selected service.
         459                 :            :  */
         460                 :          7 : void Account::beginGroup(const QString &prefix)
         461                 :            : {
         462                 :          7 :     d->prefix += prefix + slash;
         463                 :          7 : }
         464                 :            :
         465                 :            : /*!
         466                 :            :  * Returns all the groups which are direct children of the current group.
         467                 :            :  *
         468                 :            :  * This method operates on the currently selected service.
         469                 :            :  */
         470                 :          2 : QStringList Account::childGroups() const
         471                 :            : {
         472                 :            :     QStringList groups, all_keys;
         473                 :            :
         474                 :          2 :     all_keys = allKeys();
         475 [ +  - ][ +  + ]:         15 :     Q_FOREACH (QString key, all_keys)
                     [ +  + ]
         476                 :            :     {
         477         [ +  + ]:         13 :         if (key.contains(slash)) {
         478                 :          8 :             QString group = key.section(slash, 0, 0);
         479         [ +  + ]:          8 :             if (!groups.contains(group))
         480                 :          8 :                 groups.append(group);
         481                 :            :         }
         482                 :         15 :     }
         483                 :          2 :     return groups;
         484                 :            : }
         485                 :            :
         486                 :            : /*!
         487                 :            :  * Return all the keys which are direct children of the current group.
         488                 :            :  *
         489                 :            :  * This method operates on the currently selected service.
         490                 :            :  */
         491                 :          4 : QStringList Account::childKeys() const
         492                 :            : {
         493                 :            :     QStringList keys, all_keys;
         494                 :            :
         495                 :          4 :     all_keys = allKeys();
         496 [ +  - ][ +  + ]:         25 :     Q_FOREACH (QString key, all_keys)
                     [ +  + ]
         497                 :            :     {
         498         [ +  + ]:         21 :         if (!key.contains(slash))
         499                 :          9 :             keys.append(key);
         500                 :         25 :     }
         501                 :          4 :     return keys;
         502                 :            : }
         503                 :            :
         504                 :            : /*!
         505                 :            :  * Removes all the keys in the currently selected service.
         506                 :            :  * @see remove(const QString &key)
         507                 :            :  */
         508                 :          1 : void Account::clear()
         509                 :            : {
         510                 :            :     /* clear() must ignore the group: so, temporarily reset it and call
         511                 :            :      * remove("") */
         512                 :          1 :     QString saved_prefix = d->prefix;
         513                 :          1 :     d->prefix = QString();
         514                 :          1 :     remove(QString());
         515                 :          1 :     d->prefix = saved_prefix;
         516                 :          1 : }
         517                 :            :
         518                 :            : /*!
         519                 :            :  * Checks whether the given key is in the current group.
         520                 :            :  * @param key The key name of the settings.
         521                 :            :  *
         522                 :            :  * This method operates on the currently selected service.
         523                 :            :  */
         524                 :          2 : bool Account::contains(const QString &key) const
         525                 :            : {
         526                 :          4 :     return childKeys().contains(key);
         527                 :            : }
         528                 :            :
         529                 :            : /*!
         530                 :            :  * Exits a group.
         531                 :            :  *
         532                 :            :  * This method operates on the currently selected service.
         533                 :            :  */
         534                 :          5 : void Account::endGroup()
         535                 :            : {
         536                 :            :     d->prefix = d->prefix.section(slash, 0, -3,
         537                 :          5 :                                   QString::SectionIncludeTrailingSep);
         538         [ +  + ]:          5 :     if (d->prefix[0] == slash) d->prefix.remove(0, 1);
         539                 :          5 : }
         540                 :            :
         541                 :            : /*!
         542                 :            :  * Returns the name of the current group.
         543                 :            :  *
         544                 :            :  * This method operates on the currently selected service.
         545                 :            :  */
         546                 :          4 : QString Account::group() const
         547                 :            : {
         548         [ +  - ]:          4 :     if (d->prefix.endsWith(slash))
         549                 :          4 :         return d->prefix.left(d->prefix.size() - 1);
         550                 :          0 :     return d->prefix;
         551                 :            : }
         552                 :            :
         553                 :            : /*!
         554                 :            :  * Checks whether the account is writable. This always returns true.
         555                 :            :  */
         556                 :          1 : bool Account::isWritable() const
         557                 :            : {
         558                 :          1 :     return true;
         559                 :            : }
         560                 :            :
         561                 :            : /*!
         562                 :            :  * Removes the given key. If the key is the empty string, all keys in the
         563                 :            :  * current group are removed.
         564                 :            :  * @param key The key name of the settings.
         565                 :            :  *
         566                 :            :  * This method operates on the currently selected service.
         567                 :            :  */
         568                 :         11 : void Account::remove(const QString &key)
         569                 :            : {
         570         [ +  + ]:         11 :     if (key.isEmpty())
         571                 :            :     {
         572                 :            :         /* delete all keys in the group */
         573                 :          2 :         QStringList keys = allKeys();
         574 [ +  - ][ +  + ]:         10 :         Q_FOREACH (QString key, keys)
                     [ +  + ]
         575                 :            :         {
         576         [ +  - ]:          8 :             if (!key.isEmpty())
         577                 :          8 :                 remove(key);
         578                 :         10 :         }
         579                 :            :     }
         580                 :            :     else
         581                 :            :     {
         582                 :          9 :         QString full_key = d->prefix + key;
         583                 :          9 :         QByteArray tmpkey = full_key.toLatin1();
         584                 :          9 :         ag_account_set_variant(d->m_account, tmpkey.constData(), NULL);
         585                 :            :     }
         586                 :         11 : }
         587                 :            :
         588                 :            : /*!
         589                 :            :  * Changes the value of an account setting.
         590                 :            :  * @param key The key name of the setting.
         591                 :            :  * @param value The new value.
         592                 :            :  *
         593                 :            :  * This method operates on the currently selected service.
         594                 :            :  */
         595                 :         34 : void Account::setValue(const QString &key, const QVariant &value)
         596                 :            : {
         597                 :         34 :     GVariant *variant = qVariantToGVariant(value);
         598         [ +  - ]:         34 :     if (variant == 0) {
         599                 :         34 :         return;
         600                 :            :     }
         601                 :            :
         602                 :         34 :     QString full_key = d->prefix + key;
         603                 :         34 :     QByteArray tmpkey = full_key.toLatin1();
         604                 :         34 :     ag_account_set_variant(d->m_account, tmpkey.constData(), variant);
         605                 :            : }
         606                 :            :
         607                 :          7 : void Account::Private::account_store_cb(AgAccount *account,
         608                 :            :                                         GAsyncResult *res,
         609                 :            :                                         Account *self)
         610                 :            : {
         611                 :          7 :     TRACE() << "Saved accunt ID:" << account->id;
         612                 :            :
         613                 :          7 :     GError *error = NULL;
         614                 :          7 :     ag_account_store_finish(account, res, &error);
         615         [ +  + ]:          7 :     if (error) {
         616 [ +  - ][ -  + ]:          5 :         if (error->domain == G_IO_ERROR &&
                     [ +  - ]
         617                 :            :             error->code == G_IO_ERROR_CANCELLED) {
         618                 :          5 :             TRACE() << "Account destroyed, operation cancelled";
         619                 :            :         } else {
         620                 :          0 :             Q_EMIT self->error(Error(error));
         621                 :            :         }
         622                 :          5 :         g_error_free(error);
         623                 :            :     } else {
         624                 :          2 :         Q_EMIT self->synced();
         625                 :            :     }
         626                 :          7 : }
         627                 :            :
         628                 :            : /*!
         629                 :            :  * Retrieves the value of an account setting, as a QVariant.
         630                 :            :  * @param key The key whose value must be retrieved.
         631                 :            :  * @param defaultValue Value returned if the key is unset.
         632                 :            :  * @param source Indicates whether the value comes from the account, the
         633                 :            :  * service template or was unset.
         634                 :            :  * @see valueAsString
         635                 :            :  * @see valueAsInt
         636                 :            :  * @see valueAsBool
         637                 :            :  *
         638                 :            :  * @return The value associated to \a key.
         639                 :            :  *
         640                 :            :  * This method operates on the currently selected service.
         641                 :            :  */
         642                 :         20 : QVariant Account::value(const QString &key, const QVariant &defaultValue,
         643                 :            :                         SettingSource *source) const
         644                 :            : {
         645                 :         20 :     QString full_key = d->prefix + key;
         646                 :         20 :     QByteArray ba = full_key.toLatin1();
         647                 :            :     AgSettingSource settingSource;
         648                 :            :     GVariant *variant =
         649                 :         20 :         ag_account_get_variant(d->m_account, ba.constData(), &settingSource);
         650         [ +  + ]:         20 :     if (source != 0) {
         651      [ +  +  + ]:         16 :         switch (settingSource) {
         652                 :         12 :         case AG_SETTING_SOURCE_ACCOUNT: *source = ACCOUNT; break;
         653                 :          2 :         case AG_SETTING_SOURCE_PROFILE: *source = TEMPLATE; break;
         654                 :          2 :         default: *source = NONE; break;
         655                 :            :         }
         656                 :            :     }
         657                 :            :
         658         [ +  + ]:         20 :     return (variant != 0) ? gVariantToQVariant(variant) : defaultValue;
         659                 :            : }
         660                 :            :
         661                 :            : /*!
         662                 :            :  * Retrieves the value of an account setting, as a QVariant.
         663                 :            :  * @param key The key whose value must be retrieved.
         664                 :            :  * @param value A QVariant initialized to the expected type of the value.
         665                 :            :  * @see valueAsString
         666                 :            :  * @see valueAsInt
         667                 :            :  * @see valueAsBool
         668                 :            :  *
         669                 :            :  * @return Whether the value comes from the account, the service template
         670                 :            :  * or was unset.
         671                 :            :  *
         672                 :            :  * This method operates on the currently selected service.
         673                 :            :  * @deprecated Use value(const QString &key, const QVariant &defaultValue,
         674                 :            :  * SettingSource *source) const instead.
         675                 :            :  */
         676                 :         16 : SettingSource Account::value(const QString &key, QVariant &value) const
         677                 :            : {
         678                 :            :     SettingSource source;
         679                 :         16 :     QVariant variant = this->value(key, QVariant(), &source);
         680         [ +  + ]:         16 :     if (variant.isValid()) {
         681         [ +  + ]:         14 :         if (value.type() != variant.type()) {
         682         [ -  + ]:          3 :             if (!variant.convert(value.type())) source = NONE;
         683                 :            :         }
         684                 :         14 :         value = variant;
         685                 :            :     }
         686                 :            :
         687                 :         16 :     return source;
         688                 :            : }
         689                 :            :
         690                 :            : /*!
         691                 :            :  * Gets an account setting as a string.
         692                 :            :  * @param key The key whose value must be retrieved.
         693                 :            :  * @param default_value Value returned if the key is unset.
         694                 :            :  * @param source Indicates whether the value comes from the account, the
         695                 :            :  * service template or was unset.
         696                 :            :  *
         697                 :            :  * This method operates on the currently selected service.
         698                 :            :  */
         699                 :          3 : QString Account::valueAsString(const QString &key,
         700                 :            :                                QString default_value,
         701                 :            :                                SettingSource *source) const
         702                 :            : {
         703                 :          3 :     QVariant var = default_value;
         704                 :          3 :     SettingSource src = value(key, var);
         705         [ +  + ]:          3 :     if (source)
         706                 :          1 :         *source = src;
         707                 :          3 :     return var.toString();
         708                 :            : }
         709                 :            :
         710                 :            : /*!
         711                 :            :  * Gets an account setting as an integer.
         712                 :            :  * @param key The key whose value must be retrieved.
         713                 :            :  * @param default_value Value returned if the key is unset.
         714                 :            :  * @param source Indicates whether the value comes from the account, the
         715                 :            :  * service template or was unset.
         716                 :            :  *
         717                 :            :  * This method operates on the currently selected service.
         718                 :            :  */
         719                 :          2 : int Account::valueAsInt(const QString &key,
         720                 :            :                         int default_value,
         721                 :            :                         SettingSource *source) const
         722                 :            : {
         723                 :          2 :     QVariant var = default_value;
         724                 :          2 :     SettingSource src = value(key, var);
         725         [ +  + ]:          2 :     if (source)
         726                 :          1 :         *source = src;
         727                 :          2 :     return var.toInt();
         728                 :            : }
         729                 :            :
         730                 :            : /*!
         731                 :            :  * Gets an account setting as an unsigned long integer.
         732                 :            :  * @param key The key of which value must be retrieved.
         733                 :            :  * @param default_value Value returned if the key is unset.
         734                 :            :  * @param source Indicates whether the value comes from the account, the
         735                 :            :  * service template or was unset.
         736                 :            :  *
         737                 :            :  * This method operates on the currently selected service.
         738                 :            :  */
         739                 :          2 : quint64 Account::valueAsUInt64(const QString &key,
         740                 :            :                         quint64 default_value,
         741                 :            :                         SettingSource *source) const
         742                 :            : {
         743                 :          2 :     QVariant var = default_value;
         744                 :          2 :     SettingSource src = value(key, var);
         745         [ +  + ]:          2 :     if (source)
         746                 :          1 :         *source = src;
         747                 :          2 :     return var.toULongLong();
         748                 :            : }
         749                 :            :
         750                 :            : /*!
         751                 :            :  * Gets an account setting as a boolean.
         752                 :            :  * @param key The key whose value must be retrieved.
         753                 :            :  * @param default_value Value returned if the key is unset.
         754                 :            :  * @param source Indicates whether the value comes from the account, the
         755                 :            :  * service template or was unset.
         756                 :            :  *
         757                 :            :  * This method operates on the currently selected service.
         758                 :            :  */
         759                 :          2 : bool Account::valueAsBool(const QString &key,
         760                 :            :                           bool default_value,
         761                 :            :                           SettingSource *source) const
         762                 :            : {
         763                 :          2 :     QVariant var = default_value;
         764                 :          2 :     SettingSource src = value(key, var);
         765         [ +  + ]:          2 :     if (source)
         766                 :          1 :         *source = src;
         767                 :          2 :     return var.toBool();
         768                 :            : }
         769                 :            :
         770                 :          6 : void Watch::Private::account_notify_cb(AgAccount *account, const gchar *key,
         771                 :            :                                        Watch *watch)
         772                 :            : {
         773                 :          6 :     Q_EMIT watch->notify(key);
         774                 :            :
         775                 :            :     Q_UNUSED(account);
         776                 :          6 : }
         777                 :            :
         778                 :            : /*!
         779                 :            :  * Installs a key or group watch.
         780                 :            :  *
         781                 :            :  * @param key The key to watch; if %NULL, watches the currently selected
         782                 :            :  * group.
         783                 :            :  *
         784                 :            :  * @return A watch object.
         785                 :            :  *
         786                 :            :  * This method operates on the currently selected service.
         787                 :            :  */
         788                 :          3 : Watch *Account::watchKey(const QString &key)
         789                 :            : {
         790                 :            :     AgAccountWatch ag_watch;
         791                 :          3 :     Watch *watch = new Watch(this);
         792                 :            :
         793         [ +  + ]:          3 :     if (!key.isEmpty())
         794                 :            :     {
         795                 :          2 :         QString full_key = d->prefix + key;
         796                 :            :         ag_watch = ag_account_watch_key
         797                 :            :             (d->m_account, full_key.toLatin1().constData(),
         798                 :          2 :              (AgAccountNotifyCb)&Watch::Private::account_notify_cb, watch);
         799                 :            :     }
         800                 :            :     else
         801                 :            :     {
         802                 :            :         ag_watch = ag_account_watch_dir
         803                 :            :             (d->m_account, d->prefix.toLatin1().constData(),
         804                 :          1 :              (AgAccountNotifyCb)&Watch::Private::account_notify_cb, watch);
         805                 :            :     }
         806                 :            :
         807         [ -  + ]:          3 :     if (!ag_watch)
         808                 :            :     {
         809         [ #  # ]:          0 :         delete watch;
         810                 :            :         return NULL;
         811                 :            :     }
         812                 :            :
         813                 :            :     watch->setWatch(ag_watch);
         814                 :          3 :     return watch;
         815                 :            : }
         816                 :            :
         817                 :            : /*!
         818                 :            :  * Stores all account settings into the database.
         819                 :            :  * The signal synced() will be emitted in case of success, or
         820                 :            :  * error() in case of failure. No assumption must be made about when these
         821                 :            :  * signals will be emitted: if the database is locked, the signals might
         822                 :            :  * be emitted asynchronously, whereas if the operation can happen
         823                 :            :  * synchronously then the signals can be emitted before this method
         824                 :            :  * returns.
         825                 :            :  * If for some reason one would want to process the signals asynchronously
         826                 :            :  * from the event loop, one can use the Qt::QueuedConnection connection
         827                 :            :  * type as last parameter of the QObject::connect call.
         828                 :            :  */
         829                 :         28 : void Account::sync()
         830                 :            : {
         831                 :            :     ag_account_store_async(d->m_account,
         832                 :            :                            d->m_cancellable,
         833                 :            :                            (GAsyncReadyCallback)&Private::account_store_cb,
         834                 :         28 :                            this);
         835                 :         28 : }
         836                 :            :
         837                 :            : /*!
         838                 :            :  * Blocking version of the sync() method: execution of the current thread
         839                 :            :  * will block until the operation has completed.
         840                 :            :  * Usage of this method is discouraged, especially for UI applications.
         841                 :            :  *
         842                 :            :  * @return True on success, false otherwise.
         843                 :            :  */
         844                 :         10 : bool Account::syncAndBlock()
         845                 :            : {
         846                 :         10 :     GError *error = NULL;
         847                 :            :     bool ret;
         848                 :            :
         849                 :         10 :     ret = ag_account_store_blocking(d->m_account, &error);
         850         [ -  + ]:         10 :     if (error)
         851                 :            :     {
         852                 :          0 :         qWarning() << "Store operation failed: " << error->message;
         853                 :          0 :         g_error_free(error);
         854                 :            :     }
         855                 :            :
         856                 :         10 :     return ret;
         857                 :            : }
         858                 :            :
         859                 :            : /*!
         860                 :            :  * Marks the account for removal.
         861                 :            :  * The account will be deleted only when the sync() method is called.
         862                 :            :  */
         863                 :          2 : void Account::remove()
         864                 :            : {
         865                 :          2 :     ag_account_delete(d->m_account);
         866                 :          2 : }
         867                 :            :
         868                 :            : /*!
         869                 :            :  * Creates signature of key with given aegis token. The calling application
         870                 :            :  * must possess (request) the given aegis token. The account needs to be
         871                 :            :  * stored prior to executing this method.
         872                 :            :  * @param key The key or the prefix of set of the keys to be signed.
         873                 :            :  * @param token The aegis token to be used for signing the key.
         874                 :            :  *
         875                 :            :  * This method operates on the currently selected service.
         876                 :            :  */
         877                 :          0 : void Account::sign(const QString &key, const char *token)
         878                 :            : {
         879                 :          0 :     ag_account_sign (d->m_account, key.toUtf8().constData(), token);
         880                 :          0 : }
         881                 :            :
         882                 :            : /*!
         883                 :            :  * Verifies if the key is signed and the signature matches the value
         884                 :            :  * and provides the aegis token which was used for signing the key.
         885                 :            :  *
         886                 :            :  * @param key The name of the key or prefix of the keys to be verified.
         887                 :            :  * @param token Aegis token to be retrieved.
         888                 :            :  *
         889                 :            :  * @return True if the key is signed and the signature matches the value.
         890                 :            :  *
         891                 :            :  * This method operates on the currently selected service.
         892                 :            :  */
         893                 :          0 : bool Account::verify(const QString &key, const char **token)
         894                 :            : {
         895                 :          0 :     return ag_account_verify(d->m_account, key.toUtf8().constData(), token);
         896                 :            : }
         897                 :            :
         898                 :            : /*!
         899                 :            :  * Verifies if the key is signed with any of the aegis tokens and the
         900                 :            :  * signature is valid.
         901                 :            :  *
         902                 :            :  * @param key The name of the key or prefix of the keys to be verified.
         903                 :            :  * @param tokens Array of aegis tokens.
         904                 :            :  *
         905                 :            :  * @return True if the key is signed with any of the aegis tokens and
         906                 :            :  * the signature is valid.
         907                 :            :  *
         908                 :            :  * This method operates on the currently selected service.
         909                 :            :  */
         910                 :          0 : bool Account::verifyWithTokens(const QString &key, QList<const char*> tokens)
         911                 :            : {
         912                 :            :     int tokensCount = tokens.count();
         913                 :            :
         914                 :          0 :     const char *tmp[tokensCount + 1];
         915                 :            :
         916         [ #  # ]:          0 :     for (int i = 0; i < tokensCount; ++i)
         917                 :            :     {
         918                 :          0 :         tmp[i] = tokens.at(i);
         919                 :            :     }
         920                 :          0 :     tmp[tokensCount] = NULL;
         921                 :            :
         922                 :          0 :     return ag_account_verify_with_tokens(d->m_account, key.toUtf8().constData(), tmp);
         923                 :            : }
         924                 :            :
         925                 :          3 : uint Account::credentialsId()
         926                 :            : {
         927                 :          3 :     QString key = ACCOUNTS_KEY_CREDENTIALS_ID;
         928                 :          3 :     QVariant val(QVariant::Int);
         929                 :            :
         930         [ +  + ]:          3 :     if (value(key, val) != NONE)
         931                 :          2 :         return val.toUInt();
         932                 :            :
         933                 :            :     uint id = 0;
         934                 :          1 :     Service service = selectedService();
         935         [ +  - ]:          1 :     if (service.isValid()) {
         936                 :          1 :         selectService();
         937         [ +  - ]:          1 :         if (value(key, val) != NONE)
         938                 :          1 :             id = val.toUInt();
         939                 :          1 :         selectService(service);
         940                 :            :     }
         941                 :          3 :     return id;
         942                 :            : }
         943                 :            :
         944                 :          4 : AgAccount *Account::account()
         945                 :            : {
         946                 :          4 :     return d->m_account;
         947                 :          1 : }

Generated by: LCOV version 1.9