5

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)
Floern
  • 33,559
  • 24
  • 104
  • 119
tinsukE
  • 930
  • 9
  • 20
  • Did you try to add programmatically permissions for android M ? – Saveen Mar 16 '16 at 09:18
  • Not yet. As per spec it should not be needed and adding the permission check would break the UX of checking if the feature is available at all before asking if the user would want to use it. – tinsukE Mar 16 '16 at 09:36
  • If you use android M, So its mandatory to add permissions at run time. – Saveen Mar 16 '16 at 09:45

4 Answers4

1

Looks like a bug in the build process. A clean/rebuild makes the problem disappear

0

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.

tinsukE
  • 930
  • 9
  • 20
  • 1
    I started to see this issue too; so I created a bug for the Android team: https://code.google.com/p/android/issues/detail?id=223341&thanks=223341&ts=1474484201 and I'm referencing this issue. Thank you. – moxi Sep 21 '16 at 19:53
0

I Fixed the Following issue by removing a build library from dependencies and added "lib" dir from Lollipins' github sources https://github.com/omadahealth/LolliPin/tree/master/lib

  1. Remove "implementation('com.github.omadahealth:lollipin:2..." from build.gradle
  2. Add "implementation project(':lib')" to build.gradle
  3. Add "include ':lib'" to your settings.gradle

On your IDE(I am using android Studio) navigate to AppLockActivity.java line 147: Change to:

if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected() && mFingerprintUiHelper.isFingerprintAuthAvailable())
Mfuon Leonard
  • 192
  • 4
  • 19
0

FingerprintManager.isHardwareDetected() throwing java.lang.SecurityException because some devices don't have fingerprint hardware or they disable fingerprint. You can follow the below conduction to avoid crash.

if(getSystemService(Context.FINGERPRINT_SERVICE) == null) {
    notifyUser("Fingerprint hs not been enabled in settings.")
}
else {
    Here you can place your fingerprint manager code
}
Johan Paul
  • 2,203
  • 2
  • 22
  • 38