Search code examples
androidandroid-6.0-marshmallowandroid-permissionsandroid-fingerprint-api

FingerprintManager.isHardwareDetected() throwing java.lang.SecurityException?


I have an App that offers the usage of fingerprints for authentication.

Before asking if the user wants to enable it, I verify if it is available at all and it is done via:

FingerprintManager fingerprintManager = context.getSystemService(FingerprintManager.class);
return fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints();

Both FingerprintManager's methods are annotated with:

@RequiresPermission(USE_FINGERPRINT)

But, the USE_FINGERPRINT permission is a normal one, as specified in http://developer.android.com/guide/topics/security/normal-permissions.html. Which means that, once you declare that permission in the AndroidManifest.xml file (which we do, the feature is tested and working on test devices) you don't have to check for it at runtime.

What is happening now, as reported by Fabric crash reports, is that some users are crashing on the fingerprintManager.isHardwareDetected() call with:

java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10150 nor current process has android.permission.USE_FINGERPRINT.

It has happened so far with 2 users, both on Marshmallow (Android 6.0), neither of them rooted (as reported by Fabric) and the devices are the LG G4 Stylus(LG H635) and Sony Xperia Z5 Premium (Sony E6853).

Any explanations on how would this be possible and a possible fix for it?

If these users wouldn't be on vanilla Android, I'd say that they are being able to manipulate the App permission via a custom ROM feature like CyanogenMod's Privacy Guard. But that doesn't seem to be the case.

The stack trace is:

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{MY.PACKAGE/MY.PACKAGE.MYACTIVITY}: java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10150 nor current process has android.permission.USE_FINGERPRINT.
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2434)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
   at android.app.ActivityThread.access$900(ActivityThread.java:157)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:5527)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by java.lang.SecurityException: Must have android.permission.USE_FINGERPRINT permission.: Neither user 10150 nor current process has android.permission.USE_FINGERPRINT.
   at android.os.Parcel.readException(Parcel.java:1599)
   at android.os.Parcel.readException(Parcel.java:1552)
   at android.hardware.fingerprint.IFingerprintService$Stub$Proxy.isHardwareDetected(IFingerprintService.java:367)
   at android.hardware.fingerprint.FingerprintManager.isHardwareDetected(FingerprintManager.java:642)
   at MY.PACKAGE.MYACTIVITY.isSupported(MYACTIVITY.java:54)
   at MY.PACKAGE.MYACTIVITY.onCreate(MYACTIVITY.java:38)
   at android.app.Activity.performCreate(Activity.java:6272)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2387)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)
   at android.app.ActivityThread.access$900(ActivityThread.java:157)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:5527)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)

Solution

  • The issue "automagically" stopped happening.

    So far, I can only see those two affected users each one on a different version of our App (we publish every 2 weeks) and there was no change whatsoever in the App in regards to fingerprint permissions.

    The last occurrence of the crash was on March 17th.

    I see this as a Android/Play Store permissions glitch.