One Plus devices biometric prompt is dismissed after first failed - biometrics

I am using BiometricPrompt on my app. When I am trying to use on OnePlus devices and validate the fingerprint with another finger that is not enrolled on the OS, it will trigger the onAuthenticationFailed() callback and the biometricPrompt will be dismissed. This happen at first try. Is it possible to let the user to failed multiple times (on documentation we have 5 times in 30 secs and after the 5'th attempt should trigger onAuthenticationError(int errorCode, #NonNull CharSequence errString) with 7 as error code) without dismissing the dialog?

Related

When is sessionReachabilityDidChange(_:) called on a watch WCSessionDelegate?

Apple's documentation says this in the discussion section of the method description:
This method is called to let the
current process know that its counterpart session’s reachability
changed.
The description of the isReachable property says this: WatchKit
extension. The iOS device is within range, so communication can occur
and the WatchKit extension is running in the foreground, or is running
with a high priority in the background (for example, during a workout
session or when a complication is loading its initial timeline data).
I am assuming this would mean that if the watch moves out of or into range of the iOS device, the WatchKit extension would be launched and the WCSessionDelegate's sessionReachabilityDidChange() method would be called, and the WCSession's isReachable would be true if the iOS device just came into range and false if it just when out of range.
I have not found a way to verify this in xcode. For example I put a log message in sessionReachabilityDidChange(_:) and walked out of range, but xcode simply says the app lost connection with the iphone and can no longer debug it. Can someone verify this or point me to some documentation that better describes this?
I think you cannot verify this in Xcode.
I have an app on iOS and watchOS. To check this kind of situation, I can enable debug alerts on iOS and watchOS. When func sessionReachabilityDidChange(session: WCSession) is triggered, I display a debug alert.
Now, if I run (not under Xcode) my watch extension, and then switch off the paired iPhone, the debug alert is shown on the watch.
This shows that sessionReachabilityDidChange is actually called as expected.
Apparently, under Xcode a connected iOS device is always reachable.
EDIT:
To check the situation when the watch extension is not in foreground, I did the following:
Instead of showing a debug alert, I set now the complication to a unique value that is not possible otherwise. I launched the watch extension and put it into background by showing the watch face with the complication.
When I now switch off the iPhone, the complication is not updated.
This indicates to me that sessionReachabilityDidChange is not called in background.

How to check if the biometric scanner is available and initialized in Xamarin android BiometricPrompt

Failed biometric(fingerprint) scan attempts are handled by OnAuthenticationFailed() callback of BiometricPrompt.AuthenticationCallback class.
The behavior I noticed is, it lets the user attempt 5 invalid fingerprint scans (each time the fail callback is invoked) and then the prompt dismisses. Within the next 30 secs, if we try to re-build a BiometricPrompt instance and try to authenticate, it does not show the prompt which I think is the default behavior of BiometricPrompt.
Is there anyway to check if the biometric scanner is available and initialised if the user attempts to re-invoke biometric prompt within the said 30secs?
How can I handle that use case?
xamarin android BiometricPrompt.AuthenticationCallback does not have an override method "onAuthenticationError" to handle error callbacks and thus I'm unable to handle error code "BIOMETRIC_ERROR_TIMEOUT".
If someone has a solution for this, please do let me know your resolution.
I believe that BiometricPrompt is not fully ported to Xamarin yet...
I'm still looking for a source that can double check this info for me, but I haven't found it either.

Android BLE - BT stack alarm errors

I'm trying to get basic Bluetooth LE connections working in my app, but I'm running into problems. I have a couple of sensors that I can connect to just fine with the iOS version of this app, but I simply cannot connect to them with the Android version. The only thing I seem to be able to connect to is a beacon I've set to configuration mode.
After checking my ADB logs again, I noticed that whenever it fails to connect to a device, there's always four calls to bt_osi_alarm and bta_gattc_conn_cback. I'm wondering how to interpret this.
An unsuccessful connection attempt:
D/BluetoothGatt(17824): connect() - device: 00:17:E9:C0:86:14, auto: false
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
E/bt_osi_alarm(14357): reschedule_root_alarm alarm expiration too close for posix timers, switching to guns
...
W/bt_btif (14357): bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0002
W/bt_btif (14357): bta_gattc_conn_cback() - cif=6 connected=0 conn_id=6 reason=0x0002
D/BtGatt.GattService(14357): onConnected() - clientIf=6, connId=0, address=00:17:E9:C0:86:14
D/BluetoothGatt(17824): onClientConnectionState() - status=133 clientIf=6 device=00:17:E9:C0:86:14
I/mono-stdout(17824): BLEAdapter.OnConnectionStateChange()
I/mono-stdout(17824): Gatt disconnected!
A successful connection attempt to one of those beacons does not have these sets of four bt_osi_alarm and bta_gattc_conn_cback errors. Preferably if someone knows the Android source well, hopefully they can tell me what's going on. It's a long shot I know, but I'm kinda out of options. Thanks.
Some additional information might help the community debug this issue for you. Please add the following to your original question:
Make/Model/Revision of all BLE devices that you've tested and whether or not each one works
Specific android device you have tested with
The error your app gets and at what step it fails
Are you able to get a BluetoothDevice
Does it fail when calling connectGatt()
Is your app written in java/android studio, or is this some kind of universal app that runs on both iOS and Android?
In my experience, alarm expiration too close for posix timers, switching to guns, isn't as serious as its error level suggests. On my nexus 7/marshmallow device, I see this message constantly while connected to a bluetooth device (serial profile, not BLE) so I don't think this is a bug.
I suggest checking up on the BLE device manufacturer to see if there are any firmware upgrades for them too.
More details on alarm expiration too close for posix timers, switching to guns
What's happening is some part of the android bt code is setting a very short timer. So short, that it expires before the app can measure it.
The error, alarm expiration too close for posix timers, switching to guns, was added to android source in a commit 081e4b67b44a5fd397c2d79a5566e11ae52d4aca
The commit message gives us more background on what is happening.
Ensure alarms are called back when they expire in the past
Turns out the posix timers we're dealing with aren't well behaved.
If the timer is TIMER_ABSTIME the following is supposed to be true:
"If the specified time has already passed, the function shall succeed
and the expiration notification shall be made."
But alas, this is not the case. If the expiration time happens to be
in the past (e.g. very short timer which gets hit with a context
switch before the timer can be set) the timer decides to disarm
itself. This means no more callbacks happen, and no more alarms are
processed ever.
sadness.
But thankfully, we can use timer_gettime to check the state of the
timer after timer_settime. If timer_gettime tells us the timer is
disarmed right after we armed it, we want to perform the alarm
callback ourselves.
Put all timer callbacks on the same thread (as would be the case in
the underlying timer implementation already) and used a sempahore to
signal when an alarm expires in the normal posix timer callback and
also in the timer didn't set case.
The code also includes the following comments
If next expiration was in the past (e.g. short timer that got context
switched) then the timer might have diarmed itself. Detect this case
and work around it by manually signalling the |alarm_expired|
semaphore.
It is possible that the timer was actually super short (a few
milliseconds) and the timer expired normally before we called
|timer_gettime|. Worst case, |alarm_expired| is signaled twice for
that alarm. Nothing bad should happen in that case though since the
callback dispatch function checks to make sure the timer at the head
of the list actually expired.

HKWorkoutSession isn't keeping app at front of Apple Watch

It has been stated that an app running a HKWorkoutSession will have special privileges over other watchOS 2 apps, so when a user looks at their Apple Watch, it will go to the view showing running a workout rather than the watch face.
Currently, on both my device and simulator, this is not the case. If I start a HKWorkoutSession and then leave for 5 minutes and then interact with either the Apple Watch, or the Watch Simulator, it presents the watch face.
If I then open my app, it appears to have been frozen, rather than terminated (which is what I imagine happens to other apps). As the UI will update when I need receive a response in my query.updateHandler. Also if I set it to provide haptic feedback every time my query.updateHandler receives a new HKQuantitySample it will do so, so the app must be running in the background in some form.
Has anyone else noticed this behaviour, and am I doing anything wrong, or expecting something I shouldn't?
Here is how I start my HKWorkoutSession:
self.workoutSession = HKWorkoutSession(activityType: HKWorkoutActivityType.Other, locationType: HKWorkoutSessionLocationType.Indoor)
self.healthStore.startWorkoutSession(self.workoutSession) {
success, error in
if error != nil {
print("startWorkoutSession \(error)\n")
self.printLabel.setText("startWorkoutSession \(error)")
self.printLabel.setTextColor(UIColor.redColor())
}
We're seeing that too, for the moment we've made sure 'opens last activity' is configured.
When the UI is active we start a dispatch_timer to request and process data in 1 second intervals.
Make sure you do any significant processing using the NSUserProcessInfo method though and pause the dispatch_timers whenever you are no longer active. You'll get crashes otherwise.

RemotePlaybackClient resume session on Chromecast

I am trying to use the RemotePlaybackClient to resume a Chromecast session created by the same Android app. I'm able to use this RPC vs the full Cast SDK to play, pause, resume, seek, and stop playback on the Chromecast device. My current test is in closing the Android app and using the sessionId from the session to try to reload the app and resume control of the playback. Upon closing the Android app, we are not terminating playback or the session, it keeps going.
Here is the code I'm using:
// attempt resume
mRemotePlaybackClient = new RemotePlaybackClient(getApplicationContext(), ccRoute);
// ccRoute is the selected ChromeCast RouteInfo device - same as previous
System.out.println(mRemotePlaybackClient.isSessionManagementSupported()); // true
System.out.println(mRemotePlaybackClient.hasSession()); // false
mRemotePlaybackClient.setSessionId(saved_sessionId); // saved_sessionId is the sessionId saved from the mRemotePlaybackClient.play command in success reply.
System.out.println(mRemotePlaybackClient.hasSession()); // true
mRemotePlaybackClient.startSession(null, ccStart); // callback returns error 0
mRemotePlaybackClient.setStatusCallback(ccSessionStatus); // callback returns error 0
I've asked some others familiar with the RemotePlaybackClient and the Chromecast, including those within Google but did not get an answer. Also, I seem to be seeing some of the same issues #Commonsware is seeing in that some callbacks don't reply at all. In addition, with images, metadata is not returned and the status callback returns an error whereas video returns ok (position info etc).
Really, I'd just like to resume the session for now vs having to wire up the full Cast SDK.

Resources