Merge lp:~mterry/qtmir/no-touch-no-lifecycle into lp:qtmir
- no-touch-no-lifecycle
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Gerry Boland |
Approved revision: | 394 |
Merged at revision: | 400 |
Proposed branch: | lp:~mterry/qtmir/no-touch-no-lifecycle |
Merge into: | lp:qtmir |
Diff against target: |
527 lines (+56/-165) 15 files modified
CMakeLists.txt (+1/-1) debian/control (+2/-2) src/modules/Unity/Application/application.cpp (+7/-25) src/modules/Unity/Application/application.h (+1/-3) src/modules/Unity/Application/application_manager.cpp (+2/-12) src/modules/Unity/Application/application_manager.h (+1/-2) src/modules/Unity/Application/com.canonical.qtmir.gschema.xml (+2/-0) src/modules/Unity/Application/desktopfilereader.cpp (+12/-0) src/modules/Unity/Application/desktopfilereader.h (+1/-0) tests/modules/Application/application_test.cpp (+16/-0) tests/modules/ApplicationManager/application_manager_test.cpp (+0/-117) tests/modules/DesktopFileReader/desktopfilereader_test.cpp (+3/-0) tests/modules/common/fake_desktopfilereader.h (+1/-0) tests/modules/common/mock_desktop_file_reader.h (+7/-0) tests/modules/common/qtmir_test.cpp (+0/-3) |
To merge this branch: | bzr merge lp:~mterry/qtmir/no-touch-no-lifecycle |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Gerry Boland (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email: mp+272791@code.launchpad.net |
Commit message
Support new isTouchApp property to ApplicationInfo
Now that qtmir won't decide policy for suspending anymore, we don't need all the lifecycleException handling in qtmir either. That can move to unity8.
But since the GSettings key for that was registered under the qtmir namespace (and there's no technical reason to migrate settings), I left the schema and classes dealing with GSettings alone, for future use.
Description of the change
Support new isTouchApp property to ApplicationInfo
Now that qtmir won't decide policy for suspending anymore, we don't need all the lifecycleException handling in qtmir either. That can move to unity8.
But since the GSettings key for that was registered under the qtmir namespace (and there's no technical reason to migrate settings), I left the schema and classes dealing with GSettings alone, for future use.
* Are there any related MPs required for this MP to build/function as expected? Please list.
https:/
https:/
* 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?
I'm on that team
PS Jenkins bot (ps-jenkins) wrote : | # |
Gerry Boland (gerboland) wrote : | # |
I dislike the API you've added. The requestedState property is what shell uses to set a process to be suspended or not. It is confusing for shell to request a suspended state in one place, and in another place disallow suspending. Shell should just make the correct request first time.
Sure we've had this lifecycle exceptions policy in qtmir, but as you've moved that into unity8, there is no reason I can see for this "canSuspend" concept in qtmir any more.
- 386. By Michael Terry
-
Drop canSuspend and RunningInBackground state
- 387. By Michael Terry
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:387
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 388. By Michael Terry
-
Support RoleIsTouchApp
- 389. By Michael Terry
-
minor fixes
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:388
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:389
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
This code change looks good to me.
Do we want to police apps from enabling this flag? How would we do that? There's no real way we can prevent an app from setting this. And if it results in a lifecycle exemption, many might set it!!
Perhaps having it so only Touch apps can be launched on the phone, while it is undocked, is enough motivation for app devs not to abuse this?
Gerry Boland (gerboland) wrote : | # |
Also, I'd love to kill the GSettings schema. I think only MZanetti's TweakGeek app relies on it ATM.
Michael Terry (mterry) wrote : | # |
> Do we want to police apps from enabling this flag?
From setting X-Ubuntu-
That's one of the benefits of re-using this flag. :)
> Also, I'd love to kill the GSettings schema.
Fair... The default right now is just the music-app. I don't know whether it's safe to remove that yet. Presumably that uses content-hub now? Or wants to in the future, I'd hope.
Anyway, that can be a separate MP.
Gerry Boland (gerboland) wrote : | # |
/«BUILDDIR»
ASSERT_
Please use ASSERT_FALSE
- 390. By Michael Terry
-
Merge from trunk
- 391. By Michael Terry
-
Use ASSERT_TRUE/FALSE
Michael Terry (mterry) wrote : | # |
> Please use ASSERT_FALSE
Done.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:391
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 392. By Michael Terry
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:392
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 393. By Michael Terry
-
Bump shell application version
- 394. By Michael Terry
-
Bump shell application version harder
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:393
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:394
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Gerry Boland (gerboland) wrote : | # |
Tested on device, I see no behavioural regression, +1 from me.
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-10-21 11:47:03 +0000 | |||
3 | +++ CMakeLists.txt 2015-10-30 17:00:37 +0000 | |||
4 | @@ -75,7 +75,7 @@ | |||
5 | 75 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) | 75 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) |
6 | 76 | pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED) | 76 | pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED) |
7 | 77 | pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED) | 77 | pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED) |
9 | 78 | pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=9) | 78 | pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=10) |
10 | 79 | 79 | ||
11 | 80 | include_directories(${APPLICATION_API_INCLUDE_DIRS}) | 80 | include_directories(${APPLICATION_API_INCLUDE_DIRS}) |
12 | 81 | 81 | ||
13 | 82 | 82 | ||
14 | === modified file 'debian/control' | |||
15 | --- debian/control 2015-10-21 11:46:54 +0000 | |||
16 | +++ debian/control 2015-10-30 17:00:37 +0000 | |||
17 | @@ -23,7 +23,7 @@ | |||
18 | 23 | libubuntu-app-launch2-dev, | 23 | libubuntu-app-launch2-dev, |
19 | 24 | libubuntu-application-api-dev (>= 2.1.0), | 24 | libubuntu-application-api-dev (>= 2.1.0), |
20 | 25 | libudev-dev, | 25 | libudev-dev, |
22 | 26 | libunity-api-dev (>= 7.101), | 26 | libunity-api-dev (>= 7.102), |
23 | 27 | liburl-dispatcher1-dev, | 27 | liburl-dispatcher1-dev, |
24 | 28 | libxkbcommon-dev, | 28 | libxkbcommon-dev, |
25 | 29 | libxrender-dev, | 29 | libxrender-dev, |
26 | @@ -93,7 +93,7 @@ | |||
27 | 93 | Conflicts: libqtmir, | 93 | Conflicts: libqtmir, |
28 | 94 | libunity-mir1, | 94 | libunity-mir1, |
29 | 95 | Provides: unity-application-impl, | 95 | Provides: unity-application-impl, |
31 | 96 | unity-application-impl-9, | 96 | unity-application-impl-10, |
32 | 97 | Description: Qt plugin for Unity specific Mir APIs | 97 | Description: Qt plugin for Unity specific Mir APIs |
33 | 98 | QtMir provides Qt/QML bindings for Mir features that are exposed through the | 98 | QtMir provides Qt/QML bindings for Mir features that are exposed through the |
34 | 99 | qtmir-desktop or qtmir-android QPA plugin such as Application management | 99 | qtmir-desktop or qtmir-android QPA plugin such as Application management |
35 | 100 | 100 | ||
36 | === modified file 'src/modules/Unity/Application/application.cpp' | |||
37 | --- src/modules/Unity/Application/application.cpp 2015-09-29 14:01:12 +0000 | |||
38 | +++ src/modules/Unity/Application/application.cpp 2015-10-30 17:00:37 +0000 | |||
39 | @@ -37,8 +37,6 @@ | |||
40 | 37 | namespace qtmir | 37 | namespace qtmir |
41 | 38 | { | 38 | { |
42 | 39 | 39 | ||
43 | 40 | QStringList Application::lifecycleExceptions; | ||
44 | 41 | |||
45 | 42 | Application::Application(const QSharedPointer<SharedWakelock>& sharedWakelock, | 40 | Application::Application(const QSharedPointer<SharedWakelock>& sharedWakelock, |
46 | 43 | DesktopFileReader *desktopFileReader, | 41 | DesktopFileReader *desktopFileReader, |
47 | 44 | const QStringList &arguments, | 42 | const QStringList &arguments, |
48 | @@ -80,7 +78,6 @@ | |||
49 | 80 | switch (m_state) { | 78 | switch (m_state) { |
50 | 81 | case InternalState::Starting: | 79 | case InternalState::Starting: |
51 | 82 | case InternalState::Running: | 80 | case InternalState::Running: |
52 | 83 | case InternalState::RunningInBackground: | ||
53 | 84 | case InternalState::SuspendingWaitSession: | 81 | case InternalState::SuspendingWaitSession: |
54 | 85 | case InternalState::SuspendingWaitProcess: | 82 | case InternalState::SuspendingWaitProcess: |
55 | 86 | wipeQMLCache(); | 83 | wipeQMLCache(); |
56 | @@ -212,8 +209,6 @@ | |||
57 | 212 | return "Starting"; | 209 | return "Starting"; |
58 | 213 | case InternalState::Running: | 210 | case InternalState::Running: |
59 | 214 | return "Running"; | 211 | return "Running"; |
60 | 215 | case InternalState::RunningInBackground: | ||
61 | 216 | return "RunningInBackground"; | ||
62 | 217 | case InternalState::SuspendingWaitSession: | 212 | case InternalState::SuspendingWaitSession: |
63 | 218 | return "SuspendingWaitSession"; | 213 | return "SuspendingWaitSession"; |
64 | 219 | case InternalState::SuspendingWaitProcess: | 214 | case InternalState::SuspendingWaitProcess: |
65 | @@ -282,7 +277,6 @@ | |||
66 | 282 | case InternalState::Starting: | 277 | case InternalState::Starting: |
67 | 283 | return Starting; | 278 | return Starting; |
68 | 284 | case InternalState::Running: | 279 | case InternalState::Running: |
69 | 285 | case InternalState::RunningInBackground: | ||
70 | 286 | case InternalState::SuspendingWaitSession: | 280 | case InternalState::SuspendingWaitSession: |
71 | 287 | case InternalState::SuspendingWaitProcess: | 281 | case InternalState::SuspendingWaitProcess: |
72 | 288 | case InternalState::Closing: | 282 | case InternalState::Closing: |
73 | @@ -333,7 +327,6 @@ | |||
74 | 333 | case InternalState::Running: | 327 | case InternalState::Running: |
75 | 334 | // already where it's wanted to be | 328 | // already where it's wanted to be |
76 | 335 | break; | 329 | break; |
77 | 336 | case InternalState::RunningInBackground: | ||
78 | 337 | case InternalState::SuspendingWaitSession: | 330 | case InternalState::SuspendingWaitSession: |
79 | 338 | case InternalState::Suspended: | 331 | case InternalState::Suspended: |
80 | 339 | resume(); | 332 | resume(); |
81 | @@ -366,7 +359,6 @@ | |||
82 | 366 | Q_ASSERT(m_processState == ProcessUnknown); | 359 | Q_ASSERT(m_processState == ProcessUnknown); |
83 | 367 | } | 360 | } |
84 | 368 | break; | 361 | break; |
85 | 369 | case InternalState::RunningInBackground: | ||
86 | 370 | case InternalState::SuspendingWaitSession: | 362 | case InternalState::SuspendingWaitSession: |
87 | 371 | case InternalState::SuspendingWaitProcess: | 363 | case InternalState::SuspendingWaitProcess: |
88 | 372 | case InternalState::Suspended: | 364 | case InternalState::Suspended: |
89 | @@ -416,7 +408,6 @@ | |||
90 | 416 | case InternalState::Running: | 408 | case InternalState::Running: |
91 | 417 | setInternalState(InternalState::Closing); | 409 | setInternalState(InternalState::Closing); |
92 | 418 | break; | 410 | break; |
93 | 419 | case InternalState::RunningInBackground: | ||
94 | 420 | case InternalState::SuspendingWaitSession: | 411 | case InternalState::SuspendingWaitSession: |
95 | 421 | case InternalState::SuspendingWaitProcess: | 412 | case InternalState::SuspendingWaitProcess: |
96 | 422 | case InternalState::Suspended: | 413 | case InternalState::Suspended: |
97 | @@ -461,7 +452,6 @@ | |||
98 | 461 | switch (m_state) { | 452 | switch (m_state) { |
99 | 462 | case InternalState::Starting: | 453 | case InternalState::Starting: |
100 | 463 | case InternalState::Running: | 454 | case InternalState::Running: |
101 | 464 | case InternalState::RunningInBackground: | ||
102 | 465 | case InternalState::Closing: | 455 | case InternalState::Closing: |
103 | 466 | m_session->resume(); | 456 | m_session->resume(); |
104 | 467 | break; | 457 | break; |
105 | @@ -520,9 +510,6 @@ | |||
106 | 520 | case InternalState::Running: | 510 | case InternalState::Running: |
107 | 521 | acquireWakelock(); | 511 | acquireWakelock(); |
108 | 522 | break; | 512 | break; |
109 | 523 | case InternalState::RunningInBackground: | ||
110 | 524 | releaseWakelock(); | ||
111 | 525 | break; | ||
112 | 526 | case InternalState::Suspended: | 513 | case InternalState::Suspended: |
113 | 527 | releaseWakelock(); | 514 | releaseWakelock(); |
114 | 528 | break; | 515 | break; |
115 | @@ -619,16 +606,8 @@ | |||
116 | 619 | Q_ASSERT(m_state == InternalState::Running); | 606 | Q_ASSERT(m_state == InternalState::Running); |
117 | 620 | Q_ASSERT(m_session != nullptr); | 607 | Q_ASSERT(m_session != nullptr); |
118 | 621 | 608 | ||
129 | 622 | if (!lifecycleExceptions.filter(appId().section('_',0,0)).empty()) { | 609 | setInternalState(InternalState::SuspendingWaitSession); |
130 | 623 | // Present in exceptions list. | 610 | m_session->suspend(); |
121 | 624 | // There's no need to keep the wakelock as the process is never suspended | ||
122 | 625 | // and thus has no cleanup to perform when (for example) the display is | ||
123 | 626 | // blanked. | ||
124 | 627 | setInternalState(InternalState::RunningInBackground); | ||
125 | 628 | } else { | ||
126 | 629 | setInternalState(InternalState::SuspendingWaitSession); | ||
127 | 630 | m_session->suspend(); | ||
128 | 631 | } | ||
131 | 632 | } | 611 | } |
132 | 633 | 612 | ||
133 | 634 | void Application::resume() | 613 | void Application::resume() |
134 | @@ -643,8 +622,6 @@ | |||
135 | 643 | } else if (m_state == InternalState::SuspendingWaitSession) { | 622 | } else if (m_state == InternalState::SuspendingWaitSession) { |
136 | 644 | setInternalState(InternalState::Running); | 623 | setInternalState(InternalState::Running); |
137 | 645 | m_session->resume(); | 624 | m_session->resume(); |
138 | 646 | } else if (m_state == InternalState::RunningInBackground) { | ||
139 | 647 | setInternalState(InternalState::Running); | ||
140 | 648 | } | 625 | } |
141 | 649 | } | 626 | } |
142 | 650 | 627 | ||
143 | @@ -657,6 +634,11 @@ | |||
144 | 657 | Q_EMIT startProcessRequested(); | 634 | Q_EMIT startProcessRequested(); |
145 | 658 | } | 635 | } |
146 | 659 | 636 | ||
147 | 637 | bool Application::isTouchApp() const | ||
148 | 638 | { | ||
149 | 639 | return m_desktopData->isTouchApp(); | ||
150 | 640 | } | ||
151 | 641 | |||
152 | 660 | QString Application::longAppId() const | 642 | QString Application::longAppId() const |
153 | 661 | { | 643 | { |
154 | 662 | return m_longAppId; | 644 | return m_longAppId; |
155 | 663 | 645 | ||
156 | === modified file 'src/modules/Unity/Application/application.h' | |||
157 | --- src/modules/Unity/Application/application.h 2015-09-29 14:01:12 +0000 | |||
158 | +++ src/modules/Unity/Application/application.h 2015-10-30 17:00:37 +0000 | |||
159 | @@ -68,7 +68,6 @@ | |||
160 | 68 | enum class InternalState { | 68 | enum class InternalState { |
161 | 69 | Starting, | 69 | Starting, |
162 | 70 | Running, | 70 | Running, |
163 | 71 | RunningInBackground, | ||
164 | 72 | SuspendingWaitSession, | 71 | SuspendingWaitSession, |
165 | 73 | SuspendingWaitProcess, | 72 | SuspendingWaitProcess, |
166 | 74 | Suspended, | 73 | Suspended, |
167 | @@ -104,6 +103,7 @@ | |||
168 | 104 | QColor splashColorFooter() const override; | 103 | QColor splashColorFooter() const override; |
169 | 105 | Qt::ScreenOrientations supportedOrientations() const override; | 104 | Qt::ScreenOrientations supportedOrientations() const override; |
170 | 106 | bool rotatesWindowContents() const override; | 105 | bool rotatesWindowContents() const override; |
171 | 106 | bool isTouchApp() const override; | ||
172 | 107 | 107 | ||
173 | 108 | void setStage(Stage stage); | 108 | void setStage(Stage stage); |
174 | 109 | 109 | ||
175 | @@ -131,8 +131,6 @@ | |||
176 | 131 | // for tests | 131 | // for tests |
177 | 132 | InternalState internalState() const { return m_state; } | 132 | InternalState internalState() const { return m_state; } |
178 | 133 | 133 | ||
179 | 134 | static QStringList lifecycleExceptions; | ||
180 | 135 | |||
181 | 136 | Q_SIGNALS: | 134 | Q_SIGNALS: |
182 | 137 | void fullscreenChanged(bool fullscreen); | 135 | void fullscreenChanged(bool fullscreen); |
183 | 138 | void stageChanged(Stage stage); | 136 | void stageChanged(Stage stage); |
184 | 139 | 137 | ||
185 | === modified file 'src/modules/Unity/Application/application_manager.cpp' | |||
186 | --- src/modules/Unity/Application/application_manager.cpp 2015-09-29 14:01:12 +0000 | |||
187 | +++ src/modules/Unity/Application/application_manager.cpp 2015-10-30 17:00:37 +0000 | |||
188 | @@ -196,11 +196,6 @@ | |||
189 | 196 | 196 | ||
190 | 197 | m_roleNames.insert(RoleSession, "session"); | 197 | m_roleNames.insert(RoleSession, "session"); |
191 | 198 | m_roleNames.insert(RoleFullscreen, "fullscreen"); | 198 | m_roleNames.insert(RoleFullscreen, "fullscreen"); |
192 | 199 | |||
193 | 200 | if (settings.data()) { | ||
194 | 201 | Application::lifecycleExceptions = m_settings->get("lifecycleExemptAppids").toStringList(); | ||
195 | 202 | connect(m_settings.data(), &Settings::changed, this, &ApplicationManager::onSettingsChanged); | ||
196 | 203 | } | ||
197 | 204 | } | 199 | } |
198 | 205 | 200 | ||
199 | 206 | ApplicationManager::~ApplicationManager() | 201 | ApplicationManager::~ApplicationManager() |
200 | @@ -232,6 +227,8 @@ | |||
201 | 232 | return QVariant::fromValue((int)application->state()); | 227 | return QVariant::fromValue((int)application->state()); |
202 | 233 | case RoleFocused: | 228 | case RoleFocused: |
203 | 234 | return QVariant::fromValue(application->focused()); | 229 | return QVariant::fromValue(application->focused()); |
204 | 230 | case RoleIsTouchApp: | ||
205 | 231 | return QVariant::fromValue(application->isTouchApp()); | ||
206 | 235 | case RoleSession: | 232 | case RoleSession: |
207 | 236 | return QVariant::fromValue(application->session()); | 233 | return QVariant::fromValue(application->session()); |
208 | 237 | case RoleFullscreen: | 234 | case RoleFullscreen: |
209 | @@ -538,13 +535,6 @@ | |||
210 | 538 | } | 535 | } |
211 | 539 | } | 536 | } |
212 | 540 | 537 | ||
213 | 541 | void ApplicationManager::onSettingsChanged(const QString &key) | ||
214 | 542 | { | ||
215 | 543 | if (key == "lifecycleExemptAppids") { | ||
216 | 544 | Application::lifecycleExceptions = m_settings->get("lifecycleExemptAppids").toStringList(); | ||
217 | 545 | } | ||
218 | 546 | } | ||
219 | 547 | |||
220 | 548 | void ApplicationManager::authorizeSession(const quint64 pid, bool &authorized) | 538 | void ApplicationManager::authorizeSession(const quint64 pid, bool &authorized) |
221 | 549 | { | 539 | { |
222 | 550 | tracepoint(qtmir, authorizeSession); | 540 | tracepoint(qtmir, authorizeSession); |
223 | 551 | 541 | ||
224 | === modified file 'src/modules/Unity/Application/application_manager.h' | |||
225 | --- src/modules/Unity/Application/application_manager.h 2015-08-21 00:00:16 +0000 | |||
226 | +++ src/modules/Unity/Application/application_manager.h 2015-10-30 17:00:37 +0000 | |||
227 | @@ -68,7 +68,7 @@ | |||
228 | 68 | 68 | ||
229 | 69 | // FIXME: these roles should be added to unity-api and removed from here | 69 | // FIXME: these roles should be added to unity-api and removed from here |
230 | 70 | enum MoreRoles { | 70 | enum MoreRoles { |
232 | 71 | RoleSession = RoleFocused+1, | 71 | RoleSession = RoleIsTouchApp+1, |
233 | 72 | RoleFullscreen, | 72 | RoleFullscreen, |
234 | 73 | }; | 73 | }; |
235 | 74 | 74 | ||
236 | @@ -137,7 +137,6 @@ | |||
237 | 137 | 137 | ||
238 | 138 | private Q_SLOTS: | 138 | private Q_SLOTS: |
239 | 139 | void onAppDataChanged(const int role); | 139 | void onAppDataChanged(const int role); |
240 | 140 | void onSettingsChanged(const QString &key); | ||
241 | 141 | 140 | ||
242 | 142 | private: | 141 | private: |
243 | 143 | void setFocused(Application *application); | 142 | void setFocused(Application *application); |
244 | 144 | 143 | ||
245 | === modified file 'src/modules/Unity/Application/com.canonical.qtmir.gschema.xml' | |||
246 | --- src/modules/Unity/Application/com.canonical.qtmir.gschema.xml 2015-03-13 16:12:39 +0000 | |||
247 | +++ src/modules/Unity/Application/com.canonical.qtmir.gschema.xml 2015-10-30 17:00:37 +0000 | |||
248 | @@ -1,4 +1,6 @@ | |||
249 | 1 | <schemalist> | 1 | <schemalist> |
250 | 2 | <!-- This schema is packaged in qtmir for historical reasons. | ||
251 | 3 | It is interpreted by unity8 these days. --> | ||
252 | 2 | <schema path="/com/canonical/qtmir/" id="com.canonical.qtmir" gettext-domain="qtmir"> | 4 | <schema path="/com/canonical/qtmir/" id="com.canonical.qtmir" gettext-domain="qtmir"> |
253 | 3 | <key type="as" name="lifecycle-exempt-appids"> | 5 | <key type="as" name="lifecycle-exempt-appids"> |
254 | 4 | <default>[ | 6 | <default>[ |
255 | 5 | 7 | ||
256 | === modified file 'src/modules/Unity/Application/desktopfilereader.cpp' | |||
257 | --- src/modules/Unity/Application/desktopfilereader.cpp 2015-08-11 12:08:32 +0000 | |||
258 | +++ src/modules/Unity/Application/desktopfilereader.cpp 2015-10-30 17:00:37 +0000 | |||
259 | @@ -228,6 +228,18 @@ | |||
260 | 228 | return result; | 228 | return result; |
261 | 229 | } | 229 | } |
262 | 230 | 230 | ||
263 | 231 | bool DesktopFileReader::isTouchApp() const | ||
264 | 232 | { | ||
265 | 233 | Q_D(const DesktopFileReader); | ||
266 | 234 | bool result; | ||
267 | 235 | |||
268 | 236 | if (!parseBoolean(d->getKey("X-Ubuntu-Touch"), result)) { | ||
269 | 237 | qCWarning(QTMIR_APPLICATIONS) << d->file << "has an invalid X-Ubuntu-Touch entry."; | ||
270 | 238 | } | ||
271 | 239 | |||
272 | 240 | return result; | ||
273 | 241 | } | ||
274 | 242 | |||
275 | 231 | bool DesktopFileReader::parseOrientations(const QString &rawString, Qt::ScreenOrientations &result) | 243 | bool DesktopFileReader::parseOrientations(const QString &rawString, Qt::ScreenOrientations &result) |
276 | 232 | { | 244 | { |
277 | 233 | // Default to all orientations | 245 | // Default to all orientations |
278 | 234 | 246 | ||
279 | === modified file 'src/modules/Unity/Application/desktopfilereader.h' | |||
280 | --- src/modules/Unity/Application/desktopfilereader.h 2015-08-19 20:17:56 +0000 | |||
281 | +++ src/modules/Unity/Application/desktopfilereader.h 2015-10-30 17:00:37 +0000 | |||
282 | @@ -57,6 +57,7 @@ | |||
283 | 57 | virtual QString splashColorFooter() const; | 57 | virtual QString splashColorFooter() const; |
284 | 58 | virtual Qt::ScreenOrientations supportedOrientations() const; | 58 | virtual Qt::ScreenOrientations supportedOrientations() const; |
285 | 59 | virtual bool rotatesWindowContents() const; | 59 | virtual bool rotatesWindowContents() const; |
286 | 60 | virtual bool isTouchApp() const; | ||
287 | 60 | virtual bool loaded() const; | 61 | virtual bool loaded() const; |
288 | 61 | 62 | ||
289 | 62 | static bool parseOrientations(const QString &rawString, Qt::ScreenOrientations &result); | 63 | static bool parseOrientations(const QString &rawString, Qt::ScreenOrientations &result); |
290 | 63 | 64 | ||
291 | === modified file 'tests/modules/Application/application_test.cpp' | |||
292 | --- tests/modules/Application/application_test.cpp 2015-08-20 16:04:25 +0000 | |||
293 | +++ tests/modules/Application/application_test.cpp 2015-10-30 17:00:37 +0000 | |||
294 | @@ -287,3 +287,19 @@ | |||
295 | 287 | ASSERT_EQ(0, spyAppStopped.count()); | 287 | ASSERT_EQ(0, spyAppStopped.count()); |
296 | 288 | 288 | ||
297 | 289 | } | 289 | } |
298 | 290 | |||
299 | 291 | TEST_F(ApplicationTests, passesIsTouchAppThrough) | ||
300 | 292 | { | ||
301 | 293 | using namespace ::testing; | ||
302 | 294 | |||
303 | 295 | auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(QString(), QFileInfo()); | ||
304 | 296 | QScopedPointer<Application> application(new Application( | ||
305 | 297 | QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}), | ||
306 | 298 | mockDesktopFileReader, QStringList(), nullptr)); | ||
307 | 299 | |||
308 | 300 | ON_CALL(*mockDesktopFileReader, isTouchApp()).WillByDefault(Return(true)); | ||
309 | 301 | ASSERT_TRUE(application->isTouchApp()); | ||
310 | 302 | |||
311 | 303 | ON_CALL(*mockDesktopFileReader, isTouchApp()).WillByDefault(Return(false)); | ||
312 | 304 | ASSERT_FALSE(application->isTouchApp()); | ||
313 | 305 | } | ||
314 | 290 | 306 | ||
315 | === modified file 'tests/modules/ApplicationManager/application_manager_test.cpp' | |||
316 | --- tests/modules/ApplicationManager/application_manager_test.cpp 2015-09-29 14:01:12 +0000 | |||
317 | +++ tests/modules/ApplicationManager/application_manager_test.cpp 2015-10-30 17:00:37 +0000 | |||
318 | @@ -1737,123 +1737,6 @@ | |||
319 | 1737 | } | 1737 | } |
320 | 1738 | } | 1738 | } |
321 | 1739 | 1739 | ||
322 | 1740 | TEST_F(ApplicationManagerTests,lifecycle_exempt_appId_is_not_suspended) | ||
323 | 1741 | { | ||
324 | 1742 | using namespace ::testing; | ||
325 | 1743 | quint64 a_procId = 5921; | ||
326 | 1744 | const QString appId("some_app"); | ||
327 | 1745 | QByteArray a_cmd("/usr/bin/app1"); | ||
328 | 1746 | |||
329 | 1747 | ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd)); | ||
330 | 1748 | |||
331 | 1749 | ON_CALL(appController,appIdHasProcessId(a_procId, appId)).WillByDefault(Return(true)); | ||
332 | 1750 | |||
333 | 1751 | // Set up Mocks & signal watcher | ||
334 | 1752 | auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo()); | ||
335 | 1753 | ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true)); | ||
336 | 1754 | ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId)); | ||
337 | 1755 | |||
338 | 1756 | ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader)); | ||
339 | 1757 | |||
340 | 1758 | |||
341 | 1759 | Application *the_app = applicationManager.startApplication(appId, ApplicationManager::NoFlag); | ||
342 | 1760 | applicationManager.onProcessStarting(appId); | ||
343 | 1761 | |||
344 | 1762 | std::shared_ptr<mir::scene::Session> first_session = std::make_shared<MockSession>("Oo", a_procId); | ||
345 | 1763 | std::shared_ptr<mir::scene::Session> second_session = std::make_shared<MockSession>("oO", a_procId); | ||
346 | 1764 | { | ||
347 | 1765 | bool authed = false; | ||
348 | 1766 | applicationManager.authorizeSession(a_procId, authed); | ||
349 | 1767 | ASSERT_EQ(authed, true); | ||
350 | 1768 | } | ||
351 | 1769 | |||
352 | 1770 | onSessionStarting(first_session); | ||
353 | 1771 | FakeMirSurface *aSurface = new FakeMirSurface; | ||
354 | 1772 | onSessionCreatedSurface(first_session.get(), aSurface); | ||
355 | 1773 | aSurface->drawFirstFrame(); | ||
356 | 1774 | onSessionStarting(second_session); | ||
357 | 1775 | |||
358 | 1776 | // Add to other apps to the list (Not "some_app") | ||
359 | 1777 | QVariantList lifecycleExemptAppIds; | ||
360 | 1778 | lifecycleExemptAppIds << "one_app" << "another_app"; | ||
361 | 1779 | ON_CALL(settings,get(_)).WillByDefault(Return(lifecycleExemptAppIds)); | ||
362 | 1780 | settings.changed("lifecycleExemptAppids"); | ||
363 | 1781 | |||
364 | 1782 | ASSERT_EQ(Application::InternalState::Running, the_app->internalState()); | ||
365 | 1783 | |||
366 | 1784 | EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(mir_lifecycle_state_will_suspend)); | ||
367 | 1785 | the_app->setRequestedState(Application::RequestedSuspended); | ||
368 | 1786 | ASSERT_EQ(Application::InternalState::SuspendingWaitSession, the_app->internalState()); | ||
369 | 1787 | |||
370 | 1788 | static_cast<qtmir::Session*>(the_app->session())->doSuspend(); | ||
371 | 1789 | ASSERT_EQ(Application::InternalState::SuspendingWaitProcess, the_app->internalState()); | ||
372 | 1790 | applicationManager.onProcessSuspended(the_app->appId()); | ||
373 | 1791 | ASSERT_EQ(Application::InternalState::Suspended, the_app->internalState()); | ||
374 | 1792 | |||
375 | 1793 | EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(mir_lifecycle_state_resumed)); | ||
376 | 1794 | the_app->setRequestedState(Application::RequestedRunning); | ||
377 | 1795 | |||
378 | 1796 | EXPECT_EQ(Application::Running, the_app->state()); | ||
379 | 1797 | |||
380 | 1798 | // Now add "some_app" to the exception list | ||
381 | 1799 | lifecycleExemptAppIds << "some_app"; | ||
382 | 1800 | ON_CALL(settings,get(_)).WillByDefault(Return(lifecycleExemptAppIds)); | ||
383 | 1801 | settings.changed("lifecycleExemptAppids"); | ||
384 | 1802 | |||
385 | 1803 | EXPECT_EQ(Application::Running, the_app->state()); | ||
386 | 1804 | |||
387 | 1805 | EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(_)).Times(0); | ||
388 | 1806 | the_app->setRequestedState(Application::RequestedSuspended); | ||
389 | 1807 | |||
390 | 1808 | // And expect it to be running still | ||
391 | 1809 | ASSERT_EQ(Application::InternalState::RunningInBackground, the_app->internalState()); | ||
392 | 1810 | |||
393 | 1811 | the_app->setRequestedState(Application::RequestedRunning); | ||
394 | 1812 | |||
395 | 1813 | EXPECT_EQ(Application::Running, the_app->state()); | ||
396 | 1814 | ASSERT_EQ(Application::InternalState::Running, the_app->internalState()); | ||
397 | 1815 | } | ||
398 | 1816 | |||
399 | 1817 | /* | ||
400 | 1818 | * Test lifecycle exempt applications have their wakelocks released when shell tries to suspend them | ||
401 | 1819 | */ | ||
402 | 1820 | TEST_F(ApplicationManagerTests,lifecycleExemptAppsHaveWakelockReleasedOnAttemptedSuspend) | ||
403 | 1821 | { | ||
404 | 1822 | using namespace ::testing; | ||
405 | 1823 | |||
406 | 1824 | const QString appId("com.ubuntu.music"); // member of lifecycle exemption list | ||
407 | 1825 | const quint64 procId = 12345; | ||
408 | 1826 | |||
409 | 1827 | // Set up Mocks & signal watcher | ||
410 | 1828 | auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo()); | ||
411 | 1829 | ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true)); | ||
412 | 1830 | ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId)); | ||
413 | 1831 | |||
414 | 1832 | ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader)); | ||
415 | 1833 | |||
416 | 1834 | EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _)) | ||
417 | 1835 | .Times(1) | ||
418 | 1836 | .WillOnce(Return(true)); | ||
419 | 1837 | |||
420 | 1838 | auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag); | ||
421 | 1839 | applicationManager.onProcessStarting(appId); | ||
422 | 1840 | std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId); | ||
423 | 1841 | bool authed = true; | ||
424 | 1842 | applicationManager.authorizeSession(procId, authed); | ||
425 | 1843 | onSessionStarting(session); | ||
426 | 1844 | |||
427 | 1845 | // App creates surface, focuses it so state is running | ||
428 | 1846 | FakeMirSurface *surface = new FakeMirSurface; | ||
429 | 1847 | onSessionCreatedSurface(session.get(), surface); | ||
430 | 1848 | surface->drawFirstFrame(); | ||
431 | 1849 | |||
432 | 1850 | application->setRequestedState(Application::RequestedSuspended); | ||
433 | 1851 | |||
434 | 1852 | EXPECT_FALSE(sharedWakelock.enabled()); | ||
435 | 1853 | ASSERT_EQ(Application::InternalState::RunningInBackground, application->internalState()); | ||
436 | 1854 | EXPECT_EQ(Application::Running, application->state()); | ||
437 | 1855 | } | ||
438 | 1856 | |||
439 | 1857 | /* | 1740 | /* |
440 | 1858 | * Test that when user stops an application, application does not delete QML cache | 1741 | * Test that when user stops an application, application does not delete QML cache |
441 | 1859 | */ | 1742 | */ |
442 | 1860 | 1743 | ||
443 | === modified file 'tests/modules/DesktopFileReader/desktopfilereader_test.cpp' | |||
444 | --- tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2015-08-11 12:08:32 +0000 | |||
445 | +++ tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2015-10-30 17:00:37 +0000 | |||
446 | @@ -58,6 +58,7 @@ | |||
447 | 58 | EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); | 58 | EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
448 | 59 | EXPECT_EQ(reader->splashShowHeader(), "True"); | 59 | EXPECT_EQ(reader->splashShowHeader(), "True"); |
449 | 60 | EXPECT_EQ(reader->splashTitle(), "Calculator 2.0"); | 60 | EXPECT_EQ(reader->splashTitle(), "Calculator 2.0"); |
450 | 61 | EXPECT_EQ(reader->isTouchApp(), true); | ||
451 | 61 | } | 62 | } |
452 | 62 | 63 | ||
453 | 63 | TEST(DesktopFileReader, testReadsLocalizedDesktopFile) | 64 | TEST(DesktopFileReader, testReadsLocalizedDesktopFile) |
454 | @@ -83,6 +84,7 @@ | |||
455 | 83 | EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); | 84 | EXPECT_EQ(reader->splashImage(), "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.calculator/calculator-app@30.png"); |
456 | 84 | EXPECT_EQ(reader->splashShowHeader(), "True"); | 85 | EXPECT_EQ(reader->splashShowHeader(), "True"); |
457 | 85 | EXPECT_EQ(reader->splashTitle(), "Taschenrechner 2.0"); | 86 | EXPECT_EQ(reader->splashTitle(), "Taschenrechner 2.0"); |
458 | 87 | EXPECT_EQ(reader->isTouchApp(), true); | ||
459 | 86 | } | 88 | } |
460 | 87 | 89 | ||
461 | 88 | TEST(DesktopFileReader, testMissingDesktopFile) | 90 | TEST(DesktopFileReader, testMissingDesktopFile) |
462 | @@ -108,6 +110,7 @@ | |||
463 | 108 | EXPECT_EQ(reader->splashImage(), ""); | 110 | EXPECT_EQ(reader->splashImage(), ""); |
464 | 109 | EXPECT_EQ(reader->splashShowHeader(), ""); | 111 | EXPECT_EQ(reader->splashShowHeader(), ""); |
465 | 110 | EXPECT_EQ(reader->splashTitle(), ""); | 112 | EXPECT_EQ(reader->splashTitle(), ""); |
466 | 113 | EXPECT_EQ(reader->isTouchApp(), false); | ||
467 | 111 | } | 114 | } |
468 | 112 | 115 | ||
469 | 113 | TEST(DesktopFileReader, testUTF8Characters) | 116 | TEST(DesktopFileReader, testUTF8Characters) |
470 | 114 | 117 | ||
471 | === modified file 'tests/modules/common/fake_desktopfilereader.h' | |||
472 | --- tests/modules/common/fake_desktopfilereader.h 2015-08-20 16:05:27 +0000 | |||
473 | +++ tests/modules/common/fake_desktopfilereader.h 2015-10-30 17:00:37 +0000 | |||
474 | @@ -42,6 +42,7 @@ | |||
475 | 42 | QString splashColorFooter() const override { return QString(); } | 42 | QString splashColorFooter() const override { return QString(); } |
476 | 43 | Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; } | 43 | Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; } |
477 | 44 | bool rotatesWindowContents() const override { return false; } | 44 | bool rotatesWindowContents() const override { return false; } |
478 | 45 | bool isTouchApp() const override { return true; } | ||
479 | 45 | bool loaded() const override { return true; } | 46 | bool loaded() const override { return true; } |
480 | 46 | 47 | ||
481 | 47 | QString m_appId; | 48 | QString m_appId; |
482 | 48 | 49 | ||
483 | === modified file 'tests/modules/common/mock_desktop_file_reader.h' | |||
484 | --- tests/modules/common/mock_desktop_file_reader.h 2015-08-11 12:08:32 +0000 | |||
485 | +++ tests/modules/common/mock_desktop_file_reader.h 2015-10-30 17:00:37 +0000 | |||
486 | @@ -38,6 +38,7 @@ | |||
487 | 38 | ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec)); | 38 | ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec)); |
488 | 39 | ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath)); | 39 | ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath)); |
489 | 40 | ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint)); | 40 | ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint)); |
490 | 41 | ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp)); | ||
491 | 41 | ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded)); | 42 | ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded)); |
492 | 42 | } | 43 | } |
493 | 43 | 44 | ||
494 | @@ -49,6 +50,7 @@ | |||
495 | 49 | MOCK_CONST_METHOD0(exec, QString()); | 50 | MOCK_CONST_METHOD0(exec, QString()); |
496 | 50 | MOCK_CONST_METHOD0(path, QString()); | 51 | MOCK_CONST_METHOD0(path, QString()); |
497 | 51 | MOCK_CONST_METHOD0(stageHint, QString()); | 52 | MOCK_CONST_METHOD0(stageHint, QString()); |
498 | 53 | MOCK_CONST_METHOD0(isTouchApp, bool()); | ||
499 | 52 | MOCK_CONST_METHOD0(loaded, bool()); | 54 | MOCK_CONST_METHOD0(loaded, bool()); |
500 | 53 | 55 | ||
501 | 54 | QString doFile() const | 56 | QString doFile() const |
502 | @@ -91,6 +93,11 @@ | |||
503 | 91 | return DesktopFileReader::stageHint(); | 93 | return DesktopFileReader::stageHint(); |
504 | 92 | } | 94 | } |
505 | 93 | 95 | ||
506 | 96 | bool doIsTouchApp() const | ||
507 | 97 | { | ||
508 | 98 | return DesktopFileReader::isTouchApp(); | ||
509 | 99 | } | ||
510 | 100 | |||
511 | 94 | bool doLoaded() const | 101 | bool doLoaded() const |
512 | 95 | { | 102 | { |
513 | 96 | return DesktopFileReader::loaded(); | 103 | return DesktopFileReader::loaded(); |
514 | 97 | 104 | ||
515 | === modified file 'tests/modules/common/qtmir_test.cpp' | |||
516 | --- tests/modules/common/qtmir_test.cpp 2015-08-20 15:59:48 +0000 | |||
517 | +++ tests/modules/common/qtmir_test.cpp 2015-10-30 17:00:37 +0000 | |||
518 | @@ -26,9 +26,6 @@ | |||
519 | 26 | case Application::InternalState::Running: | 26 | case Application::InternalState::Running: |
520 | 27 | *os << "Running"; | 27 | *os << "Running"; |
521 | 28 | break; | 28 | break; |
522 | 29 | case Application::InternalState::RunningInBackground: | ||
523 | 30 | *os << "RunningInBackground"; | ||
524 | 31 | break; | ||
525 | 32 | case Application::InternalState::SuspendingWaitSession: | 29 | case Application::InternalState::SuspendingWaitSession: |
526 | 33 | *os << "SuspendingWaitSession"; | 30 | *os << "SuspendingWaitSession"; |
527 | 34 | break; | 31 | break; |
FAILED: Continuous integration, rev:385 jenkins. qa.ubuntu. com/job/ qtmir-ci/ 466/ jenkins. qa.ubuntu. com/job/ qtmir-vivid- amd64-ci/ 162/console jenkins. qa.ubuntu. com/job/ qtmir-vivid- armhf-ci/ 162/console jenkins. qa.ubuntu. com/job/ qtmir-vivid- i386-ci/ 44/console jenkins. qa.ubuntu. com/job/ qtmir-wily- amd64-ci/ 199/console jenkins. qa.ubuntu. com/job/ qtmir-wily- armhf-ci/ 199/console jenkins. qa.ubuntu. com/job/ qtmir-wily- i386-ci/ 44/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtmir- ci/466/ rebuild
http://