on xenial help sign in
Appdrawer improvements
cf47c66Marius Gripsgard
debian/control+3−3
@@ -41,7 +41,7 @@ Build-Depends: cmake,
41 libubuntugestures5-private-dev (>= 1.3.2030),
41 libubuntugestures5-private-dev (>= 1.3.2030),
42 libudev-dev,
42 libudev-dev,
43 libudm-common-dev,
43 libudm-common-dev,
44− libunity-api-dev (>= 8.6),
44+ libunity-api-dev (>= 8.7),
45 libusermetricsoutput1-dev,
45 libusermetricsoutput1-dev,
46# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
46# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
47 libx11-dev[!arm64 !armhf],
47 libx11-dev[!arm64 !armhf],
@@ -138,7 +138,7 @@ Depends: dbus,
138 qtdeclarative5-qtmir-plugin (>= 0.4.8),
138 qtdeclarative5-qtmir-plugin (>= 0.4.8),
139 qtdeclarative5-ubuntu-telephony0.1,
139 qtdeclarative5-ubuntu-telephony0.1,
140 ubuntu-system-settings (>= 0.4),
140 ubuntu-system-settings (>= 0.4),
141− unity-launcher-impl-12,
141+ unity-launcher-impl-13,
142 unity8-common (= ${source:Version}),
142 unity8-common (= ${source:Version}),
143 unity8-private (= ${binary:Version}),
143 unity8-private (= ${binary:Version}),
144 unity8-private | unity-launcher-impl,
144 unity8-private | unity-launcher-impl,
@@ -242,7 +242,7 @@ Depends: accountsservice-ubuntu-schemas (>= 0.0.7),
242 ${misc:Depends},
242 ${misc:Depends},
243 ${shlibs:Depends},
243 ${shlibs:Depends},
244Provides: unity-launcher-impl,
244Provides: unity-launcher-impl,
245− unity-launcher-impl-12,
245+ unity-launcher-impl-13,
246Description: Unity 8 private libs
246Description: Unity 8 private libs
247 The Unity 8 shell is the primary user interface for Ubuntu devices.
247 The Unity 8 shell is the primary user interface for Ubuntu devices.
248 .
248 .
plugins/Greeter/Unity/Launcher/launcheritem.cpp+6
@@ -89,6 +89,12 @@ void LauncherItem::setKeywords(const QStringList &keywords)
89 }
89 }
90}
90}
91
91
92+uint LauncherItem::popularity() const
93+{
94+ // Not exposing usage order in greeter session at this point.
95+ return 0;
96+}
97+
92bool LauncherItem::pinned() const
98bool LauncherItem::pinned() const
93{
99{
94 return m_pinned;
100 return m_pinned;
plugins/Greeter/Unity/Launcher/launcheritem.h+1
@@ -35,6 +35,7 @@ public:
35 QString name() const override;
35 QString name() const override;
36 QString icon() const override;
36 QString icon() const override;
37 QStringList keywords() const override;
37 QStringList keywords() const override;
38+ uint popularity() const override;
38 bool pinned() const override;
39 bool pinned() const override;
39 bool running() const override;
40 bool running() const override;
40 bool recent() const override;
41 bool recent() const override;
plugins/Unity/Launcher/appdrawermodel.cpp+68−7
@@ -21,7 +21,8 @@
21#include <QDateTime>
21#include <QDateTime>
22
22
23AppDrawerModel::AppDrawerModel(QObject *parent):
23AppDrawerModel::AppDrawerModel(QObject *parent):
24− AppDrawerModelInterface(parent)
24+ AppDrawerModelInterface(parent),
25+ m_ual(new UalWrapper(this))
25{
26{
26 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
27 Q_FOREACH (const QString &appId, UalWrapper::installedApps()) {
27 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
28 UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
@@ -29,10 +30,16 @@ AppDrawerModel::AppDrawerModel(QObject *parent):
29 qWarning() << "Failed to get app info for app" << appId;
30 qWarning() << "Failed to get app info for app" << appId;
30 continue;
31 continue;
31 }
32 }
32− m_list.append(new LauncherItem(appId, info.name, info.icon, this));
33+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
33− m_list.last()->setKeywords(info.keywords);
34+ item->setKeywords(info.keywords);
35+ item->setPopularity(info.popularity);
36+ m_list.append(item);
34 }
37 }
35− qsrand(QDateTime::currentMSecsSinceEpoch() / 100);
38+
39+ // keep this a queued connection as it's coming from another thread.
40+ connect(m_ual, &UalWrapper::appAdded, this, &AppDrawerModel::appAdded, Qt::QueuedConnection);
41+ connect(m_ual, &UalWrapper::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
42+ connect(m_ual, &UalWrapper::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
36}
43}
37
44
38int AppDrawerModel::rowCount(const QModelIndex &parent) const
45int AppDrawerModel::rowCount(const QModelIndex &parent) const
@@ -53,10 +60,64 @@ QVariant AppDrawerModel::data(const QModelIndex &index, int role) const
53 case RoleKeywords:
60 case RoleKeywords:
54 return m_list.at(index.row())->keywords();
61 return m_list.at(index.row())->keywords();
55 case RoleUsage:
62 case RoleUsage:
56− // FIXME: u-a-l needs to provide API for usage stats.
63+ return m_list.at(index.row())->popularity();
57− // don't forget to drop the qsrand() call in the ctor when dropping this.
58− return qrand();
59 }
64 }
60
65
61 return QVariant();
66 return QVariant();
62}
67}
68+
69+void AppDrawerModel::appAdded(const QString &appId)
70+{
71+ UalWrapper::AppInfo info = UalWrapper::getApplicationInfo(appId);
72+ if (!info.valid) {
73+ qWarning() << "App added signal received but failed to get app info for app" << appId;
74+ return;
75+ }
76+
77+ beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
78+ LauncherItem* item = new LauncherItem(appId, info.name, info.icon, this);
79+ item->setKeywords(info.keywords);
80+ item->setPopularity(info.popularity);
81+ m_list.append(item);
82+ endInsertRows();
83+}
84+
85+void AppDrawerModel::appRemoved(const QString &appId)
86+{
87+ int idx = -1;
88+ for (int i = 0; i < m_list.count(); i++) {
89+ if (m_list.at(i)->appId() == appId) {
90+ idx = i;
91+ break;
92+ }
93+ }
94+ if (idx < 0) {
95+ qWarning() << "App removed signal received but app doesn't seem to be in the drawer model";
96+ return;
97+ }
98+ beginRemoveRows(QModelIndex(), idx, idx);
99+ m_list.takeAt(idx)->deleteLater();
100+ endRemoveRows();
101+}
102+
103+void AppDrawerModel::appInfoChanged(const QString &appId)
104+{
105+ LauncherItem *item = nullptr;
106+ int idx = -1;
107+
108+ for(int i = 0; i < m_list.count(); i++) {
109+ if (m_list.at(i)->appId() == appId) {
110+ item = m_list.at(i);
111+ idx = i;
112+ break;
113+ }
114+ }
115+
116+ if (!item) {
117+ return;
118+ }
119+
120+ UalWrapper::AppInfo info = m_ual->getApplicationInfo(appId);
121+ item->setPopularity(info.popularity);
122+ Q_EMIT dataChanged(index(idx), index(idx), {AppDrawerModelInterface::RoleUsage});
123+}
plugins/Unity/Launcher/appdrawermodel.h+8
@@ -19,6 +19,8 @@
19
19
20#include "launcheritem.h"
20#include "launcheritem.h"
21
21
22+class UalWrapper;
23+
22class AppDrawerModel: public AppDrawerModelInterface
24class AppDrawerModel: public AppDrawerModelInterface
23{
25{
24 Q_OBJECT
26 Q_OBJECT
@@ -28,6 +30,12 @@ public:
28 int rowCount(const QModelIndex &parent) const override;
30 int rowCount(const QModelIndex &parent) const override;
29 QVariant data(const QModelIndex &index, int role) const override;
31 QVariant data(const QModelIndex &index, int role) const override;
30
32
33+private Q_SLOTS:
34+ void appAdded(const QString &appId);
35+ void appRemoved(const QString &appId);
36+ void appInfoChanged(const QString &appId);
37+
31private:
38private:
32 QList<LauncherItem*> m_list;
39 QList<LauncherItem*> m_list;
40+ UalWrapper *m_ual;
33};
41};
plugins/Unity/Launcher/launcheritem.cpp+13
@@ -256,6 +256,19 @@ void LauncherItem::setSurfaces(const QList<QPair<QString, QString> > &surfaces)
256 }
256 }
257}
257}
258
258
259+uint LauncherItem::popularity() const
260+{
261+ return m_popularity;
262+}
263+
264+void LauncherItem::setPopularity(uint popularity)
265+{
266+ if (m_popularity != popularity) {
267+ m_popularity = popularity;
268+ Q_EMIT popularityChanged(popularity);
269+ }
270+}
271+
259unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
272unity::shell::launcher::QuickListModelInterface *LauncherItem::quickList() const
260{
273{
261 return m_quickList;
274 return m_quickList;
plugins/Unity/Launcher/launcheritem.h+3
@@ -39,6 +39,7 @@ public:
39 QString name() const override;
39 QString name() const override;
40 QString icon() const override;
40 QString icon() const override;
41 QStringList keywords() const override;
41 QStringList keywords() const override;
42+ uint popularity() const override;
42 bool pinned() const override;
43 bool pinned() const override;
43 bool running() const override;
44 bool running() const override;
44 bool recent() const override;
45 bool recent() const override;
@@ -55,6 +56,7 @@ private:
55 void setName(const QString &name);
56 void setName(const QString &name);
56 void setIcon(const QString &icon);
57 void setIcon(const QString &icon);
57 void setKeywords(const QStringList &keywords);
58 void setKeywords(const QStringList &keywords);
59+ void setPopularity(uint popularity);
58 void setPinned(bool pinned);
60 void setPinned(bool pinned);
59 void setRunning(bool running);
61 void setRunning(bool running);
60 void setRecent(bool recent);
62 void setRecent(bool recent);
@@ -70,6 +72,7 @@ private:
70 QString m_name;
72 QString m_name;
71 QString m_icon;
73 QString m_icon;
72 QStringList m_keywords;
74 QStringList m_keywords;
75+ uint m_popularity;
73 bool m_pinned;
76 bool m_pinned;
74 bool m_running;
77 bool m_running;
75 bool m_recent;
78 bool m_recent;
plugins/Unity/Launcher/launchermodel.cpp+1
@@ -167,6 +167,7 @@ void LauncherModel::pin(const QString &appId, int index)
167 appInfo.icon,
167 appInfo.icon,
168 this);
168 this);
169 item->setPinned(true);
169 item->setPinned(true);
170+ item->setPopularity(appInfo.popularity);
170 m_list.insert(index, item);
171 m_list.insert(index, item);
171 endInsertRows();
172 endInsertRows();
172 }
173 }
plugins/Unity/Launcher/ualwrapper.cpp+12−2
@@ -24,7 +24,15 @@ using namespace ubuntu::app_launch;
24UalWrapper::UalWrapper(QObject *parent):
24UalWrapper::UalWrapper(QObject *parent):
25 QObject(parent)
25 QObject(parent)
26{
26{
27−
27+ Registry::appAdded().connect([this](const std::shared_ptr<Application>&app) {
28+ Q_EMIT appAdded(QString::fromStdString(app->appId()));
29+ });
30+ Registry::appRemoved().connect([this](const AppID &appId) {
31+ Q_EMIT appRemoved(QString::fromStdString(appId));
32+ });
33+ Registry::appInfoUpdated().connect([this](const std::shared_ptr<Application>&app){
34+ Q_EMIT appInfoChanged(QString::fromStdString(app->appId()));
35+ });
28}
36}
29
37
30QStringList UalWrapper::installedApps()
38QStringList UalWrapper::installedApps()
@@ -39,7 +47,7 @@ QStringList UalWrapper::installedApps()
39 }
47 }
40 }
48 }
41 } catch (const std::runtime_error &e) {
49 } catch (const std::runtime_error &e) {
42− qWarning() << "ubuntu-all-launch threw an exception listing apps:" << e.what();
50+ qWarning() << "ubuntu-app-launch threw an exception listing apps:" << e.what();
43 }
51 }
44
52
45 return appIds;
53 return appIds;
@@ -59,11 +67,13 @@ UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
59 std::shared_ptr<Application> ualApp;
67 std::shared_ptr<Application> ualApp;
60 ualApp = Application::create(ualAppId, Registry::getDefault());
68 ualApp = Application::create(ualAppId, Registry::getDefault());
61
69
70+ info.appId = appId;
62 info.name = QString::fromStdString(ualApp->info()->name());
71 info.name = QString::fromStdString(ualApp->info()->name());
63 info.icon = QString::fromStdString(ualApp->info()->iconPath());
72 info.icon = QString::fromStdString(ualApp->info()->iconPath());
64 for (const std::string &keyword : ualApp->info()->keywords().value()) {
73 for (const std::string &keyword : ualApp->info()->keywords().value()) {
65 info.keywords << QString::fromStdString(keyword);
74 info.keywords << QString::fromStdString(keyword);
66 }
75 }
76+ info.popularity = ualApp->info()->popularity();
67 info.valid = true;
77 info.valid = true;
68 } catch (const std::runtime_error &e) {
78 } catch (const std::runtime_error &e) {
69 qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what();
79 qWarning() << "ubuntu-app-launch threw an exception getting app info for appId:" << appId << ":" << e.what();
plugins/Unity/Launcher/ualwrapper.h+6
@@ -21,10 +21,12 @@ class UalWrapper: public QObject
21 Q_OBJECT
21 Q_OBJECT
22public:
22public:
23 struct AppInfo {
23 struct AppInfo {
24+ QString appId;
24 bool valid = false;
25 bool valid = false;
25 QString name;
26 QString name;
26 QString icon;
27 QString icon;
27 QStringList keywords;
28 QStringList keywords;
29+ uint popularity = 0;
28 };
30 };
29
31
30 UalWrapper(QObject* parent = nullptr);
32 UalWrapper(QObject* parent = nullptr);
@@ -32,4 +34,8 @@ public:
32 static QStringList installedApps();
34 static QStringList installedApps();
33 static AppInfo getApplicationInfo(const QString &appId);
35 static AppInfo getApplicationInfo(const QString &appId);
34
36
37+Q_SIGNALS:
38+ void appAdded(const QString &appId);
39+ void appRemoved(const QString &appId);
40+ void appInfoChanged(const QString &appId);
35};
41};
tests/mocks/Unity/Launcher/MockLauncherItem.cpp+13
@@ -72,6 +72,11 @@ QStringList MockLauncherItem::keywords() const
72 return m_keywords;
72 return m_keywords;
73}
73}
74
74
75+uint MockLauncherItem::popularity() const
76+{
77+ return m_popularity;
78+}
79+
75bool MockLauncherItem::pinned() const
80bool MockLauncherItem::pinned() const
76{
81{
77 return m_pinned;
82 return m_pinned;
@@ -201,6 +206,14 @@ void MockLauncherItem::setSurfaceCount(int surfaceCount)
201 }
206 }
202}
207}
203
208
209+void MockLauncherItem::setPopularity(uint popularity)
210+{
211+ if (m_popularity != popularity) {
212+ m_popularity = popularity;
213+ Q_EMIT popularityChanged(m_popularity);
214+ }
215+}
216+
204unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
217unity::shell::launcher::QuickListModelInterface *MockLauncherItem::quickList() const
205{
218{
206 return m_quickList;
219 return m_quickList;
tests/mocks/Unity/Launcher/MockLauncherItem.h+3
@@ -40,6 +40,7 @@ public:
40 QString name() const override;
40 QString name() const override;
41 QString icon() const override;
41 QString icon() const override;
42 QStringList keywords() const override;
42 QStringList keywords() const override;
43+ uint popularity() const override;
43
44
44 bool pinned() const override;
45 bool pinned() const override;
45 bool running() const override;
46 bool running() const override;
@@ -55,6 +56,7 @@ public:
55
56
56private:
57private:
57 void setKeywords(const QStringList &keywords);
58 void setKeywords(const QStringList &keywords);
59+ void setPopularity(uint popularity);
58 void setPinned(bool pinned);
60 void setPinned(bool pinned);
59 void setRunning(bool running);
61 void setRunning(bool running);
60 void setRecent(bool recent);
62 void setRecent(bool recent);
@@ -70,6 +72,7 @@ private:
70 QString m_name;
72 QString m_name;
71 QString m_icon;
73 QString m_icon;
72 QStringList m_keywords;
74 QStringList m_keywords;
75+ uint m_popularity;
73 bool m_pinned;
76 bool m_pinned;
74 bool m_running;
77 bool m_running;
75 bool m_recent;
78 bool m_recent;
tests/plugins/Unity/Launcher/CMakeLists.txt+34
@@ -61,6 +61,40 @@ add_unity8_unittest(LauncherModel dbus-test-runner
61 --wait-for org.freedesktop.Accounts
61 --wait-for org.freedesktop.Accounts
62)
62)
63
63
64+### AppDrawerModelTest
65+add_executable(appdrawermodeltestExec
66+ appdrawermodeltest.cpp
67+ ualwrapper.cpp
68+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/appdrawermodel.cpp
69+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/AppDrawerModelInterface.h
70+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/launcheritem.cpp
71+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistmodel.cpp
72+ ${CMAKE_SOURCE_DIR}/plugins/Unity/Launcher/quicklistentry.cpp
73+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/LauncherItemInterface.h
74+ ${LAUNCHER_API_INCLUDEDIR}/unity/shell/launcher/QuickListModelInterface.h
75+ )
76+target_link_libraries(appdrawermodeltestExec
77+ unity8-private
78+ ${GSETTINGS_QT_LDFLAGS}
79+ ${GLIB_LIBRARIES}
80+ ${UAL_LIBRARIES}
81+ )
82+add_dependencies(appdrawermodeltestExec mock-server)
83+qt5_use_modules(appdrawermodeltestExec Test Core DBus Xml Gui Qml)
84+install(TARGETS appdrawermodeltestExec
85+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/plugins/Unity/Launcher"
86+ )
87+
88+add_unity8_unittest(AppDrawerModel dbus-test-runner
89+ ENVIRONMENT "APPDIR=${CMAKE_CURRENT_BINARY_DIR}/applications"
90+ ARG_PREFIX "--parameter"
91+ ARGS
92+ --task $<TARGET_FILE:mock-server>
93+ --ignore-return
94+ --task $<TARGET_FILE:appdrawermodeltestExec>
95+ --wait-for org.freedesktop.Accounts
96+)
97+
64# copy sample application files into build directory for shadow builds
98# copy sample application files into build directory for shadow builds
65file(COPY applications
99file(COPY applications
66 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
100 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
tests/plugins/Unity/Launcher/appdrawermodeltest.cppnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright 2017 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 as published by
6+ * the Free Software Foundation; version 3.
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+
17+#include "ualwrapper.h"
18+#include "appdrawermodel.h"
19+
20+#include <QtTest>
21+
22+class AppDrawerModelTest : public QObject
23+{
24+ Q_OBJECT
25+
26+private:
27+ AppDrawerModel *appDrawerModel;
28+
29+private Q_SLOTS:
30+
31+ void initTestCase() {
32+ UalWrapper::s_list << QStringLiteral("app1") << QStringLiteral("app2");
33+ appDrawerModel = new AppDrawerModel(this);
34+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
35+ }
36+
37+ void testUalAppAddedRemoved() {
38+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
39+
40+ UalWrapper::instance()->addMockApp("app3");
41+ qApp->processEvents(); // ualwrapper is connected Queued
42+
43+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 3);
44+
45+ UalWrapper::instance()->removeMockApp("app3");
46+ qApp->processEvents();
47+
48+ QCOMPARE(appDrawerModel->rowCount(QModelIndex()), 2);
49+ }
50+};
51+
52+QTEST_GUILESS_MAIN(AppDrawerModelTest)
53+#include "appdrawermodeltest.moc"
tests/plugins/Unity/Launcher/ualwrapper.cppnew file+60
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (C) 2017 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ualwrapper.h"
18+#include <QDebug>
19+
20+UalWrapper* UalWrapper::s_instance = nullptr;
21+QStringList UalWrapper::s_list;
22+
23+UalWrapper::UalWrapper(QObject *parent): QObject(parent)
24+{
25+ s_instance = this;
26+}
27+
28+UalWrapper* UalWrapper::instance()
29+{
30+ return s_instance;
31+}
32+
33+QStringList UalWrapper::installedApps()
34+{
35+ return s_list;
36+}
37+
38+UalWrapper::AppInfo UalWrapper::getApplicationInfo(const QString &appId)
39+{
40+ AppInfo info;
41+ info.appId = appId;
42+ info.name = "App_" + appId;
43+ info.icon = "/dummy/icon/path/" + appId + ".png";
44+ info.keywords << QStringLiteral("keyword1") << QStringLiteral("keyword2");
45+ info.popularity = 1;
46+ info.valid = true;
47+ return info;
48+}
49+
50+void UalWrapper::addMockApp(const QString &appId)
51+{
52+ s_list.append(appId);
53+ Q_EMIT appAdded(appId);
54+}
55+
56+void UalWrapper::removeMockApp(const QString &appId)
57+{
58+ s_list.removeAll(appId);
59+ Q_EMIT appRemoved(appId);
60+}
tests/plugins/Unity/Launcher/ualwrapper.hnew file+55
@@ -0,0 +1,55 @@
1+/*
2+ * Copyright (C) 2017 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include <QObject>
18+
19+// This is a mock implementation
20+
21+class UalWrapper: public QObject
22+{
23+ Q_OBJECT
24+public:
25+ struct AppInfo {
26+ QString appId;
27+ bool valid = false;
28+ QString name;
29+ QString icon;
30+ QStringList keywords;
31+ uint popularity = 0;
32+ };
33+
34+ UalWrapper(QObject* parent = nullptr);
35+
36+ static QStringList installedApps();
37+ static AppInfo getApplicationInfo(const QString &appId);
38+
39+ // for testing:
40+ static UalWrapper* instance();
41+ void addMockApp(const QString &appId);
42+ void removeMockApp(const QString &appId);
43+
44+Q_SIGNALS:
45+ void appAdded(const QString &appId);
46+ void appRemoved(const QString &appId);
47+ void appInfoChanged(const QString &appId);
48+
49+
50+private:
51+ static QStringList s_list;
52+ static UalWrapper *s_instance;
53+
54+ friend class AppDrawerModelTest;
55+};