Merge lp:~gerboland/unity-mir/namespace-to-prevent-collision into lp:unity-mir

Proposed by Gerry Boland
Status: Superseded
Proposed branch: lp:~gerboland/unity-mir/namespace-to-prevent-collision
Merge into: lp:unity-mir
Diff against target: 2504 lines (+1059/-284)
52 files modified
CMakeLists.txt (+1/-0)
cmake/LinuxCrossCompile.cmake (+39/-0)
cross-compile-chroot.sh (+85/-0)
debian/control (+1/-0)
scripts/fix-qt-cmake.sh (+10/-0)
scripts/setup-partial-armhf-chroot.sh (+67/-0)
src/modules/Unity/Application/CMakeLists.txt (+5/-6)
src/modules/Unity/Application/application.cpp (+6/-1)
src/modules/Unity/Application/application.h (+8/-2)
src/modules/Unity/Application/application_manager.cpp (+224/-132)
src/modules/Unity/Application/application_manager.h (+32/-14)
src/modules/Unity/Application/applicationcontroller.h (+5/-0)
src/modules/Unity/Application/applicationscreenshotprovider.cpp (+5/-0)
src/modules/Unity/Application/applicationscreenshotprovider.h (+5/-0)
src/modules/Unity/Application/dbuswindowstack.cpp (+5/-0)
src/modules/Unity/Application/dbuswindowstack.h (+9/-4)
src/modules/Unity/Application/desktopfilereader.cpp (+5/-0)
src/modules/Unity/Application/desktopfilereader.h (+5/-0)
src/modules/Unity/Application/inputarea.cpp (+5/-0)
src/modules/Unity/Application/inputarea.h (+7/-1)
src/modules/Unity/Application/inputfilterarea.cpp (+5/-0)
src/modules/Unity/Application/inputfilterarea.h (+4/-0)
src/modules/Unity/Application/mirsurface.cpp (+4/-0)
src/modules/Unity/Application/mirsurface.h (+6/-1)
src/modules/Unity/Application/mirsurfacemanager.cpp (+5/-0)
src/modules/Unity/Application/mirsurfacemanager.h (+6/-1)
src/modules/Unity/Application/plugin.cpp (+15/-13)
src/modules/Unity/Application/proc_info.cpp (+56/-0)
src/modules/Unity/Application/proc_info.h (+52/-0)
src/modules/Unity/Application/processcontroller.cpp (+5/-0)
src/modules/Unity/Application/processcontroller.h (+5/-0)
src/modules/Unity/Application/shellinputarea.cpp (+5/-0)
src/modules/Unity/Application/shellinputarea.h (+4/-0)
src/modules/Unity/Application/taskcontroller.cpp (+4/-1)
src/modules/Unity/Application/taskcontroller.h (+5/-0)
src/modules/Unity/Application/ubuntukeyboardinfo.cpp (+5/-0)
src/modules/Unity/Application/ubuntukeyboardinfo.h (+5/-0)
src/modules/Unity/Application/upstart/applicationcontroller.cpp (+24/-16)
src/modules/Unity/Application/upstart/applicationcontroller.h (+7/-2)
src/unity-mir/CMakeLists.txt (+3/-5)
tests/CMakeLists.txt (+1/-0)
tests/application_manager_test.cpp (+138/-64)
tests/auto/modules/Unity/Application/CMakeLists.txt (+2/-2)
tests/auto/modules/Unity/Application/main.cpp (+7/-6)
tests/mock_application_controller.h (+1/-1)
tests/mock_desktop_file_reader.h (+7/-7)
tests/mock_focus_controller.h (+37/-0)
tests/mock_oom_controller.h (+1/-1)
tests/mock_proc_info.h (+37/-0)
tests/mock_process_controller.h (+4/-4)
tests/mock_session.h (+69/-0)
tests/taskcontroller_test.cpp (+1/-0)
To merge this branch: bzr merge lp:~gerboland/unity-mir/namespace-to-prevent-collision
Reviewer Review Type Date Requested Status
Alberto Aguirre (community) Approve
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+208483@code.launchpad.net

This proposal has been superseded by a proposal from 2014-02-27.

Commit message

Wrap classes of the QML plugin in a unitymir namespace, prevents symbol collision with Mir

Description of the change

Wrap classes of the QML plugin in a unitymir namespace, prevents symbol collision with Mir

• Are there any related MPs required for this MP to build/function as expected?
No
• Did you perform an exploratory manual test run of your code change and any related functionality?
Yes
• If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Unnecessary

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Great! Confirmed this MP fixes bug #1282248 in the emulator, too.

review: Approve
Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Looks like this needs a pre-requisite branch: lp:~albaguirre/unity-mir/add-cross-compile-scripts

Revision history for this message
Alberto Aguirre (albaguirre) wrote :

Actually looks like the MP needs pre-req: lp:~andreas-pokorny/unity-mir/fix-1240400

But namespace changes look good.

review: Approve
Revision history for this message
Gerry Boland (gerboland) wrote :

> Actually looks like the MP needs pre-req: lp:~andreas-pokorny/unity-
> mir/fix-1240400
Forgot to specify that, correcting now.

187. By Gerry Boland

Wrap classes of the QML plugin in a unitymir namespace, prevents symbol collision with Mir

188. By Gerry Boland

Merge fix from fix-1240400

189. By Gerry Boland

missing namespace qualifier in Q_PROPERTY

