termux / termux-app

Termux - a terminal emulator application for Android OS extendible by variety of packages.
https://f-droid.org/en/packages/com.termux
Other
35.58k stars 3.73k forks source link

[Bug]: termux-open does not seem to work with Android 13 (should it?) #3565

Open kevinboone opened 1 year ago

kevinboone commented 1 year ago

Problem description

termux-open does not seem to work at all, in any of the many ways I have tried it, on my S5E tablet with Android 13. I'm aware that it's always been somewhat problematic, to make termux interact properly with graphical Android apps, owing to all the various security restrictions. However, I'm unsure whether it's even expected to work with Android 13.

When I run termux-open file, what generally happens is that a chooser window pops up (even if I don't use the -chooser switch). One of the choices is always 'Termux', the other usually an app that can handle the file. I don't really even know what I'm supposed to select at this point.

If I choose 'Termux', I see an error pop-up dialog from TermuxFileReceiver saying that the file is invalid. If I choose an ordinary app, it generally starts, but then either displays a blank page or an error message of some kind -- depending on the file type.

I've tried with files that are in the Termux home directory, absolute paths to files in the termux home directory, absolute paths to files in /storage, and file:/// URLs. The results differ according to where the file is, but the result is never that any file gets opened.

To be honest, I really have no idea how termux-open is supposed to work, so it's hard to troubleshoot.

Steps to reproduce the behavior.

On an Android 13 device, try to open a file using termux-open.

What is the expected behavior?

I would expect an app that can handle the file to launch, and show the file.

System information

agnostic-apollo commented 1 year ago

Have you enabled allow-external-apps?

https://github.com/termux/termux-app/releases/tag/v0.118.0

kevinboone commented 1 year ago

Yes. I tried that, although I don't really understand what it does. However, I'm not sure whether something needs to be restarted to make that setting take effect; and, if so, what.

I also added the permission for Termux to be able to raise apps from a background service, which I think is a new requirement in Android 11. However, I'm not sure that Termux actually does that.

What I'm baffled about is how termux-open is supposed to work, and where files can be stored in order for it to work. The script runs 'am broadcast -n com.termux....' which suggests to me that the Intent is supposed to be handled by the Termux app, rather than some other app. So, when I see a chooser dialog, I don't know whether that's the result of something that Termux does, or whether something in Android is intercepting the Intent and raising the chooser (I don't see why it would).

I also don't really understand where termux-open can read files from. It uses realpath to get the absolute pathname, and that seems to work correctly; but, conceivably, the absolute pathname might refer to some place that Termux can't actually read.

For example, if I do

termux-open /storage/XXXX-XXX/path/to/file

to read from a plug-in SD card, maybe Termux can't actually see that path, because of permissions restrictions? But Linux commands in Termux can see the file perfectly well, so I'm not sure that's an explanation.

My main question, though, is about Intent handling. If (for some reason), I see a chooser dialog when I run termux-open without the --chooser switch, should I select Termux as the target?

agnostic-apollo commented 1 year ago

Yes. I tried that, although I don't really understand what it does. However, I'm not sure whether something needs to be restarted to make that setting take effect; and, if so, what.

It is currently a unified property to allow external apps to access termux data. Either run termux-reload-settings or exit app and restart for changes to take effect.

https://github.com/termux/termux-tasker#allow-external-apps-property-optional

What I'm baffled about is how termux-open is supposed to work, and where files can be stored in order for it to work.

The termux-open sends a broadcast to TermuxOpenReceiver.onReceive(). It then sends an intent to start an activity with the content uri of the file passed with a temp read grant access to other apps. When the target apps open the file like with the ContentResolver.openInputStream() call, the TermuxOpenReceiver$ContentProvider.openFile() is called. If allow-external-apps is not enabled or the file is not in termux files directory /data/data/com.termux/files or /storage/emulated/0 (for primary user), then request is rejected.

https://github.com/termux/termux-app/blob/eef5ac43a72f6391a5360a7c1f123e97dee85182/app/src/main/java/com/termux/app/TermuxOpenReceiver.java#L35

https://github.com/termux/termux-app/blob/eef5ac43a72f6391a5360a7c1f123e97dee85182/app/src/main/java/com/termux/app/TermuxOpenReceiver.java#L194

https://developer.android.com/reference/android/content/ContentResolver#openFile(android.net.Uri,%20java.lang.String,%20android.os.CancellationSignal)

The /storage/XXXX-XXX path for external sd cards is not accessible as per AOSP on most devices by apps with native file and java File apis and only by android SAF apis. If you can access it with termux on your device via terminal, then it should also be accessible by termux java code, but currently you won't be able to open it with termux-open. I can make a commit now to allow it if you are using github action builds.

As for errors, it's the responsibility of receiver apps to show you proper errors for why they failed to open something. You can also check logcat for exceptions if they don't. And you should post those exact errors when filing bug reports so that developers don't need to guess what is wrong.

