Merge lp:~mzanetti/unity8/appdrawer-recent-apps into lp:unity8

Proposed by Michael Zanetti on 2017-03-13
Status: Approved
Approved by: Lukáš Tinkl on 2017-04-05
Approved revision: 2846
Proposed branch: lp:~mzanetti/unity8/appdrawer-recent-apps
Merge into: lp:unity8
Diff against target: 621 lines (+340/-13)
17 files modified
CMakeLists.txt (+1/-1)
debian/control (+3/-3)
plugins/Greeter/Unity/Launcher/launcheritem.cpp (+6/-0)
plugins/Greeter/Unity/Launcher/launcheritem.h (+1/-0)
plugins/Unity/Launcher/appdrawermodel.cpp (+68/-7)
plugins/Unity/Launcher/appdrawermodel.h (+8/-0)
plugins/Unity/Launcher/launcheritem.cpp (+13/-0)
plugins/Unity/Launcher/launcheritem.h (+3/-0)
plugins/Unity/Launcher/launchermodel.cpp (+1/-0)
plugins/Unity/Launcher/ualwrapper.cpp (+12/-2)
plugins/Unity/Launcher/ualwrapper.h (+6/-0)
tests/mocks/Unity/Launcher/MockLauncherItem.cpp (+13/-0)
tests/mocks/Unity/Launcher/MockLauncherItem.h (+3/-0)
tests/plugins/Unity/Launcher/CMakeLists.txt (+34/-0)
tests/plugins/Unity/Launcher/appdrawermodeltest.cpp (+53/-0)
tests/plugins/Unity/Launcher/ualwrapper.cpp (+60/-0)
tests/plugins/Unity/Launcher/ualwrapper.h (+55/-0)
To merge this branch: bzr merge lp:~mzanetti/unity8/appdrawer-recent-apps
Reviewer Review Type Date Requested Status
Unity8 CI Bot continuous-integration Approve on 2017-04-05
Lukáš Tinkl (community) 2017-03-13 Approve on 2017-04-05
Review via email: mp+319697@code.launchpad.net

Commit Message

Appdrawer improvements

