Merge lp:~mterry/qtmir/no-touch-no-lifecycle into lp:qtmir

Proposed by Michael Terry
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
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 ApplicationInfoInterface and move lifecycle policy logic out of qtmir.

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 ApplicationInfoInterface and move lifecycle policy logic out of qtmir.

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://code.launchpad.net/~mterry/unity-api/no-touch-no-lifecycle/+merge/272829
 https://code.launchpad.net/~mterry/unity8/no-touch-no-lifecycle/+merge/272844

 * 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

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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.

review: Needs Fixing
386. By Michael Terry

Drop canSuspend and RunningInBackground state

387. By Michael Terry

Merge from trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
388. By Michael Terry

Support RoleIsTouchApp

389. By Michael Terry

minor fixes

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
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?

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

Also, I'd love to kill the GSettings schema. I think only MZanetti's TweakGeek app relies on it ATM.

Revision history for this message
Michael Terry (mterry) wrote :

> Do we want to police apps from enabling this flag?

From setting X-Ubuntu-Touch-App=false? They already can't do that. The store will reject any app that doesn't have X-Ubuntu-Touch-App=true. And apparently always has (I grepped all store clicks).

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.

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

/«BUILDDIR»/qtmir-0.4.6+15.10.20151008.2/tests/modules/Application/application_test.cpp:304:167: error: converting 'false' to pointer type for argument 1 of 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)' [-Werror=conversion-null]
     ASSERT_EQ(false, application->isTouchApp());

Please use ASSERT_FALSE

review: Needs Fixing
390. By Michael Terry

Merge from trunk

391. By Michael Terry

Use ASSERT_TRUE/FALSE

Revision history for this message
Michael Terry (mterry) wrote :

> Please use ASSERT_FALSE

Done.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
392. By Michael Terry

Merge from trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
393. By Michael Terry

Bump shell application version

394. By Michael Terry

Bump shell application version harder

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) wrote :

