Merge lp:~andreas-pokorny/unity-mir/fix-1281075 into lp:unity-mir

Proposed by Andreas Pokorny
Status: Merged
Approved by: Gerry Boland
Approved revision: no longer in the source branch.
Merged at revision: 191
Proposed branch: lp:~andreas-pokorny/unity-mir/fix-1281075
Merge into: lp:unity-mir
Prerequisite: lp:~andreas-pokorny/unity-mir/fix-1240400
Diff against target: 154 lines (+105/-13)
3 files modified
src/modules/Unity/Application/application_manager.cpp (+1/-12)
src/modules/Unity/Application/application_manager.h (+0/-1)
tests/application_manager_test.cpp (+104/-0)
To merge this branch: bzr merge lp:~andreas-pokorny/unity-mir/fix-1281075
Reviewer Review Type Date Requested Status
kevin gunn (community) Needs Fixing
Andreas Pokorny (community) Approve
Gerry Boland (community) Approve
Michał Sawicz Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+207375@code.launchpad.net

Commit message

Use the process id found in the mir::shell::Session to match it with the Application object.

Description of the change

The issue is usually experienced when applications are started in parallel. As a result the notifications from mir/upstart do not happen in a fixed sequence. And since the application has to submit a surface before it leaves starting state the last start application will get all the sessions assigned to it.

The change ensures that mir sessions are assigned only to Applications with the same process id.

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

* Are there any related MPs required for this MP to build/function as expected? Please list.
Only the prerequisite branch.

* Did you perform an exploratory manual test run of your code change and any related functionality?
I tested the change with unity8 on nexus4, and did not experience any bad behaviour.

* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
No, nothing changed there.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Gerry Boland (gerboland) :
review: Approve
181. By Alberto Aguirre

[cmake] Use XXX_LDFLAGS for libraries found with pkg_check_modules.

Using the pkg given LDFLAGS resolves linking issues when cross-compiling

182. By Alberto Aguirre

Add dev scripts to support cross-compilation

These scripts are adapted from the mir project.
The build dependencies are parsed from debian/control and
given to debootstrap to setup a basic armhf chroot environment for cross-compilation.

These scripts are intended for development purposes only

Revision history for this message
Michał Sawicz (saviq) wrote :

This is breaking web apps - see http://bazaar.launchpad.net/~unity-team/unity-mir/rotate-n7/revision/182 for a "fix" I applied for MWC.

review: Needs Fixing
Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

Shall I turn the session member into a list - and have the session object that is returned by session() be the one with the last posted surface? ~> so that:

* screen shotting takes the right object
* closing one of the "other" sessions does not terminate the application

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

From what I know about this code, looks good.

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

• Did you perform an exploratory manual test run of the code change and any related functionality?
Yes
• Did CI run pass? If not, please explain why.
Was fine

183. By Andreas Pokorny

more log traces

184. By Andreas Pokorny

Adding Proc Info and Mock and a Mir Session Mock for unit testing

185. By Andreas Pokorny

Fixes Unity8 crash when two instances of the same application are launched
and the second one stops.

There is still misbehavior that cannot be resolved without further changes in
upstart-app-launch. I.e. when the second instance is shutdown the existing one
will be closed too, since they use the same appId.

The changes in the construction of ApplicationManager where neceessary to
replace the external parts of ApplicationManager with mock objects.

186. By Andreas Pokorny

review findings address

187. By Andreas Pokorny

Add failing test

188. By Andreas Pokorny

Fixing mismatched sessions - and hence surfaces - by using the recently introduced process id.

189. By Andreas Pokorny

Review findings adressed - two further test cases added.

Sessions can now be overridden as long as the first session has not yet provided a screenshot
(see the second test case). We could turn the Application session storage into a list though..
That would also improve the behavior during shutdown (when only of the session objects disappear).
But that is a bigger change in behavior, due to a different Session object life time.

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

I just re-based this branch on top of fix-1240400, and tested the result on N10. Looks good.

Yesterday I also played around with keeping all session objects around. But that changed life time in a way that a deadlock is triggered, between thread locking QtCoreApplication or stuff in QtMetaObject and SessionContainers in mir...