* Complete support for recent/most used apps (still hidden as u-a-l backend doesn't support it yet)
* update drawer contents when things change in the backend

Description of the Change

Prereq-archive: ppa:ci-train-ppa-service/2692

* Are there any related MPs required for this MP to build/function as expected? Please list.

https://code.launchpad.net/~mzanetti/unity-api/launcheritems-popularity/+merge/321708

 * Did you perform an exploratory manual test run of your code change and any related functionality?

yes

 * If you changed the UI, has there been a design review?

n/a

To post a comment you must log in.
2843. By Michael Zanetti on 2017-04-04

also bump version for required pkgconfig launcher api

2844. By Michael Zanetti on 2017-04-05

align appid usage

2845. By Michael Zanetti on 2017-04-05

drop debug print

2846. By Michael Zanetti on 2017-04-05

improve a little

Lukáš Tinkl (lukas-kde) wrote :

Works fine, review comments I had, addressed

* Did you perform an exploratory manual test run of the code change and any related functionality?

Yes

* Did CI run pass? If not, please explain why.

Waiting with top ack

review: Approve
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2844
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3694/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4907
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/3008
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/3008
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4935
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4743/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4743/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4743/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4743/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4743/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4743
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4743/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3694/rebuild

review: Approve (continuous-integration)
Unity8 CI Bot (unity8-ci-bot) wrote :

PASSED: Continuous integration, rev:2846
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3697/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build/4911
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial+overlay,testname=qmluitests.sh/3011
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=zesty,testname=qmluitests.sh/3011
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/4939
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial+overlay/4747/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=zesty/4747/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial+overlay/4747/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=zesty/4747/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial+overlay/4747/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4747
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=zesty/4747/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/3697/rebuild

review: Approve (continuous-integration)

Unmerged revisions

2846. By Michael Zanetti on 2017-04-05

improve a little

2845. By Michael Zanetti on 2017-04-05

drop debug print

2844. By Michael Zanetti on 2017-04-05

align appid usage

2843. By Michael Zanetti on 2017-04-04

also bump version for required pkgconfig launcher api

2842. By Michael Zanetti on 2017-04-04

bump required unity-api versions

2841. By Michael Zanetti on 2017-04-03

add appdrawermodeltest

2840. By Michael Zanetti on 2017-04-03

disable recent apps view again to we can land this without waiting on zeitgeist

2839. By Michael Zanetti on 2017-04-03

hook up to appAdded and appRemoved signals

2838. By Michael Zanetti on 2017-04-03

merge trunk

2837. By Michael Zanetti on 2017-02-27

more complete support for recently used app in the drawer

not tested yet as u-a-l doesn't fully implement it yet

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2017-03-28 21:45:31 +0000
3+++ CMakeLists.txt 2017-04-05 16:29:50 +0000
4@@ -75,7 +75,7 @@
5 pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
6 pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
7 pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
8-pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=12)
9+pkg_check_modules(LAUNCHER_API REQUIRED unity-shell-launcher=13)
10 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
11 pkg_check_modules(GD3 REQUIRED gnome-desktop-3.0)
12 pkg_check_modules(UAL REQUIRED ubuntu-app-launch-3)
13
14=== modified file 'debian/control'
15--- debian/control 2017-03-20 10:19:11 +0000
16+++ debian/control 2017-04-05 16:29:50 +0000
17@@ -40,7 +40,7 @@
18 libubuntugestures5-private-dev (>= 1.3.2030),
19 libudev-dev,
20 libudm-common-dev,
21- libunity-api-dev (>= 8.6),
22+ libunity-api-dev (>= 8.7),
23 libusermetricsoutput1-dev,
24 # Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
25 libx11-dev[!arm64 !armhf],
26@@ -135,7 +135,7 @@
27 qtdeclarative5-qtmir-plugin (>= 0.4.8),
28 qtdeclarative5-ubuntu-telephony0.1,
29 ubuntu-system-settings (>= 0.4),
30- unity-launcher-impl-12,
31+ unity-launcher-impl-13,
32 unity8-common (= ${source:Version}),
33 unity8-private (= ${binary:Version}),
34 unity8-private | unity-launcher-impl,
35@@ -239,7 +239,7 @@
36 ${misc:Depends},
37 ${shlibs:Depends},
38 Provides: unity-launcher-impl,
39- unity-launcher-impl-12,
40+ unity-launcher-impl-13,
41 Description: Unity 8 private libs
42 The Unity 8 shell is the primary user interface for Ubuntu devices.
43 .
44
45=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.cpp'
46--- plugins/Greeter/Unity/Launcher/launcheritem.cpp 2016-11-16 18:52:53 +0000
47+++ plugins/Greeter/Unity/Launcher/launcheritem.cpp 2017-04-05 16:29:50 +0000
48@@ -89,6 +89,12 @@
49 }
50 }
51
52+uint LauncherItem::popularity() const
53+{
54+ // Not exposing usage order in greeter session at this point.
55+ return 0;
56+}
57+
58 bool LauncherItem::pinned() const
59 {
60 return m_pinned;
61
62=== modified file 'plugins/Greeter/Unity/Launcher/launcheritem.h'
63--- plugins/Greeter/Unity/Launcher/launcheritem.h 2016-11-16 18:52:53 +0000
64+++ plugins/Greeter/Unity/Launcher/launcheritem.h 2017-04-05 16:29:50 +0000
65@@ -35,6 +35,7 @@
66 QString name() const override;
67 QString icon() const override;
68 QStringList keywords() const override;
69+ uint popularity() const override;
70 bool pinned() const override;
71 bool running() const override;
72 bool recent() const override;
73
74=== modified file 'plugins/Unity/Launcher/appdrawermodel.cpp'
75--- plugins/Unity/Launcher/appdrawermodel.cpp 2017-01-25 17:44:54 +0000
76+++ plugins/Unity/Launcher/appdrawermodel.cpp 2017-04-05 16:29:50 +0000
77@@ -21,7 +21,8 @@
78 #include <QDateTime>
79
80 AppDrawerModel::AppDrawerModel(QObject *parent):
81- AppDrawerModelInterface(parent)
82+ AppDrawerModelInterface(parent),
83+ m_ual(new UalWrapper(this))
84 {
85 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
86 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
87@@ -29,10 +30,16 @@
88 qWarning() << "Failed to get app info for app" << appId;
89 continue;
90 }
91- m_list.append(new LauncherItem(appId, info.name, info.icon, this));
92- m_list.last()->setKeywords(info.keywords);
93+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
94+ item->setKeywords(info.keywords);
95+ item->setPopularity(info.popularity);
96+ m_list.append(item);
97 }
98- qsrand(QDateTime::currentMSecsSinceEpoch() / 100);
99+
100+ // keep this a queued connection as it's coming from another thread.
101+ connect(m_ual, &UalWrapper::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
102+ connect(m_ual, &UalWrapper::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
103+ connect(m_ual, &UalWrapper::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
104 }
105
106 int AppDrawerModel::rowCount(const QModelIndex &parent) const
107@@ -53,10 +60,64 @@
108 case RoleKeywords:
109 return m_list.at(index.row())->keywords();
110 case RoleUsage:
111- // FIXME: u-a-l needs to provide API for usage stats.
112- // don't forget to drop the qsrand() call in the ctor when dropping this.
113- return qrand();
114+ return m_list.at(index.row())->popularity();
115 }
116
117 return QVariant();
118 }
119+
120+void AppDrawerModel::appAdded(const QString &appId)
121+{
122+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
123+ if (!info.valid) {
124+ qWarning() << "App added signal received but failed to get app info for app" << appId;
125+ return;
126+ }
127+
128+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
129+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
130+ item->setKeywords(info.keywords);
131+ item->setPopularity(info.popularity);
132+ m_list.append(item);
133+ endInsertRows();
134+}
135+
136+void AppDrawerModel::appRemoved(const QString &appId)
137+{
138+ int idx = -1;
139+ for (int i = 0; i < m_list.count(); i++) {
140+ if (m_list.at(i)->appId() == appId) {
141+ idx = i;
142+ break;
143+ }
144+ }
145+ if (idx < 0) {
146+ qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
147+ return;
148+ }
149+ beginRemoveRows(QModelIndex(), idx, idx);
150+ m_list.takeAt(idx)->deleteLater();
151+ endRemoveRows();
152+}
153+
154+void AppDrawerModel::appInfoChanged(const QString &appId)
155+{
156+ LauncherItem *item = nullptr;
157+ int idx = -1;
158+
159+ for(int i = 0; i < m_list.count(); i++) {
160+ if (m_list.at(i)->appId() == appId) {
161+ item = m_list.at(i);
162+ idx = i;
163+ break;
164+ }
165+ }
166+
167+ if (!item) {
168+ return;
169+ }
170+
171+ UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
172+ item->setPopularity(info.popularity);
173+ Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
174+}
175
176=== modified file 'plugins/Unity/Launcher/appdrawermodel.h'
177--- plugins/Unity/Launcher/appdrawermodel.h 2016-11-24 16:17:30 +0000
178+++ plugins/Unity/Launcher/appdrawermodel.h 2017-04-05 16:29:50 +0000
179@@ -19,6 +19,8 @@
180
181 #include "launcheritem.h"
182
183+class UalWrapper;
184+
185 class AppDrawerModel: public AppDrawerModelInterface
186 {
187 Q_OBJECT
188@@ -28,6 +30,12 @@
189 int rowCount(const QModelIndex &parent) const override;
190 QVariant data(const QModelIndex &index, int role) const override;
191
192+private Q_SLOTS:
193+ void appAdded(const QString &appId);
194+ void appRemoved(const QString &appId);
195+ void appInfoChanged(const QString &appId);
196+
197 private:
198 QList<LauncherItem*> m_list;
199+ UalWrapper *m_ual;
200 };
201
202=== modified file 'plugins/Unity/Launcher/launcheritem.cpp'
203--- plugins/Unity/Launcher/launcheritem.cpp 2017-03-16 11:54:13 +0000
204+++ plugins/Unity/Launcher/launcheritem.cpp 2017-04-05 16:29:50 +0000
205@@ -256,6 +256,19 @@
206 }
207 }
208
209+uint LauncherItem::popularity() const
210+{
211+ return m_popularity;
212+}
213+
214+void LauncherItem::setPopularity(uint popularity)
215+{
216+ if (m_popularity != popularity) {
217+ m_popularity = popularity;
218+ Q_EMIT popularityChanged(popularity);
219+ }
220+}
221+
222 unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
223 {
224 return m_quickList;
225
226=== modified file 'plugins/Unity/Launcher/launcheritem.h'
227--- plugins/Unity/Launcher/launcheritem.h 2017-03-02 13:28:33 +0000
228+++ plugins/Unity/Launcher/launcheritem.h 2017-04-05 16:29:50 +0000
229@@ -39,6 +39,7 @@
230 QString name() const override;
231 QString icon() const override;
232 QStringList keywords() const override;
233+ uint popularity() const override;
234 bool pinned() const override;
235 bool running() const override;
236 bool recent() const override;
237@@ -55,6 +56,7 @@
238 void setName(const QString &name);
239 void setIcon(const QString &icon);
240 void setKeywords(const QStringList &keywords);
241+ void setPopularity(uint popularity);
242 void setPinned(bool pinned);
243 void setRunning(bool running);
244 void setRecent(bool recent);
245@@ -70,6 +72,7 @@
246 QString m_name;
247 QString m_icon;
248 QStringList m_keywords;
249+ uint m_popularity;
250 bool m_pinned;
251 bool m_running;
252 bool m_recent;
253
254=== modified file 'plugins/Unity/Launcher/launchermodel.cpp'
255--- plugins/Unity/Launcher/launchermodel.cpp 2017-03-28 21:47:24 +0000
256+++ plugins/Unity/Launcher/launchermodel.cpp 2017-04-05 16:29:50 +0000
257@@ -167,6 +167,7 @@
258 appInfo.icon,
259 this);
260 item->setPinned(true);
261+ item->setPopularity(appInfo.popularity);
262 m_list.insert(index, item);
263 endInsertRows();
264 }
265
266=== modified file 'plugins/Unity/Launcher/ualwrapper.cpp'
267--- plugins/Unity/Launcher/ualwrapper.cpp 2016-11-24 16:17:30 +0000
268+++ plugins/Unity/Launcher/ualwrapper.cpp 2017-04-05 16:29:50 +0000
269@@ -24,7 +24,15 @@
270 UalWrapper::UalWrapper(QObject *parent):
271 QObject(parent)
272 {
273-
274+ Registry::appAdded().connect([this](const std::shared_ptr<Application>&app) {
275+ Q_EMIT appAdded(QString::fromStdString(app->appId()));
276+ });
277+ Registry::appRemoved().connect([this](const AppID &appId) {
278+ Q_EMIT appRemoved(QString::fromStdString(appId));
279+ });
280+ Registry::appInfoUpdated().connect([this](const std::shared_ptr<Application>&app){
281+ Q_EMIT appInfoChanged(QString::fromStdString(app->appId()));
282+ });
283 }
284
285 QStringList UalWrapper::installedApps()
286@@ -39,7 +47,7 @@
287 }
288 }
289 } catch (const std::runtime_error &e) {
290- qWarning() << "ubuntu-all-launch threw an exception listing apps:" << e.what();
291+ qWarning() << "ubuntu-app-launch threw an exception listing apps:" << e.what();
292 }
293
294 return appIds;
295@@ -59,11 +67,13 @@
296 std::shared_ptr<Application> ualApp;
297 ualApp = Application::create(ualAppId, Registry::getDefault());
298
299+ info.appId = appId;
300 info.name = QString::fromStdString(ualApp->info()->name());
301 info.icon = QString::fromStdString(ualApp->info()->iconPath());
302 for (const std::string &keyword : ualApp->info()->keywords().value()) {
303 info.keywords << QString::fromStdString(keyword);
304 }
305+ info.popularity = ualApp->info()->popularity();
306 info.valid = true;
307 } catch (const std::runtime_error &e) {
308 qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what();
309
310=== modified file 'plugins/Unity/Launcher/ualwrapper.h'
311--- plugins/Unity/Launcher/ualwrapper.h 2016-11-24 16:17:30 +0000
312+++ plugins/Unity/Launcher/ualwrapper.h 2017-04-05 16:29:50 +0000
313@@ -21,10 +21,12 @@
314 Q_OBJECT
315 public:
316 struct AppInfo {
317+ QString appId;
318 bool valid = false;
319 QString name;
320 QString icon;
321 QStringList keywords;
322+ uint popularity = 0;
323 };
324
325 UalWrapper(QObject* parent = nullptr);
326@@ -32,4 +34,8 @@
327 static QStringList installedApps();
328 static AppInfo getApplicationInfo(const QString &appId);
329
330+Q_SIGNALS:
331+ void appAdded(const QString &appId);
332+ void appRemoved(const QString &appId);
333+ void appInfoChanged(const QString &appId);
334 };
335
336=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.cpp'
337--- tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2016-12-14 15:52:45 +0000
338+++ tests/mocks/Unity/Launcher/MockLauncherItem.cpp 2017-04-05 16:29:50 +0000
339@@ -72,6 +72,11 @@
340 return m_keywords;
341 }
342
343+uint MockLauncherItem::popularity() const
344+{
345+ return m_popularity;
346+}
347+
348 bool MockLauncherItem::pinned() const
349 {
350 return m_pinned;
351@@ -201,6 +206,14 @@
352 }
353 }
354
355+void MockLauncherItem::setPopularity(uint popularity)
356+{
357+ if (m_popularity != popularity) {
358+ m_popularity = popularity;
359+ Q_EMIT popularityChanged(m_popularity);
360+ }
361+}
362+
363 unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
364 {
365 return m_quickList;
366
367=== modified file 'tests/mocks/Unity/Launcher/MockLauncherItem.h'
368--- tests/mocks/Unity/Launcher/MockLauncherItem.h 2016-11-17 12:39:57 +0000
369+++ tests/mocks/Unity/Launcher/MockLauncherItem.h 2017-04-05 16:29:50 +0000
370@@ -40,6 +40,7 @@
371 QString name() const override;
372 QString icon() const override;
373 QStringList keywords() const override;
374+ uint popularity() const override;
375
376 bool pinned() const override;
377 bool running() const override;
378@@ -55,6 +56,7 @@
379
380 private:
381 void setKeywords(const QStringList &keywords);
382+ void setPopularity(uint popularity);
383 void setPinned(bool pinned);
384 void setRunning(bool running);
385 void setRecent(bool recent);
386@@ -70,6 +72,7 @@
387 QString m_name;
388 QString m_icon;
389 QStringList m_keywords;
390+ uint m_popularity;
391 bool m_pinned;
392 bool m_running;
393 bool m_recent;
394
395=== modified file 'tests/plugins/Unity/Launcher/CMakeLists.txt'
396--- tests/plugins/Unity/Launcher/CMakeLists.txt 2017-03-02 13:28:33 +0000
397+++ tests/plugins/Unity/Launcher/CMakeLists.txt 2017-04-05 16:29:50 +0000
398@@ -61,6 +61,40 @@
399 --wait-for org.freedesktop.Accounts
400 )
401
402+### AppDrawerModelTest
403+add_executable(appdrawermodeltestExec
404+ appdrawermodeltest.cpp
405+ ualwrapper.cpp
406+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/appdrawermodel.cpp
407+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h
408+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
409+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
410+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
411+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
412+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
413+ )
414+target_link_libraries(appdrawermodeltestExec
415+ unity8-private
416+ ${GSETTINGS_QT_LDFLAGS}
417+ ${GLIB_LIBRARIES}
418+ ${UAL_LIBRARIES}
419+ )
420+add_dependencies(appdrawermodeltestExec mock-server)
421+qt5_use_modules(appdrawermodeltestExec Test Core DBus Xml Gui Qml)
422+install(TARGETS appdrawermodeltestExec
423+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/plugins/Unity/Launcher"
424+ )
425+
426+add_unity8_unittest(AppDrawerModel dbus-test-runner
427+ ENVIRONMENT "APPDIR=${CMAKE_CURRENT_BINARY_DIR}/applications"
428+ ARG_PREFIX "--parameter"
429+ ARGS
430+ --task $<TARGET_FILE:mock-server>
431+ --ignore-return
432+ --task $<TARGET_FILE:appdrawermodeltestExec>
433+ --wait-for org.freedesktop.Accounts
434+)
435+
436 # copy sample application files into build directory for shadow builds
437 file(COPY applications
438 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
439
440=== added file 'tests/plugins/Unity/Launcher/appdrawermodeltest.cpp'
441--- tests/plugins/Unity/Launcher/appdrawermodeltest.cpp 1970-01-01 00:00:00 +0000
442+++ tests/plugins/Unity/Launcher/appdrawermodeltest.cpp 2017-04-05 16:29:50 +0000
443@@ -0,0 +1,53 @@
444+/*
445+ * Copyright 2017 Canonical Ltd.
446+ *
447+ * This program is free software; you can redistribute it and/or modify
448+ * it under the terms of the GNU Lesser General Public License as published by
449+ * the Free Software Foundation; version 3.
450+ *
451+ * This program is distributed in the hope that it will be useful,
452+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
453+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
454+ * GNU Lesser General Public License for more details.
455+ *
456+ * You should have received a copy of the GNU Lesser General Public License
457+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
458+ */
459+
460+#include "ualwrapper.h"
461+#include "appdrawermodel.h"
462+
463+#include <QtTest>
464+
465+class AppDrawerModelTest : public QObject
466+{
467+ Q_OBJECT
468+
469+private:
470+ AppDrawerModel *appDrawerModel;
471+
472+private Q_SLOTS:
473+
474+ void initTestCase() {
475+ UalWrapper::s_list << QStringLiteral("app1") << QStringLiteral("app2");
476+ appDrawerModel = new AppDrawerModel(this);
477+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
478+ }
479+
480+ void testUalAppAddedRemoved() {
481+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
482+
483+ UalWrapper::instance()->addMockApp("app3");
484+ qApp->processEvents(); // ualwrapper is connected Queued
485+
486+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 3);
487+
488+ UalWrapper::instance()->removeMockApp("app3");
489+ qApp->processEvents();
490+
491+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
492+ }
493+};
494+
495+QTEST_GUILESS_MAIN(AppDrawerModelTest)
496+#include "appdrawermodeltest.moc"
497
498=== added file 'tests/plugins/Unity/Launcher/ualwrapper.cpp'
499--- tests/plugins/Unity/Launcher/ualwrapper.cpp 1970-01-01 00:00:00 +0000
500+++ tests/plugins/Unity/Launcher/ualwrapper.cpp 2017-04-05 16:29:50 +0000
501@@ -0,0 +1,60 @@
502+/*
503+ * Copyright (C) 2017 Canonical, Ltd.
504+ *
505+ * This program is free software; you can redistribute it and/or modify
506+ * it under the terms of the GNU General Public License as published by
507+ * the Free Software Foundation; version 3.
508+ *
509+ * This program is distributed in the hope that it will be useful,
510+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
511+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
512+ * GNU General Public License for more details.
513+ *
514+ * You should have received a copy of the GNU General Public License
515+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
516+ */
517+
518+#include "ualwrapper.h"
519+#include <QDebug>
520+
521+UalWrapper* UalWrapper::s_instance = nullptr;
522+QStringList UalWrapper::s_list;
523+
524+UalWrapper::UalWrapper(QObject *parent): QObject(parent)
525+{
526+ s_instance = this;
527+}
528+
529+UalWrapper* UalWrapper::instance()
530+{
531+ return s_instance;
532+}
533+
534+QStringList UalWrapper::installedApps()
535+{
536+ return s_list;
537+}
538+
539+UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
540+{
541+ AppInfo info;
542+ info.appId = appId;
543+ info.name = "App_" + appId;
544+ info.icon = "/dummy/icon/path/" + appId + ".png";
545+ info.keywords << QStringLiteral("keyword1") << QStringLiteral("keyword2");
546+ info.popularity = 1;
547+ info.valid = true;
548+ return info;
549+}
550+
551+void UalWrapper::addMockApp(const QString &appId)
552+{
553+ s_list.append(appId);
554+ Q_EMIT appAdded(appId);
555+}
556+
557+void UalWrapper::removeMockApp(const QString &appId)
558+{
559+ s_list.removeAll(appId);
560+ Q_EMIT appRemoved(appId);
561+}
562
563=== added file 'tests/plugins/Unity/Launcher/ualwrapper.h'
564--- tests/plugins/Unity/Launcher/ualwrapper.h 1970-01-01 00:00:00 +0000
565+++ tests/plugins/Unity/Launcher/ualwrapper.h 2017-04-05 16:29:50 +0000
566@@ -0,0 +1,55 @@
567+/*
568+ * Copyright (C) 2017 Canonical, Ltd.
569+ *
570+ * This program is free software; you can redistribute it and/or modify
571+ * it under the terms of the GNU General Public License as published by
572+ * the Free Software Foundation; version 3.
573+ *
574+ * This program is distributed in the hope that it will be useful,
575+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
576+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
577+ * GNU General Public License for more details.
578+ *
579+ * You should have received a copy of the GNU General Public License
580+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
581+ */
582+
583+#include <QObject>
584+
585+// This is a mock implementation
586+
587+class UalWrapper: public QObject
588+{
589+ Q_OBJECT
590+public:
591+ struct AppInfo {
592+ QString appId;
593+ bool valid = false;
594+ QString name;
595+ QString icon;
596+ QStringList keywords;
597+ uint popularity = 0;
598+ };
599+
600+ UalWrapper(QObject* parent = nullptr);
601+
602+ static QStringList installedApps();
603+ static AppInfo getApplicationInfo(const QString &appId);
604+
605+ // for testing:
606+ static UalWrapper* instance();
607+ void addMockApp(const QString &appId);
608+ void removeMockApp(const QString &appId);
609+
610+Q_SIGNALS:
611+ void appAdded(const QString &appId);
612+ void appRemoved(const QString &appId);
613+ void appInfoChanged(const QString &appId);
614+
615+
616+private:
617+ static QStringList s_list;
618+ static UalWrapper *s_instance;
619+
620+ friend class AppDrawerModelTest;
621+};

Subscribers

People subscribed via source and target branches