Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

three issues + one feature request #93

Closed
dermitza opened this issue Oct 25, 2024 · 13 comments
Closed

three issues + one feature request #93

dermitza opened this issue Oct 25, 2024 · 13 comments

Comments

@dermitza
Copy link

Hello,

thanks a lot for your efforts, its a quite nice app after a first look. Below are three issues (one important possibly) and a feature request.

Device: G8441, Android version 9, API 28

(Issue) App crashes when enabling require authentication

After enabling "require authentication", app crashes on open, clearing data is necessary (to clear the condition) in order to restore app to functional. ADB/logcat shows the following:

' --------- beginning of crash
2024-10-25 23:03:01.899 29781-29781/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.chiller3.rsaf, PID: 29781
java.lang.RuntimeException: Unable to resume activity {com.chiller3.rsaf/com.chiller3.rsaf.SettingsActivity}: java.lang.IllegalArgumentException: Authenticator combination is unsupported on API 28: BIOMETRIC_STRONG | DEVICE_CREDENTIAL
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3796)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6706)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Authenticator combination is unsupported on API 28: BIOMETRIC_STRONG | DEVICE_CREDENTIAL
at com.chiller3.rsaf.SettingsFragment.onResume(Unknown Source:489)
at androidx.fragment.app.FragmentStateManager.resume(Unknown Source:148)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(Unknown Source:58)
at androidx.fragment.app.FragmentManagerImpl.moveToState(Unknown Source:61)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(Unknown Source:35)
at androidx.appcompat.app.AppCompatActivity.onPostResume$androidx$fragment$app$FragmentActivity(Unknown Source:28)
at androidx.appcompat.app.AppCompatActivity.onPostResume(Unknown Source:0)
at android.app.Activity.performResume(Activity.java:7317)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3788)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828) 
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) 
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:280) 
at android.app.ActivityThread.main(ActivityThread.java:6706) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
2024-10-25 23:03:01.906 29781-29781/? E/MainApplication: Saving logcat to /storage/emulated/0/Android/data/com.chiller3.rsaf/files/crash.log due to uncaught exception in Thread[main,5,main]
java.lang.RuntimeException: Unable to resume activity {com.chiller3.rsaf/com.chiller3.rsaf.SettingsActivity}: java.lang.IllegalArgumentException: Authenticator combination is unsupported on API 28: BIOMETRIC_STRONG | DEVICE_CREDENTIAL
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3796)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:280)
at android.app.ActivityThread.main(ActivityThread.java:6706)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: Authenticator combination is unsupported on API 28: BIOMETRIC_STRONG | DEVICE_CREDENTIAL
at com.chiller3.rsaf.SettingsFragment.onResume(Unknown Source:489)
at androidx.fragment.app.FragmentStateManager.resume(Unknown Source:148)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(Unknown Source:58)
at androidx.fragment.app.FragmentManagerImpl.moveToState(Unknown Source:61)
at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(Unknown Source:35)
at androidx.appcompat.app.AppCompatActivity.onPostResume$androidx$fragment$app$FragmentActivity(Unknown Source:28)
at androidx.appcompat.app.AppCompatActivity.onPostResume(Unknown Source:0)
at android.app.Activity.performResume(Activity.java:7317)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3788)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828) 
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51) 
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1814) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:280) 
at android.app.ActivityThread.main(ActivityThread.java:6706) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) '

As i understand it is just an unsupported API call for this Android version, maybe a catch around the exception would mitigate this. Further, as I am not interested in the biometric aspect of authentication but rather the PIN functionality, maybe there is an easy conditional to split the options for older API versions?

(Issue) App cannot open any file on filesystem, other than files it has created

If i try to import a config file from the local filesystem, all (most) files including the config file are greyed out and non-selectable.

image

Workaround

If I then however (2) export a blank config file from the app (works, no errors), (2) edit the config file externally and adding information and (3) attempt to import it, that particular file is still selectable and I am able to import it. This looks to be some obscure FS permission issue (?) with no relevant logcat information (even when verbose mode is selected)

logcat info upon pressing "import configuration" are not relevant (at least upon first inspection):