Revision history for this message
Andreas Pokorny (andreas-pokorny) :
review: Approve
Revision history for this message
kevin gunn (kgunn72) wrote :

so, i was just trying to land this however it failed to compile when merge together (standalone was fine).
i was able to replicate locally too.
note:
start with trunk, merge on top in order the following
lp:~albaguirre/unity-mir/cross-compile-link-fix
lp:~albaguirre/unity-mir/add-cross-compile-scripts
lp:~andreas-pokorny/unity-mir/fix-1240400
then merge this on top...
the failure comes in the form of a weird complaint about the tests added below, claiming it can't find declarations of command_line_

review: Needs Fixing
190. By Andreas Pokorny

merged review findings from fix-1240400

Revision history for this message
Andreas Pokorny (andreas-pokorny) wrote :

After applying the last coding style fixes to:

> lp:~andreas-pokorny/unity-mir/fix-1240400

.. I forgot to update that branch again - should work now.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/modules/Unity/Application/application_manager.cpp'
2--- src/modules/Unity/Application/application_manager.cpp 2014-03-06 19:38:45 +0000
3+++ src/modules/Unity/Application/application_manager.cpp 2014-03-06 19:38:45 +0000
4@@ -634,9 +634,7 @@
5 return;
6 }
7
8- //FIXME(greyback) Mir not supplying any identifier that we can use to link the PID to the session
9- // so am assuming that the *most recently* launched application session is the one that connects
10- Application* application = findLastExecutedApplication();
11+ Application* application = findApplicationWithPid(session->process_id());
12 if (application && application->state() != Application::Running) {
13 application->setSession(session);
14 if (application->stage() == Application::MainStage)
15@@ -793,15 +791,6 @@
16 return nullptr;
17 }
18
19-Application* ApplicationManager::findLastExecutedApplication()
20-{
21- if (m_applications.length() > 0) {
22- return m_applications.last();
23- } else {
24- return nullptr;
25- }
26-}
27-
28 Application* ApplicationManager::applicationForStage(Application::Stage stage)
29 {
30 DLOG("ApplicationManager::focusedApplicationForStage(this=%p)", this);
31
32=== modified file 'src/modules/Unity/Application/application_manager.h'
33--- src/modules/Unity/Application/application_manager.h 2014-03-06 19:38:45 +0000
34+++ src/modules/Unity/Application/application_manager.h 2014-03-06 19:38:45 +0000
35@@ -129,7 +129,6 @@
36 void remove(Application* application);
37 Application* findApplicationWithSession(const std::shared_ptr<mir::shell::Session> &session);
38 Application* findApplicationWithSession(const mir::shell::Session *session);
39- Application* findLastExecutedApplication();
40 Application* applicationForStage(Application::Stage stage);
41 QModelIndex findIndex(Application* application);
42 bool checkFocusOnRemovedApplication(Application* application);
43
44=== modified file 'tests/application_manager_test.cpp'
45--- tests/application_manager_test.cpp 2014-03-06 19:38:45 +0000
46+++ tests/application_manager_test.cpp 2014-03-06 19:38:45 +0000
47@@ -222,3 +222,107 @@
48 EXPECT_NE(nullptr, beforeFailure);
49 EXPECT_EQ(beforeFailure, afterFailure);
50 }
51+
52+TEST_F(ApplicationManagerTests,bug_case_1281075_session_ptrs_always_distributed_to_last_started_app)
53+{
54+ using namespace ::testing;
55+ quint64 first_procId = 5921;
56+ quint64 second_procId = 5922;
57+ quint64 third_procId = 5923;
58+ std::shared_ptr<mir::shell::Surface> aSurface(nullptr);
59+ const char first_app_id[] = "app1";
60+ QByteArray first_cmdLine( "/usr/bin/app1 --desktop_file_hint=app1");
61+ const char second_app_id[] = "app2";
62+ QByteArray second_cmdLine( "/usr/bin/app2--desktop_file_hint=app2");
63+ const char third_app_id[] = "app3";
64+ QByteArray third_cmdLine( "/usr/bin/app3 --desktop_file_hint=app3");
65+
66+ EXPECT_CALL(procInfo,command_line(first_procId))
67+ .Times(1)
68+ .WillOnce(Return(first_cmdLine));
69+
70+ ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
71+
72+ EXPECT_CALL(procInfo,command_line(second_procId))
73+ .Times(1)
74+ .WillOnce(Return(second_cmdLine));
75+
76+ EXPECT_CALL(procInfo,command_line(third_procId))
77+ .Times(1)
78+ .WillOnce(Return(third_cmdLine));
79+
80+ bool authed = true;
81+
82+ std::shared_ptr<mir::shell::Session> first_session = std::make_shared<MockSession>("Oo", first_procId);
83+ std::shared_ptr<mir::shell::Session> second_session = std::make_shared<MockSession>("oO", second_procId);
84+ std::shared_ptr<mir::shell::Session> third_session = std::make_shared<MockSession>("OO", third_procId);
85+ applicationManager.authorizeSession(first_procId, authed);
86+ applicationManager.authorizeSession(second_procId, authed);
87+ applicationManager.authorizeSession(third_procId, authed);
88+ applicationManager.onSessionStarting(first_session);
89+ applicationManager.onSessionStarting(third_session);
90+ applicationManager.onSessionStarting(second_session);
91+
92+ Application * firstApp = applicationManager.findApplication(first_app_id);
93+ Application * secondApp = applicationManager.findApplication(second_app_id);
94+ Application * thirdApp = applicationManager.findApplication(third_app_id);
95+
96+ EXPECT_EQ(first_session, firstApp->session());
97+ EXPECT_EQ(second_session, secondApp->session());
98+ EXPECT_EQ(third_session, thirdApp->session());
99+}
100+
101+TEST_F(ApplicationManagerTests,two_session_on_one_application)
102+{
103+ using namespace ::testing;
104+ quint64 a_procId = 5921;
105+ const char an_app_id[] = "some_app";
106+ QByteArray a_cmd( "/usr/bin/app1 --desktop_file_hint=some_app");
107+
108+ ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd));
109+
110+ ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
111+
112+ bool authed = true;
113+
114+ std::shared_ptr<mir::shell::Session> first_session = std::make_shared<MockSession>("Oo", a_procId);
115+ std::shared_ptr<mir::shell::Session> second_session = std::make_shared<MockSession>("oO", a_procId);
116+ applicationManager.authorizeSession(a_procId, authed);
117+
118+ applicationManager.onSessionStarting(first_session);
119+ applicationManager.onSessionStarting(second_session);
120+
121+ Application * the_app = applicationManager.findApplication(an_app_id);
122+
123+ EXPECT_EQ(true, authed);
124+ EXPECT_EQ(second_session, the_app->session());
125+}
126+
127+TEST_F(ApplicationManagerTests,two_session_on_one_application_after_starting)
128+{
129+ using namespace ::testing;
130+ quint64 a_procId = 5921;
131+ const char an_app_id[] = "some_app";
132+ QByteArray a_cmd( "/usr/bin/app1 --desktop_file_hint=some_app");
133+ std::shared_ptr<mir::shell::Surface> aSurface(nullptr);
134+
135+ ON_CALL(procInfo,command_line(_)).WillByDefault(Return(a_cmd));
136+
137+ ON_CALL(appController,appIdHasProcessId(_,_)).WillByDefault(Return(false));
138+
139+ bool authed = true;
140+
141+ std::shared_ptr<mir::shell::Session> first_session = std::make_shared<MockSession>("Oo", a_procId);
142+ std::shared_ptr<mir::shell::Session> second_session = std::make_shared<MockSession>("oO", a_procId);
143+ applicationManager.authorizeSession(a_procId, authed);
144+
145+ applicationManager.onSessionStarting(first_session);
146+ applicationManager.onSessionCreatedSurface(first_session.get(), aSurface);
147+ applicationManager.onSessionStarting(second_session);
148+
149+ Application * the_app = applicationManager.findApplication(an_app_id);
150+
151+ EXPECT_EQ(true, authed);
152+ EXPECT_EQ(Application::Running, the_app->state());
153+ EXPECT_EQ(first_session, the_app->session());
154+}

Subscribers

People subscribed via source and target branches