tuntorius / mightier_amp

An alternative app for controlling NUX Mighty amps.
MIT License
192 stars 20 forks source link

Issue: Exporting presets to file not working #49

Closed TullyMore closed 1 year ago

TullyMore commented 1 year ago

Hi Tuntorius,

first I would like to thank you, for fixing all of the previous bug reports. A special thank you goes out to Alexi-Zemcov, for contributing the screen rotation feature.

It appears, that I came across three issues with the QR code handling and patch to file saving feature. I will put each in a separate ticket and also add two feature requests. You will find the devices and software versions at the bottom of each ticket.

As always, let me know, if I can do some further testing.

Regarding this ticket. Non of the exporting preset to file options are working on my devices. Neither the bulk saving option, nor saving a single preset. I also tried saving to different locations (internal memory, external SD card) and even to the Android/data/com.tuntori.mightieramp/files folder. The result is always a 0 byte file.

Regards TullyMore

Devices and versions: Android 13 on Samsung Galaxy A52s 5G Android 8.1.0 on Samsung Galaxy Tab A (2016) Mightier Amp v0.9.6 with all permissions granted

tuntorius commented 1 year ago

I had this happen once on an android 12 or 13 device. At first, it produced 0-byte files. Then I saved a file in the "Downloads" folder. That file turned ok. Then I checked the other places where the 0-byte files were and they magically got their proper size and content! Mightier Amp was not running at that time. It's not like it went over the files and fixed them. From that moment, it produced only proper files. There's this new horrible "feature" of Android 11+ called "Scoped Storage". It's something like permission management per file, implemented by an additional layer between the apps and the file system. Now files written by one app can't be read by another like they used to be with earlier androids. File managers should be an exception and automatically get permission to see any file. However, in this case, I believe the file manager of that phone couldn't get permission for the files of Mightier Amp until I somehow forced it by saving a file in Downloads.

TullyMore commented 1 year ago

Hi,

thanks for the explanation. Saved both to the DownloadS and DownloaD, as well as different other folders, but to no avail. Even tried to save it to the Android/data/mightieramp/files folder. Amp was not connected.

Then I copied one of the 0-byte files to my desktop PC via USB. Size still was zero.

Tried all of this with my Tablet A running Android 8.1.0, so the Android version might not be the issue.

Regards TullyMore

tuntorius commented 1 year ago

I did some changes in the file-saving code in the new version (0.9.9). No idea if that will change anything for you. For me, it works both ways.

TullyMore commented 1 year ago

Hi,

with the latest update, exporting as preset and QR code works both on my Android 13 on Samsung Galaxy A52s 5G, as well as an old Nexus 7 running Android 7.1.2.

Unfortunately it's not working on my main device with Android 8.1.0 on Samsung Galaxy Tab A (2016). Interestingly enough, it's also not working on another Nexus 7 running LineageOS Android 11

Sharing a QR code to another device via bluetooth however is working and produces a file with X kilobyte.

I don't know, what you changed in your last update, to make it work on Android 13 and 7.1.2(?), but I have a feeling that it's related to access permissions.

What process is handling the saving routine? Is it part of the file managers? Or is it an inbuild Android function? Do I have to grant permissions to this function?

All I can see is, that my file managers have all permissions. I also forced them to stop, so they won't interfere with the storing process of MightierAmp. As far as I can see, MightierAmp has all relevant privileges as well. So I'm kind of running out of ideas.

regards TullyMore

tuntorius commented 1 year ago

I'm using the Storage Access Framework, which opens the system file picker. That gives the app permission to the specified file just because it makes the user aware of that. This file picker may be different on each device. It's either provided by the system, or by some other apps, like file managers, but according to the official docs, it's used the same way regardless. It returns a URI to the file, which is not a file path, but some abstract identifier. Then, I must use a thing called ContentResolver, which gives me a stream to the file. Then I just write the data and close the stream and that's it. This does not require any permission, not even storage permission because picking the file manually is enough indication of the intentions of the app and the system grants access.

The difference I made between the current and last versions is tiny. The stream that ContentResolver is giving me is a binary type of stream. The JSON I'm saving is a string. In the previous versions, I was converting the Binary Stream to a Text Stream to save the string. Now I do the reverse. I convert the string to a byte array and save it using the binary stream. Both methods are valid and mostly identical. It was a change for the sake of change, really.

The Storage Access Framework gives the flexibility that you can have extensions to the file picker. Any app can add custom pickers. Some file managers do. Even apps of cloud storage services like Google Drive and Dropbox add their own file pickers. This is Google Drive on my phone: drive This way any app can save anywhere using the same code. My app can also load and save directly to google drive for example. This may be a good test for the device where saving is not working.

TullyMore commented 1 year ago

Thanks for your in depth explanation. I activated my Google Drive and managed to export presets on my Tablet (Android 8.1.0). Funny thing is, it's still 0 bytes :-)

To make sure, it's not a broken preset, I created a fresh preset in a new category with the MightyAmp connected. Still 0 bytes.

It appears, it's not the Android mechanism, that's causing the trouble.

I had a look at the /Android/data/com.tuntori.mightieramp/files/presets.json file which is 231 kB (I have quite a few presets). When opening it by tapping on it, I got the message: "The file is too long and cannot be edited, however you can read the first 51200 characters". Tried to open it with the HTML Viewer app, which couldn't open it either. Could the file size be causing the issue?

tuntorius commented 1 year ago

The files inside the private directory of an app can't be accessed by another app. This is called sandboxing and is a security feature. But you can access them when the phone is connected to a computer.

I tested the export on the 5 physical devices I have. I also tested it on over 10 emulators from the Android sdk with various android versions - from 6 to 13. Including variations with and without google services on them. Last few months I also tested it on friends' devices. None had the export problem, except the mentioned Android 13, but it was some kind of permission/ownership problem that got sorted by itself and even the broken files fixed themselves. I believe they were never broken, but were inaccessible by every possible app or service in the os.

In short, I tested this on ton of devices, I also never got a report of this bug by somebody else. I don't know why you have this happening on one device or another. Are you doing something that very few people do? Like running custom roms, degoogling your devices, or rooting them?

Have you tried exporting a preset, then deleting it from the library and then reimporting it back to see if mightier amp will read it, even if the file is 0 bytes?

Do you know how to capture logcat output?

TullyMore commented 1 year ago

Hi,

you pointed me in the right direction. I bought the tablet(s) second hand. Checked for any anomalies and found that the developer options were activated in the settings. There the "Do not keep activities" switch was activated. Turned it off and everything is working fine! This means you can close this issue and #50, #51 and #53, as well.

Just to make it clear, while I was hoping to find a solution for my issues, my main goal was to support you and your software by testing and reporting anything I thougth was a bug. Just so you know, when you find another issue created by TullyMore ;-)

Thanks for your patience!

regards TullyMore

tuntorius commented 1 year ago

It's great that you found the cause of this. It explains everything. The app is restarted in all those cases. This is a good find. I never thought what this option can do if enabled. Good to know if I get a report of strange bugs.