Merge lp:~thomas-voss/unity-mir/refactor-oom-score-adj-to-rely-on-process-cpp into lp:unity-mir
- refactor-oom-score-adj-to-rely-on-process-cpp
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~thomas-voss/unity-mir/refactor-oom-score-adj-to-rely-on-process-cpp |
Merge into: | lp:unity-mir |
Diff against target: |
1737 lines (+989/-488) 26 files modified
CMakeLists.txt (+64/-0) data/CMakeLists.txt (+7/-0) data/unity-mir.pc.in (+10/-0) debian/control (+3/-0) debian/rules (+0/-3) src/CMakeLists.txt (+2/-0) src/modules/CMakeLists.txt (+1/-0) src/modules/Unity/Application/Application.pro (+0/-58) src/modules/Unity/Application/CMakeLists.txt (+97/-0) src/modules/Unity/Application/application.cpp (+1/-0) src/modules/Unity/Application/application.h (+0/-3) src/modules/Unity/Application/application_controller.h (+61/-0) src/modules/Unity/Application/dbuswindowstack.h (+2/-2) src/modules/Unity/Application/taskcontroller.cpp (+178/-334) src/modules/Unity/Application/taskcontroller.h (+31/-10) src/modules/Unity/Application/upstart/application_controller.cpp (+154/-0) src/modules/Unity/Application/upstart/application_controller.h (+44/-0) src/modules/Unity/CMakeLists.txt (+1/-0) src/modules/modules.pro (+0/-3) src/src.pro (+0/-6) src/unity-mir/CMakeLists.txt (+72/-0) src/unity-mir/logging.h (+2/-0) src/unity-mir/unity-mir.pro (+0/-67) tests/CMakeLists.txt (+48/-0) tests/taskcontroller_test.cpp (+211/-0) unity-mir.pro (+0/-2) |
To merge this branch: | bzr merge lp:~thomas-voss/unity-mir/refactor-oom-score-adj-to-rely-on-process-cpp |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Albert Astals Cid (community) | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Michał Sawicz | Needs Fixing | ||
Review via email: mp+194797@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-01-10.
Commit message
Refactor Oom(Score)Adj to rely on process-cpp helper library.
Description of the change
Refactor Oom(Score)Adj to rely on process-cpp helper library.
- 144. By Thomas Voß
-
Add build-dependency on libprocess-cpp.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:144
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 145. By Thomas Voß
-
Refactor to core namespace.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:145
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 146. By Thomas Voß
-
[ Gerry Boland ]
* Unity.Application is not a shared library, but a plugin. (LP:
#1256014)
* Implement preStart callback added to upstart-app-launch- 2. (LP:
#1243665)
[ Ubuntu daily release ]
* Automatic snapshot from revision 157
[ Gerry Boland ]
* Install ServerStatusListener to be notified of mir server start, pause
and resume. Use start notification to send SIGSTOP signal to upstart,
so it knows mir is ready for other clients.
* Bump version number
* InputArea: don't use lambda function as slot, can cause crash on
shutdown Using lambda function as slot can introduce crash as the
slot's object deletion is not registered unlike with traditional
signal/slot connections. As a result, on signal emission, the lambda
can be called on a deleted object. (LP: #1253685)
* Misc fixes for Mir 0.1.2 support. (LP: #1254986)
[ Alan Griffiths ]
* ApplicationSession is a Mir implementation class that shouldn't be
used by unity-mir, use shell::session instead.
[ Kevin Gunn ]
* mir server abi and api broke, updating dependency to deb 0.1.1.
* update mir deb build dep to 0.1.2
[ Victor Thompson ]
* Fix mir to not suspend the music-app, or any other app granted a
lifecycle exception, when switching between apps. (LP: #1241185,
#1241045)
[ Daniel van Vugt ]
* Force the screen to redraw after turning the display back on (LP:
#1255045). Also stop the compositor when the screen is off.
Otherwise it will spin in the background, eating battery. (LP:
#1255045)
[ Ubuntu daily release ]
* Automatic snapshot from revision 154
* Cherry-pick upstream patch to avoid Unity8 crashing on stop
(LP: #1253685)
[ Gerry Boland ]
* On MirSurface destruction, any InputAreas on that surface will be
notified and remove their links to that surface. Fixes crash
bug:1243444. (LP: #1243444)
[ Alan Griffiths ]
* Remove dependency on mir::shell::SessionManager .
* Remove dependency on mir::surfaces::SurfaceControl ler.
* Remove dependency on msh::OrganisingSurfaceFactory.
* Avoid relying on an explicit Mir typename that changes in a
refactoring coming soon.
* Do all the hacky surface creation customization in
SurfaceFactory::create_ surface( ) - and don't mention SurfaceBuilder
at all. (That will allow Mir to get rid of that interface.).
[ Albert Astals ]
* Don't include the QtQml megaheader Include the one we really need.
[ Ubuntu daily release ]
* Automatic snapshot from revision 144
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:146
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:146
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : | # |
There's an indentation issue in debian/control (please use spaces).
Why do we fall back to the deprecated method? Are there any cases where we expect process cpp to raise that is an "expected failure"?
"extremal" is not a word?
Should we maybe store shellScore instead of reading it off of the shell process every time?
This would be a good time to auto-test this, would it not?
- 147. By Thomas Voß
-
Fix whitespace.
- 148. By Thomas Voß
-
Replace extremal with boundary.
Thomas Voß (thomas-voss) wrote : | # |
> There's an indentation issue in debian/control (please use spaces).
>
Fixed.
> Why do we fall back to the deprecated method? Are there any cases where we
> expect process cpp to raise that is an "expected failure"?
>
While the method is deprecated it is still present and common in the Android world.
Process-cpp just raises an exception if it is unable to adjust the score, i.e., unable to write to the respective file. I think the fallback renders the overall implementation more robust in real-world scenarios.
> "extremal" is not a word?
>
Fixed.
> Should we maybe store shellScore instead of reading it off of the shell
> process every time?
>
We need to read it everytime as the score might have been adjusted by the kernel in the meantime.
> This would be a good time to auto-test this, would it not?
True, will take care of that task.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:148
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 149. By Thomas Voß
-
Merge cmake setup.
Add testing setup.[ Daniel d'Andrada ]
* Fix OSKController.enabled property OSKController. enabled was always
True as we were missing the check for undefined. Also s/variant/var
as the "variant" QML type is deprecated. (LP: #1248795)
[ kevin gunn ]
* bump debian version dependency for mir to 0.1.3 to force rebuild
[ Ubuntu daily release ]
* Automatic snapshot from revision 160 - 150. By Thomas Voß
-
Add build-dependency on Google Mock.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:150
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
there's a src/modules/
- 151. By Thomas Voß
-
Remove leftover pro file.
- 152. By Thomas Voß
-
Merge pre-requisite branch again.
Remove stale .pro.THIS file.
Thomas Voß (thomas-voss) wrote : | # |
> there's a src/modules/
> probably has to go away.
Good catch, fixed.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:152
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 153. By Thomas Voß
-
Remove obsolete copyright notice in build system file.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:153
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 154. By Thomas Voß
-
Add missing call for finding process-cpp.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:154
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : | # |
Which this i am getting libunity-
I don't think this change is intentional, no?
- 155. By Thomas Voß
-
Merge prerequisite branch.
Thomas Voß (thomas-voss) wrote : | # |
> Which this i am getting libunity-
> get libunity-
>
> I don't think this change is intentional, no?
Nope, it is not. Also fixed in prerequisite branch.
- 156. By Thomas Voß
-
Add a first test case for application manager.
Split up mocks into their own header file. - 157. By Thomas Voß
-
Add test for focus setting behavior (disabled right now).
- 158. By Thomas Voß
-
Remove dead code.
- 159. By Thomas Voß
-
First wave of changes accounting for review.
- 160. By Thomas Voß
-
Refactor signal-slot connections in TaskController to type-safe variant.
- 161. By Thomas Voß
-
Refactor process operations into class ProcessController and an inner class ProcessControll
er::OomControll er. - 162. By Thomas Voß
-
[ Gerry Boland ]
* [cmake] set default build type to RelWithDebInfo, add workaround to
set QT_NO_DEBUG with that option.
[ Albert Astals ]
* Tests for ApplicationManager start/stopApplication At the moment
they just work on the device (well they may as well work on Mir on
the desktop but have not tried). You need to install the libunity-
mir-tests package and then run unity-mir-test-app.
[ Ricardo Mendoza ]
* Correctly respect lifecycle exceptions in the new sidestage model.
(LP: #1269414)
[ Ubuntu daily release ]
* Automatic snapshot from revision 168
[ thomas-voss ]
* Switch to cmake.
[ Albert Astals ]
* Recover the Requires line in the .pc file.
[ Ricardo Mendoza ]
* Re-enable Sidestage as it was under SF.
[ Ubuntu daily release ]
* Automatic snapshot from revision 164 - 163. By Thomas Voß
-
Adjust slot signatures.
- 164. By Thomas Voß
-
Adjust copyright year.
- 165. By Thomas Voß
-
Replace auto variables with pid_t where appropriate.
- 166. By Thomas Voß
-
Switch to Q_EMIT for passing on signals originating from upstart app launch.
- 167. By Thomas Voß
- 168. By Thomas Voß
-
[ Kevin Gunn ]
* bump debian version for mir to 0.1.4
[ Łukasz 'sil2100' Zemczak ]
* Fix the multi-arch stanza in the new -tests package. - 169. By Thomas Voß
-
Initialize ApplicationMana
ger::m_ focusedApplicat ion to nullptr in ctor.
Unmerged revisions
Preview Diff
1 | === added file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 1970-01-01 00:00:00 +0000 |
3 | +++ CMakeLists.txt 2014-01-10 09:14:26 +0000 |
4 | @@ -0,0 +1,64 @@ |
5 | +cmake_minimum_required(VERSION 2.8) |
6 | + |
7 | +project(Unity-Mir) |
8 | + |
9 | +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
10 | + |
11 | +# Find includes in corresponding build directories |
12 | +set(CMAKE_INCLUDE_CURRENT_DIR ON) |
13 | +# Instruct CMake to run moc automatically when needed. |
14 | +set(CMAKE_AUTOMOC ON) |
15 | + |
16 | +include(GNUInstallDirs) |
17 | + |
18 | +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -pedantic -Wextra") |
19 | +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -fno-strict-aliasing -pedantic -Wextra") |
20 | +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") |
21 | + |
22 | +option(Werror "Treat warnings as errors" ON) |
23 | +if (Werror) |
24 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wno-error=format") |
25 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-error=format") |
26 | +endif() |
27 | + |
28 | +string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lower) |
29 | + |
30 | +##################################################################### |
31 | +# Enable code coverage calculation with gcov/gcovr/lcov |
32 | +# Usage: |
33 | +# * Switch build type to coverage (use ccmake or cmake-gui) |
34 | +# * Invoke make, make test, make coverage |
35 | +# * Find html report in subdir coveragereport |
36 | +# * Find xml report feasible for jenkins in coverage.xml |
37 | +##################################################################### |
38 | +IF(cmake_build_type_lower MATCHES coverage) |
39 | + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage -fprofile-arcs" ) |
40 | + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage -fprofile-arcs" ) |
41 | + SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -ftest-coverage -fprofile-arcs" ) |
42 | + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -ftest-coverage -fprofile-arcs" ) |
43 | +ENDIF(cmake_build_type_lower MATCHES coverage) |
44 | + |
45 | +include(CTest) |
46 | + |
47 | +set(UNITY_MIR_VERSION_MAJOR 1) |
48 | +set(UNITY_MIR_VERSION_MINOR 0) |
49 | +set(UNITY_MIR_VERSION_PATCH 0) |
50 | + |
51 | +find_package(PkgConfig REQUIRED) |
52 | +find_package(Threads REQUIRED) |
53 | + |
54 | +find_package(Qt5Core REQUIRED) |
55 | +find_package(Qt5Quick REQUIRED) |
56 | +find_package(Qt5DBus REQUIRED) |
57 | + |
58 | +pkg_check_modules(MIRSERVER mirserver REQUIRED) |
59 | +pkg_check_modules(MIRCOMMON mircommon REQUIRED) |
60 | +pkg_check_modules(UBUNTU_PLATFORM_API ubuntu-platform-api REQUIRED) |
61 | + |
62 | +add_subdirectory(src) |
63 | +add_subdirectory(data) |
64 | + |
65 | +add_subdirectory(tests) |
66 | + |
67 | +# TODO(tvoss): Enable coverage reporting once we have tests in place. |
68 | +#enable_coverage_report(posix_process_test linux_process_test) |
69 | |
70 | === added directory 'data' |
71 | === added file 'data/CMakeLists.txt' |
72 | --- data/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
73 | +++ data/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
74 | @@ -0,0 +1,7 @@ |
75 | +configure_file( |
76 | + ${CMAKE_CURRENT_SOURCE_DIR}/unity-mir.pc.in |
77 | + ${CMAKE_CURRENT_BINARY_DIR}/unity-mir.pc @ONLY) |
78 | + |
79 | +install( |
80 | + FILES ${CMAKE_CURRENT_BINARY_DIR}/unity-mir.pc |
81 | + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) |
82 | |
83 | === added file 'data/unity-mir.pc.in' |
84 | --- data/unity-mir.pc.in 1970-01-01 00:00:00 +0000 |
85 | +++ data/unity-mir.pc.in 2014-01-10 09:14:26 +0000 |
86 | @@ -0,0 +1,10 @@ |
87 | +prefix=@CMAKE_INSTALL_PREFIX@ |
88 | +exec_prefix=${prefix} |
89 | +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ |
90 | +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ |
91 | + |
92 | +Name: @CMAKE_PROJECT_NAME@ |
93 | +Description: Qt wrapper for Mir functionality required by Unity |
94 | +Version: @UNITY_MIR_VERSION_MAJOR@.@UNITY_MIR_VERSION_MINOR@.@UNITY_MIR_VERSION_PATCH@ |
95 | +Libs: -L${libdir} -lunity-mir |
96 | +Cflags: -I${includedir}/unity-mir |
97 | |
98 | === modified file 'debian/control' |
99 | --- debian/control 2014-01-02 21:27:18 +0000 |
100 | +++ debian/control 2014-01-10 09:14:26 +0000 |
101 | @@ -3,10 +3,13 @@ |
102 | Priority: optional |
103 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
104 | Build-Depends: debhelper (>= 9), |
105 | + cmake, |
106 | + google-mock (>= 1.6.0+svn437), |
107 | pkg-config, |
108 | libplatform-api1-dev, |
109 | libmirserver-dev (>= 0.1.3), |
110 | libmirclient-dev (>= 0.1.3), |
111 | + libprocess-cpp-dev, |
112 | libunity-api-dev, |
113 | libupstart-app-launch2-dev, |
114 | qt5-default, |
115 | |
116 | === modified file 'debian/rules' |
117 | --- debian/rules 2013-08-19 07:40:07 +0000 |
118 | +++ debian/rules 2014-01-10 09:14:26 +0000 |
119 | @@ -6,6 +6,3 @@ |
120 | %: |
121 | dh $@ --parallel --fail-missing |
122 | |
123 | -# Force the build to generate debug symbols, so we can have -dbgsym packages |
124 | -override_dh_auto_configure: |
125 | - dh_auto_configure -- QMAKE_CXXFLAGS=-g |
126 | |
127 | === added file 'src/CMakeLists.txt' |
128 | --- src/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
129 | +++ src/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
130 | @@ -0,0 +1,2 @@ |
131 | +add_subdirectory(unity-mir) |
132 | +add_subdirectory(modules) |
133 | |
134 | === added file 'src/modules/CMakeLists.txt' |
135 | --- src/modules/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
136 | +++ src/modules/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
137 | @@ -0,0 +1,1 @@ |
138 | +add_subdirectory(Unity) |
139 | |
140 | === removed file 'src/modules/Unity/Application/Application.pro' |
141 | --- src/modules/Unity/Application/Application.pro 2013-12-06 12:30:14 +0000 |
142 | +++ src/modules/Unity/Application/Application.pro 1970-01-01 00:00:00 +0000 |
143 | @@ -1,58 +0,0 @@ |
144 | -TARGET = unityapplicationplugin |
145 | -TEMPLATE = lib |
146 | - |
147 | -QT += core quick dbus |
148 | -CONFIG += link_pkgconfig plugin |
149 | - |
150 | -# CONFIG += c++11 # only enables C++0x |
151 | -QMAKE_CXXFLAGS = -std=c++11 -fvisibility=hidden -fvisibility-inlines-hidden |
152 | -QMAKE_CXXFLAGS_RELEASE += -Werror # so no stop on warning in debug builds |
153 | -QMAKE_LFLAGS = -std=c++11 -Wl,-no-undefined |
154 | - |
155 | -PKGCONFIG += mircommon mirserver ubuntu-platform-api glib-2.0 upstart-app-launch-2 |
156 | - |
157 | -INCLUDEPATH += ../../../unity-mir |
158 | -LIBS += -L../../../unity-mir -lunity-mir \ |
159 | - -lubuntu_application_api_mirserver #FIXME platform-api pkgconfig should set this |
160 | - |
161 | -TARGET = $$qtLibraryTarget($$TARGET) |
162 | -uri = Unity.Application |
163 | - |
164 | -SOURCES += application_manager.cpp \ |
165 | - application.cpp \ |
166 | - desktopfilereader.cpp \ |
167 | - plugin.cpp \ |
168 | - applicationscreenshotprovider.cpp \ |
169 | - dbuswindowstack.cpp \ |
170 | - taskcontroller.cpp \ |
171 | - mirsurface.cpp \ |
172 | - mirsurfacemanager.cpp \ |
173 | - inputarea.cpp \ |
174 | - inputfilterarea.cpp \ |
175 | - shellinputarea.cpp \ |
176 | - ubuntukeyboardinfo.cpp |
177 | - |
178 | -HEADERS += application_manager.h \ |
179 | - application.h \ |
180 | - desktopfilereader.h \ |
181 | - applicationscreenshotprovider.h \ |
182 | - dbuswindowstack.h \ |
183 | - taskcontroller.h \ |
184 | - mirsurface.h \ |
185 | - mirsurfacemanager.h \ |
186 | - shellinputarea.h \ |
187 | - inputarea.h \ |
188 | - inputfilterarea.h \ |
189 | - ubuntukeyboardinfo.h \ |
190 | - /usr/include/unity/shell/application/ApplicationManagerInterface.h \ |
191 | - /usr/include/unity/shell/application/ApplicationInfoInterface.h |
192 | - |
193 | -installPath = $$[QT_INSTALL_IMPORTS]/Unity-Mir/$$replace(uri, \\., /) |
194 | - |
195 | -QML_FILES = qmldir ApplicationImage.qml OSKController.qml |
196 | -qml_files.path = $$installPath |
197 | -qml_files.files = $$QML_FILES |
198 | - |
199 | -target.path = $$installPath |
200 | - |
201 | -INSTALLS += target qml_files |
202 | |
203 | === added file 'src/modules/Unity/Application/CMakeLists.txt' |
204 | --- src/modules/Unity/Application/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
205 | +++ src/modules/Unity/Application/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
206 | @@ -0,0 +1,97 @@ |
207 | +pkg_check_modules(GLIB glib-2.0 REQUIRED) |
208 | +pkg_check_modules(PROCESS_CPP process-cpp REQUIRED) |
209 | +pkg_check_modules(UPSTART_APP_LAUNCH upstart-app-launch-2 REQUIRED) |
210 | + |
211 | +add_definitions(-DQT_PLUGIN) |
212 | + |
213 | +include_directories( |
214 | + ${GLIB_INCLUDE_DIRS} |
215 | + ${MIRCOMMON_INCLUDE_DIRS} |
216 | + ${MIRSERVER_INCLUDE_DIRS} |
217 | + ${PROCESS_CPP_INCLUDE_DIRS} |
218 | + ${UBUNTU_PLATFORM_API_INCLUDE_DIRS} |
219 | + ${UPSTART_APP_LAUNCH_INCLUDE_DIRS} |
220 | + |
221 | + ${CMAKE_SOURCE_DIR}/src/unity-mir |
222 | +) |
223 | + |
224 | +add_library( |
225 | + unityapplicationplugin SHARED |
226 | + |
227 | + application_manager.cpp |
228 | + application.cpp |
229 | + desktopfilereader.cpp |
230 | + plugin.cpp |
231 | + applicationscreenshotprovider.cpp |
232 | + dbuswindowstack.cpp |
233 | + taskcontroller.cpp |
234 | + mirsurface.cpp |
235 | + mirsurfacemanager.cpp |
236 | + inputarea.cpp |
237 | + inputfilterarea.cpp |
238 | + shellinputarea.cpp |
239 | + ubuntukeyboardinfo.cpp |
240 | + |
241 | + upstart/application_controller.h |
242 | + upstart/application_controller.cpp |
243 | + |
244 | + application_controller.h |
245 | + application_manager.h |
246 | + application.h |
247 | + desktopfilereader.h |
248 | + applicationscreenshotprovider.h |
249 | + dbuswindowstack.h |
250 | + taskcontroller.h |
251 | + mirsurface.h |
252 | + mirsurfacemanager.h |
253 | + shellinputarea.h |
254 | + inputarea.h |
255 | + inputfilterarea.h |
256 | + ubuntukeyboardinfo.h |
257 | + |
258 | + # We need to pull in some external header files |
259 | + /usr/include/unity/shell/application/ApplicationManagerInterface.h |
260 | + /usr/include/unity/shell/application/ApplicationInfoInterface.h |
261 | +) |
262 | + |
263 | +# We should not need this line according to the Qt5/CMake docs. |
264 | +# However, when removing it, include paths are not set and linking to Qt5 fails. |
265 | +qt5_use_modules(unityapplicationplugin Core Quick DBus) |
266 | + |
267 | +target_link_libraries( |
268 | + unityapplicationplugin |
269 | + |
270 | + unity-mir |
271 | + |
272 | + ubuntu_application_api_mirserver |
273 | + |
274 | + Qt5::Core |
275 | + Qt5::Quick |
276 | + Qt5::DBus |
277 | + |
278 | + ${CMAKE_THREAD_LIBS_INIT} |
279 | + |
280 | + ${GLIB_LDFLAGS} |
281 | + ${UBUNTU_PLATFORM_API_LIBRARIES} |
282 | + ${MIRCOMMON_LIBRARIES} |
283 | + ${MIRSERVER_LIBRARIES} |
284 | + ${PROCESS_CPP_LIBRARIES} |
285 | + ${UBUNTU_PLATFORM_API_LIBRARIES} |
286 | + ${UPSTART_APP_LAUNCH_LIBRARIES} |
287 | + |
288 | + ubuntu_application_api_mirserver |
289 | +) |
290 | + |
291 | +# Ideally, we would read the plugin installation location from cmake |
292 | +# but this does not work currently. |
293 | +set(PLUGIN_INSTALL_LOCATION "${CMAKE_INSTALL_LIBDIR}/qt5/imports/Unity-Mir/Unity/Application") |
294 | + |
295 | +message(STATUS "Installing Qt5 Unity-Application plugin to: ${PLUGIN_INSTALL_LOCATION}") |
296 | + |
297 | +install( |
298 | + TARGETS unityapplicationplugin |
299 | + LIBRARY DESTINATION ${PLUGIN_INSTALL_LOCATION}) |
300 | + |
301 | +install( |
302 | + FILES qmldir ApplicationImage.qml OSKController.qml |
303 | + DESTINATION ${PLUGIN_INSTALL_LOCATION}) |
304 | |
305 | === modified file 'src/modules/Unity/Application/application.cpp' |
306 | --- src/modules/Unity/Application/application.cpp 2013-11-15 17:53:17 +0000 |
307 | +++ src/modules/Unity/Application/application.cpp 2014-01-10 09:14:26 +0000 |
308 | @@ -25,6 +25,7 @@ |
309 | |
310 | // mir |
311 | #include <mir/shell/session.h> |
312 | +#include <mir/shell/snapshot.h> |
313 | |
314 | Application::Application(const QString &appId, Application::State state, |
315 | const QStringList &arguments, QObject *parent) |
316 | |
317 | === modified file 'src/modules/Unity/Application/application.h' |
318 | --- src/modules/Unity/Application/application.h 2013-10-28 15:39:00 +0000 |
319 | +++ src/modules/Unity/Application/application.h 2014-01-10 09:14:26 +0000 |
320 | @@ -20,9 +20,6 @@ |
321 | // std |
322 | #include <memory> |
323 | |
324 | -// Mir |
325 | -#include <mir/shell/snapshot.h> |
326 | - |
327 | //Qt |
328 | #include <QtCore/QtCore> |
329 | #include <QImage> |
330 | |
331 | === added file 'src/modules/Unity/Application/application_controller.h' |
332 | --- src/modules/Unity/Application/application_controller.h 1970-01-01 00:00:00 +0000 |
333 | +++ src/modules/Unity/Application/application_controller.h 2014-01-10 09:14:26 +0000 |
334 | @@ -0,0 +1,61 @@ |
335 | +/* |
336 | + * Copyright (C) 2013 Canonical, Ltd. |
337 | + * |
338 | + * This program is free software: you can redistribute it and/or modify it under |
339 | + * the terms of the GNU Lesser General Public License version 3, as published by |
340 | + * the Free Software Foundation. |
341 | + * |
342 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
343 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
344 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
345 | + * Lesser General Public License for more details. |
346 | + * |
347 | + * You should have received a copy of the GNU Lesser General Public License |
348 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
349 | + * |
350 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
351 | + */ |
352 | + |
353 | +#ifndef APPLICATION_CONTROLLER_H |
354 | +#define APPLICATION_CONTROLLER_H |
355 | + |
356 | +#include <QObject> |
357 | +#include <QString> |
358 | +#include <QStringList> |
359 | + |
360 | +class ApplicationController : public QObject |
361 | +{ |
362 | + Q_OBJECT |
363 | + |
364 | +public: |
365 | + enum class Error |
366 | + { |
367 | + APPLICATION_CRASHED, |
368 | + APPLICATION_FAILED_TO_START |
369 | + }; |
370 | + |
371 | + ApplicationController(const ApplicationController&) = delete; |
372 | + virtual ~ApplicationController() = default; |
373 | + |
374 | + ApplicationController& operator=(const ApplicationController&) = delete; |
375 | + |
376 | + virtual pid_t primaryPidForAppId(const QString& appId) = 0; |
377 | + virtual bool appIdHasProcessId(pid_t pid, const QString& appId) = 0; |
378 | + |
379 | + virtual bool stopApplicationWithAppId(const QString& appId) = 0; |
380 | + virtual bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments) = 0; |
381 | + |
382 | +Q_SIGNALS: |
383 | + void applicationAboutToBeStarted(QString id); |
384 | + void applicationStarted(QString id); |
385 | + void applicationStopped(QString id); |
386 | + void applicationFocusRequest(QString id); |
387 | + void applicationResumeRequest(QString id); |
388 | + |
389 | + void applicationError(QString id, ApplicationController::Error error); |
390 | + |
391 | +protected: |
392 | + ApplicationController() = default; |
393 | +}; |
394 | + |
395 | +#endif // APPLICATION_CONTROLLER_H |
396 | |
397 | === modified file 'src/modules/Unity/Application/dbuswindowstack.h' |
398 | --- src/modules/Unity/Application/dbuswindowstack.h 2013-10-09 09:02:23 +0000 |
399 | +++ src/modules/Unity/Application/dbuswindowstack.h 2014-01-10 09:14:26 +0000 |
400 | @@ -62,7 +62,7 @@ |
401 | void WindowDestroyed(unsigned int window_id, const QString &app_id); |
402 | }; |
403 | |
404 | -Q_DECLARE_METATYPE(AppIdDesktopFile); |
405 | -Q_DECLARE_METATYPE(WindowInfo); |
406 | +Q_DECLARE_METATYPE(AppIdDesktopFile) |
407 | +Q_DECLARE_METATYPE(WindowInfo) |
408 | |
409 | #endif // DBUSWINDOWSTACK_H |
410 | |
411 | === modified file 'src/modules/Unity/Application/taskcontroller.cpp' |
412 | --- src/modules/Unity/Application/taskcontroller.cpp 2013-12-05 17:30:57 +0000 |
413 | +++ src/modules/Unity/Application/taskcontroller.cpp 2014-01-10 09:14:26 +0000 |
414 | @@ -18,6 +18,7 @@ |
415 | |
416 | // local |
417 | #include "taskcontroller.h" |
418 | +#include "upstart/application_controller.h" |
419 | |
420 | // unity-mir |
421 | #include <logging.h> |
422 | @@ -25,6 +26,12 @@ |
423 | // Qt |
424 | #include <QStringList> |
425 | |
426 | +// Process C++ |
427 | +#include <core/posix/process.h> |
428 | +#include <core/posix/this_process.h> |
429 | +#include <core/posix/linux/proc/process/oom_adj.h> |
430 | +#include <core/posix/linux/proc/process/oom_score_adj.h> |
431 | + |
432 | // STL |
433 | #include <mutex> |
434 | |
435 | @@ -35,362 +42,156 @@ |
436 | #include <signal.h> |
437 | #include <unistd.h> |
438 | |
439 | -// linux specific |
440 | -#include <linux/oom.h> |
441 | - |
442 | -namespace |
443 | -{ |
444 | -/** |
445 | - * From man proc: |
446 | - * |
447 | - * This file can be used to adjust the score used to select which |
448 | - * process should be killed in an out-of-memory (OOM) situation. The |
449 | - * kernel uses this value for a bit-shift opera‐ tion of the process's |
450 | - * oom_score value: valid values are in the range -16 to +15, plus the |
451 | - * special value -17, which disables OOM-killing altogether for this |
452 | - * process. A posi‐ tive score increases the likelihood of this process |
453 | - * being killed by the OOM-killer; a negative score decreases the |
454 | - * likelihood. |
455 | - * |
456 | - * The default value for this file is 0; a new process inherits its |
457 | - * parent's oom_adj setting. A process must be privileged |
458 | - * (CAP_SYS_RESOURCE) to update this file. |
459 | - |
460 | - * Since Linux 2.6.36, use of this file is deprecated in favor of |
461 | - * /proc/[pid]/oom_score_adj. |
462 | - */ |
463 | -struct OomAdjuster |
464 | -{ |
465 | - static int disableOomKillerValue() |
466 | - { |
467 | - return OOM_DISABLE; |
468 | - } |
469 | - |
470 | - static int minValue() |
471 | - { |
472 | - return OOM_ADJUST_MIN; |
473 | - } |
474 | - |
475 | - static int maxValue() |
476 | - { |
477 | - return OOM_ADJUST_MAX; |
478 | - } |
479 | - |
480 | - static OomAdjuster leastLikelyToBeKilled() |
481 | - { |
482 | +namespace plpp = core::posix::linux::proc::process; |
483 | + |
484 | +TaskController::OomController::OomController() |
485 | +{ |
486 | +} |
487 | + |
488 | +void TaskController::OomController::ensureProcessLikelyToBeKilled(pid_t pid) |
489 | +{ |
490 | + // We avoid boundary values for oom_score_adj. For that, we |
491 | + // set it to 80% of the total available range. |
492 | + static const float defaultPercentage = 0.8; |
493 | + |
494 | + core::posix::Process process(pid); |
495 | + |
496 | + try |
497 | + { |
498 | + plpp::OomScoreAdj shellScore; |
499 | + core::posix::this_process::instance() >> shellScore; |
500 | + |
501 | + plpp::OomScoreAdj processScore |
502 | + { |
503 | + static_cast<int>((plpp::OomScoreAdj::max_value() - shellScore.value) * defaultPercentage) + shellScore.value |
504 | + }; |
505 | + |
506 | + process << processScore; |
507 | + } catch(...) |
508 | + { |
509 | + // Accessing OomScoreAdj resulted in an exception being thrown. |
510 | + // Trying with the deprecated OomAdj now as a last resort. |
511 | + try |
512 | + { |
513 | + process << plpp::OomAdj{plpp::OomAdj::max_value()}; |
514 | + } catch(...) |
515 | + { |
516 | + LOG("ensureProcessIsLikelyToBeKilled failed"); |
517 | + } |
518 | + } |
519 | +} |
520 | + |
521 | +void TaskController::OomController::ensureProcessUnlikelyToBeKilled(pid_t pid) |
522 | +{ |
523 | + // By system default, we set the oom_score_adj of Unity8 to -10 (via lightdm). |
524 | + // As we want to avoid that any app's oom_score_adj is <= Unity8's oom_score_adj, |
525 | + // we choose a default increase of +1. |
526 | + static const int default_increase = 1; |
527 | + |
528 | + core::posix::Process process(pid); |
529 | + |
530 | + try |
531 | + { |
532 | + plpp::OomScoreAdj shellScore; |
533 | + core::posix::this_process::instance() >> shellScore; |
534 | + |
535 | + plpp::OomScoreAdj processScore |
536 | + { |
537 | + shellScore.value + default_increase |
538 | + }; |
539 | + |
540 | + process << processScore; |
541 | + } catch(...) |
542 | + { |
543 | + // Accessing OomScoreAdj resulted in an exception being thrown. |
544 | + // Trying with the deprecated OomAdj now as a last resort. |
545 | // By system default, we set the oom_score_adj of Unity8 to -10 (via lightdm). |
546 | // As we want to avoid that any app's oom_score_adj or oom_adj is <= Unity8's oom_score_adj, |
547 | // we choose a default value of -9 for oom_score_adj and 0 for oom_adj. |
548 | - static const int default_value = 0; |
549 | - |
550 | - return OomAdjuster(default_value); |
551 | - } |
552 | - |
553 | - static OomAdjuster mostLikelyToBeKilled() |
554 | - { |
555 | - return OomAdjuster(maxValue()); |
556 | - } |
557 | - |
558 | - OomAdjuster(int value) : value(value) |
559 | - { |
560 | - } |
561 | - |
562 | - bool isValid() const |
563 | - { |
564 | - return !(value < disableOomKillerValue() || value > maxValue()); |
565 | - } |
566 | - |
567 | - bool applyForPid(pid_t pid) const |
568 | - { |
569 | - auto fn = QString("/proc/%1/oom_adj").arg(pid); |
570 | - QFile file(fn); |
571 | - |
572 | - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) |
573 | - return false; |
574 | - |
575 | - QTextStream out(&file); |
576 | - out << value; |
577 | - |
578 | - return true; |
579 | - } |
580 | - |
581 | - int value; |
582 | -}; |
583 | - |
584 | -/** |
585 | - * From man proc: |
586 | - * |
587 | - * This file can be used to adjust the badness heuristic used to |
588 | - * select which process gets killed in out-of-memory conditions. |
589 | - * |
590 | - * The badness heuristic assigns a value to each candidate |
591 | - * task ranging from 0 (never kill) to 1000 (always kill) |
592 | - * to determine which process is targeted. The units are |
593 | - * roughly a proportion along that range of allowed memory |
594 | - * the process may allocate from, based on an estimation of |
595 | - * its current memory and swap use. For example, if a task |
596 | - * is using all allowed memory, its badness score will be |
597 | - * 1000. If it is using half of its allowed memory, its |
598 | - * score will be 500. |
599 | - * |
600 | - * There is an additional factor included in the badness score: root |
601 | - * processes are given 3% extra memory over other tasks. |
602 | - * |
603 | - * The amount of "allowed" memory depends on the context in |
604 | - * which the OOM-killer was called. If it is due to the |
605 | - * memory assigned to the allocating task's cpuset being |
606 | - * exhausted, the allowed memory represents the set of mems |
607 | - * assigned to that cpuset (see cpuset(7)). If it is due |
608 | - * to a mempolicy's node(s) being exhausted, the allowed |
609 | - * memory represents the set of mempolicy nodes. If it is |
610 | - * due to a memory limit (or swap limit) being reached, the |
611 | - * allowed memory is that configured limit. Finally, if it |
612 | - * is due to the entire system being out of memory, the |
613 | - * allowed memory represents all allocatable resources. |
614 | - * |
615 | - * The value of oom_score_adj is added to the badness score before it |
616 | - * is used to determine which task to kill. Acceptable values range |
617 | - * from -1000 (OOM_SCORE_ADJ_MIN) to +1000 (OOM_SCORE_ADJ_MAX). This |
618 | - * allows user space to control the preference for OOM-killing, |
619 | - * ranging from always preferring a certain task or completely |
620 | - * disabling it from OOM- killing. The lowest possible value, -1000, |
621 | - * is equivalent to disabling OOM-killing entirely for that task, |
622 | - * since it will always report a badness score of 0. |
623 | - * |
624 | - * Consequently, it is very simple for user space to define the amount |
625 | - * of memory to consider for each task. Setting a oom_score_adj value |
626 | - * of +500, for example, is roughly equiv‐ alent to allowing the |
627 | - * remainder of tasks sharing the same system, cpuset, mempolicy, or |
628 | - * memory controller resources to use at least 50% more memory. A |
629 | - * value of -500, on the other hand, would be roughly equivalent to |
630 | - * discounting 50% of the task's allowed memory from being considered |
631 | - * as scoring against the task. |
632 | - * |
633 | - * For backward compatibility with previous kernels, |
634 | - * /proc/[pid]/oom_adj can still be used to tune the badness score. |
635 | - * Its value is scaled linearly with oom_score_adj. |
636 | - * |
637 | - * Writing to /proc/[pid]/oom_score_adj or |
638 | - * /proc/[pid]/oom_adj will change the other with its |
639 | - * scaled value. |
640 | - */ |
641 | -struct OomScoreAdjuster |
642 | -{ |
643 | - static int disableOomKillerValue() |
644 | - { |
645 | - return OOM_SCORE_ADJ_MIN; |
646 | - } |
647 | - |
648 | - static int minValue() |
649 | - { |
650 | - return OOM_SCORE_ADJ_MIN; |
651 | - } |
652 | - |
653 | - static int maxValue() |
654 | - { |
655 | - return OOM_SCORE_ADJ_MAX; |
656 | - } |
657 | - |
658 | - static OomScoreAdjuster leastLikelyToBeKilled() |
659 | - { |
660 | - // By system default, we set the oom_score_adj of Unity8 to -10 (via lightdm). |
661 | - // As we want to avoid that any app's oom_score_adj is <= Unity8's oom_score_adj, |
662 | - // we choose a default value of -9, and a default increase of +1. |
663 | - static const int default_value = -9; |
664 | - static const int default_increase = 1; |
665 | - |
666 | - |
667 | - // We could be way more clever here if we knew the distribution |
668 | - // of oom_score_adj values of all app processes. However, we just |
669 | - // make sure that the process is not ignored by the oom killer for now. |
670 | - return OomScoreAdjuster( |
671 | - OomScoreAdjuster::thisProcess().isValid() ? |
672 | - OomScoreAdjuster::thisProcess().value + default_increase : |
673 | - default_value); |
674 | - } |
675 | - |
676 | - static OomScoreAdjuster mostLikelyToBeKilled() |
677 | - { |
678 | - // We avoid extremal values for oom_score_adj. For that, we |
679 | - // set it to 80% of the total available range. If we cannot |
680 | - // determine the oom_score_adj of the current process, i.e., |
681 | - // Unity8, we substract -200 by default. |
682 | - static const float default_percentage = 0.8; |
683 | - static const int default_decrease = -200; |
684 | - |
685 | - return OomScoreAdjuster( |
686 | - OomScoreAdjuster::thisProcess().isValid() ? |
687 | - (maxValue() - OomScoreAdjuster::thisProcess().value) * default_percentage + OomScoreAdjuster::thisProcess().value : |
688 | - maxValue() - default_decrease); |
689 | - } |
690 | - |
691 | - static const OomScoreAdjuster& thisProcess() |
692 | - { |
693 | - // Initialize as invalid. |
694 | - static OomScoreAdjuster adjusterForThisProcess(minValue()-1); |
695 | - |
696 | - static std::once_flag query_once; |
697 | - std::call_once( |
698 | - query_once, |
699 | - []() |
700 | - { |
701 | - pid_t pid = getpid(); |
702 | - |
703 | - auto fn = QString("/proc/%1/oom_score_adj").arg(pid); |
704 | - QFile file(fn); |
705 | - |
706 | - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) |
707 | - return; |
708 | - |
709 | - QTextStream in(&file); |
710 | - int value; in >> value; |
711 | - |
712 | - adjusterForThisProcess.value = value; |
713 | - }); |
714 | - |
715 | - return adjusterForThisProcess; |
716 | - } |
717 | - |
718 | - OomScoreAdjuster(int value) : value(value) |
719 | - { |
720 | - } |
721 | - |
722 | - bool isValid() const |
723 | - { |
724 | - return !(value < disableOomKillerValue() || value > maxValue()); |
725 | - } |
726 | - |
727 | - bool applyForPid(pid_t pid) const |
728 | - { |
729 | - auto fn = QString("/proc/%1/oom_score_adj").arg(pid); |
730 | - QFile file(fn); |
731 | - |
732 | - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) |
733 | - return false; |
734 | - |
735 | - QTextStream out(&file); |
736 | - out << value; |
737 | - |
738 | - return true; |
739 | - } |
740 | - |
741 | - int value; |
742 | -}; |
743 | - |
744 | -void ensureProcessIsUnlikelyToBeKilled(pid_t pid) |
745 | -{ |
746 | - if (!OomScoreAdjuster::leastLikelyToBeKilled().applyForPid(pid)) |
747 | - if (!OomAdjuster::leastLikelyToBeKilled().applyForPid(pid)) |
748 | + static const int defaultValue = 0; |
749 | + |
750 | + try |
751 | + { |
752 | + process << plpp::OomAdj{defaultValue}; |
753 | + } catch(...) |
754 | + { |
755 | LOG("ensureProcessIsUnlikelyToBeKilled failed"); |
756 | + } |
757 | + } |
758 | } |
759 | |
760 | -void ensureProcessIsLikelyToBeKilled(pid_t pid) |
761 | +TaskController* theTaskController = nullptr; |
762 | + |
763 | +void cleanup_task_controller_singleton_instance() |
764 | { |
765 | - if (!OomScoreAdjuster::mostLikelyToBeKilled().applyForPid(pid)) |
766 | - if (!OomAdjuster::mostLikelyToBeKilled().applyForPid(pid)) |
767 | - LOG("ensureProcessIsLikelyToBeKilled failed"); |
768 | -} |
769 | -} |
770 | - |
771 | -TaskController* TaskController::m_theTaskController = nullptr; |
772 | + delete theTaskController; |
773 | +} |
774 | |
775 | TaskController* TaskController::singleton() |
776 | { |
777 | - if (!m_theTaskController) { |
778 | - m_theTaskController = new TaskController(); |
779 | + if (!theTaskController) { |
780 | + theTaskController = new TaskController( |
781 | + nullptr, |
782 | + QSharedPointer<ApplicationController>(new upstart::ApplicationController())); |
783 | + |
784 | + atexit(cleanup_task_controller_singleton_instance); |
785 | } |
786 | - return m_theTaskController; |
787 | + return theTaskController; |
788 | } |
789 | |
790 | -TaskController::TaskController(QObject *parent) : |
791 | - QObject(parent) |
792 | +TaskController::TaskController( |
793 | + QObject* parent, |
794 | + const QSharedPointer<ApplicationController>& app_controller, |
795 | + const QSharedPointer<TaskController::OomController>& oom_controller) : |
796 | + QObject(parent), |
797 | + app_controller(app_controller), |
798 | + oom_controller(oom_controller) |
799 | { |
800 | - preStartCallback = [](const gchar * appId, gpointer userData) { |
801 | - Q_UNUSED(userData) |
802 | - Q_EMIT TaskController::singleton()->processStartReport(QString(appId), false); |
803 | - }; |
804 | - |
805 | - startedCallback = [](const gchar * appId, gpointer userData) { |
806 | - Q_UNUSED(userData) |
807 | - pid_t pid = upstart_app_launch_get_primary_pid(appId); |
808 | - ensureProcessIsUnlikelyToBeKilled(pid); |
809 | - }; |
810 | - |
811 | - stopCallback = [](const gchar * appId, gpointer userData) { |
812 | - Q_UNUSED(userData) |
813 | - Q_EMIT TaskController::singleton()->processStopped(QString(appId), false); |
814 | - }; |
815 | - |
816 | - focusCallback = [](const gchar * appId, gpointer userData) { |
817 | - Q_UNUSED(userData) |
818 | - pid_t pid = upstart_app_launch_get_primary_pid(appId); |
819 | - ensureProcessIsUnlikelyToBeKilled(pid); |
820 | - Q_EMIT TaskController::singleton()->requestFocus(QString(appId)); |
821 | - }; |
822 | - |
823 | - resumeCallback = [](const gchar * appId, gpointer userData) { |
824 | - Q_UNUSED(userData) |
825 | - Q_EMIT TaskController::singleton()->requestResume(QString(appId)); |
826 | - }; |
827 | - |
828 | - failureCallback = [](const gchar * appId, upstart_app_launch_app_failed_t failureType, gpointer userData) { |
829 | - Q_UNUSED(userData) |
830 | - if (failureType == UPSTART_APP_LAUNCH_APP_FAILED_CRASH) { |
831 | - Q_EMIT TaskController::singleton()->processStopped(QString(appId), true); |
832 | - } else if (failureType == UPSTART_APP_LAUNCH_APP_FAILED_START_FAILURE) { |
833 | - Q_EMIT TaskController::singleton()->processStartReport(QString(appId), true); |
834 | - } else { |
835 | - LOG("TaskController: unknown failure type returned from upstart-app-launch"); |
836 | - } |
837 | - Q_EMIT TaskController::singleton()->requestResume(QString(appId)); |
838 | - }; |
839 | - |
840 | - upstart_app_launch_observer_add_app_starting(preStartCallback, nullptr); |
841 | - upstart_app_launch_observer_add_app_started(startedCallback, nullptr); |
842 | - upstart_app_launch_observer_add_app_stop(stopCallback, nullptr); |
843 | - upstart_app_launch_observer_add_app_focus(focusCallback, nullptr); |
844 | - upstart_app_launch_observer_add_app_resume(resumeCallback, nullptr); |
845 | - upstart_app_launch_observer_add_app_failed(failureCallback, nullptr); |
846 | + connect(app_controller.data(), |
847 | + SIGNAL(applicationAboutToBeStarted(QString)), |
848 | + this, |
849 | + SLOT(onApplicationAboutToBeStarted(QString))); |
850 | + |
851 | + connect(app_controller.data(), |
852 | + SIGNAL(applicationStarted(QString)), |
853 | + this, |
854 | + SLOT(onApplicationStarted(QString))); |
855 | + |
856 | + connect(app_controller.data(), |
857 | + SIGNAL(applicationStopped(QString)), |
858 | + this, |
859 | + SLOT(onApplicationStopped(QString))); |
860 | + |
861 | + connect(app_controller.data(), |
862 | + SIGNAL(applicationFocusRequest(QString)), |
863 | + this, |
864 | + SLOT(onApplicationFocusRequest(QString))); |
865 | + |
866 | + connect(app_controller.data(), |
867 | + SIGNAL(applicationResumeRequest(QString)), |
868 | + this, |
869 | + SLOT(onApplicationResumeRequest(QString))); |
870 | + |
871 | + connect(app_controller.data(), |
872 | + SIGNAL(applicationError(QString, ApplicationController::Error)), |
873 | + this, |
874 | + SLOT(onApplicationError(QString, ApplicationController::Error))); |
875 | } |
876 | |
877 | TaskController::~TaskController() |
878 | { |
879 | - upstart_app_launch_observer_delete_app_starting(preStartCallback, nullptr); |
880 | - upstart_app_launch_observer_delete_app_started(startedCallback, nullptr); |
881 | - upstart_app_launch_observer_delete_app_stop(stopCallback, nullptr); |
882 | - upstart_app_launch_observer_delete_app_focus(focusCallback, nullptr); |
883 | - upstart_app_launch_observer_delete_app_resume(resumeCallback, nullptr); |
884 | - upstart_app_launch_observer_delete_app_failed(failureCallback, nullptr); |
885 | } |
886 | |
887 | bool TaskController::start(const QString& appId, const QStringList& arguments) |
888 | { |
889 | DLOG("TaskController::start appId='%s'", qPrintable(appId)); |
890 | - gchar ** upstartArgs = nullptr; |
891 | - bool result = false; |
892 | - |
893 | - // Convert arguments QStringList into format suitable for upstart-app-launch |
894 | - upstartArgs = g_new0(gchar *, arguments.length()); |
895 | - |
896 | - for (int i=0; i<arguments.length(); i++) { |
897 | - upstartArgs[i] = arguments.at(i).toLatin1().data(); |
898 | - } |
899 | - |
900 | - result = upstart_app_launch_start_application(appId.toLatin1().constData(), |
901 | - static_cast<const gchar * const *>(upstartArgs)); |
902 | - g_free(upstartArgs); |
903 | - |
904 | - DLOG_IF(!result, "TaskController::startApplication appId='%s' FAILED", qPrintable(appId)); |
905 | - return result; |
906 | + return app_controller->startApplicationWithAppIdAndArgs(appId, arguments); |
907 | } |
908 | |
909 | bool TaskController::stop(const QString& appId) |
910 | { |
911 | DLOG("TaskController::stop appId='%s'", qPrintable(appId)); |
912 | - bool result = false; |
913 | - |
914 | - result = upstart_app_launch_stop_application(appId.toLatin1().constData()); |
915 | - |
916 | + auto result = app_controller->stopApplicationWithAppId(appId); |
917 | DLOG_IF(!result, "TaskController::stopApplication appId='%s' FAILED", qPrintable(appId)); |
918 | return result; |
919 | } |
920 | @@ -398,15 +199,14 @@ |
921 | bool TaskController::appIdHasProcessId(const QString& appId, const quint64 pid) |
922 | { |
923 | DLOG("TaskController::isApplicationPid appId='%s', pid=%lld", qPrintable(appId), pid); |
924 | - return upstart_app_launch_pid_in_app_id(pid, appId.toLatin1().constData()); |
925 | + return app_controller->appIdHasProcessId(pid, appId); |
926 | } |
927 | |
928 | bool TaskController::suspend(const QString& appId) |
929 | { |
930 | DLOG("TaskController::suspend (this=%p, application=%p)", this, qPrintable(appId)); |
931 | - pid_t pid = upstart_app_launch_get_primary_pid(appId.toLatin1().constData()); |
932 | - |
933 | - ensureProcessIsLikelyToBeKilled(pid); |
934 | + auto pid = app_controller->primaryPidForAppId(appId); |
935 | + oom_controller->ensureProcessLikelyToBeKilled(pid); |
936 | |
937 | if (pid) { |
938 | // We do assume that the app was launched by upstart and with that, |
939 | @@ -422,9 +222,9 @@ |
940 | bool TaskController::resume(const QString& appId) |
941 | { |
942 | DLOG("TaskController::resume (this=%p, application=%p)", this, qPrintable(appId)); |
943 | - pid_t pid = upstart_app_launch_get_primary_pid(appId.toLatin1().constData()); |
944 | + auto pid = app_controller->primaryPidForAppId(appId); |
945 | |
946 | - ensureProcessIsUnlikelyToBeKilled(pid); |
947 | + oom_controller->ensureProcessUnlikelyToBeKilled(pid); |
948 | |
949 | if (pid) { |
950 | // We do assume that the app was launched by upstart and with that, |
951 | @@ -436,3 +236,47 @@ |
952 | return false; |
953 | } |
954 | } |
955 | + |
956 | +void TaskController::onApplicationAboutToBeStarted(QString id) |
957 | +{ |
958 | + Q_EMIT processStartReport(id, false); |
959 | +} |
960 | + |
961 | +void TaskController::onApplicationStarted(QString id) |
962 | +{ |
963 | + auto pid = app_controller->primaryPidForAppId(id); |
964 | + oom_controller->ensureProcessUnlikelyToBeKilled(pid); |
965 | +} |
966 | + |
967 | +void TaskController::onApplicationStopped(QString id) |
968 | +{ |
969 | + Q_EMIT processStopped(id, false); |
970 | +} |
971 | + |
972 | +void TaskController::onApplicationFocusRequest(QString id) |
973 | +{ |
974 | + auto pid = app_controller->primaryPidForAppId(id); |
975 | + oom_controller->ensureProcessUnlikelyToBeKilled(pid); |
976 | + Q_EMIT requestFocus(id); |
977 | +} |
978 | + |
979 | +void TaskController::onApplicationResumeRequest(QString id) |
980 | +{ |
981 | + Q_EMIT requestResume(id); |
982 | +} |
983 | + |
984 | +void TaskController::onApplicationError(QString id, ApplicationController::Error error) |
985 | +{ |
986 | + switch(error) |
987 | + { |
988 | + case ApplicationController::Error::APPLICATION_CRASHED: |
989 | + Q_EMIT processStopped(id, true); |
990 | + break; |
991 | + case ApplicationController::Error::APPLICATION_FAILED_TO_START: |
992 | + Q_EMIT processStartReport(id, true); |
993 | + break; |
994 | + } |
995 | + |
996 | + // Is this really the signal we want to emit? |
997 | + Q_EMIT requestResume(id); |
998 | +} |
999 | |
1000 | === modified file 'src/modules/Unity/Application/taskcontroller.h' |
1001 | --- src/modules/Unity/Application/taskcontroller.h 2013-12-05 17:11:36 +0000 |
1002 | +++ src/modules/Unity/Application/taskcontroller.h 2014-01-10 09:14:26 +0000 |
1003 | @@ -22,17 +22,32 @@ |
1004 | #include <QObject> |
1005 | |
1006 | #include "application.h" |
1007 | - |
1008 | -// upstart |
1009 | -extern "C" { |
1010 | - #include "upstart-app-launch.h" |
1011 | -} |
1012 | +#include "application_controller.h" |
1013 | |
1014 | class TaskController : public QObject |
1015 | { |
1016 | Q_OBJECT |
1017 | public: |
1018 | + |
1019 | + class OomController |
1020 | + { |
1021 | + public: |
1022 | + OomController(); |
1023 | + OomController(const OomController&) = delete; |
1024 | + virtual ~OomController() = default; |
1025 | + |
1026 | + OomController& operator=(const OomController&) = delete; |
1027 | + |
1028 | + virtual void ensureProcessLikelyToBeKilled(pid_t); |
1029 | + virtual void ensureProcessUnlikelyToBeKilled(pid_t); |
1030 | + }; |
1031 | + |
1032 | static TaskController* singleton(); |
1033 | + |
1034 | + TaskController( |
1035 | + QObject* parent, |
1036 | + const QSharedPointer<ApplicationController>& app_controller, |
1037 | + const QSharedPointer<OomController>& oom_controller = QSharedPointer<OomController>(new OomController())); |
1038 | ~TaskController(); |
1039 | |
1040 | bool start(const QString& appId, const QStringList& args); |
1041 | @@ -49,12 +64,18 @@ |
1042 | void requestFocus(const QString& appId); |
1043 | void requestResume(const QString& appId); |
1044 | |
1045 | +private Q_SLOTS: |
1046 | + void onApplicationAboutToBeStarted(QString id); |
1047 | + void onApplicationStarted(QString id); |
1048 | + void onApplicationStopped(QString id); |
1049 | + void onApplicationFocusRequest(QString id); |
1050 | + void onApplicationResumeRequest(QString id); |
1051 | + |
1052 | + void onApplicationError(QString id, ApplicationController::Error error); |
1053 | + |
1054 | private: |
1055 | - TaskController(QObject *parent = 0); |
1056 | - |
1057 | - static TaskController* m_theTaskController; |
1058 | - upstart_app_launch_app_observer_t preStartCallback, startedCallback, stopCallback, focusCallback, resumeCallback; |
1059 | - upstart_app_launch_app_failed_observer_t failureCallback; |
1060 | + QSharedPointer<ApplicationController> app_controller; |
1061 | + QSharedPointer<OomController> oom_controller; |
1062 | }; |
1063 | |
1064 | #endif // TASKCONTROLLER_H |
1065 | |
1066 | === added directory 'src/modules/Unity/Application/upstart' |
1067 | === added file 'src/modules/Unity/Application/upstart/application_controller.cpp' |
1068 | --- src/modules/Unity/Application/upstart/application_controller.cpp 1970-01-01 00:00:00 +0000 |
1069 | +++ src/modules/Unity/Application/upstart/application_controller.cpp 2014-01-10 09:14:26 +0000 |
1070 | @@ -0,0 +1,154 @@ |
1071 | +/* |
1072 | + * Copyright (C) 2013 Canonical, Ltd. |
1073 | + * |
1074 | + * This program is free software: you can redistribute it and/or modify it under |
1075 | + * the terms of the GNU Lesser General Public License version 3, as published by |
1076 | + * the Free Software Foundation. |
1077 | + * |
1078 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
1079 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
1080 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1081 | + * Lesser General Public License for more details. |
1082 | + * |
1083 | + * You should have received a copy of the GNU Lesser General Public License |
1084 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1085 | + * |
1086 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1087 | + */ |
1088 | + |
1089 | +#include "application_controller.h" |
1090 | + |
1091 | +// unity-mir |
1092 | +#include <logging.h> |
1093 | + |
1094 | +// upstart |
1095 | +extern "C" { |
1096 | + #include "upstart-app-launch.h" |
1097 | +} |
1098 | + |
1099 | +struct upstart::ApplicationController::Private |
1100 | +{ |
1101 | + upstart_app_launch_app_observer_t preStartCallback = nullptr; |
1102 | + upstart_app_launch_app_observer_t startedCallback = nullptr; |
1103 | + upstart_app_launch_app_observer_t stopCallback = nullptr; |
1104 | + upstart_app_launch_app_observer_t focusCallback = nullptr; |
1105 | + upstart_app_launch_app_observer_t resumeCallback = nullptr; |
1106 | + upstart_app_launch_app_failed_observer_t failureCallback = nullptr; |
1107 | +}; |
1108 | + |
1109 | +upstart::ApplicationController::ApplicationController() |
1110 | + : ::ApplicationController(), |
1111 | + impl(new Private()) |
1112 | +{ |
1113 | + impl->preStartCallback = [](const gchar * appId, gpointer userData) { |
1114 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1115 | + QMetaObject::invokeMethod(thiz, |
1116 | + "applicationAboutToBeStarted", |
1117 | + Qt::QueuedConnection, // This might happen on a different thread. |
1118 | + Q_ARG(QString, QString(appId))); |
1119 | + }; |
1120 | + |
1121 | + impl->startedCallback = [](const gchar * appId, gpointer userData) { |
1122 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1123 | + QMetaObject::invokeMethod(thiz, |
1124 | + "applicationStarted", |
1125 | + Qt::QueuedConnection, // This might happen on a different thread. |
1126 | + Q_ARG(QString, QString(appId))); |
1127 | + }; |
1128 | + |
1129 | + impl->stopCallback = [](const gchar * appId, gpointer userData) { |
1130 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1131 | + QMetaObject::invokeMethod(thiz, |
1132 | + "applicationStopped", |
1133 | + Qt::QueuedConnection, // This might happen on a different thread. |
1134 | + Q_ARG(QString, QString(appId))); |
1135 | + }; |
1136 | + |
1137 | + impl->focusCallback = [](const gchar * appId, gpointer userData) { |
1138 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1139 | + QMetaObject::invokeMethod(thiz, |
1140 | + "applicationFocusRequest", |
1141 | + Qt::QueuedConnection, // This might happen on a different thread. |
1142 | + Q_ARG(QString, QString(appId))); |
1143 | + }; |
1144 | + |
1145 | + impl->resumeCallback = [](const gchar * appId, gpointer userData) { |
1146 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1147 | + QMetaObject::invokeMethod(thiz, |
1148 | + "applicationResumeRequest", |
1149 | + Qt::QueuedConnection, // This might happen on a different thread. |
1150 | + Q_ARG(QString, QString(appId))); |
1151 | + }; |
1152 | + |
1153 | + impl->failureCallback = [](const gchar * appId, upstart_app_launch_app_failed_t failureType, gpointer userData) { |
1154 | + ApplicationController::Error error; |
1155 | + switch(failureType) |
1156 | + { |
1157 | + case UPSTART_APP_LAUNCH_APP_FAILED_CRASH: error = ApplicationController::Error::APPLICATION_CRASHED; |
1158 | + case UPSTART_APP_LAUNCH_APP_FAILED_START_FAILURE: error = ApplicationController::Error::APPLICATION_FAILED_TO_START; |
1159 | + } |
1160 | + |
1161 | + auto thiz = static_cast<upstart::ApplicationController*>(userData); |
1162 | + QMetaObject::invokeMethod(thiz, |
1163 | + "applicationError", |
1164 | + Qt::QueuedConnection, // This might happen on a different thread. |
1165 | + Q_ARG(QString, QString(appId)), |
1166 | + Q_ARG(::ApplicationController::Error, error)); |
1167 | + }; |
1168 | + |
1169 | + upstart_app_launch_observer_add_app_starting(impl->preStartCallback, this); |
1170 | + upstart_app_launch_observer_add_app_started(impl->startedCallback, this); |
1171 | + upstart_app_launch_observer_add_app_stop(impl->stopCallback, this); |
1172 | + upstart_app_launch_observer_add_app_focus(impl->focusCallback, this); |
1173 | + upstart_app_launch_observer_add_app_resume(impl->resumeCallback, this); |
1174 | + upstart_app_launch_observer_add_app_failed(impl->failureCallback, this); |
1175 | +} |
1176 | + |
1177 | +upstart::ApplicationController::~ApplicationController() |
1178 | +{ |
1179 | + upstart_app_launch_observer_delete_app_starting(impl->preStartCallback, this); |
1180 | + upstart_app_launch_observer_delete_app_started(impl->startedCallback, this); |
1181 | + upstart_app_launch_observer_delete_app_stop(impl->stopCallback, this); |
1182 | + upstart_app_launch_observer_delete_app_focus(impl->focusCallback, this); |
1183 | + upstart_app_launch_observer_delete_app_resume(impl->resumeCallback, this); |
1184 | + upstart_app_launch_observer_delete_app_failed(impl->failureCallback, this); |
1185 | +} |
1186 | + |
1187 | +pid_t upstart::ApplicationController::primaryPidForAppId(const QString& appId) |
1188 | +{ |
1189 | + auto pid = upstart_app_launch_get_primary_pid(appId.toLatin1().constData()); |
1190 | + DLOG_IF(!pid, "ApplicationController::stopApplication appId='%s' FAILED", qPrintable(appId)); |
1191 | + |
1192 | + return pid; |
1193 | +} |
1194 | + |
1195 | +bool upstart::ApplicationController::appIdHasProcessId(pid_t pid, const QString& appId) |
1196 | +{ |
1197 | + return upstart_app_launch_pid_in_app_id(pid, appId.toLatin1().constData()); |
1198 | +} |
1199 | + |
1200 | +bool upstart::ApplicationController::stopApplicationWithAppId(const QString& appId) |
1201 | +{ |
1202 | + auto result = upstart_app_launch_stop_application(appId.toLatin1().constData()); |
1203 | + DLOG_IF(!result, "upstart::ApplicationController::stopApplicationWithAppId appId='%s' FAILED", qPrintable(appId)); |
1204 | + return result; |
1205 | +} |
1206 | + |
1207 | +bool upstart::ApplicationController::startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments) |
1208 | +{ |
1209 | + // Convert arguments QStringList into format suitable for upstart-app-launch |
1210 | + auto upstartArgs = g_new0(gchar *, arguments.length()); |
1211 | + |
1212 | + for (int i=0; i<arguments.length(); i++) { |
1213 | + upstartArgs[i] = arguments.at(i).toLatin1().data(); |
1214 | + } |
1215 | + |
1216 | + auto result = upstart_app_launch_start_application( |
1217 | + appId.toLatin1().constData(), |
1218 | + static_cast<const gchar * const *>(upstartArgs)); |
1219 | + |
1220 | + g_free(upstartArgs); |
1221 | + |
1222 | + DLOG_IF(!result, "upstart::Application::Controller::startApplicationWithAppIdAndArgs appId='%s' FAILED", qPrintable(appId)); |
1223 | + return result; |
1224 | +} |
1225 | |
1226 | === added file 'src/modules/Unity/Application/upstart/application_controller.h' |
1227 | --- src/modules/Unity/Application/upstart/application_controller.h 1970-01-01 00:00:00 +0000 |
1228 | +++ src/modules/Unity/Application/upstart/application_controller.h 2014-01-10 09:14:26 +0000 |
1229 | @@ -0,0 +1,44 @@ |
1230 | +/* |
1231 | + * Copyright (C) 2013 Canonical, Ltd. |
1232 | + * |
1233 | + * This program is free software: you can redistribute it and/or modify it under |
1234 | + * the terms of the GNU Lesser General Public License version 3, as published by |
1235 | + * the Free Software Foundation. |
1236 | + * |
1237 | + * This program is distributed in the hope that it will be useful, but WITHOUT |
1238 | + * ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, |
1239 | + * SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1240 | + * Lesser General Public License for more details. |
1241 | + * |
1242 | + * You should have received a copy of the GNU Lesser General Public License |
1243 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1244 | + * |
1245 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1246 | + */ |
1247 | + |
1248 | +#ifndef UPSTART_APPLICATION_CONTROLLER_H |
1249 | +#define UPSTART_APPLICATION_CONTROLLER_H |
1250 | + |
1251 | +#include "../application_controller.h" |
1252 | + |
1253 | +namespace upstart |
1254 | +{ |
1255 | +class ApplicationController : public ::ApplicationController |
1256 | +{ |
1257 | +public: |
1258 | + ApplicationController(); |
1259 | + ~ApplicationController(); |
1260 | + |
1261 | + pid_t primaryPidForAppId(const QString& appId); |
1262 | + bool appIdHasProcessId(pid_t pid, const QString& appId); |
1263 | + |
1264 | + bool stopApplicationWithAppId(const QString& appId); |
1265 | + bool startApplicationWithAppIdAndArgs(const QString& appId, const QStringList& arguments); |
1266 | + |
1267 | +private: |
1268 | + struct Private; |
1269 | + QScopedPointer<Private> impl; |
1270 | +}; |
1271 | +} |
1272 | + |
1273 | +#endif // UPSTART_APPLICATION_CONTROLLER_H |
1274 | |
1275 | === added file 'src/modules/Unity/CMakeLists.txt' |
1276 | --- src/modules/Unity/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1277 | +++ src/modules/Unity/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
1278 | @@ -0,0 +1,1 @@ |
1279 | +add_subdirectory(Application) |
1280 | |
1281 | === removed file 'src/modules/modules.pro' |
1282 | --- src/modules/modules.pro 2013-08-29 14:46:43 +0000 |
1283 | +++ src/modules/modules.pro 1970-01-01 00:00:00 +0000 |
1284 | @@ -1,3 +0,0 @@ |
1285 | -TEMPLATE = subdirs |
1286 | - |
1287 | -SUBDIRS += Unity/Application |
1288 | |
1289 | === removed file 'src/src.pro' |
1290 | --- src/src.pro 2013-07-19 17:29:44 +0000 |
1291 | +++ src/src.pro 1970-01-01 00:00:00 +0000 |
1292 | @@ -1,6 +0,0 @@ |
1293 | -TEMPLATE = subdirs |
1294 | - |
1295 | -SUBDIRS += unity-mir \ |
1296 | - modules \ |
1297 | - |
1298 | -modules.depends = unity-mir |
1299 | |
1300 | === added file 'src/unity-mir/CMakeLists.txt' |
1301 | --- src/unity-mir/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1302 | +++ src/unity-mir/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
1303 | @@ -0,0 +1,72 @@ |
1304 | +include_directories( |
1305 | + ${MIRCOMMON_INCLUDE_DIRS} |
1306 | + ${MIRSERVER_INCLUDE_DIRS} |
1307 | + ${UBUNTU_PLATFORM_API_INCLUDE_DIRS} |
1308 | +) |
1309 | + |
1310 | +set( |
1311 | + UNITY_MIR_HEADERS |
1312 | + |
1313 | + dbusscreen.h |
1314 | + initialsurfaceplacementstrategy.h |
1315 | + qmirserverapplication.h |
1316 | + qmirserver.h |
1317 | + sessionauthorizer.h |
1318 | + sessionlistener.h |
1319 | + shellserverconfiguration.h |
1320 | + surfacefactory.h |
1321 | + surfaceconfigurator.h |
1322 | + logging.h |
1323 | + focussetter.h |
1324 | + serverstatuslistener.h) |
1325 | + |
1326 | +add_library( |
1327 | + unity-mir SHARED |
1328 | + |
1329 | + dbusscreen.cpp |
1330 | + initialsurfaceplacementstrategy.cpp |
1331 | + qmirserverapplication.cpp |
1332 | + qmirserver.cpp |
1333 | + sessionauthorizer.cpp |
1334 | + sessionlistener.cpp |
1335 | + shellserverconfiguration.cpp |
1336 | + surfacefactory.cpp |
1337 | + surfaceconfigurator.cpp |
1338 | + focussetter.cpp |
1339 | + serverstatuslistener.cpp |
1340 | + |
1341 | + ${UNITY_MIR_HEADERS}) |
1342 | + |
1343 | +# We should not need this line according to the Qt5/CMake docs. |
1344 | +# However, when removing it, include paths are not set and linking to Qt5 fails. |
1345 | +qt5_use_modules(unity-mir Core Quick DBus) |
1346 | + |
1347 | +set_target_properties( |
1348 | + unity-mir |
1349 | + |
1350 | + PROPERTIES |
1351 | + VERSION ${UNITY_MIR_VERSION_MAJOR}.${UNITY_MIR_VERSION_MINOR}.${UNITY_MIR_VERSION_PATCH} |
1352 | + SOVERSION ${UNITY_MIR_VERSION_MAJOR}) |
1353 | + |
1354 | +target_link_libraries( |
1355 | + unity-mir |
1356 | + |
1357 | + Qt5::Core |
1358 | + Qt5::Quick |
1359 | + Qt5::DBus |
1360 | + |
1361 | + ${CMAKE_THREAD_LIBS_INIT} |
1362 | + |
1363 | + ${UBUNTU_PLATFORM_API_LIBRARIES} |
1364 | + ${MIRCOMMON_LIBRARIES} |
1365 | + ${MIRSERVER_LIBRARIES} |
1366 | + |
1367 | + ubuntu_application_api_mirserver) |
1368 | + |
1369 | +install( |
1370 | + TARGETS unity-mir |
1371 | + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) |
1372 | + |
1373 | +install( |
1374 | + FILES ${UNITY_MIR_HEADERS} |
1375 | + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/unity-mir) |
1376 | |
1377 | === modified file 'src/unity-mir/logging.h' |
1378 | --- src/unity-mir/logging.h 2013-08-22 12:06:58 +0000 |
1379 | +++ src/unity-mir/logging.h 2014-01-10 09:14:26 +0000 |
1380 | @@ -17,6 +17,8 @@ |
1381 | #ifndef UBUNTU_APPLICATION_PLUGIN_LOGGING_H |
1382 | #define UBUNTU_APPLICATION_PLUGIN_LOGGING_H |
1383 | |
1384 | +#pragma GCC diagnostic ignored "-Wformat" |
1385 | + |
1386 | #include <QDebug> |
1387 | |
1388 | // Logging and assertion macros. |
1389 | |
1390 | === removed file 'src/unity-mir/unity-mir.pro' |
1391 | --- src/unity-mir/unity-mir.pro 2013-11-18 16:05:56 +0000 |
1392 | +++ src/unity-mir/unity-mir.pro 1970-01-01 00:00:00 +0000 |
1393 | @@ -1,67 +0,0 @@ |
1394 | -TARGET = unity-mir |
1395 | -TEMPLATE = lib |
1396 | - |
1397 | -QT += core quick dbus |
1398 | -CONFIG += link_pkgconfig |
1399 | - |
1400 | -# CONFIG += c++11 # only enables C++0x |
1401 | -QMAKE_CXXFLAGS = -std=c++11 |
1402 | -QMAKE_CXXFLAGS_RELEASE += -Werror # so no stop on warning in debug builds |
1403 | -QMAKE_LFLAGS = -std=c++11 -Wl,-no-undefined |
1404 | - |
1405 | -PKGCONFIG += mircommon mirserver ubuntu-platform-api |
1406 | - |
1407 | -LIBS += -lubuntu_application_api_mirserver #FIXME platform-api pkgconfig should set this |
1408 | - |
1409 | -SOURCES += \ |
1410 | - dbusscreen.cpp \ |
1411 | - initialsurfaceplacementstrategy.cpp \ |
1412 | - qmirserverapplication.cpp \ |
1413 | - qmirserver.cpp \ |
1414 | - sessionauthorizer.cpp \ |
1415 | - sessionlistener.cpp \ |
1416 | - shellserverconfiguration.cpp \ |
1417 | - surfacefactory.cpp \ |
1418 | - surfaceconfigurator.cpp \ |
1419 | - focussetter.cpp \ |
1420 | - serverstatuslistener.cpp |
1421 | - |
1422 | -HEADERS += \ |
1423 | - dbusscreen.h \ |
1424 | - initialsurfaceplacementstrategy.h \ |
1425 | - qmirserverapplication.h \ |
1426 | - qmirserver.h \ |
1427 | - sessionauthorizer.h \ |
1428 | - sessionlistener.h \ |
1429 | - shellserverconfiguration.h \ |
1430 | - surfacefactory.h \ |
1431 | - surfaceconfigurator.h \ |
1432 | - logging.h \ |
1433 | - focussetter.h \ |
1434 | - serverstatuslistener.h |
1435 | - |
1436 | -target.path = $$[QT_INSTALL_LIBS] |
1437 | - |
1438 | -install_headers.files = qmirserverapplication.h \ |
1439 | - qmirserver.h \ |
1440 | - initialsurfaceplacementstrategy.h \ |
1441 | - sessionauthorizer.h \ |
1442 | - sessionlistener.h \ |
1443 | - shellserverconfiguration.h \ |
1444 | - surfacebuilder.h \ |
1445 | - surfacefactory.h |
1446 | -install_headers.path = /usr/include/unity-mir |
1447 | - |
1448 | -### Generate pkg-config file |
1449 | -CONFIG += create_pc create_prl no_install_prl |
1450 | - |
1451 | -QMAKE_PKGCONFIG_NAME = Unity-Mir |
1452 | -QMAKE_PKGCONFIG_DESCRIPTION = Qt wrapper for Mir functionality required by Unity |
1453 | -QMAKE_PKGCONFIG_PREFIX = $$INSTALLBASE |
1454 | -QMAKE_PKGCONFIG_LIBDIR = $$target.path |
1455 | -QMAKE_PKGCONFIG_INCDIR = $$installheaders.path |
1456 | -QMAKE_PKGCONFIG_VERSION = $$VERSION |
1457 | -QMAKE_PKGCONFIG_REQUIRES = ubuntu-platform-api mirclient mirserver Qt5Core |
1458 | -QMAKE_PKGCONFIG_DESTDIR = pkgconfig |
1459 | - |
1460 | -INSTALLS += target install_headers |
1461 | |
1462 | === added file 'tests/CMakeLists.txt' |
1463 | --- tests/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1464 | +++ tests/CMakeLists.txt 2014-01-10 09:14:26 +0000 |
1465 | @@ -0,0 +1,48 @@ |
1466 | +find_package(Qt5Core REQUIRED) |
1467 | +find_package(Qt5Quick REQUIRED) |
1468 | +find_package(Qt5DBus REQUIRED) |
1469 | + |
1470 | +# Build with system gmock and embedded gtest |
1471 | +set (GMOCK_INCLUDE_DIR "/usr/include/gmock/include" CACHE PATH "gmock source include directory") |
1472 | +set (GMOCK_SOURCE_DIR "/usr/src/gmock" CACHE PATH "gmock source directory") |
1473 | +set (GTEST_INCLUDE_DIR "${GMOCK_SOURCE_DIR}/gtest/include" CACHE PATH "gtest source include directory") |
1474 | + |
1475 | +add_subdirectory(${GMOCK_SOURCE_DIR} "${CMAKE_CURRENT_BINARY_DIR}/gmock") |
1476 | + |
1477 | +#set (OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) |
1478 | +# Don't treat warnings as errors in 3rd_party/{gmock,cucumber-cpp} |
1479 | +#string (REPLACE " -Werror " " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) |
1480 | +#find_package(Gtest REQUIRED) |
1481 | +#include_directories(${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR}) |
1482 | +#set (CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS}) |
1483 | + |
1484 | +include_directories( |
1485 | + ${CMAKE_SOURCE_DIR}/src/modules |
1486 | + ${GMOCK_INCLUDE_DIR} |
1487 | + ${GTEST_INCLUDE_DIR} |
1488 | +) |
1489 | + |
1490 | +add_executable( |
1491 | + taskcontroller_test |
1492 | + taskcontroller_test.cpp |
1493 | +) |
1494 | + |
1495 | +# We should not need this line according to the Qt5/CMake docs. |
1496 | +# However, when removing it, include paths are not set and linking to Qt5 fails. |
1497 | +qt5_use_modules(taskcontroller_test Core Quick DBus) |
1498 | + |
1499 | +target_link_libraries( |
1500 | + taskcontroller_test |
1501 | + |
1502 | + unityapplicationplugin |
1503 | + |
1504 | + Qt5::Core |
1505 | + Qt5::Quick |
1506 | + Qt5::DBus |
1507 | + |
1508 | + gtest |
1509 | + gtest_main |
1510 | + gmock |
1511 | +) |
1512 | + |
1513 | +add_test(taskcontroller_test ${CMAKE_CURRENT_BINARY_DIR}/taskcontroller_test) |
1514 | |
1515 | === added file 'tests/taskcontroller_test.cpp' |
1516 | --- tests/taskcontroller_test.cpp 1970-01-01 00:00:00 +0000 |
1517 | +++ tests/taskcontroller_test.cpp 2014-01-10 09:14:26 +0000 |
1518 | @@ -0,0 +1,211 @@ |
1519 | +/* |
1520 | + * Copyright (C) 2013 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 | + * Authored by: Thomas Voß <thomas.voss@canonical.com> |
1535 | + * |
1536 | + */ |
1537 | + |
1538 | +#include <Unity/Application/taskcontroller.h> |
1539 | + |
1540 | +#include <gmock/gmock.h> |
1541 | +#include <gtest/gtest.h> |
1542 | + |
1543 | +namespace |
1544 | +{ |
1545 | +struct MockOomController : public TaskController::OomController |
1546 | +{ |
1547 | + MOCK_METHOD1(ensureProcessLikelyToBeKilled, void(pid_t)); |
1548 | + MOCK_METHOD1(ensureProcessUnlikelyToBeKilled, void(pid_t)); |
1549 | +}; |
1550 | + |
1551 | +struct TriggerableApplicationController : public ApplicationController |
1552 | +{ |
1553 | + void triggerApplicationStarted(const QString& appId) |
1554 | + { |
1555 | + Q_EMIT applicationStarted(appId); |
1556 | + } |
1557 | + |
1558 | + void triggerApplicationStopped(const QString& appId) |
1559 | + { |
1560 | + Q_EMIT applicationStopped(appId); |
1561 | + } |
1562 | + |
1563 | + void triggerApplicationFocusRequest(const QString& appId) |
1564 | + { |
1565 | + Q_EMIT applicationFocusRequest(appId); |
1566 | + } |
1567 | + |
1568 | + MOCK_METHOD1(primaryPidForAppId, pid_t (const QString&)); |
1569 | + MOCK_METHOD2(appIdHasProcessId, bool(pid_t, const QString&)); |
1570 | + MOCK_METHOD1(stopApplicationWithAppId, bool(const QString&)); |
1571 | + MOCK_METHOD2(startApplicationWithAppIdAndArgs, bool(const QString&, const QStringList&)); |
1572 | +}; |
1573 | +} |
1574 | + |
1575 | +TEST(TaskController, startingAnApplicationCallsCorrectlyIntoApplicationController) |
1576 | +{ |
1577 | + using namespace ::testing; |
1578 | + |
1579 | + const QString appId{"com.canonical.does.not.exist"}; |
1580 | + |
1581 | + testing::NiceMock<TriggerableApplicationController> appController; |
1582 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1583 | + &appController, |
1584 | + [](ApplicationController*){}); |
1585 | + |
1586 | + EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, QStringList())).Times(1).WillRepeatedly(Return(true)); |
1587 | + |
1588 | + testing::NiceMock<MockOomController> oomController; |
1589 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1590 | + &oomController, |
1591 | + [](TaskController::OomController*){}); |
1592 | + |
1593 | + TaskController taskController(nullptr, |
1594 | + appControllerPtr, |
1595 | + oomControllerPtr); |
1596 | + |
1597 | + taskController.start("com.canonical.does.not.exist", QStringList()); |
1598 | +} |
1599 | + |
1600 | +TEST(TaskController, stoppingAnApplicationCallsCorrectlyIntoApplicationController) |
1601 | +{ |
1602 | + using namespace ::testing; |
1603 | + |
1604 | + const QString appId{"com.canonical.does.not.exist"}; |
1605 | + |
1606 | + testing::NiceMock<TriggerableApplicationController> appController; |
1607 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1608 | + &appController, |
1609 | + [](ApplicationController*){}); |
1610 | + |
1611 | + EXPECT_CALL(appController, stopApplicationWithAppId(appId)).Times(1).WillRepeatedly(Return(true)); |
1612 | + |
1613 | + testing::NiceMock<MockOomController> oomController; |
1614 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1615 | + &oomController, |
1616 | + [](TaskController::OomController*){}); |
1617 | + |
1618 | + TaskController taskController(nullptr, |
1619 | + appControllerPtr, |
1620 | + oomControllerPtr); |
1621 | + |
1622 | + taskController.stop("com.canonical.does.not.exist"); |
1623 | +} |
1624 | + |
1625 | +TEST(TaskController, suspendingAnApplicationAdjustsOomScoreForCorrectPid) |
1626 | +{ |
1627 | + using namespace ::testing; |
1628 | + |
1629 | + const QString appId{"com.canonical.does.not.exist"}; |
1630 | + |
1631 | + testing::NiceMock<TriggerableApplicationController> appController; |
1632 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1633 | + &appController, |
1634 | + [](ApplicationController*){}); |
1635 | + |
1636 | + EXPECT_CALL(appController, primaryPidForAppId(appId)).Times(1).WillRepeatedly(Return(-1)); |
1637 | + |
1638 | + testing::NiceMock<MockOomController> oomController; |
1639 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1640 | + &oomController, |
1641 | + [](TaskController::OomController*){}); |
1642 | + |
1643 | + EXPECT_CALL(oomController, ensureProcessLikelyToBeKilled(-1)).Times(1); |
1644 | + |
1645 | + TaskController taskController(nullptr, |
1646 | + appControllerPtr, |
1647 | + oomControllerPtr); |
1648 | + |
1649 | + taskController.suspend("com.canonical.does.not.exist"); |
1650 | +} |
1651 | + |
1652 | +TEST(TaskController, resumingAnApplicationAdjustsOomScoreForCorrectPid) |
1653 | +{ |
1654 | + using namespace ::testing; |
1655 | + |
1656 | + const QString appId{"com.canonical.does.not.exist"}; |
1657 | + |
1658 | + testing::NiceMock<TriggerableApplicationController> appController; |
1659 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1660 | + &appController, |
1661 | + [](ApplicationController*){}); |
1662 | + |
1663 | + EXPECT_CALL(appController, primaryPidForAppId(appId)).Times(1).WillRepeatedly(Return(-1)); |
1664 | + |
1665 | + testing::NiceMock<MockOomController> oomController; |
1666 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1667 | + &oomController, |
1668 | + [](TaskController::OomController*){}); |
1669 | + |
1670 | + EXPECT_CALL(oomController, ensureProcessUnlikelyToBeKilled(-1)).Times(1); |
1671 | + |
1672 | + TaskController taskController(nullptr, |
1673 | + appControllerPtr, |
1674 | + oomControllerPtr); |
1675 | + |
1676 | + taskController.resume("com.canonical.does.not.exist"); |
1677 | +} |
1678 | + |
1679 | +TEST(TaskController, aStartedApplicationIsOomScoreAdjusted) |
1680 | +{ |
1681 | + using namespace ::testing; |
1682 | + |
1683 | + const QString appId{"com.canonical.does.not.exist"}; |
1684 | + |
1685 | + testing::NiceMock<TriggerableApplicationController> appController; |
1686 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1687 | + &appController, |
1688 | + [](ApplicationController*){}); |
1689 | + EXPECT_CALL(appController, primaryPidForAppId(appId)).Times(1).WillRepeatedly(Return(42)); |
1690 | + |
1691 | + testing::NiceMock<MockOomController> oomController; |
1692 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1693 | + &oomController, |
1694 | + [](TaskController::OomController*){}); |
1695 | + |
1696 | + EXPECT_CALL(oomController, ensureProcessUnlikelyToBeKilled(42)).Times(1); |
1697 | + |
1698 | + TaskController taskController(nullptr, |
1699 | + appControllerPtr, |
1700 | + oomControllerPtr); |
1701 | + |
1702 | + appControllerPtr->triggerApplicationStarted("com.canonical.does.not.exist"); |
1703 | +} |
1704 | + |
1705 | +TEST(TaskController, aFocusedApplicationIsOomScoreAdjusted) |
1706 | +{ |
1707 | + using namespace ::testing; |
1708 | + |
1709 | + const QString appId{"com.canonical.does.not.exist"}; |
1710 | + |
1711 | + testing::NiceMock<TriggerableApplicationController> appController; |
1712 | + QSharedPointer<TriggerableApplicationController> appControllerPtr( |
1713 | + &appController, |
1714 | + [](ApplicationController*){}); |
1715 | + EXPECT_CALL(appController, primaryPidForAppId(appId)).Times(1).WillRepeatedly(Return(42)); |
1716 | + |
1717 | + testing::NiceMock<MockOomController> oomController; |
1718 | + QSharedPointer<TaskController::OomController> oomControllerPtr( |
1719 | + &oomController, |
1720 | + [](TaskController::OomController*){}); |
1721 | + |
1722 | + EXPECT_CALL(oomController, ensureProcessUnlikelyToBeKilled(42)).Times(1); |
1723 | + |
1724 | + TaskController taskController(nullptr, |
1725 | + appControllerPtr, |
1726 | + oomControllerPtr); |
1727 | + |
1728 | + appControllerPtr->triggerApplicationFocusRequest("com.canonical.does.not.exist"); |
1729 | +} |
1730 | |
1731 | === removed file 'tests/tests.pro' |
1732 | === removed file 'unity-mir.pro' |
1733 | --- unity-mir.pro 2013-09-26 09:48:22 +0000 |
1734 | +++ unity-mir.pro 1970-01-01 00:00:00 +0000 |
1735 | @@ -1,2 +0,0 @@ |
1736 | -TEMPLATE = subdirs |
1737 | -SUBDIRS = src #tests |
Missing debian/control entry.