Merge lp:~mterry/unity8/dialer-above into lp:unity8

Proposed by Michael Terry
Status: Superseded
Proposed branch: lp:~mterry/unity8/dialer-above
Merge into: lp:unity8
Prerequisite: lp:~mterry/unity8/is-active
Diff against target: 867 lines (+376/-59)
18 files modified
plugins/LightDM/DBusGreeter.cpp (+5/-0)
plugins/LightDM/DBusGreeter.h (+1/-0)
plugins/LightDM/Greeter.h (+1/-0)
qml/Components/Lockscreen.qml (+17/-5)
qml/Shell.qml (+86/-28)
qml/Stages/PhoneStage.qml (+13/-1)
tests/autopilot/unity8/shell/tests/test_notifications.py (+4/-4)
tests/mocks/LightDM/single-pin/GreeterPrivate.cpp (+1/-9)
tests/mocks/Unity/Application/ApplicationManager.cpp (+3/-3)
tests/mocks/Unity/Launcher/MockLauncherModel.cpp (+1/-1)
tests/plugins/LightDM/dbus.cpp (+7/-0)
tests/qmltests/CMakeLists.txt (+2/-2)
tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml (+2/-2)
tests/qmltests/Greeter/tst_Lockscreen.qml (+1/-1)
tests/qmltests/Launcher/tst_Launcher.qml (+2/-2)
tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml (+1/-1)
tests/qmltests/tst_Shell.qml (+27/-0)
tests/qmltests/tst_ShellWithPin.qml (+202/-0)
To merge this branch: bzr merge lp:~mterry/unity8/dialer-above
Reviewer Review Type Date Requested Status
Seth Arnold (community) Approve
Albert Astals Cid (community) Needs Fixing
PS Jenkins bot (community) continuous-integration Needs Fixing
Marc Deslauriers Pending
Review via email: mp+224947@code.launchpad.net

This proposal supersedes a proposal from 2014-06-30.

This proposal has been superseded by a proposal from 2014-07-11.

Commit message

Allow running the dialer-app in emergency mode when the screen is locked.

Description of the change

Allow running the dialer-app in emergency mode when the screen is locked.

The intent is to unlock the phone temporarily, and only give access to the dialer app.

This has some risk, security wise. After talking to Marc from security, here is the approach used:

0) (not in this branch) Have the dialer-app pay attention to when the phone is locked and expose a different, emergency mode UI. This reduces functionality and does not give access to contact information or call history.

1) Disable all edges while in emergency mode. This is to help stop us switching to a different app as well as to remove all distractions or even accidental app switching while the user is having an emergency.

2) If an app does requests focus or manages to get launched somehow (maybe a notification is clicked, or the dialer-app crashes, or it has a bug where it lets you launch another app or whatever), we lock the screen.

All that said, if there is a bug in this branch, it is a security problem, because the screen might become unlocked without entering the password.

== Checklist ==

 * Are there any related MPs required for this MP to build/function as expected? Please list.
 - Yes. lp:~mterry/unity8/is-active and lp:~mterry/unity8/show-greeter-dbus both expose information that dialer-app will need and there is a dialer-app branch we'll want that uses the emergency mode UI (link coming)

 * Did you perform an exploratory manual test run of your code change and any related functionality?
 - Yes

 * Did you make sure that your branch does not contain spurious tags?
 - Yes

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

 * If you changed the UI, has there been a design review?
 - NA

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/dialer-above updated
985. By Michael Terry

Disable emergency call button on wider devices (tablets)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~mterry/unity8/dialer-above updated
986. By Michael Terry

Fix qmluitest

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Albert Astals Cid (aacid) wrote :

Text conflict in qml/Shell.qml
1 conflicts encountered.

review: Needs Fixing
lp:~mterry/unity8/dialer-above updated
987. By Michael Terry

Merge from show-greeter-dbus

988. By Michael Terry

Set mock lightdm for PhoneStage test

989. By Michael Terry

Fix qmluitest

990. By Michael Terry

