What changed, and why it matters
This commit fixes a crash in the Electrum Android app when it starts on older Android devices. The app was trying to load modern fingerprint/face-unlock Java classes that don't exist on old Android versions, causing an uncaught exception and preventing the app from opening. The fix catches that loading error and gracefully disables biometric features instead of crashing.
No immediate security action required; this is a robustness fix. Users on affected old Android devices should update to a release containing this commit. Consider adding a minimum Android API level check or feature flag to avoid similar import-time failures.
Security signals we found
Denial-of-service (app crash on startup) on older Android devices due to uncaught Java class-loading exception
Graceful degradation pattern: catch import-time platform-availability failure and disable feature
Evidence from the diff
In electrum/gui/qml/qebiometrics.py, autoclass() calls for Android biometric Java classes are now wrapped in a try/except catching jnius.JavaException. If loading fails (e.g., NoClassDefFoundError for android/hardware/biometrics/BiometricPrompt$AuthenticationResult on old API levels), the biometric helper variables remain None and isAvailable returns False. This prevents an unhandled exception during QML GUI module import at daemon startup.
Changed components
electrum/gui/qml/qebiometrics.pyAndroid QML GUI biometric authentication initializationInspect captured patch +10 / −7
diff --git a/electrum/gui/qml/qebiometrics.py b/electrum/gui/qml/qebiometrics.py
index 3d806a6..b2d896b 100644
--- a/electrum/gui/qml/qebiometrics.py
+++ b/electrum/gui/qml/qebiometrics.py
@@ -26,13 +26,16 @@ jIntent = None
jString = None
if 'ANDROID_DATA' in os.environ:
- from jnius import autoclass
+ from jnius import autoclass, JavaException
from android import activity
- jPythonActivity = autoclass('org.kivy.android.PythonActivity').mActivity
- jBiometricHelper = autoclass('org.electrum.biometry.BiometricHelper')
- jBiometricActivity = autoclass('org.electrum.biometry.BiometricActivity')
- jIntent = autoclass('android.content.Intent')
- jString = autoclass('java.lang.String')
+ try:
+ jPythonActivity = autoclass('org.kivy.android.PythonActivity').mActivity
+ jIntent = autoclass('android.content.Intent')
+ jString = autoclass('java.lang.String')
+ jBiometricActivity = autoclass('org.electrum.biometry.BiometricActivity')
+ jBiometricHelper = autoclass('org.electrum.biometry.BiometricHelper')
+ except JavaException as e:
+ _logger.error(f"Could not load Biometric java classes (maybe due to old api version): {e}")
class BiometricAction(str, Enum):
@@ -56,7 +59,7 @@ class QEBiometrics(AuthMixin, QObject):
@pyqtProperty(bool, constant=True)
def isAvailable(self) -> bool:
- if 'ANDROID_DATA' not in os.environ:
+ if 'ANDROID_DATA' not in os.environ or jBiometricHelper is None:
return False
try:
return jBiometricHelper.isAvailable(jPythonActivity)
Why this scored 23/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.