--------- beginning of main 2024-10-25 23:22:23.173 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 4, app_layer_count: 3, gpu_target_index: 3, display type: 0 2024-10-25 23:22:23.176 30824-30824/? W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@f61f959 2024-10-25 23:22:23.173 927-927/? W/memtrack@1.0-se: type=1400 audit(0.0:468026): avc: denied { search } for name="proc" dev="debugfs" ino=11572 scontext=u:r:hal_memtrack_default:s0 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0 ppid=1 pcomm="init" pgid=1 pgcomm="init" 2024-10-25 23:22:23.184 1717-1782/? I/DisplayBooster: DisplayBoosterService: CABC is not supported in this model 2024-10-25 23:22:23.186 3611-3657/? I/android_os_HwBinder: HwBinder: Starting thread pool for default::vendor.somc.hardware.swiqi@1.0::IHidlSwiqi 2024-10-25 23:22:23.187 3611-3657/? I/android_os_HwBinder: HwBinder: Starting thread pool for default::vendor.somc.hardware.swiqi@1.0::IHidlSwiqi 2024-10-25 23:22:23.205 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 4, app_layer_count: 3, gpu_target_index: 3, display type: 0 2024-10-25 23:22:23.211 1717-1741/? I/InputDispatcher: Focus entered window: Window{9750988 u0 com.android.documentsui/com.android.documentsui.picker.PickActivity} 2024-10-25 23:22:23.222 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 4, app_layer_count: 3, gpu_target_index: 3, display type: 0 2024-10-25 23:22:23.253 3528-3528/? I/LatinIME: onFinishInput 2024-10-25 23:22:23.267 1717-1803/? I/ActivityManager: Displayed com.android.documentsui/.picker.PickActivity: +92ms 2024-10-25 23:22:23.289 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 5, app_layer_count: 4, gpu_target_index: 4, display type: 0 2024-10-25 23:22:23.524 924-924/? I/chatty: uid=1000(system) composer@2.1-se identical 14 lines 2024-10-25 23:22:23.541 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 5, app_layer_count: 4, gpu_target_index: 4, display type: 0 2024-10-25 23:22:23.550 1717-1803/? I/Timeline: Timeline: Activity_windows_visible id: ActivityRecord{e0830f u0 com.android.documentsui/.picker.PickActivity t2021} time:155119498 diff:375 start:lukewarm|cch-empty batt:76|2 mw:off|358 mem:1577056|0|56|2|22 cpu:[1,1,1,1,1,1,1,1],[1900,2457] 2024-10-25 23:22:23.558 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 4, app_layer_count: 3, gpu_target_index: 3, display type: 0 2024-10-25 23:22:23.580 1717-1782/? I/DisplayBooster: DisplayBoosterService: CABC is not supported in this model 2024-10-25 23:22:23.583 3611-3634/? I/android_os_HwBinder: HwBinder: Starting thread pool for default::vendor.somc.hardware.swiqi@1.0::IHidlSwiqi

logcat info upon pressing a greyed out file is a drawing update, also not relevant:

2024-10-25 23:14:40.054 924-924/? D/SDM: DisplayBase::BuildLayerStackStats: LayerStack layer_count: 4, app_layer_count: 3, gpu_target_index: 3, display type: 0

I also checked whether there are any fs permissions missing but I do not have any available selectable permissions at all for the app.

(Minor issue) App window overextends under bottom navigation bar

image
image

This is not as important, the app borders do not snap to within the active display area and overextend under the bottom navigation bar (maybe the minSize sets are too large - given i am using a small display).

(Feature request) Selectable theme

A dark (selectable) theme would be nice but not really of any importance.

Again thanks a lot for your efforts and a nice app :)

@chenxiaolong
Copy link
Owner

Thanks for the detailed report and glad you like the app!

(Issue) App crashes when enabling require authentication

Hmm, I wasn't aware of this. It looks like both BIOMETRIC_STRONG or DEVICE_CREDENTIAL are only supported since API 30. I'll have to check to see if this functionality can be supported in API 28. I don't have an Android 9 device for testing--do you know if other third party apps support biometric auth?

(Issue) App cannot open any file on filesystem, other than files it has created

What were the exact filenames of the files that could and could not be selected for importing? I think this might be caused by the file extension. There's a chance it might only be allowing you to select files where the extension is unrecognized by Android. This should be an easy fix once I know what's going on.

(Minor issue) App window overextends under bottom navigation bar

It is expected for the list to extend into the navigation bar, but there is supposed to be extra padding after scrolling to the very bottom. This one might be a bug in Android's compatibility libraries. "edge to edge" mode is now mandatory in Android 15, but the Google's compatibility layer is meant to make it work properly in previous versions of Android too. I'll see if I can find a workaround for this.