Unmerged revisions

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 2014-02-14 15:42:49 +0000
3+++ CMakeLists.txt 2014-02-26 21:35:04 +0000
4@@ -59,6 +59,7 @@
5 find_package(Qt5Core REQUIRED)
6 find_package(Qt5Quick REQUIRED)
7 find_package(Qt5DBus REQUIRED)
8+find_package(Boost 1.50 COMPONENTS system REQUIRED)
9
10 find_package(Protobuf REQUIRED)
11 if(PROTOBUF_PROTOC_EXECUTABLE STREQUAL "PROTOBUF_PROTOC_EXECUTABLE-NOTFOUND")
12
13=== added directory 'cmake'
14=== added file 'cmake/LinuxCrossCompile.cmake'
15--- cmake/LinuxCrossCompile.cmake 1970-01-01 00:00:00 +0000
16+++ cmake/LinuxCrossCompile.cmake 2014-02-26 21:35:04 +0000
17@@ -0,0 +1,39 @@
18+set(CMAKE_SYSTEM_NAME Linux)
19+set(CMAKE_SYSTEM_VERSION 1)
20+
21+set(UNITYMIR_CHROOT_DIR $ENV{UNITYMIR_CHROOT_DIR} CACHE STRING "directory containing partial chroot for unity-mir cross-compilation")
22+set(UNITYMIR_ARM_EABI "arm-linux-gnueabihf")
23+
24+set(CMAKE_C_COMPILER /usr/bin/${UNITYMIR_ARM_EABI}-gcc)
25+set(CMAKE_CXX_COMPILER /usr/bin/${UNITYMIR_ARM_EABI}-g++)
26+
27+# where to look to find dependencies in the target environment
28+set(CMAKE_FIND_ROOT_PATH "${UNITYMIR_CHROOT_DIR}")
29+
30+#treat the chroot's includes as system includes
31+include_directories(SYSTEM "${UNITYMIR_CHROOT_DIR}/usr/include" "${UNITYMIR_CHROOT_DIR}/usr/include/${UNITYMIR_ARM_EABI}")
32+
33+list(APPEND CMAKE_SYSTEM_INCLUDE_PATH "${UNITYMIR_CHROOT_DIR}/usr/include" "${UNITYMIR_CHROOT_DIR}/usr/include/${UNITYMIR_ARM_EABI}" )
34+
35+# Add the chroot libraries as system libraries
36+list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
37+ "${UNITYMIR_CHROOT_DIR}/lib"
38+ "${UNITYMIR_CHROOT_DIR}/lib/${UNITYMIR_ARM_EABI}"
39+ "${UNITYMIR_CHROOT_DIR}/usr/lib"
40+ "${UNITYMIR_CHROOT_DIR}/usr/lib/${UNITYMIR_ARM_EABI}"
41+)
42+
43+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
44+set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
45+set(CMAKE_EXECUTABLE_RUNTIME_C_FLAG "-Wl,-rpath-link,")
46+set(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG "-Wl,-rpath-link,")
47+set(CMAKE_INSTALL_RPATH "${UNITYMIR_CHROOT_DIR}/lib:${UNITYMIR_CHROOT_DIR}/lib/${UNITYMIR_ARM_EABI}:${UNITYMIR_CHROOT_DIR}/usr/lib:${UNITYMIR_CHROOT_DIR}/usr/lib/${UNITYMIR_ARM_EABI}:${UNITYMIR_CHROOT_DIR}/usr/lib/${UNITYMIR_ARM_EABI}/mesa-egl")
48+
49+set(ENV{PKG_CONFIG_PATH} "${UNITYMIR_CHROOT_DIR}/usr/lib/pkgconfig:${UNITYMIR_CHROOT_DIR}/usr/lib/${UNITYMIR_ARM_EABI}/pkgconfig")
50+set(ENV{PKG_CONFIG_SYSROOT_DIR} "${UNITYMIR_CHROOT_DIR}")
51+
52+#use only the cross compile system
53+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
54+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
55+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
56+
57
58=== added file 'cross-compile-chroot.sh'
59--- cross-compile-chroot.sh 1970-01-01 00:00:00 +0000
60+++ cross-compile-chroot.sh 2014-02-26 21:35:04 +0000
61@@ -0,0 +1,85 @@
62+#!/bin/bash
63+# build script to compile unity-mir for armhf devices
64+
65+set -e
66+
67+usage() {
68+ echo "usage: $(basename $0) [-c] [-u]"
69+ echo "-c clean before building"
70+ echo "-u update partial chroot directory"
71+ echo "-h this message"
72+}
73+
74+clean_build_dir() {
75+ rm -rf ${1}
76+ mkdir ${1}
77+}
78+
79+BUILD_DIR=build-android-arm
80+NUM_JOBS=$(( $(grep -c ^processor /proc/cpuinfo) + 1 ))
81+_do_update_chroot=0
82+
83+while getopts "cuh" OPTNAME
84+do
85+ case $OPTNAME in
86+ c )
87+ clean_build_dir ${BUILD_DIR}
88+ ;;
89+ u )
90+ _do_update_chroot=1
91+ ;;
92+ h )
93+ usage
94+ exit 0
95+ ;;
96+ * )
97+ echo "invalid option specified"
98+ usage
99+ exit 1
100+ ;;
101+ esac
102+done
103+
104+
105+if [ "${UNITYMIR_CHROOT_DIR}" = "" ]; then
106+ export UNITYMIR_CHROOT_DIR=$(pwd)/partial-armhf-chroot
107+fi
108+
109+if [ ! -d ${UNITYMIR_CHROOT_DIR} ]; then
110+ echo "no partial chroot dir detected. attempting to create one"
111+ _do_update_chroot=1
112+fi
113+
114+if [ ! -d ${BUILD_DIR} ]; then
115+ mkdir ${BUILD_DIR}
116+fi
117+
118+if [ ${_do_update_chroot} -eq 1 ] ; then
119+ pushd scripts > /dev/null
120+ ./setup-partial-armhf-chroot.sh ${UNITYMIR_CHROOT_DIR}
121+ popd > /dev/null
122+ # force a clean build after an update, since CMake cache maybe out of date
123+ clean_build_dir ${BUILD_DIR}
124+fi
125+
126+echo "Using UNITYMIR_CHROOT_DIR: ${UNITYMIR_CHROOT_DIR}"
127+
128+pushd ${BUILD_DIR} > /dev/null
129+
130+ export CMAKE_PREFIX_PATH=${UNITYMIR_CHROOT_DIR}/usr/lib/arm-linux-gnueabihf/cmake
131+ export PKG_CONFIG_PATH="${UNITYMIR_CHROOT_DIR}/usr/lib/pkgconfig:${UNITYMIR_CHROOT_DIR}/usr/lib/arm-linux-gnueabihf/pkgconfig"
132+ export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1
133+ export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1
134+ export PKG_CONFIG_SYSROOT_DIR=${UNITYMIR_CHROOT_DIR}
135+ export PKG_CONFIG_EXECUTABLE=`which pkg-config`
136+ echo "Using PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
137+ echo "Using PKG_CONFIG_EXECUTABLE: $PKG_CONFIG_EXECUTABLE"
138+
139+ # These are used to make cmake select the host machine QT MOC compiler in the AutoMocInfo module
140+ export DEB_HOST_MULTIARCH=arm-linux-gnueabihf
141+ export DEB_BUILD_MULTIARCH=$(gcc -dumpmachine)
142+
143+ cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/LinuxCrossCompile.cmake ..
144+ make -j${NUM_JOBS}
145+
146+popd ${BUILD_DIR} > /dev/null
147
148=== modified file 'debian/control'
149--- debian/control 2014-02-14 15:42:49 +0000
150+++ debian/control 2014-02-26 21:35:04 +0000
151@@ -6,6 +6,7 @@
152 cmake,
153 google-mock (>= 1.6.0+svn437),
154 pkg-config,
155+ libboost-dev,
156 libboost-system-dev,
157 libplatform-api1-dev,
158 libmirserver-dev (>= 0.1.5),
159
160=== added directory 'scripts'
161=== added file 'scripts/fix-qt-cmake.sh'
162--- scripts/fix-qt-cmake.sh 1970-01-01 00:00:00 +0000
163+++ scripts/fix-qt-cmake.sh 2014-02-26 21:35:04 +0000
164@@ -0,0 +1,10 @@
165+#!/bin/bash
166+
167+# $1 must contain path to QT cmake files
168+# Given that path, all hardcoded root paths are fixed up
169+for file in $(find ${1} -type f -name \*.cmake)
170+do
171+ echo "fixing $file"
172+ sed -i 's/NO_DEFAULT_PATH/ONLY_CMAKE_FIND_ROOT_PATH/g' $file
173+ sed -i 's/\/usr/${CMAKE_FIND_ROOT_PATH}\/usr/g' $file
174+done
175
176=== added file 'scripts/setup-partial-armhf-chroot.sh'
177--- scripts/setup-partial-armhf-chroot.sh 1970-01-01 00:00:00 +0000
178+++ scripts/setup-partial-armhf-chroot.sh 2014-02-26 21:35:04 +0000
179@@ -0,0 +1,67 @@
180+#!/bin/bash
181+
182+set -e
183+
184+if [ -z ${1} ]; then
185+ echo "please supply directory to create partial chroot in. (eg, ./setup-partial-armhf-chroot.sh mychroot-dir)"
186+ exit
187+fi
188+
189+echo "creating phablet-compatible armhf partial chroot for unity-mir compilation in directory ${1}"
190+
191+if [ ! -d ${1} ]; then
192+ mkdir -p ${1}
193+fi
194+
195+DEBCONTROL=$(pwd)/../debian/control
196+
197+pushd ${1} > /dev/null
198+
199+# Empty dpkg status file, so that ALL dependencies are listed with dpkg-checkbuilddeps
200+echo "" > status
201+
202+# Manual error code checking is needed for dpkg-checkbuilddeps
203+set +e
204+
205+# Parse dependencies from debian/control
206+# dpkg-checkbuilddeps returns 1 when dependencies are not met and the list is sent to stderr
207+builddeps=$(dpkg-checkbuilddeps -a armhf --admindir=. ${DEBCONTROL} 2>&1 )
208+if [ $? -ne 1 ] ; then
209+ echo "${builddeps}"
210+ exit 2
211+fi
212+
213+# now turn exit on error option
214+set -e
215+
216+# Sanitize dependencies list for submission to debootstrap
217+# build-essential is not needed as we are cross-compiling
218+builddeps=$(echo ${builddeps} | sed -e 's/dpkg-checkbuilddeps://g' -e 's/Unmet build dependencies://g' -e 's/build-essential:native//g')
219+builddeps=$(echo ${builddeps} | sed 's/([^)]*)//g')
220+# TODO: figure out why debootstrap is not finding libunity-api-dev package - it doesn't seem to be needed for cross-compilation - is it needed in debian/control?
221+builddeps=$(echo ${builddeps} | sed 's/libunity-api-dev//g')
222+builddeps=$(echo ${builddeps} | sed 's/ /,/g')
223+
224+fakeroot debootstrap --include=${builddeps} --arch=armhf --download-only --variant=buildd trusty .
225+
226+# Remove libc libraries that confuse the cross-compiler
227+rm var/cache/apt/archives/libc-dev*.deb
228+rm var/cache/apt/archives/libc6*.deb
229+
230+for deb in var/cache/apt/archives/* ; do
231+if [ ! -d ${deb} ] ; then
232+ echo "unpacking: ${deb}"
233+ dpkg -x ${deb} .
234+fi
235+done
236+
237+# Fix up symlinks which asssumed the usual root path
238+for broken_symlink in $(find . -name \*.so -type l -xtype l) ; do
239+ ln -sf $(pwd)$(readlink ${broken_symlink}) ${broken_symlink}
240+done
241+
242+popd > /dev/null
243+
244+# QT CMake files have hardcoded root paths - fix them up
245+./fix-qt-cmake.sh ${1}/usr/lib/arm-linux-gnueabihf/cmake/
246+
247
248=== modified file 'src/modules/Unity/Application/CMakeLists.txt'
249--- src/modules/Unity/Application/CMakeLists.txt 2014-01-27 11:29:44 +0000
250+++ src/modules/Unity/Application/CMakeLists.txt 2014-02-26 21:35:04 +0000
251@@ -31,6 +31,7 @@
252 inputfilterarea.cpp
253 processcontroller.h
254 processcontroller.cpp
255+ proc_info.cpp
256 shellinputarea.cpp
257 ubuntukeyboardinfo.cpp
258
259@@ -74,12 +75,10 @@
260 ${CMAKE_THREAD_LIBS_INIT}
261
262 ${GLIB_LDFLAGS}
263- ${UBUNTU_PLATFORM_API_LIBRARIES}
264- ${MIRCOMMON_LIBRARIES}
265- ${MIRSERVER_LIBRARIES}
266- ${PROCESS_CPP_LIBRARIES}
267- ${UBUNTU_PLATFORM_API_LIBRARIES}
268- ${UPSTART_APP_LAUNCH_LIBRARIES}
269+ ${UBUNTU_PLATFORM_API_LDFLAGS}
270+ ${MIRSERVER_LDFLAGS}
271+ ${PROCESS_CPP_LDFLAGS}
272+ ${UPSTART_APP_LAUNCH_LDFLAGS}
273
274 ubuntu_application_api_mirserver
275 )
276
277=== modified file 'src/modules/Unity/Application/application.cpp'
278--- src/modules/Unity/Application/application.cpp 2014-01-27 11:29:44 +0000
279+++ src/modules/Unity/Application/application.cpp 2014-02-26 21:35:04 +0000
280@@ -27,6 +27,9 @@
281 #include <mir/shell/session.h>
282 #include <mir/shell/snapshot.h>
283
284+namespace unitymir
285+{
286+
287 Application::Application(const QSharedPointer<TaskController>& taskController,
288 DesktopFileReader *desktopFileReader,
289 State state,
290@@ -52,7 +55,7 @@
291
292 Application::~Application()
293 {
294- DLOG("Application::~Application");
295+ DLOG("Application::~Application (this=%p)", this);
296 delete m_desktopData;
297 }
298
299@@ -233,3 +236,5 @@
300 DLOG("Application::respawn (this=%p)", this);
301 m_taskController->start(appId(), m_arguments);
302 }
303+
304+} // namespace unitymir
305
306=== modified file 'src/modules/Unity/Application/application.h'
307--- src/modules/Unity/Application/application.h 2014-01-27 11:29:44 +0000
308+++ src/modules/Unity/Application/application.h 2014-02-26 21:35:04 +0000
309@@ -29,9 +29,13 @@
310 #include <unity/shell/application/ApplicationInfoInterface.h>
311
312 class QImage;
313+namespace mir { namespace shell { class Session; }}
314+
315+namespace unitymir
316+{
317+
318 class DesktopFileReader;
319 class TaskController;
320-namespace mir { namespace shell { class Session; }}
321
322 class Application : public unity::shell::application::ApplicationInfoInterface {
323 Q_OBJECT
324@@ -100,6 +104,8 @@
325 friend class MirSurfaceManager;
326 };
327
328-Q_DECLARE_METATYPE(Application*)
329+} // namespace unity-mir
330+
331+Q_DECLARE_METATYPE(unitymir::Application*)
332
333 #endif // APPLICATION_H
334
335=== modified file 'src/modules/Unity/Application/application_manager.cpp'
336--- src/modules/Unity/Application/application_manager.cpp 2014-02-11 09:47:56 +0000
337+++ src/modules/Unity/Application/application_manager.cpp 2014-02-26 21:35:04 +0000
338@@ -16,6 +16,7 @@
339
340 // local
341 #include "application_manager.h"
342+#include "proc_info.h"
343 #include "application.h"
344 #include "desktopfilereader.h"
345 #include "dbuswindowstack.h"
346@@ -51,26 +52,133 @@
347
348 using namespace unity::shell::application;
349
350-ApplicationManager *ApplicationManager::the_application_manager = nullptr;
351+namespace unitymir
352+{
353+
354+namespace
355+{
356+
357+QSize get_display_size(std::shared_ptr<mir::graphics::Display> const& display) {
358+ // Obtain display size
359+ mir::geometry::Rectangles view_area;
360+ display->for_each_display_buffer(
361+ [&view_area](mir::graphics::DisplayBuffer const& db)
362+ {
363+ view_area.add(db.view_area());
364+ });
365+
366+ return QSize(
367+ view_area.bounding_rectangle().size.width.as_uint32_t(),
368+ view_area.bounding_rectangle().size.height.as_uint32_t()
369+ );
370+}
371+
372+
373+void connectToSessionListener(ApplicationManager * manager, SessionListener * listener)
374+{
375+
376+ QObject::connect(listener, &SessionListener::sessionStarting,
377+ manager, &ApplicationManager::onSessionStarting);
378+ QObject::connect(listener, &SessionListener::sessionStopping,
379+ manager, &ApplicationManager::onSessionStopping);
380+ QObject::connect(listener, &SessionListener::sessionFocused,
381+ manager, &ApplicationManager::onSessionFocused, Qt::QueuedConnection);
382+ QObject::connect(listener, &SessionListener::sessionUnfocused,
383+ manager, &ApplicationManager::onSessionUnfocused);
384+ QObject::connect(listener, &SessionListener::sessionCreatedSurface,
385+ manager, &ApplicationManager::onSessionCreatedSurface);
386+ QObject::connect(listener, &SessionListener::sessionStarting,
387+ manager, &ApplicationManager::onSessionStarting);
388+ QObject::connect(listener, &SessionListener::sessionStopping,
389+ manager, &ApplicationManager::onSessionStopping);
390+ QObject::connect(listener, &SessionListener::sessionFocused,
391+ manager, &ApplicationManager::onSessionFocused, Qt::QueuedConnection);
392+ QObject::connect(listener, &SessionListener::sessionUnfocused,
393+ manager, &ApplicationManager::onSessionUnfocused);
394+ QObject::connect(listener, &SessionListener::sessionCreatedSurface,
395+ manager, &ApplicationManager::onSessionCreatedSurface);
396+}
397+
398+void connectToSessionAuthorizer(ApplicationManager * manager, SessionAuthorizer * authorizer)
399+{
400+ QObject::connect(authorizer, &SessionAuthorizer::requestAuthorizationForSession,
401+ manager, &ApplicationManager::authorizeSession, Qt::BlockingQueuedConnection);
402+}
403+
404+
405+void connectToPlacementStrategy(ApplicationManager * manager, InitialSurfacePlacementStrategy * strategy)
406+{
407+ QObject::connect(strategy, &InitialSurfacePlacementStrategy::requestPlacementForSession,
408+ manager, &ApplicationManager::placeSession, Qt::DirectConnection);
409+
410+}
411+
412+void connectToTaskController(ApplicationManager * manager, TaskController * controller)
413+{
414+ QObject::connect(controller, &TaskController::processStartReport,
415+ manager, &ApplicationManager::onProcessStartReportReceived);
416+ QObject::connect(controller, &TaskController::processStopped,
417+ manager, &ApplicationManager::onProcessStopped);
418+ QObject::connect(controller, &TaskController::requestFocus,
419+ manager, &ApplicationManager::onFocusRequested);
420+ QObject::connect(controller, &TaskController::requestResume,
421+ manager, &ApplicationManager::onResumeRequested);
422+
423+}
424+}
425+
426+QSharedPointer<ApplicationManager> ApplicationManager::Factory::Factory::create()
427+{
428+ QMirServerApplication* mirServerApplication = dynamic_cast<QMirServerApplication*>(QCoreApplication::instance());
429+ if (mirServerApplication == NULL) {
430+ LOG("Need to use QMirServerApplication");
431+ QCoreApplication::quit();
432+ return QSharedPointer<ApplicationManager>(nullptr);
433+ }
434+
435+ ShellServerConfiguration * mirServer = mirServerApplication->server();
436+
437+ QSize displaySize{get_display_size(mirServer->the_display())};
438+
439+ QSharedPointer<upstart::ApplicationController> appController(new upstart::ApplicationController());
440+ QSharedPointer<TaskController> taskController(new TaskController(nullptr, appController));
441+ QSharedPointer<DesktopFileReader::Factory> fileReaderFactory(new DesktopFileReader::Factory());
442+ QSharedPointer<ProcInfo> procInfo(new ProcInfo());
443+ QSharedPointer<ApplicationManager> appManager(
444+ new ApplicationManager(
445+ taskController,
446+ fileReaderFactory,
447+ procInfo,
448+ mirServer->the_focus_controller(),
449+ displaySize
450+ )
451+ );
452+
453+
454+ connectToSessionListener(appManager.data(), mirServer->sessionListener());
455+ connectToSessionAuthorizer(appManager.data(), mirServer->sessionAuthorizer());
456+ connectToPlacementStrategy(appManager.data(), mirServer->placementStrategy());
457+ connectToTaskController(appManager.data(), taskController.data());
458+
459+ return appManager;
460+}
461
462 ApplicationManager* ApplicationManager::singleton()
463 {
464- if (!the_application_manager) {
465- the_application_manager = new ApplicationManager(
466- QSharedPointer<TaskController>(
467- new TaskController(
468- nullptr,
469- QSharedPointer<ApplicationController>(
470- new upstart::ApplicationController()))),
471- QSharedPointer<DesktopFileReader::Factory>(
472- new DesktopFileReader::Factory()));
473+ static QSharedPointer<ApplicationManager> instance;
474+ if (!instance) {
475+ Factory appFactory;
476+ instance = appFactory.create();
477 }
478- return the_application_manager;
479+ return instance.data();
480 }
481
482 ApplicationManager::ApplicationManager(
483 const QSharedPointer<TaskController>& taskController,
484 const QSharedPointer<DesktopFileReader::Factory>& desktopFileReaderFactory,
485+ const QSharedPointer<ProcInfo>& procInfo,
486+ const std::shared_ptr<mir::shell::FocusController> & controller,
487+ const QSize & displaySize,
488 QObject *parent)
489 : ApplicationManagerInterface(parent)
490 , m_focusedApplication(nullptr)
491@@ -79,63 +187,18 @@
492 , m_msApplicationToBeFocused(nullptr)
493 , m_ssApplicationToBeFocused(nullptr)
494 , m_lifecycleExceptions(QStringList() << "com.ubuntu.music")
495+ , m_focusController(controller)
496+ , m_dbusWindowStack(new DBusWindowStack(this))
497 , m_taskController(taskController)
498 , m_desktopFileReaderFactory(desktopFileReaderFactory)
499+ , m_procInfo(procInfo)
500 , m_gridUnitPx(8)
501 , m_fenceNext(false)
502+ , m_displaySize(displaySize)
503 , m_panelHeight(54)
504 {
505 DLOG("ApplicationManager::ApplicationManager (this=%p)", this);
506
507- QMirServerApplication* mirServerApplication = dynamic_cast<QMirServerApplication*>(QCoreApplication::instance());
508- if (mirServerApplication == NULL) {
509- LOG("Need to use QMirServerApplication");
510- QCoreApplication::quit();
511- return;
512- }
513- m_mirServer = mirServerApplication->server();
514-
515- QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionStarting,
516- this, &ApplicationManager::onSessionStarting);
517- QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionStopping,
518- this, &ApplicationManager::onSessionStopping);
519- QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionFocused,
520- this, &ApplicationManager::onSessionFocused, Qt::QueuedConnection);
521- QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionUnfocused,
522- this, &ApplicationManager::onSessionUnfocused);
523- QObject::connect(m_mirServer->sessionListener(), &SessionListener::sessionCreatedSurface,
524- this, &ApplicationManager::onSessionCreatedSurface);
525- QObject::connect(m_mirServer->sessionAuthorizer(), &SessionAuthorizer::requestAuthorizationForSession,
526- this, &ApplicationManager::authorizeSession, Qt::BlockingQueuedConnection);
527- QObject::connect(m_mirServer->placementStrategy(), &InitialSurfacePlacementStrategy::requestPlacementForSession,
528- this, &ApplicationManager::placeSession, Qt::DirectConnection);
529-
530- QObject::connect(m_taskController.data(), &TaskController::processStartReport,
531- this, &ApplicationManager::onProcessStartReportReceived);
532- QObject::connect(m_taskController.data(), &TaskController::processStopped,
533- this, &ApplicationManager::onProcessStopped);
534- QObject::connect(m_taskController.data(), &TaskController::requestFocus,
535- this, &ApplicationManager::onFocusRequested);
536- QObject::connect(m_taskController.data(), &TaskController::requestResume,
537- this, &ApplicationManager::onResumeRequested);
538-
539- m_dbusWindowStack = new DBusWindowStack(this);
540-
541- std::shared_ptr<mir::graphics::Display> mirDisplay = m_mirServer->the_display();
542-
543- // Obtain display size
544- mir::geometry::Rectangles view_area;
545- mirDisplay->for_each_display_buffer(
546- [&view_area](mir::graphics::DisplayBuffer const& db)
547- {
548- view_area.add(db.view_area());
549- });
550-
551- m_displaySize = QSize(
552- view_area.bounding_rectangle().size.width.as_uint32_t(),
553- view_area.bounding_rectangle().size.height.as_uint32_t()
554- );
555-
556 // Setup panel height
557 QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
558 if (!gridUnitString.isEmpty()) {
559@@ -222,6 +285,7 @@
560 if (application == nullptr)
561 return;
562
563+ DLOG("ApplicationManager::suspend(this=%p, application(%p)->appId(%s) )",this, application, qPrintable(application->appId()));
564 // Present in exceptions list, return.
565 if (!m_lifecycleExceptions.filter(application->appId().section('_',0,0)).empty())
566 return;
567@@ -232,8 +296,8 @@
568
569 bool ApplicationManager::focusApplication(const QString &appId)
570 {
571- DLOG("ApplicationManager::focusApplication (this=%p, appId=%s)", this, qPrintable(appId));
572 Application *application = findApplication(appId);
573+ DLOG("ApplicationManager::focusApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
574
575 if (!application) {
576 DLOG("No such running application '%s'", qPrintable(appId));
577@@ -256,7 +320,7 @@
578 move(from, m_applications.length()-1);
579 } else {
580 if (application->session())
581- m_mirServer->the_focus_controller()->set_focus_to(application->session());
582+ m_focusController->set_focus_to(application->session());
583 }
584
585 // FIXME(dandrader): lying here. The operation is async. So we will only know whether
586@@ -275,7 +339,7 @@
587 // Clear both stages
588 m_msApplicationToBeFocused = nullptr;
589 m_ssApplicationToBeFocused = nullptr;
590- m_mirServer->the_focus_controller()->set_focus_to(NULL); //FIXME(greyback)
591+ m_focusController->set_focus_to(NULL); //FIXME(greyback)
592 }
593
594 Application* ApplicationManager::startApplication(const QString &appId,
595@@ -294,6 +358,16 @@
596 return nullptr;
597 }
598
599+ {
600+ Application * application = findApplication(appId);
601+ if (application)
602+ {
603+ DLOG("ApplicationManager::startApplication - application already "
604+ "exists: (this=%p, app=%p, appId=%s)",
605+ this, application, qPrintable(appId));
606+ }
607+ }
608+
609 Application* application = new Application(
610 m_taskController,
611 m_desktopFileReaderFactory->createInstanceForAppId(appId),
612@@ -320,7 +394,9 @@
613 this, qPrintable(appId), (failure) ? 'Y' : 'N');
614
615 if (failure) {
616- onProcessStopped(appId, true);
617+ DLOG("ApplicationManager::onProcessStartReportReceived handling failure:");
618+ stopStartingApplication(appId);
619+ return;
620 }
621
622 Application *application = findApplication(appId);
623@@ -338,30 +414,23 @@
624 add(application);
625 Q_EMIT focusRequested(appId);
626 }
627+ else {
628+ DLOG("ApplicationManager::onProcessStartReportReceived application already found: (app=%p, appId=%s)", application, qPrintable(appId));
629+ }
630 }
631
632 bool ApplicationManager::stopApplication(const QString &appId)
633 {
634- DLOG("ApplicationManager::stopApplication (this=%p, appId=%s)", this, qPrintable(appId));
635-
636 Application *application = findApplication(appId);
637+ DLOG("ApplicationManager::stopApplication (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
638
639 if (!application) {
640 DLOG("No such running application '%s'", qPrintable(appId));
641 return false;
642 }
643
644- if (application == m_focusedApplication) {
645- // TODO(greyback) What to do?? Focus next app, or unfocus everything??
646- m_focusedApplication = NULL;
647- Q_EMIT focusedApplicationIdChanged();
648- }
649+ checkFocusOnRemovedApplication(application);
650
651- if (application == m_mainStageApplication)
652- m_mainStageApplication = nullptr;
653- if (application == m_sideStageApplication)
654- m_sideStageApplication = nullptr;
655-
656 remove(application);
657 m_dbusWindowStack->WindowDestroyed(0, application->appId());
658
659@@ -376,37 +445,28 @@
660 return result;
661 }
662
663+void ApplicationManager::stopStartingApplication(const QString &appId)
664+{
665+ Application *application = findApplication(appId);
666+
667+ if (application && application->state() == Application::Starting) {
668+ shutdownApplication(application);
669+ }
670+ else if (application) {
671+ DLOG("onProcessStartReportReceived failure - but application=%p, appId=%s is not in Starting state",application, qPrintable(appId));
672+ }
673+}
674+
675 void ApplicationManager::onProcessStopped(const QString &appId, const bool unexpected)
676 {
677 Application *application = findApplication(appId);
678+ DLOG("ApplicationManager::onProcessStopped (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
679
680 // if shell did not stop the application, but upstart says it died, we assume the process has been
681 // killed, so it can be respawned later. Only exception is if that application is focused or running
682 // as then it most likely crashed. Update this logic when upstart gives some failure info.
683 if (application) {
684- bool removeApplication = false;
685-
686- if (application == m_focusedApplication) {
687- // Very bad case where focused application dies. Remove from list. Should give error message
688- m_focusedApplication = nullptr;
689- Q_EMIT focusedApplicationIdChanged();
690- removeApplication = true;
691- }
692-
693- if (application->state() == Application::Running || application->state() == Application::Starting) {
694- // Application probably crashed, else OOM killer struck. Either way state wasn't saved
695- // so just remove application
696- removeApplication = true;
697- } else if (application->state() == Application::Suspended) {
698- application->setState(Application::Stopped);
699- application->setSession(nullptr);
700- }
701-
702- if (removeApplication) {
703- remove(application);
704- m_dbusWindowStack->WindowDestroyed(0, application->appId());
705- delete application;
706- }
707+ shutdownApplication(application);
708 }
709
710 if (unexpected) {
711@@ -415,6 +475,27 @@
712 }
713 }
714
715+void ApplicationManager::shutdownApplication(Application* application)
716+{
717+ bool removeApplication = checkFocusOnRemovedApplication(application);
718+
719+ if (application->state() == Application::Running || application->state() == Application::Starting) {
720+ // Application probably crashed, else OOM killer struck. Either way state wasn't saved
721+ // so just remove application
722+ removeApplication = true;
723+ } else if (application->state() == Application::Suspended) {
724+ application->setState(Application::Stopped);
725+ application->setSession(nullptr);
726+ }
727+
728+ if (removeApplication) {
729+ remove(application);
730+ m_dbusWindowStack->WindowDestroyed(0, application->appId());
731+ delete application;
732+ }
733+
734+}
735+
736 void ApplicationManager::onFocusRequested(const QString& appId)
737 {
738 DLOG("ApplicationManager::onFocusRequested (this=%p, appId=%s)", this, qPrintable(appId));
739@@ -424,9 +505,9 @@
740
741 void ApplicationManager::onResumeRequested(const QString& appId)
742 {
743- DLOG("ApplicationManager::onResumeRequested (this=%p, appId=%s)", this, qPrintable(appId));
744-
745 Application *application = findApplication(appId);
746+ DLOG("ApplicationManager::onResumeRequested (this=%p, application=%p, appId=%s)", this, application, qPrintable(appId));
747+
748
749 if (!application) {
750 DLOG("ApplicationManager::onResumeRequested: No such running application '%s'", qPrintable(appId));
751@@ -452,6 +533,7 @@
752 if (app->state() == Application::Starting
753 && m_taskController->appIdHasProcessId(app->appId(), pid)) {
754 app->setPid(pid);
755+ DLOG("ApplicationManager::authorizeSession - connecting: application=%p and pid=%lld", app, pid);
756 authorized = true;
757 return;
758 }
759@@ -463,41 +545,35 @@
760 * notify shell it is starting an application and so shell should allow it. Also reads
761 * the --stage parameter to determine the desired stage
762 */
763- QFile cmdline(QString("/proc/%1/cmdline").arg(pid));
764- if (!cmdline.open(QIODevice::ReadOnly | QIODevice::Text)) {
765+ std::unique_ptr<ProcInfo::CommandLine> info = m_procInfo->command_line(pid);
766+ if (!info) {
767 DLOG("ApplicationManager REJECTED connection from app with pid %lld as unable to read process command", pid);
768 return;
769 }
770
771- QByteArray command = cmdline.readLine().replace('\0', ' ');
772-
773- // FIXME: special exception for the OSK - maliit-server - not very secure
774- if (command.startsWith("maliit-server") || command.startsWith("/usr/lib/arm-linux-gnueabihf/qt5/libexec/QtWebProcess")
775- || command.startsWith("/usr/bin/signon-ui")) {
776+ if (info->starts_with("maliit-server") || info->starts_with("/usr/lib/arm-linux-gnueabihf/qt5/libexec/QtWebProcess")
777+ || info->starts_with("/usr/bin/signon-ui")) {
778 authorized = true;
779 m_fenceNext = true;
780 return;
781 }
782
783- QString pattern = QRegularExpression::escape("--desktop_file_hint=") + "(\\S+)";
784- QRegularExpression regExp(pattern);
785- QRegularExpressionMatch regExpMatch = regExp.match(command);
786+ boost::optional<QString> desktopFileName{ info->get_parameter("--desktop_file_hint=") };
787
788- if (!regExpMatch.hasMatch()) {
789+ if (!desktopFileName) {
790 LOG("ApplicationManager REJECTED connection from app with pid %lld as no desktop_file_hint specified", pid);
791 return;
792 }
793
794- QString desktopFileName = regExpMatch.captured(1);
795- DLOG("Process supplied desktop_file_hint, loading '%s'", desktopFileName.toLatin1().data());
796+ DLOG("Process supplied desktop_file_hint, loading '%s'", desktopFileName.get().toLatin1().data());
797
798 // FIXME: right now we support --desktop_file_hint=appId for historical reasons. So let's try that in
799 // case we didn't get an existing .desktop file path
800 DesktopFileReader* desktopData;
801- if (QFileInfo(desktopFileName).exists()) {
802- desktopData = m_desktopFileReaderFactory->createInstanceForDesktopFile(QFileInfo(desktopFileName));
803+ if (QFileInfo(desktopFileName.get()).exists()) {
804+ desktopData = m_desktopFileReaderFactory->createInstanceForDesktopFile(QFileInfo(desktopFileName.get()));
805 } else {
806- desktopData = m_desktopFileReaderFactory->createInstanceForAppId(desktopFileName);
807+ desktopData = m_desktopFileReaderFactory->createInstanceForAppId(desktopFileName.get());
808 }
809
810 if (!desktopData->loaded()) {
811@@ -521,18 +597,15 @@
812
813 // if stage supplied in CLI, fetch that
814 Application::Stage stage = Application::MainStage;
815- pattern = QRegularExpression::escape("--stage_hint=") + "(\\S+)";
816- regExp.setPattern(pattern);
817- regExpMatch = regExp.match(command);
818+ boost::optional<QString> stageParam = info->get_parameter("--stage_hint=");
819
820- if (regExpMatch.hasMatch() && regExpMatch.captured(1) == "side_stage") {
821+ if (stageParam && stageParam.get() == "side_stage") {
822 stage = Application::SideStage;
823 }
824
825 DLOG("Existing process with pid %lld appeared, adding '%s' to application lists", pid, desktopData->name().toLatin1().data());
826
827- QString argStr(command.data());
828- QStringList arguments(argStr.split(' '));
829+ QStringList arguments(info->as_string_list());
830 application = new Application(m_taskController, desktopData, Application::Starting, arguments, this);
831 application->setPid(pid);
832 application->setStage(stage);
833@@ -542,9 +615,9 @@
834
835 void ApplicationManager::placeSession(msh::Session const* session, uint32_t &x, uint32_t &y)
836 {
837- DLOG("ApplicationManager::placeSession (this=%p, session=%p)", this, session);
838+ Application* application = findApplicationWithSession(session);
839+ DLOG("ApplicationManager::placeSession (this=%p, application=%p, session=%p, name=%s)", this, application, session, session?(session->name().c_str()):"null");
840
841- Application* application = findApplicationWithSession(session);
842
843 // Application defaults
844 x = 0;
845@@ -569,7 +642,7 @@
846
847 void ApplicationManager::onSessionStarting(std::shared_ptr<msh::Session> const& session)
848 {
849- DLOG("ApplicationManager::onSessionStarting (this=%p, application=%s)", this, session->name().c_str());
850+ DLOG("ApplicationManager::onSessionStarting (this=%p, application=%s)", this, session?session->name().c_str():"null");
851
852 if (m_fenceNext) {
853 m_fenceNext = false;
854@@ -592,10 +665,11 @@
855
856 void ApplicationManager::onSessionStopping(std::shared_ptr<msh::Session> const& session)
857 {
858- DLOG("ApplicationManager::onSessionStopping (this=%p, application=%s)", this, session->name().c_str());
859-
860 // in case application closed not by hand of shell, check again here:
861 Application* application = findApplicationWithSession(session);
862+
863+ DLOG("ApplicationManager::onSessionStopping (this=%p, application=%p, appId=%s, session name=%s)", this, application, application?qPrintable(application->appId()):"null", session?session->name().c_str():"null");
864+
865 if (application) {
866 bool removeApplication = true;
867
868@@ -604,7 +678,7 @@
869 application->setSession(nullptr);
870 m_dbusWindowStack->WindowDestroyed(0, application->appId());
871 if (application != m_focusedApplication) {
872- removeApplication = false;
873+ removeApplication = false;
874 }
875 }
876
877@@ -626,8 +700,8 @@
878
879 void ApplicationManager::onSessionFocused(std::shared_ptr<msh::Session> const& session)
880 {
881- DLOG("ApplicationManager::onSessionFocused (this=%p, session=%p)", this, session.get());
882 Application* application = findApplicationWithSession(session);
883+ DLOG("ApplicationManager::onSessionFocused (this=%p, application=%p, appId=%s, session name=%s)", this, application, application?qPrintable(application->appId()):"null", session?session->name().c_str():"null");
884
885 // Don't give application focus until it has created it's surface, when it is set as state "Running"
886 // and only notify shell of focus changes that it actually expects
887@@ -649,7 +723,7 @@
888
889 void ApplicationManager::onSessionUnfocused()
890 {
891- DLOG("ApplicationManager::onSessionUnfocused (this=%p)", this);
892+ DLOG("ApplicationManager::onSessionUnfocused (this=%p, application=%p)", this, m_focusedApplication);
893 if (NULL != m_focusedApplication) {
894 Q_ASSERT(m_focusedApplication->focused());
895 m_focusedApplication->setFocused(false);
896@@ -683,7 +757,7 @@
897
898 void ApplicationManager::setFocused(Application *application)
899 {
900- DLOG("ApplicationManager::setFocused (appId=%s)", qPrintable(application->appId()));
901+ DLOG("ApplicationManager::setFocused (application=%p, appId=%s)", application, qPrintable(application->appId()));
902
903 if (application == m_focusedApplication)
904 return;
905@@ -769,6 +843,11 @@
906 DASSERT(application != NULL);
907 DLOG("ApplicationManager::remove (this=%p, application='%s')", this, qPrintable(application->name()));
908
909+ if (application == m_sideStageApplication)
910+ m_sideStageApplication = nullptr;
911+ if (application == m_mainStageApplication)
912+ m_mainStageApplication = nullptr;
913+
914 int i = m_applications.indexOf(application);
915 if (i != -1) {
916 beginRemoveRows(QModelIndex(), i, i);
917@@ -803,3 +882,16 @@
918
919 return QModelIndex();
920 }
921+
922+bool ApplicationManager::checkFocusOnRemovedApplication(Application * application)
923+{
924+ if (application == m_focusedApplication) {
925+ // TODO(greyback) What to do?? Focus next app, or unfocus everything??
926+ m_focusedApplication = nullptr;
927+ Q_EMIT focusedApplicationIdChanged();
928+ return true;
929+ }
930+ return false;
931+}
932+
933+} // namespace unitymir
934
935=== modified file 'src/modules/Unity/Application/application_manager.h'
936--- src/modules/Unity/Application/application_manager.h 2014-01-27 11:29:44 +0000
937+++ src/modules/Unity/Application/application_manager.h 2014-02-26 21:35:04 +0000
938@@ -34,11 +34,6 @@
939 // local
940 #include "application.h"
941
942-class ShellServerConfiguration;
943-class DBusWindowStack;
944-class MirSurfaceManager;
945-class TaskController;
946-
947 namespace mir {
948 namespace geometry {
949 class Size;
950@@ -46,15 +41,30 @@
951 namespace shell {
952 class Session;
953 class Surface;
954+ class FocusController;
955 }
956 }
957
958+class ShellServerConfiguration;
959+
960+namespace unitymir
961+{
962+class DBusWindowStack;
963+class MirSurfaceManager;
964+class TaskController;
965+class ProcInfo;
966+
967 class ApplicationManager : public unity::shell::application::ApplicationManagerInterface
968 {
969 Q_OBJECT
970 Q_FLAGS(ExecFlags)
971
972 public:
973+ class Factory
974+ {
975+ public:
976+ QSharedPointer<ApplicationManager> create();
977+ };
978 // Mapping enums to Ubuntu Platform API enums.
979 enum Flag {
980 NoFlag = 0x0,
981@@ -66,28 +76,31 @@
982
983 explicit ApplicationManager(const QSharedPointer<TaskController>& taskController,
984 const QSharedPointer<DesktopFileReader::Factory>& desktopFileReaderFactory,
985+ const QSharedPointer<ProcInfo>& processInfo,
986+ std::shared_ptr<mir::shell::FocusController> const& controller,
987+ QSize const& displaySize,
988 QObject *parent = 0);
989 virtual ~ApplicationManager();
990
991 // ApplicationManagerInterface
992 QString focusedApplicationId() const override;
993- Q_INVOKABLE Application* get(int index) const override;
994- Q_INVOKABLE Application* findApplication(const QString &appId) const override;
995+ Q_INVOKABLE unitymir::Application* get(int index) const override;
996+ Q_INVOKABLE unitymir::Application* findApplication(const QString &appId) const override;
997 Q_INVOKABLE bool focusApplication(const QString &appId) override;
998 Q_INVOKABLE void unfocusCurrentApplication() override;
999- Q_INVOKABLE Application* startApplication(const QString &appId, const QStringList &arguments) override;
1000+ Q_INVOKABLE unitymir::Application* startApplication(const QString &appId, const QStringList &arguments) override;
1001 Q_INVOKABLE bool stopApplication(const QString &appId) override;
1002
1003 // QAbstractListModel
1004 int rowCount(const QModelIndex & parent = QModelIndex()) const override;
1005 QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
1006
1007- Q_INVOKABLE Application *startApplication(const QString &appId, ExecFlags flags,
1008- const QStringList &arguments = QStringList());
1009+ Q_INVOKABLE unitymir::Application *startApplication(const QString &appId, ExecFlags flags,
1010+ const QStringList &arguments = QStringList());
1011 Q_INVOKABLE void move(int from, int to);
1012
1013 const QList<Application*> &list() const { return m_applications; }
1014- Application* findApplicationWithPid(const qint64 pid);
1015+ unitymir::Application* findApplicationWithPid(const qint64 pid);
1016
1017 // Internal helpers
1018 void suspendApplication(Application *application);
1019@@ -122,6 +135,9 @@
1020 Application* findLastExecutedApplication();
1021 Application* applicationForStage(Application::Stage stage);
1022 QModelIndex findIndex(Application* application);
1023+ bool checkFocusOnRemovedApplication(Application* application);
1024+ void shutdownApplication(Application* application);
1025+ void stopStartingApplication(const QString &appId);
1026
1027 QList<Application*> m_applications;
1028 Application* m_focusedApplication; // remove as Mir has API for this
1029@@ -130,11 +146,11 @@
1030 Application* m_msApplicationToBeFocused; // placeholder store for async focusing
1031 Application* m_ssApplicationToBeFocused; // placeholder store for async focusing
1032 QStringList m_lifecycleExceptions;
1033- ShellServerConfiguration* m_mirServer;
1034+ std::shared_ptr<mir::shell::FocusController> m_focusController;
1035 DBusWindowStack* m_dbusWindowStack;
1036 QSharedPointer<TaskController> m_taskController;
1037 QSharedPointer<DesktopFileReader::Factory> m_desktopFileReaderFactory;
1038- static ApplicationManager* the_application_manager;
1039+ QSharedPointer<ProcInfo> m_procInfo;
1040 int m_gridUnitPx;
1041 bool m_fenceNext;
1042 QSize m_displaySize;
1043@@ -144,6 +160,8 @@
1044 friend class MirSurfaceManager;
1045 };
1046
1047-Q_DECLARE_METATYPE(ApplicationManager*)
1048+} // namespace unitymir
1049+
1050+Q_DECLARE_METATYPE(unitymir::ApplicationManager*)
1051
1052 #endif // APPLICATIONMANAGER_H
1053
1054=== modified file 'src/modules/Unity/Application/applicationcontroller.h'
1055--- src/modules/Unity/Application/applicationcontroller.h 2014-01-27 11:29:44 +0000
1056+++ src/modules/Unity/Application/applicationcontroller.h 2014-02-26 21:35:04 +0000
1057@@ -22,6 +22,9 @@
1058 #include <QString>
1059 #include <QStringList>
1060
1061+namespace unitymir
1062+{
1063+
1064 class ApplicationController : public QObject
1065 {
1066 Q_OBJECT
1067@@ -57,4 +60,6 @@
1068 ApplicationController() = default;
1069 };
1070
1071+} // namespace unitymir
1072+
1073 #endif // APPLICATION_CONTROLLER_H
1074
1075=== modified file 'src/modules/Unity/Application/applicationscreenshotprovider.cpp'
1076--- src/modules/Unity/Application/applicationscreenshotprovider.cpp 2013-12-20 03:38:43 +0000
1077+++ src/modules/Unity/Application/applicationscreenshotprovider.cpp 2014-02-26 21:35:04 +0000
1078@@ -25,6 +25,9 @@
1079 // mir
1080 #include "mirserver/mir/shell/session.h"
1081
1082+namespace unitymir
1083+{
1084+
1085 ApplicationScreenshotProvider::ApplicationScreenshotProvider(ApplicationManager *appManager)
1086 : QQuickImageProvider(QQuickImageProvider::Image)
1087 , m_appManager(appManager)
1088@@ -92,3 +95,5 @@
1089 mutex.unlock();
1090 return image;
1091 }
1092+
1093+} // namespace unitymir
1094
1095=== modified file 'src/modules/Unity/Application/applicationscreenshotprovider.h'
1096--- src/modules/Unity/Application/applicationscreenshotprovider.h 2013-08-14 14:24:17 +0000
1097+++ src/modules/Unity/Application/applicationscreenshotprovider.h 2014-02-26 21:35:04 +0000
1098@@ -19,7 +19,10 @@
1099
1100 #include <QQuickImageProvider>
1101
1102+namespace unitymir
1103+{
1104 class ApplicationManager;
1105+
1106 class ApplicationScreenshotProvider : public QQuickImageProvider
1107 {
1108 public:
1109@@ -33,4 +36,6 @@
1110 int m_panelHeight;
1111 };
1112
1113+} // namespace unitymir
1114+
1115 #endif // APPLICATIONSCREENSHOTPROVIDER_H
1116
1117=== modified file 'src/modules/Unity/Application/dbuswindowstack.cpp'
1118--- src/modules/Unity/Application/dbuswindowstack.cpp 2013-10-09 09:02:23 +0000
1119+++ src/modules/Unity/Application/dbuswindowstack.cpp 2014-02-26 21:35:04 +0000
1120@@ -22,6 +22,9 @@
1121 #include <QDBusConnection>
1122 #include <QDBusMetaType>
1123
1124+namespace unitymir
1125+{
1126+
1127 DBusWindowStack::DBusWindowStack(ApplicationManager *parent) : QObject(parent)
1128 {
1129 qRegisterMetaType<AppIdDesktopFile>();
1130@@ -110,3 +113,5 @@
1131
1132 return a;
1133 }
1134+
1135+} // namespace unitymir
1136
1137=== modified file 'src/modules/Unity/Application/dbuswindowstack.h'
1138--- src/modules/Unity/Application/dbuswindowstack.h 2014-01-09 08:40:51 +0000
1139+++ src/modules/Unity/Application/dbuswindowstack.h 2014-02-26 21:35:04 +0000
1140@@ -20,6 +20,9 @@
1141 #include <QObject>
1142 #include <QDBusArgument>
1143
1144+namespace unitymir
1145+{
1146+
1147 class ApplicationManager;
1148
1149 class AppIdDesktopFile
1150@@ -52,8 +55,8 @@
1151 explicit DBusWindowStack(ApplicationManager* parent);
1152 ~DBusWindowStack();
1153
1154- Q_INVOKABLE Q_SCRIPTABLE AppIdDesktopFile GetAppIdFromPid(unsigned int pid);
1155- Q_INVOKABLE Q_SCRIPTABLE QList<WindowInfo> GetWindowStack();
1156+ Q_INVOKABLE Q_SCRIPTABLE unitymir::AppIdDesktopFile GetAppIdFromPid(unsigned int pid);
1157+ Q_INVOKABLE Q_SCRIPTABLE QList<unitymir::WindowInfo> GetWindowStack();
1158 Q_INVOKABLE Q_SCRIPTABLE QStringList GetWindowProperties(unsigned int window_id, const QString &app_id, const QStringList &names);
1159
1160 signals:
1161@@ -62,7 +65,9 @@
1162 void WindowDestroyed(unsigned int window_id, const QString &app_id);
1163 };
1164
1165-Q_DECLARE_METATYPE(AppIdDesktopFile)
1166-Q_DECLARE_METATYPE(WindowInfo)
1167+} // namespace unitymir
1168+
1169+Q_DECLARE_METATYPE(unitymir::AppIdDesktopFile)
1170+Q_DECLARE_METATYPE(unitymir::WindowInfo)
1171
1172 #endif // DBUSWINDOWSTACK_H
1173
1174=== modified file 'src/modules/Unity/Application/desktopfilereader.cpp'
1175--- src/modules/Unity/Application/desktopfilereader.cpp 2014-01-13 11:13:40 +0000
1176+++ src/modules/Unity/Application/desktopfilereader.cpp 2014-02-26 21:35:04 +0000
1177@@ -25,6 +25,9 @@
1178 #include <QDir>
1179 #include <QStandardPaths>
1180
1181+namespace unitymir
1182+{
1183+
1184 DesktopFileReader::Factory::Factory()
1185 {
1186 }
1187@@ -187,3 +190,5 @@
1188 return false;
1189 }
1190 }
1191+
1192+} // namespace unitymir
1193
1194=== modified file 'src/modules/Unity/Application/desktopfilereader.h'
1195--- src/modules/Unity/Application/desktopfilereader.h 2014-01-13 11:13:40 +0000
1196+++ src/modules/Unity/Application/desktopfilereader.h 2014-02-26 21:35:04 +0000
1197@@ -21,6 +21,9 @@
1198 #include <QVector>
1199 #include <QFileInfo>
1200
1201+namespace unitymir
1202+{
1203+
1204 class DesktopFileReader {
1205 public:
1206 class Factory
1207@@ -72,4 +75,6 @@
1208 bool loaded_;
1209 };
1210
1211+} // namespace unitymir
1212+
1213 #endif // DESKTOPFILEREADER_H
1214
1215=== modified file 'src/modules/Unity/Application/inputarea.cpp'
1216--- src/modules/Unity/Application/inputarea.cpp 2013-11-26 08:56:08 +0000
1217+++ src/modules/Unity/Application/inputarea.cpp 2014-02-26 21:35:04 +0000
1218@@ -31,6 +31,9 @@
1219 #include "surfacefactory.h"
1220 #include "logging.h"
1221
1222+namespace unitymir
1223+{
1224+
1225 InputArea::InputArea(QQuickItem *parent)
1226 : QQuickItem(parent)
1227 , m_enabled(true)
1228@@ -187,3 +190,5 @@
1229 m_surface->installInputArea(this);
1230 }
1231 }
1232+
1233+} // namespace unitymir
1234
1235=== modified file 'src/modules/Unity/Application/inputarea.h'
1236--- src/modules/Unity/Application/inputarea.h 2013-11-26 08:56:08 +0000
1237+++ src/modules/Unity/Application/inputarea.h 2014-02-26 21:35:04 +0000
1238@@ -25,8 +25,12 @@
1239 // mir
1240 #include <mircommon/mir/geometry/rectangle.h>
1241
1242+namespace mir { namespace shell { class Surface; }}
1243+
1244+namespace unitymir
1245+{
1246 class MirSurface;
1247-namespace mir { namespace shell { class Surface; }}
1248+
1249 class InputArea : public QQuickItem
1250 {
1251 Q_OBJECT
1252@@ -70,4 +74,6 @@
1253 friend class MirSurface;
1254 };
1255
1256+} // namespace unitymir
1257+
1258 #endif // INPUTAREA_H
1259
1260=== modified file 'src/modules/Unity/Application/inputfilterarea.cpp'
1261--- src/modules/Unity/Application/inputfilterarea.cpp 2013-08-29 14:46:43 +0000
1262+++ src/modules/Unity/Application/inputfilterarea.cpp 2014-02-26 21:35:04 +0000
1263@@ -23,6 +23,9 @@
1264 // Qt
1265 #include <QDebug>
1266
1267+namespace unitymir
1268+{
1269+
1270 InputFilterArea::InputFilterArea(QQuickItem *parent) : InputArea(parent)
1271 {
1272 auto surface = MirSurfaceManager::singleton()->shellSurface();
1273@@ -56,3 +59,5 @@
1274 {
1275 setEnabled(enable);
1276 }
1277+
1278+} // namespace unitymir
1279
1280=== modified file 'src/modules/Unity/Application/inputfilterarea.h'
1281--- src/modules/Unity/Application/inputfilterarea.h 2013-08-29 14:46:43 +0000
1282+++ src/modules/Unity/Application/inputfilterarea.h 2014-02-26 21:35:04 +0000
1283@@ -19,6 +19,8 @@
1284
1285 #include "inputarea.h"
1286
1287+namespace unitymir
1288+{
1289 class MirSurface;
1290
1291 /*
1292@@ -50,4 +52,6 @@
1293 void setShellSurface(MirSurface *surface);
1294 };
1295
1296+} // namespace unitymir
1297+
1298 #endif // INPUTFILTERAREA_H
1299
1300=== modified file 'src/modules/Unity/Application/mirsurface.cpp'
1301--- src/modules/Unity/Application/mirsurface.cpp 2013-12-20 04:48:14 +0000
1302+++ src/modules/Unity/Application/mirsurface.cpp 2014-02-26 21:35:04 +0000
1303@@ -27,6 +27,9 @@
1304
1305 namespace mg = mir::geometry;
1306
1307+namespace unitymir
1308+{
1309+
1310 MirSurface::MirSurface(std::shared_ptr<mir::shell::Surface> surface, Application* application, QQuickItem *parent)
1311 : QQuickItem(parent)
1312 , m_surface(surface)
1313@@ -223,3 +226,4 @@
1314 }
1315 }
1316
1317+} // namespace unitymir
1318
1319=== modified file 'src/modules/Unity/Application/mirsurface.h'
1320--- src/modules/Unity/Application/mirsurface.h 2013-09-06 05:34:01 +0000
1321+++ src/modules/Unity/Application/mirsurface.h 2014-02-26 21:35:04 +0000
1322@@ -26,6 +26,9 @@
1323 #include <mir_toolkit/common.h>
1324
1325 namespace mir { namespace geometry { struct Rectangle; }}
1326+
1327+namespace unitymir
1328+{
1329 class MirSurfaceManager;
1330 class InputArea;
1331 class Application;
1332@@ -127,6 +130,8 @@
1333 friend class InputArea;
1334 };
1335
1336-Q_DECLARE_METATYPE(MirSurface*)
1337+} // namespace unitymir
1338+
1339+Q_DECLARE_METATYPE(unitymir::MirSurface*)
1340
1341 #endif // MIRSURFACE_H
1342
1343=== modified file 'src/modules/Unity/Application/mirsurfacemanager.cpp'
1344--- src/modules/Unity/Application/mirsurfacemanager.cpp 2013-12-20 03:38:43 +0000
1345+++ src/modules/Unity/Application/mirsurfacemanager.cpp 2014-02-26 21:35:04 +0000
1346@@ -36,6 +36,9 @@
1347
1348 namespace msh = mir::shell;
1349
1350+namespace unitymir
1351+{
1352+
1353 MirSurfaceManager *MirSurfaceManager::the_surface_manager = nullptr;
1354
1355 MirSurfaceManager* MirSurfaceManager::singleton()
1356@@ -161,3 +164,5 @@
1357 }
1358 }
1359 }
1360+
1361+} // namespace unitymir
1362
1363=== modified file 'src/modules/Unity/Application/mirsurfacemanager.h'
1364--- src/modules/Unity/Application/mirsurfacemanager.h 2013-11-15 17:40:27 +0000
1365+++ src/modules/Unity/Application/mirsurfacemanager.h 2014-02-26 21:35:04 +0000
1366@@ -29,8 +29,11 @@
1367 // local
1368 #include "mirsurface.h"
1369
1370+namespace mir { namespace shell { class Surface; class Session; }}
1371 class ShellServerConfiguration;
1372-namespace mir { namespace shell { class Surface; class Session; }}
1373+
1374+namespace unitymir
1375+{
1376
1377 class MirSurfaceManager : public QObject
1378 {
1379@@ -67,4 +70,6 @@
1380 static MirSurfaceManager *the_surface_manager;
1381 };
1382
1383+} // namespace unitymir
1384+
1385 #endif // MIR_SURFACE_MANAGER_H
1386
1387=== modified file 'src/modules/Unity/Application/plugin.cpp'
1388--- src/modules/Unity/Application/plugin.cpp 2013-11-19 16:42:52 +0000
1389+++ src/modules/Unity/Application/plugin.cpp 2014-02-26 21:35:04 +0000
1390@@ -36,14 +36,14 @@
1391 Q_UNUSED(scriptEngine);
1392 DLOG("applicationManagerSingleton (engine=%p, scriptEngine=%p)", engine, scriptEngine);
1393
1394- return ApplicationManager::singleton();
1395+ return unitymir::ApplicationManager::singleton();
1396 }
1397
1398 static QObject* surfaceManagerSingleton(QQmlEngine* engine, QJSEngine* scriptEngine) {
1399 Q_UNUSED(engine);
1400 Q_UNUSED(scriptEngine);
1401 DLOG("surfaceManagerSingleton (engine=%p, scriptEngine=%p)", engine, scriptEngine);
1402- return MirSurfaceManager::singleton();
1403+ return unitymir::MirSurfaceManager::singleton();
1404 }
1405
1406 class UnityApplicationPlugin : public QQmlExtensionPlugin {
1407@@ -55,32 +55,34 @@
1408 DLOG("UnityApplicationPlugin::registerTypes (this=%p, uri='%s')", this, uri);
1409 ASSERT(QLatin1String(uri) == QLatin1String("Unity.Application"));
1410
1411- qRegisterMetaType<ApplicationManager*>("ApplicationManager*"); //need for queueing signals
1412+ qRegisterMetaType<unitymir::ApplicationManager*>("ApplicationManager*"); //need for queueing signals
1413
1414 qmlRegisterUncreatableType<unity::shell::application::ApplicationManagerInterface>(
1415 uri, 0, 1, "ApplicationManagerInterface", "Abstract interface. Cannot be created in QML");
1416- qmlRegisterSingletonType<ApplicationManager>(
1417+ qmlRegisterSingletonType<unitymir::ApplicationManager>(
1418 uri, 0, 1, "ApplicationManager", applicationManagerSingleton);
1419 qmlRegisterUncreatableType<unity::shell::application::ApplicationInfoInterface>(
1420 uri, 0, 1, "ApplicationInfoInterface", "Abstract interface. Cannot be created in QML");
1421- qmlRegisterUncreatableType<Application>(
1422+ qmlRegisterUncreatableType<unitymir::Application>(
1423 uri, 0, 1, "ApplicationInfo", "ApplicationInfo can't be instantiated");
1424- qmlRegisterSingletonType<MirSurfaceManager>(
1425+ qmlRegisterSingletonType<unitymir::MirSurfaceManager>(
1426 uri, 0, 1, "SurfaceManager", surfaceManagerSingleton);
1427- qmlRegisterUncreatableType<MirSurface>(
1428+ qmlRegisterUncreatableType<unitymir::MirSurface>(
1429 uri, 0, 1, "MirSurface", "MirSurface can't be instantiated");
1430- qmlRegisterType<InputArea>(uri, 0, 1, "InputArea");
1431- qmlRegisterType<ShellInputArea>(uri, 0, 1, "ShellInputArea");
1432- qmlRegisterType<InputFilterArea>(uri, 0, 1, "InputFilterArea");
1433- qmlRegisterType<UbuntuKeyboardInfo>(uri, 0, 1, "UbuntuKeyboardInfo");
1434+ qmlRegisterType<unitymir::InputArea>(uri, 0, 1, "InputArea");
1435+ qmlRegisterType<unitymir::ShellInputArea>(uri, 0, 1, "ShellInputArea");
1436+ qmlRegisterType<unitymir::InputFilterArea>(uri, 0, 1, "InputFilterArea");
1437+ qmlRegisterType<unitymir::UbuntuKeyboardInfo>(uri, 0, 1, "UbuntuKeyboardInfo");
1438 }
1439
1440 virtual void initializeEngine(QQmlEngine *engine, const char *uri)
1441 {
1442 QQmlExtensionPlugin::initializeEngine(engine, uri);
1443
1444- ApplicationManager* appManager = static_cast<ApplicationManager*>(applicationManagerSingleton(engine, NULL));
1445- engine->addImageProvider(QLatin1String("screenshot"), new ApplicationScreenshotProvider(appManager));
1446+ unitymir::ApplicationManager* appManager =
1447+ static_cast<unitymir::ApplicationManager*>(applicationManagerSingleton(engine, NULL));
1448+ engine->addImageProvider(QLatin1String("screenshot"),
1449+ new unitymir::ApplicationScreenshotProvider(appManager));
1450 }
1451 };
1452
1453
1454=== added file 'src/modules/Unity/Application/proc_info.cpp'
1455--- src/modules/Unity/Application/proc_info.cpp 1970-01-01 00:00:00 +0000
1456+++ src/modules/Unity/Application/proc_info.cpp 2014-02-26 21:35:04 +0000
1457@@ -0,0 +1,56 @@
1458+/*
1459+ * Copyright (C) 2014 Canonical, Ltd.
1460+ *
1461+ * This program is free software: you can redistribute it and/or modify it under
1462+ * the terms of the GNU Lesser General Public License version 3, as published by
1463+ * the Free Software Foundation.
1464+ *
1465+ * This program is distributed in the hope that it will be useful, but WITHOUT
1466+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1467+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1468+ * Lesser General Public License for more details.
1469+ *
1470+ * You should have received a copy of the GNU Lesser General Public License
1471+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1472+ */
1473+
1474+#include "proc_info.h"
1475+
1476+#include <QFile>
1477+#include <QRegularExpression>
1478+
1479+namespace unitymir
1480+{
1481+
1482+ProcInfo::~ProcInfo() {
1483+}
1484+
1485+std::unique_ptr<ProcInfo::CommandLine> ProcInfo::command_line(quint64 pid) {
1486+ QFile cmdline(QString("/proc/%1/cmdline").arg(pid));
1487+ if (!cmdline.open(QIODevice::ReadOnly | QIODevice::Text)) {
1488+ return nullptr;
1489+ }
1490+
1491+ return std::unique_ptr<CommandLine>(new CommandLine{ cmdline.readLine().replace('\0', ' ') });
1492+}
1493+QStringList ProcInfo::CommandLine::as_string_list() const {
1494+ return QString(command.data()).split(' ');
1495+}
1496+
1497+bool ProcInfo::CommandLine::starts_with(char const* prefix) const {
1498+ return command.startsWith(prefix);
1499+}
1500+
1501+boost::optional<QString> ProcInfo::CommandLine::get_parameter(const char* name) const {
1502+ QString pattern = QRegularExpression::escape(name) + "(\\S+)";
1503+ QRegularExpression regExp(pattern);
1504+ QRegularExpressionMatch regExpMatch = regExp.match(command);
1505+
1506+ if (!regExpMatch.hasMatch()) {
1507+ return boost::optional<QString>{};
1508+ }
1509+
1510+ return boost::optional<QString>{regExpMatch.captured(1)};
1511+}
1512+
1513+} // namespace unitymir
1514
1515=== added file 'src/modules/Unity/Application/proc_info.h'
1516--- src/modules/Unity/Application/proc_info.h 1970-01-01 00:00:00 +0000
1517+++ src/modules/Unity/Application/proc_info.h 2014-02-26 21:35:04 +0000
1518@@ -0,0 +1,52 @@
1519+/*
1520+ * Copyright (C) 2014 Canonical, Ltd.
1521+ *
1522+ * This program is free software: you can redistribute it and/or modify it under
1523+ * the terms of the GNU Lesser General Public License version 3, as published by
1524+ * the Free Software Foundation.
1525+ *
1526+ * This program is distributed in the hope that it will be useful, but WITHOUT
1527+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
1528+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1529+ * Lesser General Public License for more details.
1530+ *
1531+ * You should have received a copy of the GNU Lesser General Public License
1532+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1533+ */
1534+
1535+// Process Information
1536+
1537+#ifndef PROC_INFO_H
1538+#define PROC_INFO_H
1539+
1540+#include <memory>
1541+
1542+#include <boost/optional.hpp>
1543+
1544+#include <QByteArray>
1545+#include <QStringList>
1546+
1547+class QString;
1548+
1549+namespace unitymir
1550+{
1551+
1552+class ProcInfo
1553+{
1554+public:
1555+ class CommandLine
1556+ {
1557+ public:
1558+ QByteArray command;
1559+
1560+ bool starts_with(const char* prefix) const;
1561+ boost::optional<QString> get_parameter(const char* name) const;
1562+ QStringList as_string_list() const;
1563+ };
1564+ virtual std::unique_ptr<CommandLine> command_line(quint64 pid);
1565+ virtual ~ProcInfo();
1566+};
1567+
1568+} // namespace unitymir
1569+
1570+#endif
1571
1572=== modified file 'src/modules/Unity/Application/processcontroller.cpp'
1573--- src/modules/Unity/Application/processcontroller.cpp 2014-01-29 09:14:01 +0000
1574+++ src/modules/Unity/Application/processcontroller.cpp 2014-02-26 21:35:04 +0000
1575@@ -31,6 +31,9 @@
1576
1577 namespace plpp = core::posix::linux::proc::process;
1578
1579+namespace unitymir
1580+{
1581+
1582 ProcessController::OomController::OomController()
1583 {
1584 }
1585@@ -126,3 +129,5 @@
1586 {
1587 return -1 != kill(-pid, SIGCONT);
1588 }
1589+
1590+} // namespace unitymir
1591
1592=== modified file 'src/modules/Unity/Application/processcontroller.h'
1593--- src/modules/Unity/Application/processcontroller.h 2014-01-29 09:14:01 +0000
1594+++ src/modules/Unity/Application/processcontroller.h 2014-02-26 21:35:04 +0000
1595@@ -22,6 +22,9 @@
1596
1597 #include <sys/types.h>
1598
1599+namespace unitymir
1600+{
1601+
1602 class ProcessController
1603 {
1604 public:
1605@@ -53,4 +56,6 @@
1606 QSharedPointer<OomController> m_oomController;
1607 };
1608
1609+} // namespace unitymir
1610+
1611 #endif // PROCESS_CONTROLLER_H
1612
1613=== modified file 'src/modules/Unity/Application/shellinputarea.cpp'
1614--- src/modules/Unity/Application/shellinputarea.cpp 2013-08-29 14:46:43 +0000
1615+++ src/modules/Unity/Application/shellinputarea.cpp 2014-02-26 21:35:04 +0000
1616@@ -23,6 +23,9 @@
1617 // Qt
1618 #include <QDebug>
1619
1620+namespace unitymir
1621+{
1622+
1623 ShellInputArea::ShellInputArea(QQuickItem *parent) : InputArea(parent)
1624 {
1625 auto surface = MirSurfaceManager::singleton()->shellSurface();
1626@@ -43,3 +46,5 @@
1627 {
1628 doSetSurface(surface);
1629 }
1630+
1631+} // namespace unitymir
1632
1633=== modified file 'src/modules/Unity/Application/shellinputarea.h'
1634--- src/modules/Unity/Application/shellinputarea.h 2013-08-29 14:46:43 +0000
1635+++ src/modules/Unity/Application/shellinputarea.h 2014-02-26 21:35:04 +0000
1636@@ -19,6 +19,8 @@
1637
1638 #include "inputarea.h"
1639
1640+namespace unitymir
1641+{
1642 class MirSurface;
1643
1644 class ShellInputArea : public InputArea
1645@@ -34,4 +36,6 @@
1646 void setShellSurface(MirSurface *surface);
1647 };
1648
1649+} // namespace unitymir
1650+
1651 #endif // SHELLINPUTAREA_H
1652
1653=== modified file 'src/modules/Unity/Application/taskcontroller.cpp'
1654--- src/modules/Unity/Application/taskcontroller.cpp 2014-01-29 09:30:45 +0000
1655+++ src/modules/Unity/Application/taskcontroller.cpp 2014-02-26 21:35:04 +0000
1656@@ -41,7 +41,8 @@
1657 #include <signal.h>
1658 #include <unistd.h>
1659
1660-
1661+namespace unitymir
1662+{
1663
1664 TaskController::TaskController(
1665 QObject* parent,
1666@@ -183,3 +184,5 @@
1667 // Is this really the signal we want to emit?
1668 Q_EMIT requestResume(id);
1669 }
1670+
1671+} // namespace unitymir
1672
1673=== modified file 'src/modules/Unity/Application/taskcontroller.h'
1674--- src/modules/Unity/Application/taskcontroller.h 2014-01-27 11:47:14 +0000
1675+++ src/modules/Unity/Application/taskcontroller.h 2014-02-26 21:35:04 +0000
1676@@ -25,6 +25,9 @@
1677 #include "applicationcontroller.h"
1678 #include "processcontroller.h"
1679
1680+namespace unitymir
1681+{
1682+
1683 class TaskController : public QObject
1684 {
1685 Q_OBJECT
1686@@ -63,4 +66,6 @@
1687 QSharedPointer<ProcessController> m_processController;
1688 };
1689
1690+} // namespace unitymir
1691+
1692 #endif // TASKCONTROLLER_H
1693
1694=== modified file 'src/modules/Unity/Application/ubuntukeyboardinfo.cpp'
1695--- src/modules/Unity/Application/ubuntukeyboardinfo.cpp 2013-10-14 18:39:55 +0000
1696+++ src/modules/Unity/Application/ubuntukeyboardinfo.cpp 2014-02-26 21:35:04 +0000
1697@@ -24,6 +24,9 @@
1698 const char gServerName[] = "ubuntu-keyboard-info";
1699 }
1700
1701+namespace unitymir
1702+{
1703+
1704 UbuntuKeyboardInfo::UbuntuKeyboardInfo(QObject *parent)
1705 : QObject(parent),
1706 m_consecutiveAttempts(0),
1707@@ -151,3 +154,5 @@
1708 }
1709
1710 }
1711+
1712+} // namespace unitymir
1713
1714=== modified file 'src/modules/Unity/Application/ubuntukeyboardinfo.h'
1715--- src/modules/Unity/Application/ubuntukeyboardinfo.h 2013-10-14 18:39:55 +0000
1716+++ src/modules/Unity/Application/ubuntukeyboardinfo.h 2014-02-26 21:35:04 +0000
1717@@ -20,6 +20,9 @@
1718 #include <QLocalSocket>
1719 #include <QTimer>
1720
1721+namespace unitymir
1722+{
1723+
1724 // Temporary solution to get information about the onscreen keyboard
1725 // This shouldn't be needed once the OSK is a properly sized surface
1726 // instead of a fullscreen one.
1727@@ -75,4 +78,6 @@
1728 QString m_socketFilePath;
1729 };
1730
1731+} // namespace unitymir
1732+
1733 #endif // UBUNTU_KEYBOARD_INFO_H
1734
1735=== modified file 'src/modules/Unity/Application/upstart/applicationcontroller.cpp'
1736--- src/modules/Unity/Application/upstart/applicationcontroller.cpp 2014-01-30 06:59:33 +0000
1737+++ src/modules/Unity/Application/upstart/applicationcontroller.cpp 2014-02-26 21:35:04 +0000
1738@@ -25,7 +25,12 @@
1739 #include "upstart-app-launch.h"
1740 }
1741
1742-struct upstart::ApplicationController::Private
1743+namespace unitymir
1744+{
1745+namespace upstart
1746+{
1747+
1748+struct ApplicationController::Private
1749 {
1750 upstart_app_launch_app_observer_t preStartCallback = nullptr;
1751 upstart_app_launch_app_observer_t startedCallback = nullptr;
1752@@ -35,32 +40,32 @@
1753 upstart_app_launch_app_failed_observer_t failureCallback = nullptr;
1754 };
1755
1756-upstart::ApplicationController::ApplicationController()
1757- : ::ApplicationController(),
1758+ApplicationController::ApplicationController()
1759+ : unitymir::ApplicationController(),
1760 impl(new Private())
1761 {
1762 impl->preStartCallback = [](const gchar * appId, gpointer userData) {
1763- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1764+ auto thiz = static_cast<ApplicationController*>(userData);
1765 Q_EMIT(thiz->applicationAboutToBeStarted(appId));
1766 };
1767
1768 impl->startedCallback = [](const gchar * appId, gpointer userData) {
1769- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1770+ auto thiz = static_cast<ApplicationController*>(userData);
1771 Q_EMIT(thiz->applicationStarted(appId));
1772 };
1773
1774 impl->stopCallback = [](const gchar * appId, gpointer userData) {
1775- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1776+ auto thiz = static_cast<ApplicationController*>(userData);
1777 Q_EMIT(thiz->applicationStopped(appId));
1778 };
1779
1780 impl->focusCallback = [](const gchar * appId, gpointer userData) {
1781- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1782+ auto thiz = static_cast<ApplicationController*>(userData);
1783 Q_EMIT(thiz->applicationFocusRequest(appId));
1784 };
1785
1786 impl->resumeCallback = [](const gchar * appId, gpointer userData) {
1787- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1788+ auto thiz = static_cast<ApplicationController*>(userData);
1789 Q_EMIT(thiz->applicationResumeRequest(appId));
1790 };
1791
1792@@ -72,7 +77,7 @@
1793 case UPSTART_APP_LAUNCH_APP_FAILED_START_FAILURE: error = ApplicationController::Error::APPLICATION_FAILED_TO_START;
1794 }
1795
1796- auto thiz = static_cast<upstart::ApplicationController*>(userData);
1797+ auto thiz = static_cast<ApplicationController*>(userData);
1798 Q_EMIT(thiz->applicationError(appId, error));
1799 };
1800
1801@@ -84,7 +89,7 @@
1802 upstart_app_launch_observer_add_app_failed(impl->failureCallback, this);
1803 }
1804
1805-upstart::ApplicationController::~ApplicationController()
1806+ApplicationController::~ApplicationController()
1807 {
1808 upstart_app_launch_observer_delete_app_starting(impl->preStartCallback, this);
1809 upstart_app_launch_observer_delete_app_started(impl->startedCallback, this);
1810@@ -94,7 +99,7 @@
1811 upstart_app_launch_observer_delete_app_failed(impl->failureCallback, this);
1812 }
1813
1814-pid_t upstart::ApplicationController::primaryPidForAppId(const QString& appId)
1815+pid_t ApplicationController::primaryPidForAppId(const QString& appId)
1816 {
1817 GPid pid = upstart_app_launch_get_primary_pid(appId.toLatin1().constData());
1818 DLOG_IF(!pid, "ApplicationController::stopApplication appId='%s' FAILED", qPrintable(appId));
1819@@ -102,19 +107,19 @@
1820 return pid;
1821 }
1822
1823-bool upstart::ApplicationController::appIdHasProcessId(pid_t pid, const QString& appId)
1824+bool ApplicationController::appIdHasProcessId(pid_t pid, const QString& appId)
1825 {
1826 return upstart_app_launch_pid_in_app_id(pid, appId.toLatin1().constData());
1827 }
1828
1829-bool upstart::ApplicationController::stopApplicationWithAppId(const QString& appId)
1830+bool ApplicationController::stopApplicationWithAppId(const QString& appId)
1831 {
1832 auto result = upstart_app_launch_stop_application(appId.toLatin1().constData());
1833- DLOG_IF(!result, "upstart::ApplicationController::stopApplicationWithAppId appId='%s' FAILED", qPrintable(appId));
1834+ DLOG_IF(!result, "ApplicationController::stopApplicationWithAppId appId='%s' FAILED", qPrintable(appId));
1835 return result;
1836 }
1837
1838-bool upstart::ApplicationController::startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments)
1839+bool ApplicationController::startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments)
1840 {
1841 // Convert arguments QStringList into format suitable for upstart-app-launch
1842 auto upstartArgs = g_new0(gchar *, arguments.length());
1843@@ -129,6 +134,9 @@
1844
1845 g_free(upstartArgs);
1846
1847- DLOG_IF(!result, "upstart::Application::Controller::startApplicationWithAppIdAndArgs appId='%s' FAILED", qPrintable(appId));
1848+ DLOG_IF(!result, "Application::Controller::startApplicationWithAppIdAndArgs appId='%s' FAILED", qPrintable(appId));
1849 return result;
1850 }
1851+
1852+} // namespace upstart
1853+} // namespace unitymir
1854
1855=== modified file 'src/modules/Unity/Application/upstart/applicationcontroller.h'
1856--- src/modules/Unity/Application/upstart/applicationcontroller.h 2014-01-27 11:29:44 +0000
1857+++ src/modules/Unity/Application/upstart/applicationcontroller.h 2014-02-26 21:35:04 +0000
1858@@ -20,9 +20,12 @@
1859
1860 #include "../applicationcontroller.h"
1861
1862+namespace unitymir
1863+{
1864 namespace upstart
1865 {
1866-class ApplicationController : public ::ApplicationController
1867+
1868+class ApplicationController : public unitymir::ApplicationController
1869 {
1870 public:
1871 ApplicationController();
1872@@ -38,6 +41,8 @@
1873 struct Private;
1874 QScopedPointer<Private> impl;
1875 };
1876-}
1877+
1878+} // namespace upstart
1879+} // namespace unitymir
1880
1881 #endif // UPSTART_APPLICATION_CONTROLLER_H
1882
1883=== modified file 'src/unity-mir/CMakeLists.txt'
1884--- src/unity-mir/CMakeLists.txt 2014-02-07 16:10:12 +0000
1885+++ src/unity-mir/CMakeLists.txt 2014-02-26 21:35:04 +0000
1886@@ -74,12 +74,10 @@
1887
1888 ${CMAKE_THREAD_LIBS_INIT}
1889
1890- ${UBUNTU_PLATFORM_API_LIBRARIES}
1891- ${MIRCOMMON_LIBRARIES}
1892- ${MIRSERVER_LIBRARIES}
1893+ ${UBUNTU_PLATFORM_API_LDFLAGS}
1894+ ${MIRSERVER_LDFLAGS}
1895 ${PROTOBUF_LIBRARIES}
1896-
1897- boost_system
1898+ ${Boost_SYSTEM_LIBRARY_RELEASE}
1899
1900 ubuntu_application_api_mirserver)
1901
1902
1903=== modified file 'tests/CMakeLists.txt'
1904--- tests/CMakeLists.txt 2014-01-27 11:29:44 +0000
1905+++ tests/CMakeLists.txt 2014-02-26 21:35:04 +0000
1906@@ -20,6 +20,7 @@
1907 ${CMAKE_SOURCE_DIR}/src/modules
1908 ${GMOCK_INCLUDE_DIR}
1909 ${GTEST_INCLUDE_DIR}
1910+ ${MIRSERVER_INCLUDE_DIRS}
1911 )
1912
1913 add_executable(
1914
1915=== modified file 'tests/application_manager_test.cpp'
1916--- tests/application_manager_test.cpp 2014-01-27 11:29:44 +0000
1917+++ tests/application_manager_test.cpp 2014-02-26 21:35:04 +0000
1918@@ -19,6 +19,7 @@
1919
1920 #include <Unity/Application/applicationcontroller.h>
1921 #include <Unity/Application/taskcontroller.h>
1922+#include <Unity/Application/proc_info.h>
1923
1924 #include <core/posix/linux/proc/process/oom_score_adj.h>
1925
1926@@ -29,43 +30,55 @@
1927 #include "mock_desktop_file_reader.h"
1928 #include "mock_oom_controller.h"
1929 #include "mock_process_controller.h"
1930-
1931-TEST(ApplicationManager, SuspendingAndResumingARunningApplicationResultsInOomScoreAdjustment)
1932+#include "mock_proc_info.h"
1933+#include "mock_session.h"
1934+#include "mock_focus_controller.h"
1935+
1936+using namespace unitymir;
1937+
1938+class ApplicationManagerTests : public ::testing::Test
1939 {
1940- using namespace ::testing;
1941-
1942- const QString appId("com.canonical.does.not.exist");
1943-
1944- NiceMock<testing::MockOomController> oomController;
1945- QSharedPointer<ProcessController::OomController> oomControllerPtr(
1946+public:
1947+ ApplicationManagerTests()
1948+ : processController{
1949+ QSharedPointer<ProcessController::OomController> (
1950 &oomController,
1951- [](ProcessController::OomController*){});
1952-
1953- NiceMock<testing::MockProcessController> processController(oomControllerPtr);
1954- QSharedPointer<ProcessController> processControllerPtr(
1955- &processController,
1956- [](ProcessController*){});
1957-
1958- NiceMock<testing::MockApplicationController> appController;
1959- QSharedPointer<ApplicationController> appControllerPtr(
1960- &appController,
1961- [](ApplicationController*){});
1962-
1963- QSharedPointer<TaskController> taskController(
1964+ [](ProcessController::OomController*){})
1965+ },
1966+ applicationManager{
1967+ QSharedPointer<TaskController>{
1968 new TaskController(
1969 nullptr,
1970- appControllerPtr,
1971- processControllerPtr
1972- ));
1973-
1974- NiceMock<MockDesktopFileReaderFactory> desktopFileReaderFactory;
1975- QSharedPointer<DesktopFileReader::Factory> desktopFileReaderFactoryPtr(
1976+ QSharedPointer<ApplicationController>(
1977+ &appController,
1978+ [](ApplicationController*){}),
1979+ QSharedPointer<ProcessController>(
1980+ &processController,
1981+ [](ProcessController*){})
1982+ )},
1983+ QSharedPointer<DesktopFileReader::Factory>(
1984 &desktopFileReaderFactory,
1985- [](DesktopFileReader::Factory*){});
1986-
1987- ApplicationManager applicationManager(
1988- taskController,
1989- desktopFileReaderFactoryPtr);
1990+ [](DesktopFileReader::Factory*){}),
1991+ QSharedPointer<ProcInfo>(&procInfo,[](ProcInfo *){}),
1992+ std::shared_ptr<mir::shell::FocusController>(&focusController, [](void*){}),
1993+ QSize(400,400)
1994+ }
1995+ {
1996+ }
1997+ testing::NiceMock<testing::MockOomController> oomController;
1998+ testing::NiceMock<testing::MockProcessController> processController;
1999+ testing::NiceMock<testing::MockApplicationController> appController;
2000+ testing::NiceMock<testing::MockProcInfo> procInfo;
2001+ testing::NiceMock<testing::MockDesktopFileReaderFactory> desktopFileReaderFactory;
2002+ testing::NiceMock<testing::MockFocusController> focusController;
2003+ ApplicationManager applicationManager;
2004+};
2005+
2006+TEST_F(ApplicationManagerTests, SuspendingAndResumingARunningApplicationResultsInOomScoreAdjustment)
2007+{
2008+ using namespace ::testing;
2009+
2010+ const QString appId("com.canonical.does.not.exist");
2011
2012 EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(_, _)).Times(1);
2013
2014@@ -86,43 +99,12 @@
2015 }
2016
2017 // Currently disabled as we need to make sure that we have a corresponding mir session, too.
2018-TEST(ApplicationManager, DISABLED_FocusingRunningApplicationResultsInOomScoreAdjustment)
2019+TEST_F(ApplicationManagerTests, DISABLED_FocusingRunningApplicationResultsInOomScoreAdjustment)
2020 {
2021 using namespace ::testing;
2022
2023 const QString appId("com.canonical.does.not.exist");
2024
2025- NiceMock<testing::MockOomController> oomController;
2026- QSharedPointer<ProcessController::OomController> oomControllerPtr(
2027- &oomController,
2028- [](ProcessController::OomController*){});
2029-
2030- NiceMock<testing::MockProcessController> processController(oomControllerPtr);
2031- QSharedPointer<ProcessController> processControllerPtr(
2032- &processController,
2033- [](ProcessController*){});
2034-
2035- NiceMock<testing::MockApplicationController> appController;
2036- QSharedPointer<ApplicationController> appControllerPtr(
2037- &appController,
2038- [](ApplicationController*){});
2039-
2040- QSharedPointer<TaskController> taskController(
2041- new TaskController(
2042- nullptr,
2043- appControllerPtr,
2044- processControllerPtr
2045- ));
2046-
2047- NiceMock<MockDesktopFileReaderFactory> desktopFileReaderFactory;
2048- QSharedPointer<DesktopFileReader::Factory> desktopFileReaderFactoryPtr(
2049- &desktopFileReaderFactory,
2050- [](DesktopFileReader::Factory*){});
2051-
2052- ApplicationManager applicationManager(
2053- taskController,
2054- desktopFileReaderFactoryPtr);
2055-
2056 QSet<QString> appIds;
2057
2058 for (unsigned int i = 0; i < 50; i++)
2059@@ -135,6 +117,9 @@
2060 ApplicationManager::NoFlag,
2061 QStringList());
2062
2063+ std::shared_ptr<mir::shell::Session> mirSession = std::make_shared<MockSession>(appIdFormat.toStdString(), i);
2064+ applicationManager.onSessionStarting( mirSession );
2065+
2066 EXPECT_NE(nullptr, application);
2067
2068 appIds.insert(appId);
2069@@ -149,3 +134,92 @@
2070 applicationManager.focusApplication(appId);
2071 }
2072 }
2073+
2074+
2075+TEST_F(ApplicationManagerTests,bug_case_1240400_second_dialer_app_fails_to_authorize_and_gets_mixed_up_with_first_one)
2076+{
2077+ using namespace ::testing;
2078+ std::shared_ptr<mir::shell::Surface> aSurface(nullptr);
2079+ quint64 firstProcId = 5921;
2080+ quint64 secondProcId = 5922;
2081+ const char dialer_app_id[] = "dialer-app";
2082+ QByteArray cmdLine( "/usr/bin/dialer-app --desktop_file_hint=dialer-app");
2083+ QByteArray secondcmdLine( "/usr/bin/dialer-app");
2084+
2085+ EXPECT_CALL(procInfo,command_line_(firstProcId))
2086+ .Times(1)
2087+ .WillOnce(Return(cmdLine));
2088+ EXPECT_CALL(procInfo,command_line_(secondProcId))
2089+ .Times(1)
2090+ .WillOnce(Return(secondcmdLine));
2091+
2092+ bool authed = true;
2093+
2094+ std::shared_ptr<mir::shell::Session> mirSession = std::make_shared<MockSession>(dialer_app_id, firstProcId);
2095+ applicationManager.authorizeSession(firstProcId, authed);
2096+ EXPECT_EQ(true, authed);
2097+ applicationManager.onSessionStarting(mirSession);
2098+ applicationManager.onSessionCreatedSurface(mirSession.get(),aSurface);
2099+ Application * app = applicationManager.findApplication(dialer_app_id);
2100+ EXPECT_NE(nullptr,app);
2101+
2102+ // now a second session without desktop file is launched:
2103+ applicationManager.authorizeSession(secondProcId, authed);
2104+ applicationManager.onProcessStartReportReceived(dialer_app_id, true);
2105+
2106+ EXPECT_EQ(false,authed);
2107+ EXPECT_EQ(app,applicationManager.findApplication(dialer_app_id));
2108+ EXPECT_EQ(QString(dialer_app_id),applicationManager.focusedApplicationId());
2109+}
2110+
2111+TEST_F(ApplicationManagerTests,application_dies_while_starting)
2112+{
2113+ using namespace ::testing;
2114+ quint64 procId = 5921;
2115+ const char app_id[] = "my-app";
2116+ QByteArray cmdLine( "/usr/bin/my-app --desktop_file_hint=my-app");
2117+
2118+ EXPECT_CALL(procInfo,command_line_(procId))
2119+ .Times(1)
2120+ .WillOnce(Return(cmdLine));
2121+
2122+ bool authed = true;
2123+
2124+ std::shared_ptr<mir::shell::Session> mirSession = std::make_shared<MockSession>(app_id, procId);
2125+ applicationManager.authorizeSession(procId, authed);
2126+ applicationManager.onSessionStarting(mirSession);
2127+ Application * beforeFailure = applicationManager.findApplication(app_id);
2128+ applicationManager.onProcessStartReportReceived(app_id,true);
2129+ Application * afterFailure = applicationManager.findApplication(app_id);
2130+
2131+ EXPECT_EQ(true, authed);
2132+ EXPECT_NE(nullptr, beforeFailure);
2133+ EXPECT_EQ(nullptr, afterFailure);
2134+}
2135+
2136+TEST_F(ApplicationManagerTests,application_start_failure_after_starting)
2137+{
2138+ using namespace ::testing;
2139+ quint64 procId = 5921;
2140+ std::shared_ptr<mir::shell::Surface> aSurface(nullptr);
2141+ const char app_id[] = "my-app";
2142+ QByteArray cmdLine( "/usr/bin/my-app --desktop_file_hint=my-app");
2143+
2144+ EXPECT_CALL(procInfo,command_line_(procId))
2145+ .Times(1)
2146+ .WillOnce(Return(cmdLine));
2147+
2148+ bool authed = true;
2149+
2150+ std::shared_ptr<mir::shell::Session> mirSession = std::make_shared<MockSession>(app_id, procId);
2151+ applicationManager.authorizeSession(procId, authed);
2152+ applicationManager.onSessionStarting(mirSession);
2153+ Application * beforeFailure = applicationManager.findApplication(app_id);
2154+ applicationManager.onSessionCreatedSurface(mirSession.get(), aSurface);
2155+ applicationManager.onProcessStartReportReceived(app_id, true);
2156+ Application * afterFailure = applicationManager.findApplication(app_id);
2157+
2158+ EXPECT_EQ(true, authed);
2159+ EXPECT_NE(nullptr, beforeFailure);
2160+ EXPECT_EQ(beforeFailure, afterFailure);
2161+}
2162
2163=== modified file 'tests/auto/modules/Unity/Application/CMakeLists.txt'
2164--- tests/auto/modules/Unity/Application/CMakeLists.txt 2014-01-27 11:29:44 +0000
2165+++ tests/auto/modules/Unity/Application/CMakeLists.txt 2014-02-26 21:35:04 +0000
2166@@ -19,8 +19,8 @@
2167 unity-mir
2168 unityapplicationplugin
2169
2170- ${MIRSERVER_LIBRARIES}
2171- ${UPSTART_APP_LAUNCH_LIBRARIES})
2172+ ${MIRSERVER_LDFLAGS}
2173+ ${UPSTART_APP_LAUNCH_LDFLAGS})
2174
2175 install(
2176 TARGETS unity-mir-test-app
2177
2178=== modified file 'tests/auto/modules/Unity/Application/main.cpp'
2179--- tests/auto/modules/Unity/Application/main.cpp 2014-01-27 11:29:44 +0000
2180+++ tests/auto/modules/Unity/Application/main.cpp 2014-02-26 21:35:04 +0000
2181@@ -18,6 +18,7 @@
2182
2183 #include "application_manager.h"
2184 #include "processcontroller.h"
2185+#include "proc_info.h"
2186 #include "taskcontroller.h"
2187 #include "upstart/applicationcontroller.h"
2188
2189@@ -26,6 +27,8 @@
2190
2191 #include <signal.h>
2192
2193+using namespace unitymir;
2194+
2195 static QString pidCommandLine(qint64 pid)
2196 {
2197 QFile cmdline(QString("/proc/%1/cmdline").arg(pid));
2198@@ -44,12 +47,10 @@
2199
2200 void ApplicationManagerTests::testStartStop()
2201 {
2202- QSharedPointer<upstart::ApplicationController> appController(new upstart::ApplicationController());
2203- QSharedPointer<TaskController> taskController(new TaskController(nullptr, appController));
2204- QSharedPointer<DesktopFileReader::Factory> fileReaderFactory(new DesktopFileReader::Factory());
2205+ ApplicationManager::Factory appFactory;
2206+ QSharedPointer<ApplicationManager> manager{appFactory.create()};
2207
2208- ApplicationManager manager(taskController, fileReaderFactory);
2209- Application *app = manager.startApplication("unity-mir-test-helper-app", QStringList());
2210+ Application *app = manager->startApplication("unity-mir-test-helper-app", QStringList());
2211 QVERIFY(app);
2212 QCOMPARE(app->desktopFile(), QString("/usr/share/applications/unity-mir-test-helper-app.desktop"));
2213 QCOMPARE(app->name(), QString("My Fake App"));
2214@@ -61,7 +62,7 @@
2215 QString simplifiedCommand = pidCommandLine(app->pid());
2216 QCOMPARE(simplifiedCommand, QString("unity-mir-test-helper-app"));
2217
2218- manager.stopApplication(app->appId());
2219+ manager->stopApplication(app->appId());
2220
2221 QDir d;
2222 QTRY_VERIFY(!d.exists(QString("/proc/%1").arg(app->pid())));
2223
2224=== modified file 'tests/mock_application_controller.h'
2225--- tests/mock_application_controller.h 2014-01-27 11:29:44 +0000
2226+++ tests/mock_application_controller.h 2014-02-26 21:35:04 +0000
2227@@ -26,7 +26,7 @@
2228
2229 namespace testing
2230 {
2231-struct MockApplicationController : public ApplicationController
2232+struct MockApplicationController : public unitymir::ApplicationController
2233 {
2234 MOCK_METHOD1(primaryPidForAppId, pid_t(const QString& appId));
2235 MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&));
2236
2237=== modified file 'tests/mock_desktop_file_reader.h'
2238--- tests/mock_desktop_file_reader.h 2014-01-23 11:30:52 +0000
2239+++ tests/mock_desktop_file_reader.h 2014-02-26 21:35:04 +0000
2240@@ -24,10 +24,10 @@
2241
2242 namespace testing
2243 {
2244-struct MockDesktopFileReader : public DesktopFileReader
2245+struct MockDesktopFileReader : public unitymir::DesktopFileReader
2246 {
2247 MockDesktopFileReader(const QString& appId)
2248- : DesktopFileReader(appId)
2249+ : unitymir::DesktopFileReader(appId)
2250 {
2251 using namespace ::testing;
2252
2253@@ -122,7 +122,7 @@
2254 }
2255 };
2256
2257-struct MockDesktopFileReaderFactory : public DesktopFileReader::Factory
2258+struct MockDesktopFileReaderFactory : public unitymir::DesktopFileReader::Factory
2259 {
2260 MockDesktopFileReaderFactory()
2261 {
2262@@ -139,7 +139,7 @@
2263 &MockDesktopFileReaderFactory::doCreateInstanceForDesktopFile));
2264 }
2265
2266- virtual DesktopFileReader* doCreateInstanceForAppId(const QString& appId)
2267+ virtual unitymir::DesktopFileReader* doCreateInstanceForAppId(const QString& appId)
2268 {
2269 using namespace ::testing;
2270 auto instance = new NiceMock<MockDesktopFileReader>(appId);
2271@@ -148,7 +148,7 @@
2272 return instance;
2273 }
2274
2275- virtual DesktopFileReader* doCreateInstanceForDesktopFile(const QFileInfo& fi)
2276+ virtual unitymir::DesktopFileReader* doCreateInstanceForDesktopFile(const QFileInfo& fi)
2277 {
2278 using namespace ::testing;
2279 auto instance = new NiceMock<MockDesktopFileReader>(fi);
2280@@ -157,8 +157,8 @@
2281 return instance;
2282 }
2283
2284- MOCK_METHOD1(createInstanceForAppId, DesktopFileReader*(const QString&));
2285- MOCK_METHOD1(createInstanceForDesktopFile, DesktopFileReader*(const QFileInfo&));
2286+ MOCK_METHOD1(createInstanceForAppId, unitymir::DesktopFileReader*(const QString&));
2287+ MOCK_METHOD1(createInstanceForDesktopFile, unitymir::DesktopFileReader*(const QFileInfo&));
2288 };
2289 }
2290
2291
2292=== added file 'tests/mock_focus_controller.h'
2293--- tests/mock_focus_controller.h 1970-01-01 00:00:00 +0000
2294+++ tests/mock_focus_controller.h 2014-02-26 21:35:04 +0000
2295@@ -0,0 +1,37 @@
2296+/*
2297+ * Copyright (C) 2014 Canonical, Ltd.
2298+ *
2299+ * This program is free software: you can redistribute it and/or modify it under
2300+ * the terms of the GNU Lesser General Public License version 3, as published by
2301+ * the Free Software Foundation.
2302+ *
2303+ * This program is distributed in the hope that it will be useful, but WITHOUT
2304+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2305+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2306+ * Lesser General Public License for more details.
2307+ *
2308+ * You should have received a copy of the GNU Lesser General Public License
2309+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2310+ *
2311+ */
2312+
2313+#ifndef MOCK_MIR_SHELL_FOCUS_CONTROLLER_H
2314+#define MOCK_MIR_SHELL_FOCUS_CONTROLLER_H
2315+
2316+#include <mir/shell/focus_controller.h>
2317+#include <gmock/gmock.h>
2318+
2319+#include <string>
2320+
2321+namespace testing
2322+{
2323+class MockFocusController : public mir::shell::FocusController
2324+{
2325+public:
2326+ MOCK_METHOD0(focus_next, void());
2327+ MOCK_CONST_METHOD0(focussed_application, std::weak_ptr<mir::shell::Session>());
2328+ MOCK_METHOD1(set_focus_to, void(std::shared_ptr<mir::shell::Session>const&));
2329+};
2330+}
2331+
2332+#endif // MOCK_MIR_SHELL_FOCUS_CONTROLLER_H_
2333
2334=== modified file 'tests/mock_oom_controller.h'
2335--- tests/mock_oom_controller.h 2014-01-27 11:29:44 +0000
2336+++ tests/mock_oom_controller.h 2014-02-26 21:35:04 +0000
2337@@ -23,7 +23,7 @@
2338
2339 namespace testing
2340 {
2341-struct MockOomController : public ProcessController::OomController
2342+struct MockOomController : public unitymir::ProcessController::OomController
2343 {
2344 MOCK_METHOD1(ensureProcessLikelyToBeKilled, void(pid_t));
2345 MOCK_METHOD1(ensureProcessUnlikelyToBeKilled, void(pid_t));
2346
2347=== added file 'tests/mock_proc_info.h'
2348--- tests/mock_proc_info.h 1970-01-01 00:00:00 +0000
2349+++ tests/mock_proc_info.h 2014-02-26 21:35:04 +0000
2350@@ -0,0 +1,37 @@
2351+/*
2352+ * Copyright (C) 2014 Canonical, Ltd.
2353+ *
2354+ * This program is free software: you can redistribute it and/or modify it under
2355+ * the terms of the GNU Lesser General Public License version 3, as published by
2356+ * the Free Software Foundation.
2357+ *
2358+ * This program is distributed in the hope that it will be useful, but WITHOUT
2359+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2360+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2361+ * Lesser General Public License for more details.
2362+ *
2363+ * You should have received a copy of the GNU Lesser General Public License
2364+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2365+ *
2366+ */
2367+
2368+#ifndef MOCK_PROC_INFO_H
2369+#define MOCK_PROC_INFO_H
2370+
2371+#include <Unity/Application/proc_info.h>
2372+
2373+#include <gmock/gmock.h>
2374+
2375+namespace testing
2376+{
2377+struct MockProcInfo : public unitymir::ProcInfo
2378+{
2379+ MOCK_METHOD1(command_line_, QByteArray(quint64));
2380+ std::unique_ptr<CommandLine> command_line(quint64 pid)
2381+ {
2382+ return std::unique_ptr<CommandLine>(new CommandLine{command_line_(pid)});
2383+ }
2384+};
2385+}
2386+
2387+#endif // MOCK_OOM_CONTROLLER_H
2388
2389=== modified file 'tests/mock_process_controller.h'
2390--- tests/mock_process_controller.h 2014-01-27 11:29:44 +0000
2391+++ tests/mock_process_controller.h 2014-02-26 21:35:04 +0000
2392@@ -23,14 +23,14 @@
2393
2394 namespace testing
2395 {
2396-struct MockProcessController : public ProcessController
2397+struct MockProcessController : public unitymir::ProcessController
2398 {
2399- MockProcessController(const QSharedPointer<ProcessController::OomController>& oomController)
2400+ MockProcessController(const QSharedPointer<unitymir::ProcessController::OomController>& oomController)
2401 : m_oomController(oomController)
2402 {
2403 }
2404
2405- const QSharedPointer<OomController>& oomController() const
2406+ const QSharedPointer<unitymir::ProcessController::OomController>& oomController() const
2407 {
2408 return m_oomController;
2409 }
2410@@ -38,7 +38,7 @@
2411 MOCK_CONST_METHOD1(sigStopProcessGroupForPid, bool(pid_t));
2412 MOCK_CONST_METHOD1(sigContinueProcessGroupForPid, bool(pid_t));
2413
2414- QSharedPointer<ProcessController::OomController> m_oomController;
2415+ QSharedPointer<unitymir::ProcessController::OomController> m_oomController;
2416 };
2417 }
2418
2419
2420=== added file 'tests/mock_session.h'
2421--- tests/mock_session.h 1970-01-01 00:00:00 +0000
2422+++ tests/mock_session.h 2014-02-26 21:35:04 +0000
2423@@ -0,0 +1,69 @@
2424+/*
2425+ * Copyright (C) 2014 Canonical, Ltd.
2426+ *
2427+ * This program is free software: you can redistribute it and/or modify it under
2428+ * the terms of the GNU Lesser General Public License version 3, as published by
2429+ * the Free Software Foundation.
2430+ *
2431+ * This program is distributed in the hope that it will be useful, but WITHOUT
2432+ * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
2433+ * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2434+ * Lesser General Public License for more details.
2435+ *
2436+ * You should have received a copy of the GNU Lesser General Public License
2437+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
2438+ *
2439+ */
2440+
2441+#ifndef MOCK_MIR_SHELL_SESSION_H
2442+#define MOCK_MIR_SHELL_SESSION_H
2443+
2444+#include <mir/shell/session.h>
2445+#include <mir/graphics/display_configuration.h>
2446+#include <mir/shell/surface_creation_parameters.h>
2447+#include <gmock/gmock.h>
2448+
2449+#include <string>
2450+
2451+namespace testing
2452+{
2453+struct MockSession : public mir::shell::Session
2454+{
2455+ MockSession() {}
2456+ MockSession(std::string const& sessionName, pid_t processId)
2457+ : m_sessionName(sessionName), m_sessionId(processId)
2458+ {}
2459+
2460+ std::string name() const override
2461+ {
2462+ return m_sessionName;
2463+ }
2464+
2465+ pid_t process_id() const override
2466+ {
2467+ return m_sessionId;
2468+ }
2469+
2470+ typedef mir::frontend::SurfaceId SurfaceId;
2471+
2472+ MOCK_METHOD0(force_requests_to_complete, void());
2473+
2474+ MOCK_CONST_METHOD0(default_surface, std::shared_ptr<mir::shell::Surface>());
2475+ MOCK_CONST_METHOD1(get_surface, std::shared_ptr<mir::frontend::Surface>(SurfaceId));
2476+
2477+ MOCK_METHOD1(take_snapshot, void(mir::shell::SnapshotCallback const&));
2478+ MOCK_METHOD1(set_lifecycle_state, void(MirLifecycleState));
2479+ MOCK_METHOD1(create_surface, SurfaceId(mir::shell::SurfaceCreationParameters const&));
2480+ MOCK_METHOD1(destroy_surface, void (SurfaceId));
2481+
2482+ MOCK_METHOD0(hide, void());
2483+ MOCK_METHOD0(show, void());
2484+ MOCK_METHOD1(send_display_config, void(mir::graphics::DisplayConfiguration const&));
2485+ MOCK_METHOD3(configure_surface, int(SurfaceId, MirSurfaceAttrib, int));
2486+private:
2487+ std::string m_sessionName;
2488+ pid_t m_sessionId;
2489+};
2490+}
2491+
2492+#endif // MOCK_MIR_SHELL_SESSION_H
2493
2494=== modified file 'tests/taskcontroller_test.cpp'
2495--- tests/taskcontroller_test.cpp 2014-01-27 08:01:40 +0000
2496+++ tests/taskcontroller_test.cpp 2014-02-26 21:35:04 +0000
2497@@ -28,6 +28,7 @@
2498
2499 namespace
2500 {
2501+using namespace unitymir;
2502
2503 struct TriggerableApplicationController : public ApplicationController
2504 {

Subscribers

People subscribed via source and target branches