on xenial help sign in
Don't show greeter when screen turns off during a call, even if proximity sensor isn't active. Fixes: 1347001
7f545d0Michael Terry
plugins/Powerd/Powerd.cpp+16−2
@@ -39,7 +39,8 @@ void dimTimeoutChanged(GSettings *settings, const gchar *key, QDBusInterface *un
39
39
40Powerd::Powerd(QObject* parent)
40Powerd::Powerd(QObject* parent)
41 : QObject(parent),
41 : QObject(parent),
42− unityScreen(nullptr)
42+ unityScreen(nullptr),
43+ cachedStatus(Status::On)
43{
44{
44 unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
45 unityScreen = new QDBusInterface("com.canonical.Unity.Screen",
45 "/com/canonical/Unity/Screen",
46 "/com/canonical/Unity/Screen",
@@ -51,7 +52,7 @@ Powerd::Powerd(QObject* parent)
51 "com.canonical.Unity.Screen",
52 "com.canonical.Unity.Screen",
52 "DisplayPowerStateChange",
53 "DisplayPowerStateChange",
53 this,
54 this,
54− SIGNAL(displayPowerStateChange(int, int)));
55+ SLOT(handleDisplayPowerStateChange(int, int)));
55
56
56 systemSettings = g_settings_new("com.ubuntu.touch.system");
57 systemSettings = g_settings_new("com.ubuntu.touch.system");
57 g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
58 g_signal_connect(systemSettings, "changed::auto-brightness", G_CALLBACK(autoBrightnessChanged), unityScreen);
@@ -67,3 +68,16 @@ Powerd::~Powerd()
67 g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
68 g_signal_handlers_disconnect_by_data(systemSettings, unityScreen);
68 g_object_unref(systemSettings);
69 g_object_unref(systemSettings);
69}
70}
71+
72+Powerd::Status Powerd::status() const
73+{
74+ return cachedStatus;
75+}
76+
77+void Powerd::handleDisplayPowerStateChange(int status, int reason)
78+{
79+ if (cachedStatus != (Status)status) {
80+ cachedStatus = (Status)status;
81+ Q_EMIT statusChanged((DisplayStateChangeReason)reason);
82+ }
83+}
plugins/Powerd/Powerd.h+8−1
@@ -29,6 +29,7 @@ class Powerd: public QObject
29 Q_OBJECT
29 Q_OBJECT
30 Q_ENUMS(Status)
30 Q_ENUMS(Status)
31 Q_ENUMS(DisplayStateChangeReason)
31 Q_ENUMS(DisplayStateChangeReason)
32+ Q_PROPERTY(Status status READ status NOTIFY statusChanged)
32
33
33public:
34public:
34 enum DisplayStateChangeReason {
35 enum DisplayStateChangeReason {
@@ -46,12 +47,18 @@ public:
46 explicit Powerd(QObject *parent = 0);
47 explicit Powerd(QObject *parent = 0);
47 ~Powerd();
48 ~Powerd();
48
49
50+ Status status() const;
51+
49Q_SIGNALS:
52Q_SIGNALS:
50− void displayPowerStateChange(int status, int reason);
53+ void statusChanged(DisplayStateChangeReason reason);
54+
55+private Q_SLOTS:
56+ void handleDisplayPowerStateChange(int status, int reason);
51
57
52private:
58private:
53 QDBusInterface *unityScreen;
59 QDBusInterface *unityScreen;
54 GSettings *systemSettings;
60 GSettings *systemSettings;
61+ Status cachedStatus;
55};
62};
56
63
57#endif
64#endif
plugins/Powerd/Powerd.qmltypes+3−3
@@ -30,10 +30,10 @@ Module {
30 "On": 1
30 "On": 1
31 }
31 }
32 }
32 }
33+ Property { name: "status"; type: "Status"; isReadonly: true }
33 Signal {
34 Signal {
34− name: "displayPowerStateChange"
35+ name: "statusChanged"
35− Parameter { name: "status"; type: "int" }
36− Parameter { name: "reason"; type: "int" }
36+ Parameter { name: "reason"; type: "DisplayStateChangeReason" }
37 }
37 }
38 }
38 }
39}
39}
qml/Panel/Indicators/IndicatorsLight.qml+4−7
@@ -27,12 +27,9 @@ QtObject {
27 Component.onDestruction: Lights.state = Lights.Off
27 Component.onDestruction: Lights.state = Lights.Off
28
28
29 // QtObject does not have children
29 // QtObject does not have children
30− property var _connections: Connections {
30+ property var _binding: Binding {
31− id: powerConnection
32−
33− target: Powerd
31+ target: Lights
34− onDisplayPowerStateChange: {
32+ property: "state"
35− Lights.state = (status === Powerd.Off) ? Lights.On : Lights.Off
33+ value: (Powerd.status === Powerd.Off) ? Lights.On : Lights.Off
36− }
37 }
34 }
38}
35}
qml/Shell.qml+5−12
@@ -22,6 +22,7 @@ import Ubuntu.Components 0.1
22import Ubuntu.Components.Popups 1.0
22import Ubuntu.Components.Popups 1.0
23import Ubuntu.Gestures 0.1
23import Ubuntu.Gestures 0.1
24import Ubuntu.SystemImage 0.1
24import Ubuntu.SystemImage 0.1
25+import Ubuntu.Telephony 0.1 as Telephony
25import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
26import Unity.Launcher 0.1
27import Unity.Launcher 0.1
27import Utils 0.1
28import Utils 0.1
@@ -457,18 +458,9 @@ Item {
457 id: powerConnection
458 id: powerConnection
458 target: Powerd
459 target: Powerd
459
460
460− onDisplayPowerStateChange: {
461+ onStatusChanged: {
461− // We ignore any display-off signals when the proximity sensor
462− // is active. This usually indicates something like a phone call.
463− if (status == Powerd.Off && reason != Powerd.Proximity && !edgeDemo.running) {
462+ if (Powerd.status === Powerd.Off && !callManager.hasCalls && !edgeDemo.running) {
464− greeter.showNow();
463+ greeter.showNow()
465− }
466−
467− // No reason to chew demo CPU when user isn't watching
468− if (status == Powerd.Off) {
469− edgeDemo.paused = true;
470− } else if (status == Powerd.On) {
471− edgeDemo.paused = false;
472 }
464 }
473 }
465 }
474 }
466 }
@@ -637,6 +629,7 @@ Item {
637 EdgeDemo {
629 EdgeDemo {
638 id: edgeDemo
630 id: edgeDemo
639 z: alphaDisclaimerLabel.z + 10
631 z: alphaDisclaimerLabel.z + 10
632+ paused: Powerd.status === Powerd.Off // Saves power
640 greeter: greeter
633 greeter: greeter
641 launcher: launcher
634 launcher: launcher
642 indicators: panel.indicators
635 indicators: panel.indicators
tests/mocks/Powerd/Powerd.cpp+15−1
@@ -19,6 +19,20 @@
19#include "Powerd.h"
19#include "Powerd.h"
20
20
21Powerd::Powerd(QObject* parent)
21Powerd::Powerd(QObject* parent)
22− : QObject(parent)
22+ : QObject(parent),
23+ m_status(Powerd::Status::On)
23{
24{
24}
25}
26+
27+void Powerd::setStatus(Powerd::Status status)
28+{
29+ if (m_status != status) {
30+ m_status = status;
31+ Q_EMIT statusChanged(DisplayStateChangeReason::Unknown);
32+ }
33+}
34+
35+Powerd::Status Powerd::status() const
36+{
37+ return m_status;
38+}
tests/mocks/Powerd/Powerd.h+8−1
@@ -26,6 +26,7 @@ class Powerd: public QObject
26 Q_OBJECT
26 Q_OBJECT
27 Q_ENUMS(Status)
27 Q_ENUMS(Status)
28 Q_ENUMS(DisplayStateChangeReason)
28 Q_ENUMS(DisplayStateChangeReason)
29+ Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged) // write only exists for tests
29
30
30public:
31public:
31 enum DisplayStateChangeReason {
32 enum DisplayStateChangeReason {
@@ -42,8 +43,14 @@ public:
42
43
43 explicit Powerd(QObject *parent = 0);
44 explicit Powerd(QObject *parent = 0);
44
45
46+ Status status() const;
47+ void setStatus(Status status);
48+
45Q_SIGNALS:
49Q_SIGNALS:
46− void displayPowerStateChange(int status, int reason);
50+ void statusChanged(DisplayStateChangeReason reason);
51+
52+private:
53+ Status m_status;
47};
54};
48
55
49#endif
56#endif
tests/mocks/Powerd/Powerd.qmltypes+3−3
@@ -30,10 +30,10 @@ Module {
30 "On": 1
30 "On": 1
31 }
31 }
32 }
32 }
33+ Property { name: "status"; type: "Status" }
33 Signal {
34 Signal {
34− name: "displayPowerStateChange"
35+ name: "statusChanged"
35− Parameter { name: "status"; type: "int" }
36− Parameter { name: "reason"; type: "int" }
36+ Parameter { name: "reason"; type: "DisplayStateChangeReason" }
37 }
37 }
38 }
38 }
39}
39}
tests/qmltests/tst_Shell.qml+14−7
@@ -21,6 +21,7 @@ import QtQuick 2.0
21import QtTest 1.0
21import QtTest 1.0
22import GSettings 1.0
22import GSettings 1.0
23import LightDM 0.1 as LightDM
23import LightDM 0.1 as LightDM
24+import Ubuntu.Telephony 0.1 as Telephony
24import Unity.Application 0.1
25import Unity.Application 0.1
25import Unity.Connectivity 0.1
26import Unity.Connectivity 0.1
26import Unity.Test 0.1 as UT
27import Unity.Test 0.1 as UT
@@ -74,6 +75,11 @@ Item {
74 signalName: "unlockingAllModems"
75 signalName: "unlockingAllModems"
75 }
76 }
76
77
78+ Telephony.CallEntry {
79+ id: phoneCall
80+ phoneNumber: "+447812221111"
81+ }
82+
77 UT.UnityTestCase {
83 UT.UnityTestCase {
78 name: "Shell"
84 name: "Shell"
79 when: windowShown
85 when: windowShown
@@ -146,21 +152,22 @@ Item {
146 verify(mainApp);
152 verify(mainApp);
147 tryCompare(mainApp, "state", ApplicationInfoInterface.Running);
153 tryCompare(mainApp, "state", ApplicationInfoInterface.Running);
148
154
149− // Try to suspend while proximity is engaged...
155+ // Suspend while call is active...
156+ callManager.foregroundCall = phoneCall;
150− Powerd.displayPowerStateChange(Powerd.Off, Powerd.Proximity);
157+ Powerd.status = Powerd.Off;
151 tryCompare(greeter, "showProgress", 0);
158 tryCompare(greeter, "showProgress", 0);
152
159
153− // Now really suspend
160+ // Now try again after ending call
154− print("suspending")
161+ callManager.foregroundCall = null;
162+ Powerd.status = Powerd.On;
155− Powerd.displayPowerStateChange(Powerd.Off, 0);
163+ Powerd.status = Powerd.Off;
156− print("done suspending")
157 tryCompare(greeter, "showProgress", 1);
164 tryCompare(greeter, "showProgress", 1);
158
165
159 tryCompare(ApplicationManager, "suspended", true);
166 tryCompare(ApplicationManager, "suspended", true);
160 compare(mainApp.state, ApplicationInfoInterface.Suspended);
167 compare(mainApp.state, ApplicationInfoInterface.Suspended);
161
168
162 // And wake up
169 // And wake up
163− Powerd.displayPowerStateChange(Powerd.On, 0);
170+ Powerd.status = Powerd.On;
164 tryCompare(greeter, "showProgress", 1);
171 tryCompare(greeter, "showProgress", 1);
165
172
166 // Swipe away greeter to focus app
173 // Swipe away greeter to focus app