Only enable greeter drag area if greeter is also enabled (I keep forgetting that isn't automatic)

991. By Michael Terry

Add some more braces for single-line ifs

Revision history for this message
Seth Arnold (seth-arnold) wrote :

I think I should have reviewed this MP first, some of this has been replaced elsewhere. Oh well, the parts that looked new looked good. One comment inline, of no real consequence. Thanks!

review: Approve
lp:~mterry/unity8/dialer-above updated
992. By Michael Terry

Merge from trunk

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/LightDM/DBusGreeter.cpp'
2--- plugins/LightDM/DBusGreeter.cpp 2014-07-02 19:12:51 +0000
3+++ plugins/LightDM/DBusGreeter.cpp 2014-07-02 19:12:51 +0000
4@@ -34,6 +34,11 @@
5 return m_greeter->isActive();
6 }
7
8+void DBusGreeter::ShowGreeter()
9+{
10+ return Q_EMIT m_greeter->showGreeter();
11+}
12+
13 void DBusGreeter::isActiveChangedHandler()
14 {
15 notifyPropertyChanged("IsActive", isActive());
16
17=== modified file 'plugins/LightDM/DBusGreeter.h'
18--- plugins/LightDM/DBusGreeter.h 2014-07-02 19:12:51 +0000
19+++ plugins/LightDM/DBusGreeter.h 2014-07-02 19:12:51 +0000
20@@ -37,6 +37,7 @@
21 explicit DBusGreeter(Greeter *greeter, const QDBusConnection &connection, const QString &path);
22
23 bool isActive() const;
24+ Q_SCRIPTABLE void ShowGreeter(); // temporary, until we split the greeter again
25
26 Q_SIGNALS:
27 void isActiveChanged();
28
29=== modified file 'plugins/LightDM/Greeter.h'
30--- plugins/LightDM/Greeter.h 2014-07-02 19:12:51 +0000
31+++ plugins/LightDM/Greeter.h 2014-07-02 19:12:51 +0000
32@@ -60,6 +60,7 @@
33 void authenticationUserChanged(const QString &user);
34 void isActiveChanged();
35 void promptlessChanged();
36+ void showGreeter();
37
38 // This signal is emitted by external agents like indicators, and the UI
39 // should switch to this user if possible.
40
41=== modified file 'qml/Components/Lockscreen.qml'
42--- qml/Components/Lockscreen.qml 2014-06-11 15:36:51 +0000
43+++ qml/Components/Lockscreen.qml 2014-07-02 19:12:51 +0000
44@@ -186,6 +186,17 @@
45 }
46
47 Column {
48+ id: emergencyCallColumn
49+
50+ // FIXME: We *should* show emergency dialer if there is a SIM present,
51+ // regardless of whether the side stage is enabled. But right now,
52+ // the assumption is that narrow screens are phones which have SIMs
53+ // and wider screens are tablets which don't. When we do allow this
54+ // on devices with a side stage and a SIM, work should be done to
55+ // ensure that the main stage is disabled while the dialer is present
56+ // in the side stage.
57+ visible: !shell.sideStageEnabled
58+
59 anchors {
60 left: parent.left
61 bottom: parent.bottom
62@@ -203,11 +214,6 @@
63 name: "phone-app-call-symbolic"
64 color: "#f3f3e7"
65 opacity: 0.6
66-
67- MouseArea {
68- anchors.fill: parent
69- onClicked: root.emergencyCall()
70- }
71 }
72
73 Label {
74@@ -219,6 +225,12 @@
75 }
76 }
77
78+ MouseArea {
79+ anchors.fill: emergencyCallColumn
80+ onClicked: root.emergencyCall()
81+ enabled: emergencyCallColumn.visible
82+ }
83+
84 Component {
85 id: infoPopupComponent
86 Dialog {
87
88=== renamed file 'qml/Dash/graphics/phone/screenshots/phone@12.png' => 'qml/Dash/graphics/phone/screenshots/dialer@12.png'
89=== modified file 'qml/Shell.qml'
90--- qml/Shell.qml 2014-07-02 19:12:51 +0000
91+++ qml/Shell.qml 2014-07-02 19:12:51 +0000
92@@ -136,7 +136,7 @@
93 id: dash
94 objectName: "dash"
95
96- available: !greeter.shown && !lockscreen.shown
97+ available: !LightDM.Greeter.active
98 hides: [stages, launcher, panel.indicators]
99 shown: disappearingAnimationProgress !== 1.0 && greeterWrapper.showProgress !== 1.0
100 enabled: disappearingAnimationProgress === 0.0 && greeterWrapper.showProgress === 0.0 && edgeDemo.dashEnabled
101@@ -199,7 +199,7 @@
102
103 x: {
104 if (shown) {
105- if (overlayMode || locked) {
106+ if (overlayMode || locked || greeter.fakeActiveForApp !== "") {
107 return 0;
108 }
109 return launcher.progress
110@@ -244,10 +244,17 @@
111 target: ApplicationManager
112
113 onFocusRequested: {
114+ if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== appId) {
115+ lockscreen.show();
116+ }
117+ greeter.hide();
118 stages.show(true);
119 }
120
121 onFocusedApplicationIdChanged: {
122+ if (greeter.fakeActiveForApp !== "" && greeter.fakeActiveForApp !== ApplicationManager.focusedApplicationId) {
123+ lockscreen.show();
124+ }
125 if (ApplicationManager.focusedApplicationId.length > 0) {
126 stages.show(false);
127 } else {
128@@ -300,6 +307,11 @@
129
130 Binding {
131 target: applicationsDisplayLoader.item
132+ property: "objectName"
133+ value: "stage"
134+ }
135+ Binding {
136+ target: applicationsDisplayLoader.item
137 property: "moving"
138 value: !stages.fullyShown
139 }
140@@ -313,6 +325,11 @@
141 property: "dragAreaWidth"
142 value: shell.edgeSize
143 }
144+ Binding {
145+ target: applicationsDisplayLoader.item
146+ property: "spreadEnabled"
147+ value: greeter.fakeActiveForApp === "" // to support emergency dialer hack
148+ }
149 }
150 }
151
152@@ -337,6 +354,13 @@
153
154 onEntered: LightDM.Greeter.respond(passphrase);
155 onCancel: greeter.show()
156+ onEmergencyCall: {
157+ greeter.fakeActiveForApp = "dialer-app"
158+ shell.activateApplication("dialer-app")
159+ lockscreen.hide()
160+ }
161+
162+ onShownChanged: if (shown) greeter.fakeActiveForApp = ""
163
164 Component.onCompleted: {
165 if (LightDM.Users.count == 1) {
166@@ -348,6 +372,8 @@
167 Connections {
168 target: LightDM.Greeter
169
170+ onShowGreeter: greeter.show()
171+
172 onShowPrompt: {
173 if (LightDM.Users.count == 1) {
174 // TODO: There's no better way for now to determine if its a PIN or a passphrase.
175@@ -367,6 +393,7 @@
176 }
177 if (LightDM.Greeter.authenticated) {
178 lockscreen.hide();
179+ greeter.login();
180 } else {
181 lockscreen.clear(true);
182 }
183@@ -376,7 +403,7 @@
184 Binding {
185 target: LightDM.Greeter
186 property: "active"
187- value: greeter.shown || lockscreen.shown
188+ value: greeter.shown || lockscreen.shown || greeter.fakeActiveForApp != ""
189 }
190
191 Rectangle {
192@@ -399,11 +426,16 @@
193 }
194
195 readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1)
196+ onShowProgressChanged: if (LightDM.Greeter.promptless && showProgress === 0) greeter.login()
197
198 Greeter {
199 id: greeter
200 objectName: "greeter"
201
202+ signal sessionStarted() // helpful for tests
203+
204+ property string fakeActiveForApp: ""
205+
206 available: true
207 hides: [launcher, panel.indicators]
208 shown: true
209@@ -415,14 +447,28 @@
210
211 dragHandleWidth: shell.edgeSize
212
213+ function login() {
214+ enabled = false;
215+ LightDM.Greeter.startSessionSync();
216+ sessionStarted();
217+ greeter.hide();
218+ lockscreen.hide();
219+ launcher.hide();
220+ enabled = true;
221+ }
222+
223 onShownChanged: {
224 if (shown) {
225 lockscreen.reset();
226+ if (!LightDM.Greeter.promptless) {
227+ lockscreen.show();
228+ }
229 // If there is only one user, we start authenticating with that one here.
230 // If there are more users, the Greeter will handle that
231 if (LightDM.Users.count == 1) {
232 LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole));
233 }
234+ greeter.fakeActiveForApp = "";
235 greeter.forceActiveFocus();
236 }
237 }
238@@ -472,12 +518,36 @@
239 }
240
241 function showHome() {
242- var animate = !greeter.shown && !stages.shown
243- greeter.hide()
244+ if (edgeDemo.running)
245+ return
246+
247+ if (LightDM.Greeter.active) {
248+ if (!LightDM.Greeter.promptless)
249+ lockscreen.show()
250+ greeter.hide()
251+ }
252+
253+ var animate = !LightDM.Greeter.active && !stages.shown
254 dash.setCurrentScope("clickscope", animate, false)
255 stages.hide()
256 }
257
258+ function showDash() {
259+ if (LightDM.Greeter.active && !LightDM.Greeter.promptless)
260+ return;
261+
262+ if (stages.shown && !stages.overlayMode) {
263+ if (!stages.locked) {
264+ stages.hide();
265+ launcher.hide();
266+ }
267+ }
268+ if (greeter.shown) {
269+ greeter.hideRight();
270+ launcher.hide();
271+ }
272+ }
273+
274 function hideIndicatorMenu(delay) {
275 panel.hideIndicatorMenu(delay);
276 }
277@@ -489,17 +559,18 @@
278
279 Panel {
280 id: panel
281+ objectName: "panel"
282 anchors.fill: parent //because this draws indicator menus
283 indicatorsMenuWidth: parent.width > units.gu(60) ? units.gu(40) : parent.width
284 indicators {
285 hides: [launcher]
286- available: edgeDemo.panelEnabled
287+ available: edgeDemo.panelEnabled && greeter.fakeActiveForApp === ""
288 contentEnabled: edgeDemo.panelContentEnabled
289 }
290 property string focusedAppId: ApplicationManager.focusedApplicationId
291 property var focusedApplication: ApplicationManager.findApplication(focusedAppId)
292- fullscreenMode: focusedApplication && stages.fullscreen && !greeter.shown && !lockscreen.shown
293- searchVisible: !greeter.shown && !lockscreen.shown && dash.shown && dash.searchable
294+ fullscreenMode: (focusedApplication && stages.fullscreen && !LightDM.Greeter.active) || greeter.fakeActiveForApp !== ""
295+ searchVisible: !LightDM.Greeter.active && dash.shown && dash.searchable
296
297 InputFilterArea {
298 anchors {
299@@ -524,6 +595,7 @@
300
301 Launcher {
302 id: launcher
303+ objectName: "launcher"
304
305 readonly property bool dashSwipe: progress > 0
306
307@@ -531,28 +603,14 @@
308 anchors.bottom: parent.bottom
309 width: parent.width
310 dragAreaWidth: shell.edgeSize
311- available: edgeDemo.launcherEnabled
312-
313- onShowDashHome: {
314- if (edgeDemo.running)
315- return;
316-
317- showHome()
318- }
319- onDash: {
320- if (stages.shown && !stages.overlayMode) {
321- if (!stages.locked) {
322- stages.hide();
323- launcher.hide();
324- }
325- }
326- if (greeter.shown) {
327- greeter.hideRight();
328- launcher.hide();
329- }
330- }
331+ available: edgeDemo.launcherEnabled && greeter.fakeActiveForApp === ""
332+
333+ onShowDashHome: showHome()
334+ onDash: showDash()
335 onDashSwipeChanged: if (dashSwipe && stages.shown) dash.setCurrentScope("clickscope", false, true)
336 onLauncherApplicationSelected: {
337+ if (greeter.fakeActiveForApp !== "")
338+ lockscreen.show()
339 if (!edgeDemo.running)
340 shell.activateApplication(appId)
341 }
342
343=== modified file 'qml/Stages/PhoneStage.qml'
344--- qml/Stages/PhoneStage.qml 2014-05-26 14:12:20 +0000
345+++ qml/Stages/PhoneStage.qml 2014-07-02 19:12:51 +0000
346@@ -18,6 +18,7 @@
347 import Ubuntu.Components 0.1
348 import Ubuntu.Gestures 0.1
349 import Unity.Application 0.1
350+import LightDM 0.1 as LightDM
351 import Utils 0.1
352 import "../Components"
353
354@@ -33,6 +34,7 @@
355 readonly property bool painting: mainScreenshotImage.visible || fadeInScreenshotImage.visible || appSplash.visible || spreadView.visible
356 property bool fullscreen: priv.focusedApplication ? priv.focusedApplication.fullscreen : false
357 property bool locked: spreadView.visible
358+ property bool spreadEnabled: true
359
360 // Not used for PhoneStage, only useful for SideStage and similar
361 property bool overlayMode: false
362@@ -131,6 +133,11 @@
363 mainScreenshotImage.visible = true;
364 } else if (priv.secondApplicationStarting && priv.waitingForScreenshot) {
365 applicationSwitchingAnimation.start();
366+ if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
367+ // When greeter is up, no fancy animations, since user may
368+ // glimpse an app they shouldn't
369+ applicationSwitchingAnimation.complete();
370+ }
371 }
372 waitingForScreenshot = false;
373 }
374@@ -145,6 +152,11 @@
375 priv.newFocusedAppId = appId;
376 root.fullscreen = ApplicationManager.findApplication(appId).fullscreen;
377 applicationSwitchingAnimation.start();
378+ if (LightDM.Greeter.active && !LightDM.Greeter.promptless) {
379+ // When greeter is up, no fancy animations, since user may
380+ // glimpse an app they shouldn't
381+ applicationSwitchingAnimation.complete();
382+ }
383 } else {
384 ApplicationManager.focusApplication(appId);
385 }
386@@ -244,7 +256,7 @@
387 EdgeDragArea {
388 id: spreadDragArea
389 direction: Direction.Leftwards
390- enabled: ApplicationManager.count > 1 && spreadView.phase != 2
391+ enabled: ApplicationManager.count > 1 && spreadView.phase != 2 && root.spreadEnabled
392
393 anchors { top: parent.top; right: parent.right; bottom: parent.bottom }
394 width: root.dragAreaWidth
395
396=== renamed file 'qml/graphics/applicationIcons/phone-app@18.png' => 'qml/graphics/applicationIcons/dialer-app@18.png'
397=== modified file 'tests/autopilot/unity8/shell/tests/test_notifications.py'
398--- tests/autopilot/unity8/shell/tests/test_notifications.py 2014-06-11 15:36:51 +0000
399+++ tests/autopilot/unity8/shell/tests/test_notifications.py 2014-07-02 19:12:51 +0000
400@@ -137,7 +137,7 @@
401 ("x-canonical-switch-to-application", "true"),
402 (
403 "x-canonical-secondary-icon",
404- self._get_icon_path('applicationIcons/phone-app.png')
405+ self._get_icon_path('applicationIcons/dialer-app.png')
406 )
407 ]
408
409@@ -172,7 +172,7 @@
410 hints = [
411 (
412 "x-canonical-secondary-icon",
413- self._get_icon_path('applicationIcons/phone-app.png')
414+ self._get_icon_path('applicationIcons/dialer-app.png')
415 ),
416 ("x-canonical-snap-decisions", "true"),
417 ]
418@@ -435,7 +435,7 @@
419 hints = [
420 (
421 "x-canonical-secondary-icon",
422- self._get_icon_path('applicationIcons/phone-app.png')
423+ self._get_icon_path('applicationIcons/dialer-app.png')
424 )
425 ]
426
427@@ -677,7 +677,7 @@
428 body = 'This bubble uses the icon-title-body layout with a ' \
429 'secondary icon.'
430 icon_path = self._get_icon_path('avatars/anna_olsson.png')
431- hint_icon = self._get_icon_path('applicationIcons/phone-app.png')
432+ hint_icon = self._get_icon_path('applicationIcons/dialer-app.png')
433
434 notification = shell.create_ephemeral_notification(
435 summary,
436
437=== modified file 'tests/mocks/LightDM/single-pin/GreeterPrivate.cpp'
438--- tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2013-06-06 12:18:34 +0000
439+++ tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2014-07-02 19:12:51 +0000
440@@ -19,8 +19,6 @@
441 #include "../Greeter.h"
442 #include "../GreeterPrivate.h"
443
444-#include <QDebug>
445-
446 namespace QLightDM
447 {
448
449@@ -34,19 +32,13 @@
450 void GreeterPrivate::handleAuthenticate()
451 {
452 Q_Q(Greeter);
453-
454- qDebug() << "handleAuthentication called!" << authenticationUser;
455-
456- Q_EMIT q->showPrompt("PIN:", Greeter::PromptTypeSecret);
457+ Q_EMIT q->showPrompt("PIN", Greeter::PromptTypeSecret);
458 }
459
460 void GreeterPrivate::handleRespond(const QString &response)
461 {
462 Q_Q(Greeter);
463-
464-
465 authenticated = (response == "1234");
466- qDebug() << "responding" << response << authenticated;
467 Q_EMIT q->authenticationComplete();
468 }
469
470
471=== modified file 'tests/mocks/Unity/Application/ApplicationManager.cpp'
472--- tests/mocks/Unity/Application/ApplicationManager.cpp 2014-03-20 09:45:39 +0000
473+++ tests/mocks/Unity/Application/ApplicationManager.cpp 2014-07-02 19:12:51 +0000
474@@ -361,9 +361,9 @@
475 ApplicationInfo *application;
476
477 application = new ApplicationInfo(this);
478- application->setAppId("phone-app");
479- application->setName("Phone");
480- application->setIcon(QUrl("phone"));
481+ application->setAppId("dialer-app");
482+ application->setName("Dialer");
483+ application->setIcon(QUrl("dialer"));
484 application->setStage(ApplicationInfo::SideStage);
485 application->setScreenshot(QString("image://application/%1/%2").arg(application->appId()).arg(QDateTime::currentMSecsSinceEpoch()));
486 generateQmlStrings(application);
487
488=== modified file 'tests/mocks/Unity/Launcher/MockLauncherModel.cpp'
489--- tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2014-05-29 14:32:07 +0000
490+++ tests/mocks/Unity/Launcher/MockLauncherModel.cpp 2014-07-02 19:12:51 +0000
491@@ -22,7 +22,7 @@
492
493 MockLauncherModel::MockLauncherModel(QObject* parent): LauncherModelInterface(parent)
494 {
495- MockLauncherItem *item = new MockLauncherItem("phone-app", "/usr/share/applications/phone-app.desktop", "Phone", "phone-app", this);
496+ MockLauncherItem *item = new MockLauncherItem("dialer-app", "/usr/share/applications/dialer-app.desktop", "Dialer", "dialer-app", this);
497 item->setProgress(0);
498 m_list.append(item);
499 item->setFocused(true);
500
501=== modified file 'tests/plugins/LightDM/dbus.cpp'
502--- tests/plugins/LightDM/dbus.cpp 2014-07-02 19:12:51 +0000
503+++ tests/plugins/LightDM/dbus.cpp 2014-07-02 19:12:51 +0000
504@@ -187,6 +187,13 @@
505 QVERIFY(arguments.at(1).toMap()["IsActive"].toBool());
506 }
507
508+ void testShowGreeter()
509+ {
510+ // Just confirm the call exists and doesn't fail
511+ QDBusReply<void> reply = dbusMain->call("ShowGreeter");
512+ QVERIFY(reply.isValid());
513+ }
514+
515 private:
516 QQuickView *view;
517 Greeter *greeter;
518
519=== modified file 'tests/qmltests/CMakeLists.txt'
520--- tests/qmltests/CMakeLists.txt 2014-06-18 07:24:08 +0000
521+++ tests/qmltests/CMakeLists.txt 2014-07-02 19:12:51 +0000
522@@ -19,8 +19,8 @@
523 set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
524 set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
525
526-add_qml_test(. Shell IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/tests/mocks
527- ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
528+add_qml_test(. Shell ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single")
529+add_qml_test(. ShellWithPin ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single-pin")
530 add_qml_test(Components Carousel)
531 add_qml_test(Components DraggingArea)
532 add_qml_test(Components EdgeDemoOverlay)
533
534=== modified file 'tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml'
535--- tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml 2014-02-06 19:12:15 +0000
536+++ tests/qmltests/Dash/Apps/tst_RunningApplicationsGrid.qml 2014-07-02 19:12:51 +0000
537@@ -30,7 +30,7 @@
538 ApplicationManager.stopApplication(ApplicationManager.get(0).appId)
539 }
540
541- ApplicationManager.startApplication("phone-app");
542+ ApplicationManager.startApplication("dialer-app");
543 ApplicationManager.startApplication("webbrowser-app");
544 }
545
546@@ -70,7 +70,7 @@
547 verify(browserTile != undefined)
548 browserTile.onPressAndHold.connect(onBrowserLongPressed)
549
550- phoneTile = findChild(runningApplicationsGrid, "runningAppTile Phone")
551+ phoneTile = findChild(runningApplicationsGrid, "runningAppTile Dialer")
552 verify(phoneTile != undefined)
553 phoneTile.onPressAndHold.connect(onPhoneLongPressed)
554
555
556=== modified file 'tests/qmltests/Greeter/tst_Lockscreen.qml'
557--- tests/qmltests/Greeter/tst_Lockscreen.qml 2014-06-11 15:36:51 +0000
558+++ tests/qmltests/Greeter/tst_Lockscreen.qml 2014-07-02 19:12:51 +0000
559@@ -57,7 +57,7 @@
560 target: LightDM.Greeter
561
562 onShowPrompt: {
563- if (text.indexOf("PIN") >= 0) {
564+ if (text === "PIN") {
565 pinPadCheckBox.checked = false
566 } else {
567 pinPadCheckBox.checked = true
568
569=== modified file 'tests/qmltests/Launcher/tst_Launcher.qml'
570--- tests/qmltests/Launcher/tst_Launcher.qml 2014-04-14 17:26:06 +0000
571+++ tests/qmltests/Launcher/tst_Launcher.qml 2014-07-02 19:12:51 +0000
572@@ -115,7 +115,7 @@
573 /* If I click on the icon of an application on the launcher
574 Launcher::launcherApplicationSelected signal should be emitted with the
575 corresponding desktop file. E.g. clicking on phone icon should yield
576- launcherApplicationSelected("[...]phone-app.desktop") */
577+ launcherApplicationSelected("[...]dialer-app.desktop") */
578 function test_clickingOnAppIconCausesSignalEmission() {
579 launcher.lastSelectedApplication = ""
580
581@@ -131,7 +131,7 @@
582 mouseClick(appIcon, appIcon.width/2, appIcon.height/2)
583
584 tryCompare(launcher, "lastSelectedApplication",
585- "phone-app")
586+ "dialer-app")
587
588 // Tapping on an application icon also dismisses the launcher
589 revealer.waitUntilLauncherDisappears()
590
591=== modified file 'tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml'
592--- tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml 2014-03-31 10:47:51 +0000
593+++ tests/qmltests/Notifications/tst_VisualSnapDecisionsQueue.qml 2014-07-02 19:12:51 +0000
594@@ -67,7 +67,7 @@
595 summary: "Incoming call",
596 body: "Frank Zappa\n+44 (0)7736 027340",
597 icon: "../graphics/avatars/funky.png",
598- secondaryIcon: "../graphics/applicationIcons/phone-app.png",
599+ secondaryIcon: "../graphics/applicationIcons/dialer-app.png",
600 actions: [{ id: "pickup_id", label: "Pick up"},
601 { id: "decline_1_id", label: "Decline"},
602 { id: "decline_2_id", label: "Can't talk now, what's up?"},
603
604=== modified file 'tests/qmltests/tst_Shell.qml'
605--- tests/qmltests/tst_Shell.qml 2014-06-17 03:52:58 +0000
606+++ tests/qmltests/tst_Shell.qml 2014-07-02 19:12:51 +0000
607@@ -20,6 +20,7 @@
608 import QtQuick 2.0
609 import QtTest 1.0
610 import GSettings 1.0
611+import LightDM 0.1 as LightDM
612 import Unity.Application 0.1
613 import Unity.Test 0.1 as UT
614 import Powerd 0.1
615@@ -50,6 +51,11 @@
616 id: shell
617 }
618
619+ SignalSpy {
620+ id: sessionSpy
621+ signalName: "sessionStarted"
622+ }
623+
624 UT.UnityTestCase {
625 name: "Shell"
626 when: windowShown
627@@ -91,6 +97,8 @@
628 verify(ok);
629
630 swipeAwayGreeter();
631+
632+ sessionSpy.target = findChild(shell, "greeter")
633 }
634
635 function cleanup() {
636@@ -556,5 +564,24 @@
637 tryCompare(greeter, "showProgress", 0)
638 waitUntilApplicationWindowIsFullyVisible()
639 }
640+
641+ function test_showGreeterDBusCall() {
642+ var greeter = findChild(shell, "greeter")
643+ tryCompare(greeter, "showProgress", 0)
644+ LightDM.Greeter.showGreeter()
645+ tryCompare(greeter, "showProgress", 1)
646+ }
647+
648+ function test_login() {
649+ sessionSpy.clear()
650+
651+ var greeter = findChild(shell, "greeter")
652+ greeter.show()
653+ tryCompare(greeter, "showProgress", 1)
654+
655+ tryCompare(sessionSpy, "count", 0)
656+ swipeAwayGreeter()
657+ tryCompare(sessionSpy, "count", 1)
658+ }
659 }
660 }
661
662=== added file 'tests/qmltests/tst_ShellWithPin.qml'
663--- tests/qmltests/tst_ShellWithPin.qml 1970-01-01 00:00:00 +0000
664+++ tests/qmltests/tst_ShellWithPin.qml 2014-07-02 19:12:51 +0000
665@@ -0,0 +1,202 @@
666+/*
667+ * Copyright (C) 2014 Canonical, Ltd.
668+ *
669+ * This program is free software; you can redistribute it and/or modify
670+ * it under the terms of the GNU General Public License as published by
671+ * the Free Software Foundation; version 3.
672+ *
673+ * This program is distributed in the hope that it will be useful,
674+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
675+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
676+ * GNU General Public License for more details.
677+ *
678+ * You should have received a copy of the GNU General Public License
679+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
680+ */
681+
682+import QtQuick 2.0
683+import QtTest 1.0
684+import GSettings 1.0
685+import LightDM 0.1 as LightDM
686+import Unity.Application 0.1
687+import Unity.Test 0.1 as UT
688+import Powerd 0.1
689+
690+import "../../qml"
691+
692+Item {
693+ width: shell.width
694+ height: shell.height
695+
696+ QtObject {
697+ id: applicationArguments
698+
699+ function hasGeometry() {
700+ return false;
701+ }
702+
703+ function width() {
704+ return 0;
705+ }
706+
707+ function height() {
708+ return 0;
709+ }
710+ }
711+
712+ Shell {
713+ id: shell
714+ }
715+
716+ SignalSpy {
717+ id: sessionSpy
718+ signalName: "sessionStarted"
719+ }
720+
721+ UT.UnityTestCase {
722+ name: "ShellWithPin"
723+ when: windowShown
724+
725+ function initTestCase() {
726+ var ok = false;
727+ var attempts = 0;
728+ var maxAttempts = 1000;
729+
730+ // Qt loads a qml scene asynchronously. So early on, some findChild() calls made in
731+ // tests may fail because the desired child item wasn't loaded yet.
732+ // Thus here we try to ensure the scene has been fully loaded before proceeding with the tests.
733+ // As I couldn't find an API in QQuickView & friends to tell me that the scene is 100% loaded
734+ // (all items instantiated, etc), I resort to checking the existence of some key items until
735+ // repeatedly until they're all there.
736+ do {
737+ var dashContentList = findChild(shell, "dashContentList");
738+ waitForRendering(dashContentList);
739+ var homeLoader = findChild(dashContentList, "clickscope loader");
740+ ok = homeLoader !== null
741+ && homeLoader.item !== undefined;
742+
743+ var greeter = findChild(shell, "greeter");
744+ ok &= greeter !== null;
745+
746+ var launcherPanel = findChild(shell, "launcherPanel");
747+ ok &= launcherPanel !== null;
748+
749+ attempts++;
750+ if (!ok) {
751+ console.log("Attempt " + attempts + " failed. Waiting a bit before trying again.");
752+ // wait a bit before retrying
753+ wait(100);
754+ } else {
755+ console.log("All seem fine after " + attempts + " attempts.");
756+ }
757+ } while (!ok && attempts <= maxAttempts);
758+
759+ verify(ok);
760+
761+ sessionSpy.target = findChild(shell, "greeter")
762+ }
763+
764+ function init() {
765+ swipeAwayGreeter()
766+ }
767+
768+ function cleanup() {
769+ LightDM.Greeter.showGreeter()
770+ var greeter = findChild(shell, "greeter")
771+ tryCompare(greeter, "showProgress", 1)
772+
773+ // kill all (fake) running apps
774+ killApps()
775+ }
776+
777+ function killApps() {
778+ while (ApplicationManager.count > 0) {
779+ ApplicationManager.stopApplication(ApplicationManager.get(0).appId)
780+ }
781+ compare(ApplicationManager.count, 0)
782+ }
783+
784+ function swipeAwayGreeter() {
785+ var greeter = findChild(shell, "greeter");
786+ tryCompare(greeter, "showProgress", 1);
787+
788+ var touchX = shell.width - (shell.edgeSize / 2);
789+ var touchY = shell.height / 2;
790+ touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
791+
792+ // wait until the animation has finished
793+ tryCompare(greeter, "showProgress", 0);
794+
795+ // and for pin to be ready
796+ var lockscreen = findChild(shell, "lockscreen");
797+ var pinPadLoader = findChild(lockscreen, "pinPadLoader");
798+ tryCompare(pinPadLoader, "status", Loader.Ready)
799+ waitForRendering(lockscreen)
800+ }
801+
802+ function enterPin(pin) {
803+ var inputField = findChild(shell, "pinentryField")
804+ for (var i = 0; i < pin.length; ++i) {
805+ var character = pin.charAt(i)
806+ var button = findChild(shell, "pinPadButton" + character)
807+ mouseClick(button, units.gu(1), units.gu(1))
808+ }
809+ }
810+
811+ function test_login() {
812+ tryCompare(sessionSpy, "count", 0)
813+ enterPin("1234")
814+ tryCompare(sessionSpy, "count", 1)
815+ }
816+
817+ function test_emergencyCall() {
818+ var greeter = findChild(shell, "greeter")
819+ var lockscreen = findChild(shell, "lockscreen")
820+ var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
821+ var panel = findChild(shell, "panel")
822+ var indicators = findChild(shell, "indicators")
823+ var launcher = findChild(shell, "launcher")
824+ var stage = findChild(shell, "stage")
825+
826+ mouseClick(emergencyButton, units.gu(1), units.gu(1))
827+
828+ tryCompare(lockscreen, "shown", false)
829+ tryCompare(greeter, "fakeActiveForApp", "dialer-app")
830+ tryCompare(panel, "fullscreenMode", true)
831+ tryCompare(indicators, "available", false)
832+ tryCompare(launcher, "available", false)
833+ tryCompare(stage, "spreadEnabled", false)
834+
835+ // Cancel emergency mode, and go back to normal
836+ LightDM.Greeter.showGreeter()
837+
838+ tryCompare(lockscreen, "shown", true)
839+ tryCompare(greeter, "shown", true)
840+ tryCompare(greeter, "fakeActiveForApp", "")
841+ tryCompare(panel, "fullscreenMode", false)
842+ tryCompare(indicators, "available", true)
843+ tryCompare(launcher, "available", true)
844+ tryCompare(stage, "spreadEnabled", true)
845+ }
846+
847+ function test_emergencyCallCrash() {
848+ var lockscreen = findChild(shell, "lockscreen")
849+ var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
850+ mouseClick(emergencyButton, units.gu(1), units.gu(1))
851+
852+ tryCompare(lockscreen, "shown", false)
853+ killApps() // kill dialer-app, as if it crashed
854+ tryCompare(lockscreen, "shown", true)
855+ }
856+
857+ function test_emergencyCallAppLaunch() {
858+ var lockscreen = findChild(shell, "lockscreen")
859+ var emergencyButton = findChild(lockscreen, "emergencyCallIcon")
860+ mouseClick(emergencyButton, units.gu(1), units.gu(1))
861+
862+ tryCompare(lockscreen, "shown", false)
863+ ApplicationManager.startApplication("gallery-app", ApplicationManager.NoFlag)
864+ tryCompare(lockscreen, "shown", true)
865+ }
866+ }
867+}

Subscribers

People subscribed via source and target branches