My main question, though, is about Intent handling. If (for some reason), I see a chooser dialog when I run termux-open without the --chooser switch, should I select Termux as the target?

If you select Termux in chooser screen, the file will be sent to termux-file-editor.

https://wiki.termux.com/wiki/Intents_and_Hooks

kevinboone commented 1 year ago

Hi. Thank you for the detailed response. I'm aware that the handling of /storage/XXXX-XXXX for plug-in SD cards is very variable between implementations, so I'm not surprised to find it not to work with Termux. Right now, I'll concentrate on the things that I believe should work, based on your post.

So here are my observations.

  1. If I have a .jpg file in $HOME, and I run termux-open xxx.jpg then I see a file chooser, where the choices are 'Termux', 'Gallery', and 'Simple Gallery Pro' (which I installed) If I choose 'Termux', I see a File save/edit dialog, which I think is in line with your description.

  2. If I choose 'Gallery', then the Gallery app starts, but shows a blank screen. logcat shows nothing, so I can't figure out whether the problem is in Gallery, or permissions, or something else.

  3. If I choose Simple Gallery Pro, the app is raised, and shows the image correctly.

  4. If I copy the .jpg file to $HOME/storage/shared and run termux-open from that location, the Simple Gallery Pro does open the image file correctly. 'Gallery', again, shows a blank screen.

  5. I installed SimpleTextEditor, and tried with a .txt file in $HOME. This works properly -- I can choose SimpleTextEditor from the chooser, the app starts, and shows the text file. I can't save its contents, but I think that's in line with other discussion I've seen.

  6. If I copy the text file to $HOME/storage/shared/, and then run termux-open from that location, then the chooser does not give me an option to run SimpleTextEditor (even though it's the same file). I do get an option to run Browser, which I guess is the AOSP browser (the other browser I installed isn't offered as an option). The browser opens the text file fine.

  7. I installed MuPDF and put a .pdf file in $HOME. When I run termux-open on the file, it works fine -- I get offered MuPDF as a choice, and it reads the file.

  8. But if I copy the same file to $HOME/storage/shared, I do get offered 'MuPDF' as a choice (which is different to what I saw with the text file, where I didn't get a suitable app), but the MuPDF app isn't even raised. Again, nothing in logcat.

So in summary:

Is this broadly in line with what other people have found (for the latest Android versions)? From the perspective of a Linux developer, Android file management sucks, and it's sucking harder with each new Android release. I'm certainly not blaming Termux for that.

BTW none of this is a show-stopper. termux-open does mostly work for files in $HOME, and this is a location that is hard to find from regular Android apps. Files in external and shared storage are easy to find using a regular Android file manager, so the fact that termux-open does not seem to work reliably with these locations does not stop it being useful. It would be nice to be able to raise a specific app for a specific file from the command line, regardless of location, but it isn't essential.

BW Kevin

agnostic-apollo commented 1 year ago

If some apps are working from external storage and some not, then that would likely be an issue with target app, not with termux. You can check with adb logcat -d > /sdcard/logcat.txt for exceptions or errors, if any are logged. Running logcat inside termux without adb or root will not show logs of other apps. You can post logs here after removing sensitive information, or email it to me.

I can't save its contents, but I think that's in line with other discussion I've seen.

I can add --allow-write support.

so far I have not find many apps that will open the file, and in many cases I don't get offered a suitable app at all.

This is weird, do you use same file name when copying? The mime type is generated based on file extension, if there is no valid extension, chooser apps won't show. You can try passing text/plain and application/pdf to --content-type and see if that works.

If something is broken on termux end for external storage, then it should be fixed.

kevinboone commented 1 year ago

Thanks. It never occurred to me that logcat would produce different output as root. I will try that if I continue to have problems.

But...

Since I rebooted my tablet, most of the weird behaviour has gone away. Even the built-in gallery app, which was previously showing a blank page, is now showing pictures. I'm getting offered apps that correspond to the correct file types -- I suspect that failures in this area were the result of a bug in LineageOS: there are some bugs logged in this area.

So the only outstanding issues are

I unerstand that both of these would need code changes. It would nice if this were done at some point, but there's no urgency at all.

agnostic-apollo commented 1 year ago

Write access should be easy enough, but will require updating termux-tools packages.

The /storage/XXXX-XXXX access will require some work to implement with the new provider implementation, will look into it.

kevinboone commented 1 year ago

I'm happy to close this, and raise new enhancement requests for the write access and /storage issues -- I guess these aren't bugs, but just the way it works. Up to you.

agnostic-apollo commented 1 year ago

It's fine, keep this open. I have added them to the my todo list.

FalconSN commented 1 year ago

termux-share -a edit <file> does give write permission, for files in both internal storage and Termux home. Though it did not work on Google Photos, only Simple Gallery and MiXplorer's text editor out of three.