auth: make fingerprint initialization async (#544)

This commit is contained in:
moggiesir 2024-11-05 05:12:26 -08:00 committed by GitHub
parent f225e23e5b
commit 1cd3231537
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 75 additions and 73 deletions

View file

@ -48,15 +48,33 @@ CFingerprint::CFingerprint() {
std::shared_ptr<sdbus::IConnection> CFingerprint::start() {
if (!m_bEnabled)
return {};
m_sDBUSState.connection = sdbus::createSystemBusConnection();
registerSleepHandler();
// When entering sleep, the wake signal will trigger startVerify().
if (m_sDBUSState.sleeping)
return m_sDBUSState.connection;
startVerify();
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
m_sDBUSState.login->getPropertyAsync("PreparingForSleep").onInterface(LOGIN_MANAGER).uponReplyInvoke([this](std::optional<sdbus::Error> e, sdbus::Variant preparingForSleep) {
if (e) {
Debug::log(WARN, "fprint: Failed getting value for PreparingForSleep: {}", e->what());
return;
}
m_sDBUSState.sleeping = preparingForSleep.get<bool>();
// When entering sleep, the wake signal will trigger startVerify().
if (m_sDBUSState.sleeping)
return;
inhibitSleep();
startVerify();
});
m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) {
Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start);
if (start) {
m_sDBUSState.sleeping = true;
stopVerify();
m_sDBUSState.inhibitLock.reset();
} else {
m_sDBUSState.sleeping = false;
inhibitSleep();
startVerify();
}
});
return m_sDBUSState.connection;
}
@ -73,30 +91,16 @@ void CFingerprint::terminate() {
releaseDevice();
}
void CFingerprint::registerSleepHandler() {
m_sDBUSState.login = sdbus::createProxy(*m_sDBUSState.connection, sdbus::ServiceName{"org.freedesktop.login1"}, sdbus::ObjectPath{"/org/freedesktop/login1"});
m_sDBUSState.sleeping = m_sDBUSState.login->getProperty("PreparingForSleep").onInterface(LOGIN_MANAGER).get<bool>();
m_sDBUSState.login->uponSignal("PrepareForSleep").onInterface(LOGIN_MANAGER).call([this](bool start) {
Debug::log(LOG, "fprint: PrepareForSleep (start: {})", start);
if (start) {
m_sDBUSState.sleeping = true;
stopVerify();
m_sDBUSState.inhibitLock.reset();
} else {
m_sDBUSState.sleeping = false;
inhibitSleep();
startVerify();
}
});
if (!m_sDBUSState.sleeping)
inhibitSleep();
}
void CFingerprint::inhibitSleep() {
m_sDBUSState.login->callMethod("Inhibit")
m_sDBUSState.login->callMethodAsync("Inhibit")
.onInterface(LOGIN_MANAGER)
.withArguments("sleep", "hyprlock", "Fingerprint verifcation must be stopped before sleep", "delay")
.storeResultsTo(m_sDBUSState.inhibitLock);
.uponReplyInvoke([this](std::optional<sdbus::Error> e, sdbus::UnixFd fd) {
if (e)
Debug::log(WARN, "fprint: could not inhibit sleep: {}", e->what());
else
m_sDBUSState.inhibitLock = fd;
});
}
bool CFingerprint::createDeviceProxy() {
@ -145,12 +149,9 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
stopVerify();
if (m_sDBUSState.retries >= 3) {
m_sDBUSState.message = "Fingerprint auth disabled: too many failed attempts";
} else if (startVerify(/* showMessage= */ false)) {
done = false;
m_sDBUSState.retries++;
m_sDBUSState.message = RETRY_MESSAGE;
} else {
m_sDBUSState.message = "Fingerprint auth disabled: could not restart verification";
done = false;
startVerify(true);
}
break;
case MATCH_UNKNOWN_ERROR:
@ -173,44 +174,46 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
break;
}
g_pHyprlock->enqueueForceUpdateTimers();
if (done || m_sDBUSState.abort) {
if (done || m_sDBUSState.abort)
m_sDBUSState.done = true;
m_sDBUSState.connection->leaveEventLoop();
}
}
bool CFingerprint::claimDevice() {
try {
const auto currentUser = ""; // Empty string means use the caller's id.
m_sDBUSState.device->callMethod("Claim").onInterface(DEVICE).withArguments(currentUser);
} catch (sdbus::Error& e) {
Debug::log(WARN, "fprint: could not claim device, {}", e.what());
return false;
}
Debug::log(LOG, "fprint: claimed device");
return true;
void CFingerprint::claimDevice() {
const auto currentUser = ""; // Empty string means use the caller's id.
m_sDBUSState.device->callMethodAsync("Claim").onInterface(DEVICE).withArguments(currentUser).uponReplyInvoke([this](std::optional<sdbus::Error> e) {
if (e)
Debug::log(WARN, "fprint: could not claim device, {}", e->what());
else {
Debug::log(LOG, "fprint: claimed device");
startVerify();
}
});
}
bool CFingerprint::startVerify(bool updateMessage) {
void CFingerprint::startVerify(bool isRetry) {
if (!m_sDBUSState.device) {
if (!createDeviceProxy())
return false;
return;
claimDevice();
return;
}
try {
auto finger = "any"; // Any finger.
m_sDBUSState.device->callMethod("VerifyStart").onInterface(DEVICE).withArguments(finger);
} catch (sdbus::Error& e) {
Debug::log(WARN, "fprint: could not start verifying, {}", e.what());
return false;
}
Debug::log(LOG, "fprint: started verifying");
if (updateMessage) {
m_sDBUSState.message = m_sFingerprintReady;
auto finger = "any"; // Any finger.
m_sDBUSState.device->callMethodAsync("VerifyStart").onInterface(DEVICE).withArguments(finger).uponReplyInvoke([this, isRetry](std::optional<sdbus::Error> e) {
if (e) {
Debug::log(WARN, "fprint: could not start verifying, {}", e->what());
if (isRetry)
m_sDBUSState.message = "Fingerprint auth disabled: could not restart verification";
} else {
Debug::log(LOG, "fprint: started verifying");
if (isRetry) {
m_sDBUSState.retries++;
m_sDBUSState.message = RETRY_MESSAGE;
} else
m_sDBUSState.message = m_sFingerprintReady;
}
g_pHyprlock->enqueueForceUpdateTimers();
}
return true;
});
}
bool CFingerprint::stopVerify() {

View file

@ -31,21 +31,20 @@ class CFingerprint {
bool sleeping = false;
} m_sDBUSState;
std::string m_sFingerprintReady;
std::string m_sFingerprintPresent;
bool m_bAuthenticated = false;
bool m_bEnabled = false;
std::string m_sFingerprintReady;
std::string m_sFingerprintPresent;
bool m_bAuthenticated = false;
bool m_bEnabled = false;
void handleVerifyStatus(const std::string& result, const bool done);
void handleVerifyStatus(const std::string& result, const bool done);
void registerSleepHandler();
void inhibitSleep();
void inhibitSleep();
bool createDeviceProxy();
bool claimDevice();
bool startVerify(bool updateMessage = true);
bool stopVerify();
bool releaseDevice();
bool createDeviceProxy();
void claimDevice();
void startVerify(bool isRetry = false);
bool stopVerify();
bool releaseDevice();
};
inline std::unique_ptr<CFingerprint> g_pFingerprint;