File indexing completed on 2024-04-28 16:45:11
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 // own 0007 #include "../ksldapp.h" 0008 // KDE Frameworks 0009 #include <KIdleTime> 0010 // Qt 0011 #include <QProcess> 0012 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0013 #include <private/qtx11extras_p.h> 0014 #else 0015 #include <QX11Info> 0016 #endif 0017 #include <QtTest> 0018 // xcb 0019 #include <xcb/xcb.h> 0020 #include <xcb/xtest.h> 0021 0022 class KSldTest : public QObject 0023 { 0024 Q_OBJECT 0025 private Q_SLOTS: 0026 void initTestCase(); 0027 void testEstablishGrab(); 0028 void testActivateOnTimeout(); 0029 void testGraceTimeUnlocking(); 0030 }; 0031 0032 void KSldTest::initTestCase() 0033 { 0034 QCoreApplication::setAttribute(Qt::AA_ForceRasterWidgets); 0035 // change to the build bin dir 0036 QDir::setCurrent(QCoreApplication::applicationDirPath()); 0037 } 0038 0039 void KSldTest::testEstablishGrab() 0040 { 0041 ScreenLocker::KSldApp ksld; 0042 ksld.initialize(); 0043 QVERIFY(ksld.establishGrab()); 0044 // grab is established, trying again should succeed as well 0045 QVERIFY(ksld.establishGrab()); 0046 0047 // let's ungrab 0048 ksld.doUnlock(); 0049 0050 // to get the grab to fail we need another X client 0051 // we start another process to perform our grab 0052 QProcess keyboardGrabber; 0053 keyboardGrabber.start(QStringLiteral("./keyboardGrabber"), QStringList()); 0054 QVERIFY(keyboardGrabber.waitForStarted()); 0055 0056 // let's add some delay to be sure that keyboardGrabber has it's X stuff done 0057 QTest::qWait(100); 0058 0059 // now grabbing should fail 0060 QVERIFY(!ksld.establishGrab()); 0061 0062 // let's terminate again 0063 keyboardGrabber.terminate(); 0064 QVERIFY(keyboardGrabber.waitForFinished()); 0065 0066 // now grabbing should succeed again 0067 QVERIFY(ksld.establishGrab()); 0068 0069 ksld.doUnlock(); 0070 0071 // now the same with pointer 0072 QProcess pointerGrabber; 0073 pointerGrabber.start(QStringLiteral("./pointerGrabber"), QStringList()); 0074 QVERIFY(pointerGrabber.waitForStarted()); 0075 0076 // let's add some delay to be sure that pointerGrabber has it's X stuff done 0077 QTest::qWait(100); 0078 0079 // now grabbing should fail 0080 QVERIFY(!ksld.establishGrab()); 0081 0082 // let's terminate again 0083 pointerGrabber.terminate(); 0084 QVERIFY(pointerGrabber.waitForFinished()); 0085 0086 // now grabbing should succeed again 0087 QVERIFY(ksld.establishGrab()); 0088 } 0089 0090 void KSldTest::testActivateOnTimeout() 0091 { 0092 // this time verifies that the screen gets locked on idle timeout, requires the system to be idle 0093 ScreenLocker::KSldApp ksld; 0094 ksld.initialize(); 0095 0096 // we need to modify the idle timeout of KSLD, it's in minutes we cannot wait that long 0097 if (ksld.idleId() != 0) { 0098 // remove old Idle id 0099 KIdleTime::instance()->removeIdleTimeout(ksld.idleId()); 0100 } 0101 ksld.setIdleId(KIdleTime::instance()->addIdleTimeout(5000)); 0102 0103 QSignalSpy lockStateChangedSpy(&ksld, &ScreenLocker::KSldApp::lockStateChanged); 0104 QVERIFY(lockStateChangedSpy.isValid()); 0105 0106 // let's wait the double of the idle timeout 0107 QVERIFY(lockStateChangedSpy.wait(10000)); 0108 QCOMPARE(ksld.lockState(), ScreenLocker::KSldApp::AcquiringLock); 0109 0110 // let's simulate unlock to get rid of started greeter process 0111 const auto children = ksld.children(); 0112 for (auto it = children.begin(); it != children.end(); ++it) { 0113 if (qstrcmp((*it)->metaObject()->className(), "LogindIntegration") != 0) { 0114 continue; 0115 } 0116 QMetaObject::invokeMethod(*it, "requestUnlock"); 0117 break; 0118 } 0119 QVERIFY(lockStateChangedSpy.wait()); 0120 0121 KIdleTime::instance()->removeIdleTimeout(ksld.idleId()); 0122 } 0123 0124 void KSldTest::testGraceTimeUnlocking() 0125 { 0126 // this time verifies that the screen gets unlocked during grace time by simulated user activity 0127 ScreenLocker::KSldApp ksld(this); 0128 ksld.initialize(); 0129 0130 // we need to modify the idle timeout of KSLD, it's in minutes we cannot wait that long 0131 if (ksld.idleId() != 0) { 0132 // remove old Idle id 0133 KIdleTime::instance()->removeIdleTimeout(ksld.idleId()); 0134 } 0135 ksld.setIdleId(KIdleTime::instance()->addIdleTimeout(5000)); 0136 // infinite 0137 ksld.setGraceTime(-1); 0138 0139 QSignalSpy lockedSpy(&ksld, &ScreenLocker::KSldApp::locked); 0140 QVERIFY(lockedSpy.isValid()); 0141 QSignalSpy unlockedSpy(&ksld, &ScreenLocker::KSldApp::unlocked); 0142 QVERIFY(unlockedSpy.isValid()); 0143 0144 // let's wait quite some time to give the greeter a chance to come up 0145 QVERIFY(lockedSpy.wait(30000)); 0146 QCOMPARE(ksld.lockState(), ScreenLocker::KSldApp::Locked); 0147 0148 // let's simulate unlock by faking input 0149 const QPoint cursorPos = QCursor::pos(); 0150 xcb_test_fake_input(QX11Info::connection(), XCB_MOTION_NOTIFY, 0, XCB_TIME_CURRENT_TIME, XCB_WINDOW_NONE, cursorPos.x() + 1, cursorPos.y() + 1, 0); 0151 xcb_flush(QX11Info::connection()); 0152 QVERIFY(unlockedSpy.wait()); 0153 0154 // now let's test again without grace time 0155 ksld.setGraceTime(0); 0156 QVERIFY(lockedSpy.wait(30000)); 0157 QCOMPARE(ksld.lockState(), ScreenLocker::KSldApp::Locked); 0158 0159 xcb_test_fake_input(QX11Info::connection(), XCB_MOTION_NOTIFY, 0, XCB_TIME_CURRENT_TIME, XCB_WINDOW_NONE, cursorPos.x(), cursorPos.y(), 0); 0160 xcb_flush(QX11Info::connection()); 0161 QVERIFY(!unlockedSpy.wait()); 0162 0163 // and unlock 0164 const auto children = ksld.children(); 0165 for (auto it = children.begin(); it != children.end(); ++it) { 0166 if (qstrcmp((*it)->metaObject()->className(), "LogindIntegration") != 0) { 0167 continue; 0168 } 0169 QMetaObject::invokeMethod(*it, "requestUnlock"); 0170 break; 0171 } 0172 QVERIFY(unlockedSpy.wait()); 0173 } 0174 0175 QTEST_MAIN(KSldTest) 0176 #include "ksldtest.moc"