on xenial help sign in
Update mock ApplicationManager APIs to use that defined in unity-api
commitfebd4752059c228e5c7d936200d7747dc6d0d718 authorGerry Boland <gerry.boland@canonical.com> dateThu 5 Sep 2013, 14:21 (13 years ago) parent6a3d0df
8 files changed+230−418
tests/mocks/Unity/Application/ApplicationInfo.cpp+15−2 tests/mocks/Unity/Application/ApplicationInfo.h+12−18 tests/mocks/Unity/Application/ApplicationListModel.cpp−144 tests/mocks/Unity/Application/ApplicationListModel.h−71 tests/mocks/Unity/Application/ApplicationManager.cpp+164−154 tests/mocks/Unity/Application/ApplicationManager.h+34−26 tests/mocks/Unity/Application/CMakeLists.txt+5−1 tests/mocks/Unity/Application/plugin.cpp−2
tests/mocks/Unity/Application/ApplicationInfo.cpp+15−2
@@ -21,11 +21,24 @@
2121#include <QQuickView>
2222#include <QQmlComponent>
2323
24+ApplicationInfo::ApplicationInfo(const QString &appId, QObject *parent)
25+ : ApplicationInfoInterface(appId, parent)
26+ ,m_appId(appId)
27+ ,m_stage(MainStage)
28+ ,m_state(Starting)
29+ ,m_focused(false)
30+ ,m_fullscreen(false)
31+ ,m_windowItem(0)
32+ ,m_windowComponent(0)
33+ ,m_parentItem(0)
34+{
35+}
36+
2437ApplicationInfo::ApplicationInfo(QObject *parent)
25− : QObject(parent)
26− ,m_handle(0)
38+ : ApplicationInfoInterface(QString(), parent)
2739 ,m_stage(MainStage)
2840 ,m_state(Starting)
41+ ,m_focused(false)
2942 ,m_fullscreen(false)
3043 ,m_windowItem(0)
3144 ,m_windowComponent(0)
tests/mocks/Unity/Application/ApplicationInfo.h+12−18
@@ -22,21 +22,18 @@
2222
2323class QQuickItem;
2424
25+// unity-api
26+#include <unity/shell/application/ApplicationInfoInterface.h>
27+
2528// A pretty dumb file. Just a container for properties.
2629// Implemented in C++ instead of QML just because of the enumerations
2730// See QTBUG-14861
28−class ApplicationInfo : public QObject {
31+
32+using namespace unity::shell::application;
33+
34+class ApplicationInfo : public ApplicationInfoInterface {
2935 Q_OBJECT
30− Q_ENUMS(Stage)
31− Q_ENUMS(State)
32− Q_PROPERTY(QString desktopFile READ desktopFile WRITE setDesktopFile NOTIFY desktopFileChanged)
33− Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
34− Q_PROPERTY(QString comment READ comment WRITE setComment NOTIFY commentChanged)
35− Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
36− Q_PROPERTY(QString exec READ exec WRITE setExec NOTIFY execChanged)
37− Q_PROPERTY(qint64 handle READ handle WRITE setHandle NOTIFY handleChanged)
38− Q_PROPERTY(Stage stage READ stage WRITE setStage NOTIFY stageChanged)
39− Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged)
36+
4037 Q_PROPERTY(bool fullscreen READ fullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
4138
4239 // Only exists in this fake implementation
@@ -48,10 +45,8 @@ class ApplicationInfo : public QObject {
4845 Q_PROPERTY(QString windowQml READ windowQml WRITE setWindowQml NOTIFY windowQmlChanged)
4946
5047 public:
51− enum Stage { MainStage, SideStage };
52− enum State { Starting, Running };
53−
5448 ApplicationInfo(QObject *parent = NULL);
49+ ApplicationInfo(const QString &appId, QObject *parent = NULL);
5550
5651 #define IMPLEMENT_PROPERTY(name, Name, type) \
5752 public: \
@@ -68,14 +63,13 @@ class ApplicationInfo : public QObject {
6863 private: \
6964 type m_##name;
7065
71− IMPLEMENT_PROPERTY(desktopFile, DesktopFile, QString)
66+ IMPLEMENT_PROPERTY(appId, AppId, QString)
7267 IMPLEMENT_PROPERTY(name, Name, QString)
7368 IMPLEMENT_PROPERTY(comment, Comment, QString)
74− IMPLEMENT_PROPERTY(icon, Icon, QString)
75− IMPLEMENT_PROPERTY(exec, Exec, QString)
76− IMPLEMENT_PROPERTY(handle, Handle, qint64)
69+ IMPLEMENT_PROPERTY(icon, Icon, QUrl)
7770 IMPLEMENT_PROPERTY(stage, Stage, Stage)
7871 IMPLEMENT_PROPERTY(state, State, State)
72+ IMPLEMENT_PROPERTY(focused, Focused, bool)
7973 IMPLEMENT_PROPERTY(fullscreen, Fullscreen, bool)
8074 IMPLEMENT_PROPERTY(imageQml, ImageQml, QString)
8175 IMPLEMENT_PROPERTY(windowQml, WindowQml, QString)
tests/mocks/Unity/Application/ApplicationListModel.cppdeleted−144
@@ -1,144 +0,0 @@
1−/*
2− * Copyright (C) 2013 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 "ApplicationListModel.h"
18−#include "ApplicationInfo.h"
19−
20−ApplicationListModel::ApplicationListModel(QObject* parent)
21− : QAbstractListModel(parent), m_applications()
22−{
23− m_roleNames.insert(0, "application");
24−}
25−
26−ApplicationListModel::~ApplicationListModel()
27−{
28− const int kSize = m_applications.size();
29− for (int i = 0; i < kSize; i++)
30− delete m_applications.at(i);
31− m_applications.clear();
32−}
33−
34−int ApplicationListModel::rowCount(const QModelIndex& parent) const
35−{
36− return !parent.isValid() ? m_applications.size() : 0;
37−}
38−
39−QVariant ApplicationListModel::data(const QModelIndex& index, int role) const
40−{
41− if (index.row() >= 0 && index.row() < m_applications.size() && role == 0)
42− return QVariant::fromValue(m_applications.at(index.row()));
43− else
44− return QVariant();
45−}
46−
47−QVariant ApplicationListModel::get(int row) const
48−{
49− return data(index(row), 0);
50−}
51−
52−void ApplicationListModel::move(int from, int to)
53−{
54− if (from >= 0 && from < m_applications.size() && to >= 0 && to < m_applications.size()) {
55− QModelIndex parent;
56− /* When moving an item down, the destination index needs to be incremented
57− by one, as explained in the documentation:
58− http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
59− beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
60− m_applications.move(from, to);
61− endMoveRows();
62− }
63−}
64−
65−void ApplicationListModel::add(ApplicationInfo* application)
66−{
67− beginInsertRows(QModelIndex(), m_applications.size(), m_applications.size());
68− m_applications.append(application);
69− endInsertRows();
70− Q_EMIT countChanged();
71−}
72−
73−void ApplicationListModel::remove(ApplicationInfo* application)
74−{
75− int i = m_applications.indexOf(application);
76− if (i != -1) {
77− beginRemoveRows(QModelIndex(), i, i);
78− m_applications.removeAt(i);
79− endRemoveRows();
80− Q_EMIT countChanged();
81− }
82−}
83−
84−bool ApplicationListModel::contains(ApplicationInfo* application) const {
85− return m_applications.contains(application);
86−}
87−
88−void ApplicationListModel::clear()
89−{
90− beginRemoveRows(QModelIndex(), 0, m_applications.size()-1);
91− m_applications.clear();
92− endRemoveRows();
93− Q_EMIT countChanged();
94−}
95−
96−QQmlListProperty<ApplicationInfo> ApplicationListModel::applications()
97−{
98− return QQmlListProperty<ApplicationInfo>(this, 0,
99− &ApplicationListModel::appendApplication,
100− &ApplicationListModel::countApplications,
101− &ApplicationListModel::atApplication,
102− &ApplicationListModel::clearApplications);
103−}
104−
105−void ApplicationListModel::appendApplication(QQmlListProperty<ApplicationInfo> *list,
106− ApplicationInfo *application)
107−{
108− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
109− if (self) {
110− application->setParent(self);
111− self->add(application);
112− }
113−}
114−
115−int ApplicationListModel::countApplications(QQmlListProperty<ApplicationInfo> *list)
116−{
117− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
118− if (self) {
119− return self->m_applications.size();
120− } else {
121− return 0;
122− }
123−}
124−
125−ApplicationInfo* ApplicationListModel::atApplication(QQmlListProperty<ApplicationInfo> *list,
126− int index)
127−{
128− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
129− if (!self) { return 0; }
130−
131− if (index >= 0 && index < self->m_applications.size()) {
132− return self->m_applications.at(index);
133− } else {
134− return 0;
135− }
136−}
137−
138−void ApplicationListModel::clearApplications(QQmlListProperty<ApplicationInfo> *list)
139−{
140− ApplicationListModel *self = qobject_cast<ApplicationListModel *>(list->object);
141− if (self) {
142− self->clear();
143− }
144−}
tests/mocks/Unity/Application/ApplicationListModel.hdeleted−71
@@ -1,71 +0,0 @@
1−/*
2− * Copyright (C) 2013 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−#ifndef APPLICATION_LIST_MODEL_H
18−#define APPLICATION_LIST_MODEL_H
19−
20−#include <QAbstractListModel>
21−#include <QQmlListProperty>
22−#include "ApplicationInfo.h"
23−
24−class ApplicationManager;
25−
26−class ApplicationListModel : public QAbstractListModel {
27− Q_OBJECT
28−
29− Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
30− Q_PROPERTY(QQmlListProperty<ApplicationInfo> applications READ applications)
31− Q_CLASSINFO("DefaultProperty", "applications")
32−
33− public:
34− explicit ApplicationListModel(QObject* parent = 0);
35− virtual ~ApplicationListModel();
36−
37− // QAbstractItemModel methods.
38− int rowCount(const QModelIndex& parent = QModelIndex()) const;
39− QVariant data(const QModelIndex& index, int role) const;
40− QHash<int,QByteArray> roleNames() const { return m_roleNames; }
41− Q_INVOKABLE QVariant get(int index) const;
42− Q_INVOKABLE void move(int from, int to);
43−
44− QQmlListProperty<ApplicationInfo> applications();
45−
46− Q_INVOKABLE void add(ApplicationInfo* application);
47− Q_INVOKABLE void remove(ApplicationInfo* application);
48− Q_INVOKABLE bool contains(ApplicationInfo* application) const;
49− Q_INVOKABLE void clear();
50−
51− Q_SIGNALS:
52− void countChanged();
53−
54− private:
55− Q_DISABLE_COPY(ApplicationListModel)
56−
57− static void appendApplication(QQmlListProperty<ApplicationInfo> *list,
58− ApplicationInfo *application);
59− static int countApplications(QQmlListProperty<ApplicationInfo> *list);
60− static ApplicationInfo* atApplication(QQmlListProperty<ApplicationInfo> *list, int index);
61− static void clearApplications(QQmlListProperty<ApplicationInfo> *list);
62−
63− QHash<int,QByteArray> m_roleNames;
64− QList<ApplicationInfo*> m_applications;
65−
66− friend class ApplicationManager;
67−};
68−
69−Q_DECLARE_METATYPE(ApplicationListModel*)
70−
71−#endif // APPLICATION_LIST_MODEL_H
tests/mocks/Unity/Application/ApplicationManager.cpp+164−154
@@ -16,7 +16,6 @@
1616
1717#include "ApplicationManager.h"
1818#include "ApplicationInfo.h"
19−#include "ApplicationListModel.h"
2019#include "paths.h"
2120
2221#include <QDir>
@@ -26,11 +25,7 @@
2625#include <QQmlComponent>
2726
2827ApplicationManager::ApplicationManager(QObject *parent)
29− : QObject(parent)
30− , m_mainStageApplications(new ApplicationListModel())
31− , m_sideStageApplications(new ApplicationListModel())
32− , m_mainStageFocusedApplication(0)
33− , m_sideStageFocusedApplication(0)
28+ : ApplicationManagerInterface(parent)
3429 , m_mainStageComponent(0)
3530 , m_mainStage(0)
3631 , m_sideStageComponent(0)
@@ -41,8 +36,65 @@ ApplicationManager::ApplicationManager(QObject *parent)
4136
4237ApplicationManager::~ApplicationManager()
4338{
44− delete m_mainStageApplications;
45− delete m_sideStageApplications;
39+}
40+
41+int ApplicationManager::rowCount(const QModelIndex& parent) const {
42+ return !parent.isValid() ? m_runningApplications.size() : 0;
43+}
44+
45+QVariant ApplicationManager::data(const QModelIndex& index, int role) const {
46+ if (index.row() < 0 || index.row() >= m_runningApplications.size())
47+ return QVariant();
48+
49+ auto app = m_runningApplications.at(index.row());
50+ switch(role) {
51+ case RoleAppId:
52+ return app->appId();
53+ case RoleName:
54+ return app->name();
55+ case RoleComment:
56+ return app->comment();
57+ case RoleIcon:
58+ return app->icon();
59+ case RoleStage:
60+ return app->stage();
61+ case RoleState:
62+ return app->state();
63+ case RoleFocused:
64+ return app->focused();
65+ default:
66+ return QVariant();
67+ }
68+}
69+
70+ApplicationInfo *ApplicationManager::get(int row) const {
71+ if (row < 0 || row >= m_runningApplications.size())
72+ return nullptr;
73+
74+ return m_runningApplications.at(row);
75+}
76+
77+ApplicationInfo *ApplicationManager::findApplication(const QString &appId) const {
78+ for (ApplicationInfo *app : m_runningApplications) {
79+ if (app->appId() == appId) {
80+ return app;
81+ }
82+ }
83+ return nullptr;
84+}
85+
86+void ApplicationManager::move(int from, int to) {
87+ if (from == to) return;
88+
89+ if (from >= 0 && from < m_runningApplications.size() && to >= 0 && to < m_runningApplications.size()) {
90+ QModelIndex parent;
91+ /* When moving an item down, the destination index needs to be incremented
92+ * by one, as explained in the documentation:
93+ * http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html#beginMoveRows */
94+ beginMoveRows(parent, from, from, parent, to + (to > from ? 1 : 0));
95+ m_runningApplications.move(from, to);
96+ endMoveRows();
97+ }
4698}
4799
48100int ApplicationManager::keyboardHeight() const
@@ -70,36 +122,22 @@ ApplicationManager::FormFactorHint ApplicationManager::formFactorHint() const
70122 return PhoneFormFactor;
71123}
72124
73−ApplicationListModel* ApplicationManager::mainStageApplications() const
74−{
75− return m_mainStageApplications;
76−}
77−
78−ApplicationListModel* ApplicationManager::sideStageApplications() const
125+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
126+ const QStringList &arguments)
79127{
80− return m_sideStageApplications;
128+ return this->startApplication(appId, NoFlag, arguments);
81129}
82130
83−ApplicationInfo* ApplicationManager::mainStageFocusedApplication() const
84−{
85− return m_mainStageFocusedApplication;
86−}
87−
88−ApplicationInfo* ApplicationManager::sideStageFocusedApplication() const
89−{
90− return m_sideStageFocusedApplication;
91−}
92−
93−ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
131+ApplicationInfo* ApplicationManager::startApplication(const QString &appId,
94132 ExecFlags flags,
95− QStringList arguments)
133+ const QStringList &arguments)
96134{
97135 Q_UNUSED(arguments)
98136 ApplicationInfo *application = 0;
99137
100138 for (int i = 0; i < m_availableApplications.count(); ++i) {
101139 ApplicationInfo *availableApp = m_availableApplications[i];
102− if (availableApp->desktopFile() == desktopFile) {
140+ if (availableApp->appId() == appId) {
103141 application = availableApp;
104142 break;
105143 }
@@ -108,87 +146,88 @@ ApplicationInfo* ApplicationManager::startProcess(QString desktopFile,
108146 if (!application)
109147 return 0;
110148
149+ m_runningApplications.append(application);
111150 if (flags.testFlag(ApplicationManager::ForceMainStage)
112− || application->stage() == ApplicationInfo::MainStage) {
113− m_mainStageApplications->add(application);
114− } else {
115− m_sideStageApplications->add(application);
151+ && application->stage() == ApplicationInfo::SideStage) {
152+ application->setStage(ApplicationInfo::MainStage);
116153 }
117154
155+ application->setFocused(true);
156+ Q_EMIT focusedApplicationIdChanged();
118157 return application;
119158}
120159
121−void ApplicationManager::stopProcess(ApplicationInfo* application)
160+bool ApplicationManager::stopApplication(const QString &appId)
122161{
123− if (m_mainStageApplications->contains(application)) {
124− m_mainStageApplications->remove(application);
125−
126− if (m_mainStageFocusedApplication == application) {
127− m_mainStageFocusedApplication = 0;
128− Q_EMIT mainStageFocusedApplicationChanged();
129− }
130− } else if (m_sideStageApplications->contains(application)){
131− m_sideStageApplications->remove(application);
162+ ApplicationInfo *application = this->findApplication(appId);
163+ if (application == nullptr)
164+ return false;
165+
166+ application->setFocused(false);
167+ m_runningApplications.removeAll(application);
168+ Q_EMIT focusedApplicationIdChanged();
169+ return true;
170+}
132171
133− if (m_sideStageFocusedApplication == application) {
134− m_sideStageFocusedApplication = 0;
135− Q_EMIT sideStageFocusedApplicationChanged();
136− }
172+QString ApplicationManager::focusedApplicationId() const {
173+ for (ApplicationInfo *app : m_runningApplications) {
174+ if (app->focused())
175+ return app->appId();
137176 }
177+ return QString();
138178}
139179
140−void ApplicationManager::focusApplication(int handle)
180+bool ApplicationManager::focusApplication(const QString &appId)
141181{
142− for (int i = 0; i < m_mainStageApplications->m_applications.count(); ++i) {
143− ApplicationInfo *application = m_mainStageApplications->m_applications[i];
144− if (application->handle() == handle) {
145− if (m_mainStageFocusedApplication)
146− m_mainStageFocusedApplication->hideWindow();
147− m_mainStageFocusedApplication = application;
148− if (!m_mainStage)
149− createMainStage();
150− application->showWindow(m_mainStage);
151− m_mainStage->setZ(-1000);
152− if (m_sideStage)
153− m_sideStage->setZ(-2000);
154− Q_EMIT mainStageFocusedApplicationChanged();
155− return;
182+ ApplicationInfo *application = this->findApplication(appId);
183+ if (application == nullptr)
184+ return false;
185+
186+ if (application->stage() == ApplicationInfo::MainStage) {
187+ // unfocus currently focused mainstage app
188+ for (ApplicationInfo *app : m_runningApplications) {
189+ if (app->focused() && app->stage() == ApplicationInfo::MainStage)
190+ app->setFocused(false);
156191 }
157− }
158192
159− for (int i = 0; i < m_sideStageApplications->m_applications.count(); ++i) {
160− ApplicationInfo *application = m_sideStageApplications->m_applications[i];
161− if (application->handle() == handle) {
162− if (m_sideStageFocusedApplication)
163− m_sideStageFocusedApplication->hideWindow();
164− m_sideStageFocusedApplication = application;
165− if (!m_sideStage)
166− createSideStage();
167− application->showWindow(m_sideStage);
168− m_sideStage->setZ(-1000);
169− if (m_mainStage)
170− m_mainStage->setZ(-2000);
171− Q_EMIT sideStageFocusedApplicationChanged();
172− return;
193+ // focus this app
194+ application->setFocused(true);
195+ if (!m_mainStage)
196+ createMainStage();
197+ application->showWindow(m_mainStage);
198+ m_mainStage->setZ(-1000);
199+ if (m_sideStage)
200+ m_sideStage->setZ(-2000);
201+ } else if (application->stage() == ApplicationInfo::SideStage) {
202+ // unfocus currently focused sidestage app
203+ for (ApplicationInfo *app : m_runningApplications) {
204+ if (app->focused() && app->stage() == ApplicationInfo::SideStage)
205+ app->setFocused(false);
173206 }
207+
208+ // focus this app
209+ application->setFocused(true);
210+ if (!m_sideStage)
211+ createSideStage();
212+ application->showWindow(m_sideStage);
213+ m_sideStage->setZ(-1000);
214+ if (m_mainStage)
215+ m_mainStage->setZ(-2000);
174216 }
217+
218+ // move app to top of stack
219+ this->move(m_runningApplications.indexOf(application), 0);
220+ Q_EMIT focusedApplicationIdChanged();
221+ return true;
175222}
176223
177−void ApplicationManager::unfocusCurrentApplication(StageHint stageHint)
224+void ApplicationManager::unfocusCurrentApplication()
178225{
179− if (stageHint == SideStage) {
180− if (m_sideStageFocusedApplication) {
181− m_sideStageFocusedApplication->hideWindow();
182− m_sideStageFocusedApplication = 0;
183− Q_EMIT sideStageFocusedApplicationChanged();
184− }
185− } else {
186− if (m_mainStageFocusedApplication) {
187− m_mainStageFocusedApplication->hideWindow();
188− m_mainStageFocusedApplication = 0;
189− Q_EMIT mainStageFocusedApplicationChanged();
190− }
226+ for (ApplicationInfo *app : m_runningApplications) {
227+ if (app->focused())
228+ app->setFocused(false);
191229 }
230+ Q_EMIT focusedApplicationIdChanged();
192231}
193232
194233void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
@@ -213,7 +252,7 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
213252 " fillMode: Image.PreserveAspectCrop\n"
214253 "}").arg(topMargin)
215254 .arg(shellAppDirectory())
216− .arg(application->icon());
255+ .arg(application->icon().toString());
217256 application->setWindowQml(windowQml);
218257
219258 QString imageQml = QString(
@@ -224,159 +263,130 @@ void ApplicationManager::generateQmlStrings(ApplicationInfo *application)
224263 " smooth: true\n"
225264 " fillMode: Image.PreserveAspectCrop\n"
226265 "}").arg(shellAppDirectory())
227− .arg(application->icon());
266+ .arg(application->icon().toString());
228267 application->setImageQml(imageQml);
229268}
230269
231270void ApplicationManager::buildListOfAvailableApplications()
232271{
233272 ApplicationInfo *application;
234− qint64 nextHandle = 1;
235273
236274 application = new ApplicationInfo(this);
237− application->setDesktopFile("/usr/share/applications/phone-app.desktop");
275+ application->setAppId("phone-app");
238276 application->setName("Phone");
239− application->setIcon("phone");
240− application->setExec("/usr/bin/phone-app");
277+ application->setIcon(QUrl("phone"));
241278 application->setStage(ApplicationInfo::SideStage);
242− application->setHandle(nextHandle++);
243279 generateQmlStrings(application);
244280 m_availableApplications.append(application);
245281
246282 application = new ApplicationInfo(this);
247− application->setDesktopFile("/usr/share/applications/camera-app.desktop");
283+ application->setAppId("camera-app");
248284 application->setName("Camera");
249− application->setIcon("camera");
285+ application->setIcon(QUrl("camera"));
250286 application->setFullscreen(true);
251− application->setExec("/usr/bin/camera-app --fullscreen");
252− application->setHandle(nextHandle++);
253287 generateQmlStrings(application);
254288 m_availableApplications.append(application);
255289
256290 application = new ApplicationInfo(this);
257− application->setDesktopFile("/usr/share/applications/gallery-app.desktop");
291+ application->setAppId("gallery-app");
258292 application->setName("Gallery");
259− application->setIcon("gallery");
260− application->setExec("/usr/bin/gallery-app");
261− application->setHandle(nextHandle++);
293+ application->setIcon(QUrl("gallery"));
262294 generateQmlStrings(application);
263295 m_availableApplications.append(application);
264296
265297 application = new ApplicationInfo(this);
266− application->setDesktopFile("/usr/share/applications/facebook-webapp.desktop");
298+ application->setAppId("facebook-webapp");
267299 application->setName("Facebook");
268− application->setIcon("facebook");
269− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.facebook.com");
300+ application->setIcon(QUrl("facebook"));
270301 application->setStage(ApplicationInfo::SideStage);
271− application->setHandle(nextHandle++);
272302 generateQmlStrings(application);
273303 m_availableApplications.append(application);
274304
275305 application = new ApplicationInfo(this);
276− application->setDesktopFile("/usr/share/applications/webbrowser-app.desktop");
306+ application->setAppId("webbrowser-app");
277307 application->setName("Browser");
278− application->setIcon("browser");
279− application->setExec("/usr/bin/webbrowser-app");
280− application->setHandle(nextHandle++);
308+ application->setIcon(QUrl("browser"));
281309 generateQmlStrings(application);
282310 m_availableApplications.append(application);
283311
284312 application = new ApplicationInfo(this);
285− application->setDesktopFile("/usr/share/applications/twitter-webapp.desktop");
313+ application->setAppId("twitter-webapp");
286314 application->setName("Twitter");
287− application->setIcon("twitter");
288− application->setExec("/usr/bin/webbrowser-app --chromeless http://www.twitter.com");
315+ application->setIcon(QUrl("twitter"));
289316 application->setStage(ApplicationInfo::SideStage);
290− application->setHandle(nextHandle++);
291317 generateQmlStrings(application);
292318 m_availableApplications.append(application);
293319
294320 application = new ApplicationInfo(this);
295− application->setDesktopFile("/usr/share/applications/gmail-webapp.desktop");
321+ application->setAppId("gmail-webapp");
296322 application->setName("GMail");
297− application->setIcon("gmail");
298− application->setExec("/usr/bin/webbrowser-app --chromeless http://m.gmail.com");
299− application->setHandle(nextHandle++);
323+ application->setIcon(QUrl("gmail"));
300324 m_availableApplications.append(application);
301325
302326 application = new ApplicationInfo(this);
303− application->setDesktopFile("/usr/share/applications/ubuntu-weather-app.desktop");
327+ application->setAppId("ubuntu-weather-app");
304328 application->setName("Weather");
305− application->setIcon("weather");
306− application->setExec("/usr/bin/qmlscene /usr/share/ubuntu-weather-app/ubuntu-weather-app.qml");
329+ application->setIcon(QUrl("weather"));
307330 application->setStage(ApplicationInfo::SideStage);
308− application->setHandle(nextHandle++);
309331 generateQmlStrings(application);
310332 m_availableApplications.append(application);
311333
312334 application = new ApplicationInfo(this);
313− application->setDesktopFile("/usr/share/applications/notes-app.desktop");
335+ application->setAppId("notes-app");
314336 application->setName("Notepad");
315− application->setIcon("notepad");
316− application->setExec("/usr/bin/qmlscene /usr/share/notes-app/NotesApp.qml");
337+ application->setIcon(QUrl("notepad"));
317338 application->setStage(ApplicationInfo::SideStage);
318− application->setHandle(nextHandle++);
319339 m_availableApplications.append(application);
320340
321341 application = new ApplicationInfo(this);
322− application->setDesktopFile("/usr/share/applications/calendar-app.desktop");
342+ application->setAppId("calendar-app");
323343 application->setName("Calendar");
324− application->setIcon("calendar");
325− application->setExec("/usr/bin/qmlscene /usr/share/calendar-app/calendar.qml");
344+ application->setIcon(QUrl("calendar"));
326345 application->setStage(ApplicationInfo::SideStage);
327− application->setHandle(nextHandle++);
328346 m_availableApplications.append(application);
329347
330348 application = new ApplicationInfo(this);
331− application->setDesktopFile("/usr/share/applications/mediaplayer-app.desktop");
349+ application->setAppId("mediaplayer-app");
332350 application->setName("Media Player");
333− application->setIcon("mediaplayer-app");
351+ application->setIcon(QUrl("mediaplayer-app"));
334352 application->setFullscreen(true);
335− application->setExec("/usr/bin/mediaplayer-app");
336− application->setHandle(nextHandle++);
337353 m_availableApplications.append(application);
338354
339355 application = new ApplicationInfo(this);
340− application->setDesktopFile("/usr/share/applications/evernote.desktop");
356+ application->setAppId("evernote");
341357 application->setName("Evernote");
342− application->setIcon("evernote");
343− application->setHandle(nextHandle++);
358+ application->setIcon(QUrl("evernote"));
344359 m_availableApplications.append(application);
345360
346361 application = new ApplicationInfo(this);
347− application->setDesktopFile("/usr/share/applications/map.desktop");
362+ application->setAppId("map");
348363 application->setName("Map");
349− application->setIcon("map");
350− application->setHandle(nextHandle++);
364+ application->setIcon(QUrl("map"));
351365 generateQmlStrings(application);
352366 m_availableApplications.append(application);
353367
354368 application = new ApplicationInfo(this);
355− application->setDesktopFile("/usr/share/applications/pinterest.desktop");
369+ application->setAppId("pinterest");
356370 application->setName("Pinterest");
357− application->setIcon("pinterest");
358− application->setHandle(nextHandle++);
371+ application->setIcon(QUrl("pinterest"));
359372 m_availableApplications.append(application);
360373
361374 application = new ApplicationInfo(this);
362− application->setDesktopFile("/usr/share/applications/soundcloud.desktop");
375+ application->setAppId("soundcloud");
363376 application->setName("SoundCloud");
364− application->setIcon("soundcloud");
365− application->setHandle(nextHandle++);
377+ application->setIcon(QUrl("soundcloud"));
366378 m_availableApplications.append(application);
367379
368380 application = new ApplicationInfo(this);
369− application->setDesktopFile("/usr/share/applications/wikipedia.desktop");
381+ application->setAppId("wikipedia");
370382 application->setName("Wikipedia");
371− application->setIcon("wikipedia");
372− application->setHandle(nextHandle++);
383+ application->setIcon(QUrl("wikipedia"));
373384 m_availableApplications.append(application);
374385
375386 application = new ApplicationInfo(this);
376− application->setDesktopFile("/usr/share/applications/youtube.desktop");
387+ application->setAppId("youtube");
377388 application->setName("YouTube");
378− application->setIcon("youtube");
379− application->setHandle(nextHandle++);
389+ application->setIcon(QUrl("youtube"));
380390 m_availableApplications.append(application);
381391}
382392
tests/mocks/Unity/Application/ApplicationManager.h+34−26
@@ -20,14 +20,18 @@
2020#include <QObject>
2121#include <QList>
2222#include <QStringList>
23−#include "ApplicationListModel.h"
2423#include "ApplicationInfo.h"
2524
25+// unity-api
26+#include <unity/shell/application/ApplicationManagerInterface.h>
27+
2628class QQuickItem;
29+using namespace unity::shell::application;
2730
28−class ApplicationManager : public QObject {
31+class ApplicationManager : public ApplicationManagerInterface {
2932 Q_OBJECT
3033 Q_ENUMS(Role)
34+ Q_ENUMS(Roles) //inherited, but want to expose to QML
3135 Q_ENUMS(StageHint)
3236 Q_ENUMS(FormFactorHint)
3337 Q_ENUMS(FavoriteApplication)
@@ -39,12 +43,6 @@ class ApplicationManager : public QObject {
3943 Q_PROPERTY(int sideStageWidth READ sideStageWidth)
4044 Q_PROPERTY(StageHint stageHint READ stageHint)
4145 Q_PROPERTY(FormFactorHint formFactorHint READ formFactorHint)
42− Q_PROPERTY(ApplicationListModel* mainStageApplications READ mainStageApplications)
43− Q_PROPERTY(ApplicationListModel* sideStageApplications READ sideStageApplications)
44− Q_PROPERTY(ApplicationInfo* mainStageFocusedApplication READ mainStageFocusedApplication
45− NOTIFY mainStageFocusedApplicationChanged)
46− Q_PROPERTY(ApplicationInfo* sideStageFocusedApplication READ sideStageFocusedApplication
47− NOTIFY sideStageFocusedApplicationChanged)
4846
4947 Q_PROPERTY(bool fake READ fake CONSTANT)
5048
@@ -64,39 +62,52 @@ class ApplicationManager : public QObject {
6462 DesktopFormFactor, PhoneFormFactor, TabletFormFactor
6563 };
6664 enum FavoriteApplication {
67− CameraApplication, GalleryApplication, BrowserApplication, ShareApplication
65+ CameraApplication, GalleryApplication, BrowserApplication, ShareApplication,
66+ PhoneApplication, DialerApplication, MessagingApplication, AddressbookApplication
6867 };
6968 enum Flag {
7069 NoFlag = 0x0,
7170 ForceMainStage = 0x1,
7271 };
7372 Q_DECLARE_FLAGS(ExecFlags, Flag)
73+ enum Roles { // Q_ENUM of inherited Roles doesn't work?!?!?!
74+ RoleAppId = Qt::UserRole,
75+ RoleName,
76+ RoleComment,
77+ RoleIcon,
78+ RoleStage,
79+ RoleState,
80+ RoleFocused,
81+ };
7482
7583 int keyboardHeight() const;
7684 bool keyboardVisible() const;
7785 int sideStageWidth() const;
7886 StageHint stageHint() const;
7987 FormFactorHint formFactorHint() const;
80− ApplicationListModel* mainStageApplications() const;
81− ApplicationListModel* sideStageApplications() const;
82− ApplicationInfo* mainStageFocusedApplication() const;
83− ApplicationInfo* sideStageFocusedApplication() const;
8488
8589 bool fake() { return true; }
8690
87− Q_INVOKABLE void focusApplication(int handle);
88− Q_INVOKABLE void unfocusCurrentApplication(StageHint stageHint);
89− Q_INVOKABLE ApplicationInfo* startProcess(QString desktopFile,
90− ExecFlags flags,
91− QStringList arguments = QStringList());
92− Q_INVOKABLE void stopProcess(ApplicationInfo* application);
93− Q_INVOKABLE void startWatcher() {}
91+ // QAbstractItemModel methods.
92+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
93+ QVariant data(const QModelIndex& index, int role) const override;
94+ Q_INVOKABLE ApplicationInfo *get(int index) const override;
95+ Q_INVOKABLE ApplicationInfo *findApplication(const QString &appId) const override;
96+
97+ Q_INVOKABLE void move(int from, int to);
98+
99+ // Application control methods
100+ Q_INVOKABLE bool focusApplication(const QString &appId) override;
101+ Q_INVOKABLE void unfocusCurrentApplication() override;
102+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, const QStringList &arguments = QStringList()) override;
103+ Q_INVOKABLE ApplicationInfo *startApplication(const QString &appId, ExecFlags flags, const QStringList &arguments = QStringList());
104+ Q_INVOKABLE bool stopApplication(const QString &appId) override;
105+
106+ QString focusedApplicationId() const override;
94107
95108 Q_SIGNALS:
96109 void keyboardHeightChanged();
97110 void keyboardVisibleChanged();
98− void mainStageFocusedApplicationChanged();
99− void sideStageFocusedApplicationChanged();
100111 void focusRequested(FavoriteApplication favoriteApplication);
101112
102113 private:
@@ -109,10 +120,7 @@ class ApplicationManager : public QObject {
109120 void createSideStage();
110121 int m_keyboardHeight;
111122 bool m_keyboardVisible;
112− ApplicationListModel* m_mainStageApplications;
113− ApplicationListModel* m_sideStageApplications;
114− ApplicationInfo* m_mainStageFocusedApplication;
115− ApplicationInfo* m_sideStageFocusedApplication;
123+ QList<ApplicationInfo*> m_runningApplications;
116124 QList<ApplicationInfo*> m_availableApplications;
117125 QQmlComponent *m_mainStageComponent;
118126 QQuickItem *m_mainStage;
tests/mocks/Unity/Application/CMakeLists.txt+5−1
@@ -1,9 +1,13 @@
1+include(FindPkgConfig)
2+pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application)
3+
14set(FakeUnityApplicationQml_SOURCES
25 plugin.cpp
36 ApplicationInfo.cpp
47 ApplicationImage.cpp
5− ApplicationListModel.cpp
68 ApplicationManager.cpp
9+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationInfoInterface.h
10+ ${APPLICATION_API_INCLUDEDIR}/unity/shell/application/ApplicationManagerInterface.h
711)
812
913add_library(FakeUnityApplicationQml MODULE ${FakeUnityApplicationQml_SOURCES})
tests/mocks/Unity/Application/plugin.cpp−2
@@ -17,7 +17,6 @@
1717#include "plugin.h"
1818#include "ApplicationInfo.h"
1919#include "ApplicationImage.h"
20−#include "ApplicationListModel.h"
2120#include "ApplicationManager.h"
2221
2322#include <qqml.h>
@@ -34,5 +33,4 @@ void FakeUnityApplicationQmlPlugin::registerTypes(const char *uri)
3433 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
3534 qmlRegisterType<ApplicationInfo>(uri, 0, 1, "ApplicationInfo");
3635 qmlRegisterType<ApplicationImage>(uri, 0, 1, "ApplicationImage");
37− qmlRegisterType<ApplicationListModel>(uri, 0, 1, "ApplicationListModel");
3836}