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

Proposed by Michael Zanetti
Status: Approved
Approved by: Lukáš Tinkl
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
Lukáš Tinkl (community) Approve
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.
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
2843. By Michael Zanetti

also bump version for required pkgconfig launcher api

Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :
review: Needs Fixing (continuous-integration)
2844. By Michael Zanetti

align appid usage

2845. By Michael Zanetti

drop debug print

2846. By Michael Zanetti

improve a little

Revision history for this message
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
Revision history for this message
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)
Revision history for this message
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

improve a little

2845. By Michael Zanetti

drop debug print

2844. By Michael Zanetti

align appid usage

2843. By Michael Zanetti

also bump version for required pkgconfig launcher api

2842. By Michael Zanetti

bump required unity-api versions

2841. By Michael Zanetti

add appdrawermodeltest

2840. By Michael Zanetti

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

2839. By Michael Zanetti

hook up to appAdded and appRemoved signals

2838. By Michael Zanetti

merge trunk

2837. By Michael Zanetti

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