Tested on device, I see no behavioural regression, +1 from me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-10-21 11:47:03 +0000
+++ CMakeLists.txt 2015-10-30 17:00:37 +0000
@@ -75,7 +75,7 @@
75pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)75pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt)
76pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)76pkg_check_modules(QTDBUSTEST libqtdbustest-1 REQUIRED)
77pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)77pkg_check_modules(QTDBUSMOCK libqtdbusmock-1 REQUIRED)
78pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=9)78pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=10)
7979
80include_directories(${APPLICATION_API_INCLUDE_DIRS})80include_directories(${APPLICATION_API_INCLUDE_DIRS})
8181
8282
=== modified file 'debian/control'
--- debian/control 2015-10-21 11:46:54 +0000
+++ debian/control 2015-10-30 17:00:37 +0000
@@ -23,7 +23,7 @@
23 libubuntu-app-launch2-dev,23 libubuntu-app-launch2-dev,
24 libubuntu-application-api-dev (>= 2.1.0),24 libubuntu-application-api-dev (>= 2.1.0),
25 libudev-dev,25 libudev-dev,
26 libunity-api-dev (>= 7.101),26 libunity-api-dev (>= 7.102),
27 liburl-dispatcher1-dev,27 liburl-dispatcher1-dev,
28 libxkbcommon-dev,28 libxkbcommon-dev,
29 libxrender-dev,29 libxrender-dev,
@@ -93,7 +93,7 @@
93Conflicts: libqtmir,93Conflicts: libqtmir,
94 libunity-mir1,94 libunity-mir1,
95Provides: unity-application-impl,95Provides: unity-application-impl,
96 unity-application-impl-9,96 unity-application-impl-10,
97Description: Qt plugin for Unity specific Mir APIs97Description: Qt plugin for Unity specific Mir APIs
98 QtMir provides Qt/QML bindings for Mir features that are exposed through the98 QtMir provides Qt/QML bindings for Mir features that are exposed through the
99 qtmir-desktop or qtmir-android QPA plugin such as Application management99 qtmir-desktop or qtmir-android QPA plugin such as Application management
100100
=== modified file 'src/modules/Unity/Application/application.cpp'
--- src/modules/Unity/Application/application.cpp 2015-09-29 14:01:12 +0000
+++ src/modules/Unity/Application/application.cpp 2015-10-30 17:00:37 +0000
@@ -37,8 +37,6 @@
37namespace qtmir37namespace qtmir
38{38{
3939
40QStringList Application::lifecycleExceptions;
41
42Application::Application(const QSharedPointer<SharedWakelock>& sharedWakelock,40Application::Application(const QSharedPointer<SharedWakelock>& sharedWakelock,
43 DesktopFileReader *desktopFileReader,41 DesktopFileReader *desktopFileReader,
44 const QStringList &arguments,42 const QStringList &arguments,
@@ -80,7 +78,6 @@
80 switch (m_state) {78 switch (m_state) {
81 case InternalState::Starting:79 case InternalState::Starting:
82 case InternalState::Running:80 case InternalState::Running:
83 case InternalState::RunningInBackground:
84 case InternalState::SuspendingWaitSession:81 case InternalState::SuspendingWaitSession:
85 case InternalState::SuspendingWaitProcess:82 case InternalState::SuspendingWaitProcess:
86 wipeQMLCache();83 wipeQMLCache();
@@ -212,8 +209,6 @@
212 return "Starting";209 return "Starting";
213 case InternalState::Running:210 case InternalState::Running:
214 return "Running";211 return "Running";
215 case InternalState::RunningInBackground:
216 return "RunningInBackground";
217 case InternalState::SuspendingWaitSession:212 case InternalState::SuspendingWaitSession:
218 return "SuspendingWaitSession";213 return "SuspendingWaitSession";
219 case InternalState::SuspendingWaitProcess:214 case InternalState::SuspendingWaitProcess:
@@ -282,7 +277,6 @@
282 case InternalState::Starting:277 case InternalState::Starting:
283 return Starting;278 return Starting;
284 case InternalState::Running:279 case InternalState::Running:
285 case InternalState::RunningInBackground:
286 case InternalState::SuspendingWaitSession:280 case InternalState::SuspendingWaitSession:
287 case InternalState::SuspendingWaitProcess:281 case InternalState::SuspendingWaitProcess:
288 case InternalState::Closing:282 case InternalState::Closing:
@@ -333,7 +327,6 @@
333 case InternalState::Running:327 case InternalState::Running:
334 // already where it's wanted to be328 // already where it's wanted to be
335 break;329 break;
336 case InternalState::RunningInBackground:
337 case InternalState::SuspendingWaitSession:330 case InternalState::SuspendingWaitSession:
338 case InternalState::Suspended:331 case InternalState::Suspended:
339 resume();332 resume();
@@ -366,7 +359,6 @@
366 Q_ASSERT(m_processState == ProcessUnknown);359 Q_ASSERT(m_processState == ProcessUnknown);
367 }360 }
368 break;361 break;
369 case InternalState::RunningInBackground:
370 case InternalState::SuspendingWaitSession:362 case InternalState::SuspendingWaitSession:
371 case InternalState::SuspendingWaitProcess:363 case InternalState::SuspendingWaitProcess:
372 case InternalState::Suspended:364 case InternalState::Suspended:
@@ -416,7 +408,6 @@
416 case InternalState::Running:408 case InternalState::Running:
417 setInternalState(InternalState::Closing);409 setInternalState(InternalState::Closing);
418 break;410 break;
419 case InternalState::RunningInBackground:
420 case InternalState::SuspendingWaitSession:411 case InternalState::SuspendingWaitSession:
421 case InternalState::SuspendingWaitProcess:412 case InternalState::SuspendingWaitProcess:
422 case InternalState::Suspended:413 case InternalState::Suspended:
@@ -461,7 +452,6 @@
461 switch (m_state) {452 switch (m_state) {
462 case InternalState::Starting:453 case InternalState::Starting:
463 case InternalState::Running:454 case InternalState::Running:
464 case InternalState::RunningInBackground:
465 case InternalState::Closing:455 case InternalState::Closing:
466 m_session->resume();456 m_session->resume();
467 break;457 break;
@@ -520,9 +510,6 @@
520 case InternalState::Running:510 case InternalState::Running:
521 acquireWakelock();511 acquireWakelock();
522 break;512 break;
523 case InternalState::RunningInBackground:
524 releaseWakelock();
525 break;
526 case InternalState::Suspended:513 case InternalState::Suspended:
527 releaseWakelock();514 releaseWakelock();
528 break;515 break;
@@ -619,16 +606,8 @@
619 Q_ASSERT(m_state == InternalState::Running);606 Q_ASSERT(m_state == InternalState::Running);
620 Q_ASSERT(m_session != nullptr);607 Q_ASSERT(m_session != nullptr);
621608
622 if (!lifecycleExceptions.filter(appId().section('_',0,0)).empty()) {609 setInternalState(InternalState::SuspendingWaitSession);
623 // Present in exceptions list.610 m_session->suspend();
624 // There's no need to keep the wakelock as the process is never suspended
625 // and thus has no cleanup to perform when (for example) the display is
626 // blanked.
627 setInternalState(InternalState::RunningInBackground);
628 } else {
629 setInternalState(InternalState::SuspendingWaitSession);
630 m_session->suspend();
631 }
632}611}
633612
634void Application::resume()613void Application::resume()
@@ -643,8 +622,6 @@
643 } else if (m_state == InternalState::SuspendingWaitSession) {622 } else if (m_state == InternalState::SuspendingWaitSession) {
644 setInternalState(InternalState::Running);623 setInternalState(InternalState::Running);
645 m_session->resume();624 m_session->resume();
646 } else if (m_state == InternalState::RunningInBackground) {
647 setInternalState(InternalState::Running);
648 }625 }
649}626}
650627
@@ -657,6 +634,11 @@
657 Q_EMIT startProcessRequested();634 Q_EMIT startProcessRequested();
658}635}
659636
637bool Application::isTouchApp() const
638{
639 return m_desktopData->isTouchApp();
640}
641
660QString Application::longAppId() const642QString Application::longAppId() const
661{643{
662 return m_longAppId;644 return m_longAppId;
663645
=== modified file 'src/modules/Unity/Application/application.h'
--- src/modules/Unity/Application/application.h 2015-09-29 14:01:12 +0000
+++ src/modules/Unity/Application/application.h 2015-10-30 17:00:37 +0000
@@ -68,7 +68,6 @@
68 enum class InternalState {68 enum class InternalState {
69 Starting,69 Starting,
70 Running,70 Running,
71 RunningInBackground,
72 SuspendingWaitSession,71 SuspendingWaitSession,
73 SuspendingWaitProcess,72 SuspendingWaitProcess,
74 Suspended,73 Suspended,
@@ -104,6 +103,7 @@
104 QColor splashColorFooter() const override;103 QColor splashColorFooter() const override;
105 Qt::ScreenOrientations supportedOrientations() const override;104 Qt::ScreenOrientations supportedOrientations() const override;
106 bool rotatesWindowContents() const override;105 bool rotatesWindowContents() const override;
106 bool isTouchApp() const override;
107107
108 void setStage(Stage stage);108 void setStage(Stage stage);
109109
@@ -131,8 +131,6 @@
131 // for tests131 // for tests
132 InternalState internalState() const { return m_state; }132 InternalState internalState() const { return m_state; }
133133
134 static QStringList lifecycleExceptions;
135
136Q_SIGNALS:134Q_SIGNALS:
137 void fullscreenChanged(bool fullscreen);135 void fullscreenChanged(bool fullscreen);
138 void stageChanged(Stage stage);136 void stageChanged(Stage stage);
139137
=== modified file 'src/modules/Unity/Application/application_manager.cpp'
--- src/modules/Unity/Application/application_manager.cpp 2015-09-29 14:01:12 +0000
+++ src/modules/Unity/Application/application_manager.cpp 2015-10-30 17:00:37 +0000
@@ -196,11 +196,6 @@
196196
197 m_roleNames.insert(RoleSession, "session");197 m_roleNames.insert(RoleSession, "session");
198 m_roleNames.insert(RoleFullscreen, "fullscreen");198 m_roleNames.insert(RoleFullscreen, "fullscreen");
199
200 if (settings.data()) {
201 Application::lifecycleExceptions = m_settings->get("lifecycleExemptAppids").toStringList();
202 connect(m_settings.data(), &Settings::changed, this, &ApplicationManager::onSettingsChanged);
203 }
204}199}
205200
206ApplicationManager::~ApplicationManager()201ApplicationManager::~ApplicationManager()
@@ -232,6 +227,8 @@
232 return QVariant::fromValue((int)application->state());227 return QVariant::fromValue((int)application->state());
233 case RoleFocused:228 case RoleFocused:
234 return QVariant::fromValue(application->focused());229 return QVariant::fromValue(application->focused());
230 case RoleIsTouchApp:
231 return QVariant::fromValue(application->isTouchApp());
235 case RoleSession:232 case RoleSession:
236 return QVariant::fromValue(application->session());233 return QVariant::fromValue(application->session());
237 case RoleFullscreen:234 case RoleFullscreen:
@@ -538,13 +535,6 @@
538 }535 }
539}536}
540537
541void ApplicationManager::onSettingsChanged(const QString &key)
542{
543 if (key == "lifecycleExemptAppids") {
544 Application::lifecycleExceptions = m_settings->get("lifecycleExemptAppids").toStringList();
545 }
546}
547
548void ApplicationManager::authorizeSession(const quint64 pid, bool &authorized)538void ApplicationManager::authorizeSession(const quint64 pid, bool &authorized)
549{539{
550 tracepoint(qtmir, authorizeSession);540 tracepoint(qtmir, authorizeSession);
551541
=== modified file 'src/modules/Unity/Application/application_manager.h'
--- src/modules/Unity/Application/application_manager.h 2015-08-21 00:00:16 +0000
+++ src/modules/Unity/Application/application_manager.h 2015-10-30 17:00:37 +0000
@@ -68,7 +68,7 @@
6868
69 // FIXME: these roles should be added to unity-api and removed from here69 // FIXME: these roles should be added to unity-api and removed from here
70 enum MoreRoles {70 enum MoreRoles {
71 RoleSession = RoleFocused+1,71 RoleSession = RoleIsTouchApp+1,
72 RoleFullscreen,72 RoleFullscreen,
73 };73 };
7474
@@ -137,7 +137,6 @@
137137
138private Q_SLOTS:138private Q_SLOTS:
139 void onAppDataChanged(const int role);139 void onAppDataChanged(const int role);
140 void onSettingsChanged(const QString &key);
141140
142private:141private:
143 void setFocused(Application *application);142 void setFocused(Application *application);
144143
=== modified file 'src/modules/Unity/Application/com.canonical.qtmir.gschema.xml'
--- src/modules/Unity/Application/com.canonical.qtmir.gschema.xml 2015-03-13 16:12:39 +0000
+++ src/modules/Unity/Application/com.canonical.qtmir.gschema.xml 2015-10-30 17:00:37 +0000
@@ -1,4 +1,6 @@
1<schemalist>1<schemalist>
2 <!-- This schema is packaged in qtmir for historical reasons.
3 It is interpreted by unity8 these days. -->
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">
3 <key type="as" name="lifecycle-exempt-appids">5 <key type="as" name="lifecycle-exempt-appids">
4 <default>[6 <default>[
57
=== modified file 'src/modules/Unity/Application/desktopfilereader.cpp'
--- src/modules/Unity/Application/desktopfilereader.cpp 2015-08-11 12:08:32 +0000
+++ src/modules/Unity/Application/desktopfilereader.cpp 2015-10-30 17:00:37 +0000
@@ -228,6 +228,18 @@
228 return result;228 return result;
229}229}
230230
231bool DesktopFileReader::isTouchApp() const
232{
233 Q_D(const DesktopFileReader);
234 bool result;
235
236 if (!parseBoolean(d->getKey("X-Ubuntu-Touch"), result)) {
237 qCWarning(QTMIR_APPLICATIONS) << d->file << "has an invalid X-Ubuntu-Touch entry.";
238 }
239
240 return result;
241}
242
231bool DesktopFileReader::parseOrientations(const QString &rawString, Qt::ScreenOrientations &result)243bool DesktopFileReader::parseOrientations(const QString &rawString, Qt::ScreenOrientations &result)
232{244{
233 // Default to all orientations245 // Default to all orientations
234246
=== modified file 'src/modules/Unity/Application/desktopfilereader.h'
--- src/modules/Unity/Application/desktopfilereader.h 2015-08-19 20:17:56 +0000
+++ src/modules/Unity/Application/desktopfilereader.h 2015-10-30 17:00:37 +0000
@@ -57,6 +57,7 @@
57 virtual QString splashColorFooter() const;57 virtual QString splashColorFooter() const;
58 virtual Qt::ScreenOrientations supportedOrientations() const;58 virtual Qt::ScreenOrientations supportedOrientations() const;
59 virtual bool rotatesWindowContents() const;59 virtual bool rotatesWindowContents() const;
60 virtual bool isTouchApp() const;
60 virtual bool loaded() const;61 virtual bool loaded() const;
6162
62 static bool parseOrientations(const QString &rawString, Qt::ScreenOrientations &result);63 static bool parseOrientations(const QString &rawString, Qt::ScreenOrientations &result);
6364
=== modified file 'tests/modules/Application/application_test.cpp'
--- tests/modules/Application/application_test.cpp 2015-08-20 16:04:25 +0000
+++ tests/modules/Application/application_test.cpp 2015-10-30 17:00:37 +0000
@@ -287,3 +287,19 @@
287 ASSERT_EQ(0, spyAppStopped.count());287 ASSERT_EQ(0, spyAppStopped.count());
288288
289}289}
290
291TEST_F(ApplicationTests, passesIsTouchAppThrough)
292{
293 using namespace ::testing;
294
295 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(QString(), QFileInfo());
296 QScopedPointer<Application> application(new Application(
297 QSharedPointer<MockSharedWakelock>(&sharedWakelock, [](MockSharedWakelock *){}),
298 mockDesktopFileReader, QStringList(), nullptr));
299
300 ON_CALL(*mockDesktopFileReader, isTouchApp()).WillByDefault(Return(true));
301 ASSERT_TRUE(application->isTouchApp());
302
303 ON_CALL(*mockDesktopFileReader, isTouchApp()).WillByDefault(Return(false));
304 ASSERT_FALSE(application->isTouchApp());
305}
290306
=== modified file 'tests/modules/ApplicationManager/application_manager_test.cpp'
--- tests/modules/ApplicationManager/application_manager_test.cpp 2015-09-29 14:01:12 +0000
+++ tests/modules/ApplicationManager/application_manager_test.cpp 2015-10-30 17:00:37 +0000
@@ -1737,123 +1737,6 @@
1737 }1737 }
1738}1738}
17391739
1740TEST_F(ApplicationManagerTests,lifecycle_exempt_appId_is_not_suspended)
1741{
1742 using namespace ::testing;
1743 quint64 a_procId = 5921;
1744 const QString appId("some_app");
1745 QByteArray a_cmd("/usr/bin/app1");
1746
1747 ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd));
1748
1749 ON_CALL(appController,appIdHasProcessId(a_procId, appId)).WillByDefault(Return(true));
1750
1751 // Set up Mocks & signal watcher
1752 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1753 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1754 ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1755
1756 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1757
1758
1759 Application *the_app = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
1760 applicationManager.onProcessStarting(appId);
1761
1762 std::shared_ptr<mir::scene::Session> first_session = std::make_shared<MockSession>("Oo", a_procId);
1763 std::shared_ptr<mir::scene::Session> second_session = std::make_shared<MockSession>("oO", a_procId);
1764 {
1765 bool authed = false;
1766 applicationManager.authorizeSession(a_procId, authed);
1767 ASSERT_EQ(authed, true);
1768 }
1769
1770 onSessionStarting(first_session);
1771 FakeMirSurface *aSurface = new FakeMirSurface;
1772 onSessionCreatedSurface(first_session.get(), aSurface);
1773 aSurface->drawFirstFrame();
1774 onSessionStarting(second_session);
1775
1776 // Add to other apps to the list (Not "some_app")
1777 QVariantList lifecycleExemptAppIds;
1778 lifecycleExemptAppIds << "one_app" << "another_app";
1779 ON_CALL(settings,get(_)).WillByDefault(Return(lifecycleExemptAppIds));
1780 settings.changed("lifecycleExemptAppids");
1781
1782 ASSERT_EQ(Application::InternalState::Running, the_app->internalState());
1783
1784 EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(mir_lifecycle_state_will_suspend));
1785 the_app->setRequestedState(Application::RequestedSuspended);
1786 ASSERT_EQ(Application::InternalState::SuspendingWaitSession, the_app->internalState());
1787
1788 static_cast<qtmir::Session*>(the_app->session())->doSuspend();
1789 ASSERT_EQ(Application::InternalState::SuspendingWaitProcess, the_app->internalState());
1790 applicationManager.onProcessSuspended(the_app->appId());
1791 ASSERT_EQ(Application::InternalState::Suspended, the_app->internalState());
1792
1793 EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(mir_lifecycle_state_resumed));
1794 the_app->setRequestedState(Application::RequestedRunning);
1795
1796 EXPECT_EQ(Application::Running, the_app->state());
1797
1798 // Now add "some_app" to the exception list
1799 lifecycleExemptAppIds << "some_app";
1800 ON_CALL(settings,get(_)).WillByDefault(Return(lifecycleExemptAppIds));
1801 settings.changed("lifecycleExemptAppids");
1802
1803 EXPECT_EQ(Application::Running, the_app->state());
1804
1805 EXPECT_CALL(*(mir::scene::MockSession*)first_session.get(), set_lifecycle_state(_)).Times(0);
1806 the_app->setRequestedState(Application::RequestedSuspended);
1807
1808 // And expect it to be running still
1809 ASSERT_EQ(Application::InternalState::RunningInBackground, the_app->internalState());
1810
1811 the_app->setRequestedState(Application::RequestedRunning);
1812
1813 EXPECT_EQ(Application::Running, the_app->state());
1814 ASSERT_EQ(Application::InternalState::Running, the_app->internalState());
1815}
1816
1817/*
1818 * Test lifecycle exempt applications have their wakelocks released when shell tries to suspend them
1819 */
1820TEST_F(ApplicationManagerTests,lifecycleExemptAppsHaveWakelockReleasedOnAttemptedSuspend)
1821{
1822 using namespace ::testing;
1823
1824 const QString appId("com.ubuntu.music"); // member of lifecycle exemption list
1825 const quint64 procId = 12345;
1826
1827 // Set up Mocks & signal watcher
1828 auto mockDesktopFileReader = new NiceMock<MockDesktopFileReader>(appId, QFileInfo());
1829 ON_CALL(*mockDesktopFileReader, loaded()).WillByDefault(Return(true));
1830 ON_CALL(*mockDesktopFileReader, appId()).WillByDefault(Return(appId));
1831
1832 ON_CALL(desktopFileReaderFactory, createInstance(appId, _)).WillByDefault(Return(mockDesktopFileReader));
1833
1834 EXPECT_CALL(appController, startApplicationWithAppIdAndArgs(appId, _))
1835 .Times(1)
1836 .WillOnce(Return(true));
1837
1838 auto application = applicationManager.startApplication(appId, ApplicationManager::NoFlag);
1839 applicationManager.onProcessStarting(appId);
1840 std::shared_ptr<mir::scene::Session> session = std::make_shared<MockSession>("", procId);
1841 bool authed = true;
1842 applicationManager.authorizeSession(procId, authed);
1843 onSessionStarting(session);
1844
1845 // App creates surface, focuses it so state is running
1846 FakeMirSurface *surface = new FakeMirSurface;
1847 onSessionCreatedSurface(session.get(), surface);
1848 surface->drawFirstFrame();
1849
1850 application->setRequestedState(Application::RequestedSuspended);
1851
1852 EXPECT_FALSE(sharedWakelock.enabled());
1853 ASSERT_EQ(Application::InternalState::RunningInBackground, application->internalState());
1854 EXPECT_EQ(Application::Running, application->state());
1855}
1856
1857/*1740/*
1858 * Test that when user stops an application, application does not delete QML cache1741 * Test that when user stops an application, application does not delete QML cache
1859 */1742 */
18601743
=== modified file 'tests/modules/DesktopFileReader/desktopfilereader_test.cpp'
--- tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2015-08-11 12:08:32 +0000
+++ tests/modules/DesktopFileReader/desktopfilereader_test.cpp 2015-10-30 17:00:37 +0000
@@ -58,6 +58,7 @@
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");
59 EXPECT_EQ(reader->splashShowHeader(), "True");59 EXPECT_EQ(reader->splashShowHeader(), "True");
60 EXPECT_EQ(reader->splashTitle(), "Calculator 2.0");60 EXPECT_EQ(reader->splashTitle(), "Calculator 2.0");
61 EXPECT_EQ(reader->isTouchApp(), true);
61}62}
6263
63TEST(DesktopFileReader, testReadsLocalizedDesktopFile)64TEST(DesktopFileReader, testReadsLocalizedDesktopFile)
@@ -83,6 +84,7 @@
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");
84 EXPECT_EQ(reader->splashShowHeader(), "True");85 EXPECT_EQ(reader->splashShowHeader(), "True");
85 EXPECT_EQ(reader->splashTitle(), "Taschenrechner 2.0");86 EXPECT_EQ(reader->splashTitle(), "Taschenrechner 2.0");
87 EXPECT_EQ(reader->isTouchApp(), true);
86}88}
8789
88TEST(DesktopFileReader, testMissingDesktopFile)90TEST(DesktopFileReader, testMissingDesktopFile)
@@ -108,6 +110,7 @@
108 EXPECT_EQ(reader->splashImage(), "");110 EXPECT_EQ(reader->splashImage(), "");
109 EXPECT_EQ(reader->splashShowHeader(), "");111 EXPECT_EQ(reader->splashShowHeader(), "");
110 EXPECT_EQ(reader->splashTitle(), "");112 EXPECT_EQ(reader->splashTitle(), "");
113 EXPECT_EQ(reader->isTouchApp(), false);
111}114}
112115
113TEST(DesktopFileReader, testUTF8Characters)116TEST(DesktopFileReader, testUTF8Characters)
114117
=== modified file 'tests/modules/common/fake_desktopfilereader.h'
--- tests/modules/common/fake_desktopfilereader.h 2015-08-20 16:05:27 +0000
+++ tests/modules/common/fake_desktopfilereader.h 2015-10-30 17:00:37 +0000
@@ -42,6 +42,7 @@
42 QString splashColorFooter() const override { return QString(); }42 QString splashColorFooter() const override { return QString(); }
43 Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; }43 Qt::ScreenOrientations supportedOrientations() const override { return Qt::PortraitOrientation; }
44 bool rotatesWindowContents() const override { return false; }44 bool rotatesWindowContents() const override { return false; }
45 bool isTouchApp() const override { return true; }
45 bool loaded() const override { return true; }46 bool loaded() const override { return true; }
4647
47 QString m_appId;48 QString m_appId;
4849
=== modified file 'tests/modules/common/mock_desktop_file_reader.h'
--- tests/modules/common/mock_desktop_file_reader.h 2015-08-11 12:08:32 +0000
+++ tests/modules/common/mock_desktop_file_reader.h 2015-10-30 17:00:37 +0000
@@ -38,6 +38,7 @@
38 ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));38 ON_CALL(*this, exec()).WillByDefault(Invoke(this, &MockDesktopFileReader::doExec));
39 ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));39 ON_CALL(*this, path()).WillByDefault(Invoke(this, &MockDesktopFileReader::doPath));
40 ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));40 ON_CALL(*this, stageHint()).WillByDefault(Invoke(this, &MockDesktopFileReader::doStageHint));
41 ON_CALL(*this, isTouchApp()).WillByDefault(Invoke(this, &MockDesktopFileReader::doIsTouchApp));
41 ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));42 ON_CALL(*this, loaded()).WillByDefault(Invoke(this, &MockDesktopFileReader::doLoaded));
42 }43 }
4344
@@ -49,6 +50,7 @@
49 MOCK_CONST_METHOD0(exec, QString());50 MOCK_CONST_METHOD0(exec, QString());
50 MOCK_CONST_METHOD0(path, QString());51 MOCK_CONST_METHOD0(path, QString());
51 MOCK_CONST_METHOD0(stageHint, QString());52 MOCK_CONST_METHOD0(stageHint, QString());
53 MOCK_CONST_METHOD0(isTouchApp, bool());
52 MOCK_CONST_METHOD0(loaded, bool());54 MOCK_CONST_METHOD0(loaded, bool());
5355
54 QString doFile() const56 QString doFile() const
@@ -91,6 +93,11 @@
91 return DesktopFileReader::stageHint();93 return DesktopFileReader::stageHint();
92 }94 }
9395
96 bool doIsTouchApp() const
97 {
98 return DesktopFileReader::isTouchApp();
99 }
100
94 bool doLoaded() const101 bool doLoaded() const
95 {102 {
96 return DesktopFileReader::loaded();103 return DesktopFileReader::loaded();
97104
=== modified file 'tests/modules/common/qtmir_test.cpp'
--- tests/modules/common/qtmir_test.cpp 2015-08-20 15:59:48 +0000
+++ tests/modules/common/qtmir_test.cpp 2015-10-30 17:00:37 +0000
@@ -26,9 +26,6 @@
26 case Application::InternalState::Running:26 case Application::InternalState::Running:
27 *os << "Running";27 *os << "Running";
28 break;28 break;
29 case Application::InternalState::RunningInBackground:
30 *os << "RunningInBackground";
31 break;
32 case Application::InternalState::SuspendingWaitSession:29 case Application::InternalState::SuspendingWaitSession:
33 *os << "SuspendingWaitSession";30 *os << "SuspendingWaitSession";
34 break;31 break;

Subscribers

People subscribed via source and target branches