@chenxiaolong
Copy link
Owner

(Feature request) Selectable theme

The app should already follow the system dark/light theme mode. (Or are you asking for a new option to force it to be always light or always dark?)

chenxiaolong added a commit that referenced this issue Oct 25, 2024
… API >=30

Previous Android versions do not support it.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@dermitza
Copy link
Author

dermitza commented Oct 25, 2024

Thanks a lot for the (very!) prompt reply.

Thanks for the detailed report and glad you like the app!

(Issue) App crashes when enabling require authentication

Hmm, I wasn't aware of this. It looks like both BIOMETRIC_STRONG or DEVICE_CREDENTIAL are only supported since API 30. I'll have to check to see if this functionality can be supported in API 28. I don't have an Android 9 device for testing--do you know if other third party apps support biometric auth?

I quickly checked functionality with KeePassDX, it has seperated biometrics and device credentials (two seperate toggle bars), biometric enabling worked fine (did not test further with a fingerprint), device credential as well, prompting me to enter device pin/password/gesture (worked fine, showing pin/password/gesture menu).

The fix might be as easy as replacing (line 220 in PreferenceBaseActivity.kt)

   val promptInfo = BiometricPrompt.PromptInfo.Builder()
       .setAllowedAuthenticators(Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL)
       .setTitle(getString(R.string.biometric_title))
       .build()

with

   val promptInfo = createPromptInfo()
       if (BiometricManager.from(context)
           .canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS) {
           biometricPrompt.authenticate(promptInfo, cryptoObject)
       } else {
           // unsupported prompt perhaps
       }

as detailed here and here. It seems as though the above call is API agnostic (everything done under the hood) for down to API 23 (?). For instantiating a crypto object (maybe i missed it), possibly relevant post for that here.

(Issue) App cannot open any file on filesystem, other than files it has created

What were the exact filenames of the files that could and could not be selected for importing? I think this might be caused by the file extension. There's a chance it might only be allowing you to select files where the extension is unrecognized by Android. This should be an easy fix once I know what's going on.

Im not sure if it is file extension dependent. The pre-existing selectable files i saw had .zdjBDp and .ini extensions.

Duplicating (in total commander) any file created by the app is also openable, irrespective of extension (tried multiple extensions). Copying a .conf file into android (from a PC) is not openable. No discernible differences between files created by RSAF or externally according to total commander (both show uid 0, gid 9997, -rw-rw----).

image
image
image

(Minor issue) App window overextends under bottom navigation bar

It is expected for the list to extend into the navigation bar, but there is supposed to be extra padding after scrolling to the very bottom. This one might be a bug in Android's compatibility libraries. "edge to edge" mode is now mandatory in Android 15, but the Google's compatibility layer is meant to make it work properly in previous versions of Android too. I'll see if I can find a workaround for this.

No worries about this one, minor enough i think.

The app should already follow the system dark/light theme mode. (Or are you asking for a new option to force it to be always light or always dark?)

Yep, but as I mentioned, not really critical, thanks a lot again.

@chenxiaolong
Copy link
Owner

Thanks for the hint about KeePassDX. I'll check that out and see how they handle device credential auth. If it's too painful to implement, I'll just stick with biometric auth only for older Android versions.

Im not sure if it is file extension dependent. The pre-existing selectable files i saw had .zdjBDp and .ini extensions.

Duplicating (in total commander) any file created by the app is also openable, irrespective of extension (tried multiple extensions). Copying a .conf file into android (from a PC) is not openable. No discernible differences between files created by RSAF or externally according to total commander (both show uid 0, gid 9997, -rw-rw----).

Interesting. The way it's set up right now is that RSAF asks Android to allow picking any file with the text/plain or application/octet-stream MIME types. On later Android versions, this is based entirely on the file extension (txt/text/pot/brf/srt for text/plain and bin/deploy/msu/msp + all unrecognized extensions for application/octet-stream).

I think it probably makes the most sense to just remove the filter. It doesn't seem all that useful anyway.

@chenxiaolong
Copy link
Owner

Oh, one quick question about the file selection: when you selected the files, was it from the hamburger menu -> "Downloads" section of the file picker or from hamburger menu -> (Phone name) -> Downloads folder?

