~unity-api-team/storage-framework/vivid

« back to all changes in this revision

Viewing changes to src/qt/internal/AccountsJobImpl.cpp

  • Committer: Bileto Bot
  • Date: 2016-11-04 12:21:58 UTC
  • mfrom: (12.1.1 merge-devel)
  • Revision ID: ci-train-bot@canonical.com-20161104122158-hu8h9qyg3vm129t5
* Added v2 of the client-side API.
* Updated server-side API to tell the provider which metadata to return.
* Update provider API to manager ProviderBase class as a shared_ptr.
* Update client to discover ownCloud/Nextcloud and OneDrive accounts.
* Add match_etag argument to Download() D-Bus method.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2016 Canonical Ltd
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU Lesser General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU Lesser General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors: Michi Henning <michi.henning@canonical.com>
 
17
 */
 
18
 
 
19
#include <unity/storage/qt/internal/AccountsJobImpl.h>
 
20
 
 
21
#include <unity/storage/qt/internal/AccountImpl.h>
 
22
#include <unity/storage/qt/internal/RuntimeImpl.h>
 
23
#include <unity/storage/qt/internal/StorageErrorImpl.h>
 
24
 
 
25
#include <OnlineAccounts/Account>
 
26
 
 
27
#include <cassert>
 
28
 
 
29
using namespace std;
 
30
 
 
31
namespace unity
 
32
{
 
33
namespace storage
 
34
{
 
35
namespace qt
 
36
{
 
37
namespace internal
 
38
{
 
39
 
 
40
namespace
 
41
{
 
42
 
 
43
// TODO: We retrieve the accounts directly from online accounts until we have a working registry.
 
44
 
 
45
static map<QString, QString> const BUS_NAMES =
 
46
{
 
47
    { "google-drive-scope", "com.canonical.StorageFramework.Provider.ProviderTest" },
 
48
    { "com.canonical.scopes.mcloud_mcloud_mcloud", "com.canonical.StorageFramework.Provider.McloudProvider" },
 
49
    { "storage-provider-owncloud", "com.canonical.StorageFramework.Provider.OwnCloud" },
 
50
    { "storage-provider-onedrive", "com.canonical.StorageFramework.Provider.OnedriveProvider" },
 
51
};
 
52
 
 
53
}  // namespace
 
54
 
 
55
AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, shared_ptr<RuntimeImpl> const& runtime_impl)
 
56
    : public_instance_(public_instance)
 
57
    , status_(AccountsJob::Status::Loading)
 
58
    , runtime_impl_(runtime_impl)
 
59
{
 
60
    assert(public_instance);
 
61
    assert(runtime_impl);
 
62
 
 
63
    initialize_accounts();
 
64
}
 
65
 
 
66
AccountsJobImpl::AccountsJobImpl(AccountsJob* public_instance, StorageError const& error)
 
67
    : public_instance_(public_instance)
 
68
    , status_(AccountsJob::Status::Loading)
 
69
    , error_(error)
 
70
{
 
71
    assert(public_instance);
 
72
    assert(error.type() != StorageError::Type::NoError);
 
73
 
 
74
    status_ = emit_status_changed(AccountsJob::Status::Error);
 
75
}
 
76
 
 
77
bool AccountsJobImpl::isValid() const
 
78
{
 
79
    return status_ != AccountsJob::Status::Error;
 
80
}
 
81
 
 
82
AccountsJob::Status AccountsJobImpl::status() const
 
83
{
 
84
    return status_;
 
85
}
 
86
 
 
87
StorageError AccountsJobImpl::error() const
 
88
{
 
89
    return error_;
 
90
}
 
91
 
 
92
QList<Account> AccountsJobImpl::accounts() const
 
93
{
 
94
    auto runtime = get_runtime_impl("AccountsJob::accounts()");
 
95
    if (!runtime)
 
96
    {
 
97
        return QList<Account>();
 
98
    }
 
99
    if (status_ != AccountsJob::Status::Finished)
 
100
    {
 
101
        return QList<Account>();
 
102
    }
 
103
    return accounts_;
 
104
}
 
105
 
 
106
QVariantList AccountsJobImpl::accountsAsVariantList() const
 
107
{
 
108
    QVariantList account_list;
 
109
    for (auto const& a : accounts())
 
110
    {
 
111
        account_list.append(QVariant::fromValue(a));
 
112
    }
 
113
    return account_list;
 
114
}
 
115
 
 
116
void AccountsJobImpl::manager_ready()
 
117
{
 
118
    timer_.stop();
 
119
    disconnect(this);
 
120
    initialize_accounts();
 
121
}
 
122
 
 
123
// LCOV_EXCL_START
 
124
void AccountsJobImpl::timeout()
 
125
{
 
126
    disconnect(this);
 
127
    error_ = StorageErrorImpl::local_comms_error("AccountsJob(): timeout retrieving Online accounts");
 
128
    status_ = emit_status_changed(AccountsJob::Status::Error);
 
129
}
 
130
// LCOV_EXCL_STOP
 
131
 
 
132
AccountsJob::Status AccountsJobImpl::emit_status_changed(AccountsJob::Status new_status) const
 
133
{
 
134
    if (status_ == AccountsJob::Status::Loading)  // Once in a final state, we don't emit the signal again.
 
135
    {
 
136
        // We defer emission of the signal so the client gets a chance to connect to the signal
 
137
        // in case we emit the signal from the constructor.
 
138
        QMetaObject::invokeMethod(public_instance_,
 
139
                                  "statusChanged",
 
140
                                  Qt::QueuedConnection,
 
141
                                  Q_ARG(unity::storage::qt::AccountsJob::Status, new_status));
 
142
    }
 
143
    return new_status;
 
144
}
 
145
 
 
146
shared_ptr<RuntimeImpl> AccountsJobImpl::get_runtime_impl(QString const& method) const
 
147
{
 
148
    auto runtime = runtime_impl_.lock();
 
149
    if (!runtime || !runtime->isValid())
 
150
    {
 
151
        QString msg = method + ": Runtime was destroyed previously";
 
152
        auto This = const_cast<AccountsJobImpl*>(this);
 
153
        This->error_ = StorageErrorImpl::runtime_destroyed_error(msg);
 
154
        This->status_ = emit_status_changed(AccountsJob::Status::Error);
 
155
    }
 
156
    return runtime;
 
157
}
 
158
 
 
159
void AccountsJobImpl::initialize_accounts()
 
160
{
 
161
    auto runtime = get_runtime_impl("AccountsJob()");
 
162
    assert(runtime);
 
163
 
 
164
    auto manager = runtime->accounts_manager();
 
165
    if (!manager->isReady())
 
166
    {
 
167
        connect(manager.get(), &OnlineAccounts::Manager::ready, this, &AccountsJobImpl::manager_ready);
 
168
        connect(&timer_, &QTimer::timeout, this, &AccountsJobImpl::timeout);
 
169
        timer_.setSingleShot(true);
 
170
        timer_.start(30000);  // TODO: Need config for this eventually.
 
171
        return;
 
172
    }
 
173
 
 
174
    for (auto const map_entry : BUS_NAMES)
 
175
    {
 
176
        auto service_id = map_entry.first;
 
177
        for (auto const& a : manager->availableAccounts(service_id))
 
178
        {
 
179
            auto object_path = QStringLiteral("/provider/%1").arg(a->id());
 
180
            auto bus_name = map_entry.second;
 
181
            accounts_.append(AccountImpl::make_account(runtime,
 
182
                                                       bus_name,
 
183
                                                       object_path,
 
184
                                                       QString::number(a->id()),
 
185
                                                       a->serviceId(),
 
186
                                                       a->displayName()));
 
187
        }
 
188
    }
 
189
    status_ = emit_status_changed(AccountsJob::Status::Finished);
 
190
}
 
191
 
 
192
}  // namespace internal
 
193
}  // namespace qt
 
194
}  // namespace storage
 
195
}  // namespace unity