(The reason I ask is because they are not the same and the files go through two completely different components in Android that may not treat file types the same way.)

@dermitza
Copy link
Author

Oh, one quick question about the file selection: when you selected the files, was it from the hamburger menu -> "Downloads" section of the file picker or from hamburger menu -> (Phone name) -> Downloads folder?

(The reason I ask is because they are not the same and the files go through two completely different components in Android that may not treat file types the same way.)

Both choices exhibit the same behaviour it seems.

chenxiaolong added a commit that referenced this issue Oct 25, 2024
Although androidx.biometric can handle biometric auth on legacy Android
versions, we're intentionally not using it. The legacy device credential
API does both biometric and device credential auth and it is not
possible to disable just the biometric part, so just let the legacy API
handle everything.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@chenxiaolong
Copy link
Owner

I wonder if that behavior is Sony-specific. I can't reproduce it with a Samsung Galaxy Note 9 running Android 9. Anyway, I'll just remove the filter.

@chenxiaolong
Copy link
Owner

I was able to get biometric + device credential auth working on Android 9 (#94). It was a lot easier than I initially thought.

chenxiaolong added a commit that referenced this issue Oct 26, 2024
Although androidx.biometric can handle biometric auth on legacy Android
versions, we're intentionally not using it. The legacy device credential
API does both biometric and device credential auth and it is not
possible to disable just the biometric part, so just let the legacy API
handle everything.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
chenxiaolong added a commit that referenced this issue Oct 26, 2024
Although androidx.biometric can handle biometric auth on legacy Android
versions, we're intentionally not using it. The legacy device credential
API does both biometric and device credential auth and it is not
possible to disable just the biometric part, so just let the legacy API
handle everything.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@dermitza
Copy link
Author

I can test run a test apk if you'd like (i'd compile the test branch and do it myself but the android dev environment i have around atm is quite outdated - was trying to resolve dependencies for the past half hour lol)

@dermitza
Copy link
Author

I wonder if that behavior is Sony-specific. I can't reproduce it with a Samsung Galaxy Note 9 running Android 9. Anyway, I'll just remove the filter.

is there a possibilty of a conflict with different content providers? But im not seeing anything in logcat tbh. Would there be a way to debug this further?

chenxiaolong added a commit that referenced this issue Oct 26, 2024
On older Android versions (at least API 29 and 30), the window insets
callback on the RecyclerView is never called if the MaterialToolbar
consumes the insets, even though the RecyclerView is not its child.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@chenxiaolong
Copy link
Owner

Yeah, sure! Could you give this a try? ShowMime.zip It's a dumb little app (requests no permissions) where you select a file and it shows the MIME type that Android detects. The zip also includes the source code in case you prefer to build it yourself.

As for an RSAF test build:

These are signed with the release key, so they can be installed on top of an existing release build. They include #94 and #95.

@dermitza
Copy link
Author

dermitza commented Oct 26, 2024

Yeah, sure! Could you give this a try? ShowMime.zip It's a dumb little app (requests no permissions) where you select a file and it shows the MIME type that Android detects. The zip also includes the source code in case you prefer to build it yourself.

Interesting, it may not be a bug in RSAF after all - instead a bug with CIFS Documents Provider. When copying a text file using the above the mime type of the file shows up as "*/*".

Copying the file over using either RSAF or Total Commander the mime appears as "application/octet-stream" and openable by RSAF. A quick search yielded this and this, so its either a (very specific) android issue or an issue with CIFSDP. I'll let them know i guess.

wa2c/cifs-documents-provider

As for an RSAF test build:

These are signed with the release key, so they can be installed on top of an existing release build. They include #94 and #95.

#94 I can verify auth now works (pin/password/gesture, I assume biometrics too but did not test).
#95 Window padding now works correctly too

Great job, thanks a lot for your time :)

chenxiaolong added a commit that referenced this issue Oct 26, 2024
While Android's builtin FileSystemProvider for local files guesses the
MIME type based on the file extension, other document providers may not
do so and could report something other than application/octet-stream or
text/plain. Let's just let the user select any file.

Issue: #93

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
@chenxiaolong
Copy link
Owner

Thanks for testing!

I only took a quick look and didn't see anything obviously wrong with what they do. They also guess based on the file extension. Maybe it is a weird Android issue, like you said.

In any case, I've removed the MIME type filter in #97.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants