Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
FAT32 SHAMER
Aug 16, 2012



I want to say that when I set it up for my QA team I copied qemu.exe out then created a bat file on their desktop that launched it but that was a while ago. I’ll double check my folders on Monday and see if I still have it

E; I think it was a folder they put on their desktop with the sdk with the batch file in there

Adbot
ADBOT LOVES YOU

PokeJoe
Aug 24, 2004

hail cgatan


Hmm I'll see if I can get it working that way, thanks. I want to get it going for mac + pc so I would be interested in your bat file.

Vesi
Jan 12, 2005

pikachu looking at?

Twerk from Home posted:

Is okhttp still the de-facto default http client option? Is there anything else out there?

I spent the day dealing with a nasty bug caused by people trying to work around old okhttp bugs like https://github.com/square/okhttp/issues/3146 and https://github.com/square/okhttp/issues/3974, and it only reproduced on Android 9. Of course, I have test devices on android 7, 8, 10, and 11 but not 9, so it was a PITA to debug. It's crazy to me that making http requests is this fraught at this point in Android's lifecycle.

I have a pretty high trust in jetbrains so if I started a new project I'd try https://ktor.io/docs/clients-index.html
you can plug in okhttp engine into it too

Head Bee Guy
Jun 12, 2011

Retarded for Busting
Grimey Drawer
I dug up a cheap old samsung phone I had, couldn't remember the password, so I factory reset it. Now i have no idea what throwaway google account I used for this thing, so I'm stuck. Any salvaging this, or did I effectively brick this?

Tuxedo Gin
May 21, 2003

Classy.

Newbie question:

Making a kotlin app. I want users to be able to subscribe to and download "packs" (would mostly just be data which will go in a DB, but also image and audio files). What is the best way of handling storing the media files on the device? Is there are way other than just throwing them in internal storage? I'd like, if possible, for them to be contained within the app and not easily strippable, since I'd like them to be inaccessible when a subscription is inactive - maybe even deleted. I'm can search and figure out how to do it once I know what methods are used, but my google searches on the topic are apparently too vague at the moment to be useful. Could somebody point me in the direction of functionality I should be reading up on (if such a thing exists)?

FAT32 SHAMER
Aug 16, 2012



Tuxedo Gin posted:

Newbie question:

Making a kotlin app. I want users to be able to subscribe to and download "packs" (would mostly just be data which will go in a DB, but also image and audio files). What is the best way of handling storing the media files on the device? Is there are way other than just throwing them in internal storage? I'd like, if possible, for them to be contained within the app and not easily strippable, since I'd like them to be inaccessible when a subscription is inactive - maybe even deleted. I'm can search and figure out how to do it once I know what methods are used, but my google searches on the topic are apparently too vague at the moment to be useful. Could somebody point me in the direction of functionality I should be reading up on (if such a thing exists)?

This is what I would do, so the play store can natively handle subscriptions etc:

https://developer.android.com/guide/app-bundle/asset-delivery

Tuxedo Gin
May 21, 2003

Classy.

FAT32 SHAMER posted:

This is what I would do, so the play store can natively handle subscriptions etc:

https://developer.android.com/guide/app-bundle/asset-delivery

Thank you so much for the reply. I'll do some more reading and research into PAD. It checks a lot of boxes, though it looks like I have to upload everything in a pack to the play store, which means if I change one of the packages, I'd have to submit the entire app for an update. Is there any way to pull assets from my own servers so I can control them and make changes on the fly and handle the download/storage/update within the app? Or is that not possible for security reasons?

Vesi
Jan 12, 2005

pikachu looking at?

Tuxedo Gin posted:

Thank you so much for the reply. I'll do some more reading and research into PAD. It checks a lot of boxes, though it looks like I have to upload everything in a pack to the play store, which means if I change one of the packages, I'd have to submit the entire app for an update. Is there any way to pull assets from my own servers so I can control them and make changes on the fly and handle the download/storage/update within the app? Or is that not possible for security reasons?

trying to protect data from a hostile user who has root access, can edit bytecode and intercept network requests is pretty hopeless and wasted effort, just put data in Context.getExternalFilesDir(), smaller structured data into sqlite and have the app delete them when subscription is inactive

I remember in 2010 I had paid downloads be encrypted with public keys, I expected it would thwart a 12 year old hacker but not a 14 year old

Vesi fucked around with this message at 07:20 on Jan 26, 2021

FAT32 SHAMER
Aug 16, 2012



Tuxedo Gin posted:

Thank you so much for the reply. I'll do some more reading and research into PAD. It checks a lot of boxes, though it looks like I have to upload everything in a pack to the play store, which means if I change one of the packages, I'd have to submit the entire app for an update. Is there any way to pull assets from my own servers so I can control them and make changes on the fly and handle the download/storage/update within the app? Or is that not possible for security reasons?

Oh yeah that’s totally valid as well, especially if you’re already serving a website for the app or whatever. Just pull down data and parse it into a local db

Vesi posted:

trying to protect data from a hostile user who has root access, can edit bytecode and intercept network requests is pretty hopeless and wasted effort, just put data in Context.getExternalFilesDir(), smaller structured data into sqlite and have the app delete them when subscription is inactive

I remember in 2010 I had paid downloads be encrypted with public keys, I expected it would thwart a 12 year old hacker but not a 14 year old

Yeah pretty much this. Android has pretty significant security limitations compared to iOS, and while I guess you could hash the data and do various crypto stuff to protect it, I want to say they would be able to figure it out if the data is valuable enough.

Could be a good way to protect it from low level pirates but I’m not sure how inconvenient that is for someone with the tools Vesi mentioned to crack

Tuxedo Gin
May 21, 2003

Classy.

Vesi posted:

trying to protect data from a hostile user who has root access, can edit bytecode and intercept network requests is pretty hopeless and wasted effort, just put data in Context.getExternalFilesDir(), smaller structured data into sqlite and have the app delete them when subscription is inactive

I remember in 2010 I had paid downloads be encrypted with public keys, I expected it would thwart a 12 year old hacker but not a 14 year old

Thank you. I'm not super concerned about hostile users stripping data, I just wanted to avoid having it being out in the open for the taking, but I guess you're right it's not really a fight worth fighting, especially since the content is not something most people would be clamoring to pirate and the target demographic probably rarely actually looks at the file system of their devices if they even know that that is possible.

My biggest concern is my being able to make updates to the packages and them going out easily. PAD and your suggestion are two methods I'll do a lot more reading about. I'm only a hobbyist programmer, but I'm hoping to be able to jerry-rig something decent to at least get my idea off the ground so I can pay someone much smarter than I am to do a much better job than I ever could.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Tuxedo Gin posted:

My biggest concern is my being able to make updates to the packages and them going out easily. PAD and your suggestion are two methods I'll do a lot more reading about. I'm only a hobbyist programmer, but I'm hoping to be able to jerry-rig something decent to at least get my idea off the ground so I can pay someone much smarter than I am to do a much better job than I ever could.

Depending on how frequently you plan to update this content, and how much of it there is, it seems like PAD may not be a good option. I don't believe Play has a nice way to provide modular content on demand, but you could probably get away with using the in app purchases API to verify that the user is allowed to use it, and to distribute it yourself from your own hosting.

FAT32 SHAMER
Aug 16, 2012



We personally use 15 different pads to dynamically download image packages and display as needed so our base app is 15mb instead of 75mb, but I’ll admit you need to use reflection to access those files from your :app package and it’s kind of messy

kitten smoothie
Dec 29, 2001

I work on an app with multiple packs purchasable via IAP.

We control it by having a backend service that validates the IAP receipt, and another backend endpoint that dishes out the actual content if you’ve authenticated it.

The app does the IAP, the receipt from Play Billing is sent to the backend. Backend calls Google’s validation endpoint to confirm it’s a legit receipt.

Upon confirming the receipt is good, the service gives you back a token you can use to get the content by calling the second service.

Our content is pretty small. If it were bigger I would probably suggest making a service that will trade an IAP receipt for a signed AWS S3 download link with a reasonable expiry date.

Same thing then happens when you restore purchases, we call Play Billing to get all your receipts, send the lot of them to that endpoint, and get back the content.

kitten smoothie fucked around with this message at 17:46 on Jan 26, 2021

Good Sphere
Jun 16, 2018

How easy is it to develop for an older version of Android, like 8? I could make different SDK settings, but does that mean I need to write older code? Is Kotlin out of the picture?

Vesi
Jan 12, 2005

pikachu looking at?

Good Sphere posted:

How easy is it to develop for an older version of Android, like 8? I could make different SDK settings, but does that mean I need to write older code? Is Kotlin out of the picture?

kotlin should be fine since it's just turned into jvm bytecode

biggest problem is all more modern apis will rely on androidx which requires sdk 14/15, also tls version will probably be insecure

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
You also have older versions of APIs where things either don't work as you expect or don't exist at all. Androidx etc will usually handle this for you behind the scenes with compatibility code, but at a certain point you need to determine the cost / benefit of supporting increasingly unused versions. Having an older version that doesn't get upgraded beyond for older API levels is how this usually happens, but for new apps you won't have that luxury.

brand engager
Mar 23, 2011

What causes android 10 to automatically grant the camera permission? I have some test app that only declares uses-permission for android.permission.camera, and when I install it the camera permission is already granted. Everything I've found in the documentation says the camera permission can only be granted by asking at runtime.

Edit: it's loving gradle doing it somehow. Doesn't happen if I install manually with adb, but using the installDebug task automatically grants the camera permission.

brand engager fucked around with this message at 22:26 on Apr 28, 2021

kitten smoothie
Dec 29, 2001

brand engager posted:

What causes android 10 to automatically grant the camera permission? I have some test app that only declares uses-permission for android.permission.camera, and when I install it the camera permission is already granted. Everything I've found in the documentation says the camera permission can only be granted by asking at runtime.

Edit: it's loving gradle doing it somehow. Doesn't happen if I install manually with adb, but using the installDebug task automatically grants the camera permission.


What version of the Gradle plugin are you using, looks like this may have been fixed in 4.2. The idea was to auto grant permissions for instrumented tests but it just granted whatever was in the manifest all the time

https://issuetracker.google.com/issues/172112073

brand engager
Mar 23, 2011

kitten smoothie posted:

What version of the Gradle plugin are you using, looks like this may have been fixed in 4.2. The idea was to auto grant permissions for instrumented tests but it just granted whatever was in the manifest all the time

https://issuetracker.google.com/issues/172112073

It was a new project so just whatever version it defaults to now

Volguus
Mar 3, 2009
I have a question that I think I know the answer to, but still, I have to ask: Can an application developer protect the resources contained in an application deployed to the Play Store?

The company I'm working with, they're doing image recognition. They have the ML model and the C++ code that's using it. At the moment, the application loads that model file as a raw resource from within the APK. They do not want to download the model on the fly since that would require internet connectivity on the phone at all times. Plus, these models can be quite big (50MB or more). So they would want to deploy the model with the application itself.

The model file is encrypted, but the decryption key, since it has to be done locally, is in the native library. An enterprising enough person can probably decompile the .so and extract from there the decryption key. The model itself is their core IP.

Is there a way to have everything stored locally so that, unless you're the NSA, the user cannot access it? I found this APK Extract tool, and for what I tried it on it looks trivial to get the application and its files.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If you're putting something (like an ML model) in your APK with the intention of it being unpacked and executed on the device, there's no practical way to prevent someone else from unpacking and executing it the same way your software does. There are ways to make it more challenging, but you're really just raising it to the level of "bored teenager with a few hours to kill".

If you're willing to relax the offline requirements then you could only provide the decryption key transiently to devices that have passed attestation, which would make your bored teenager need to work a lot harder (but still wouldn't be NSA-level stuff).

Volguus
Mar 3, 2009
Can that key be provided from google's servers (play store api? Some resource in there?) or via a company owned server and then just do a normal https request?

Edit: What is" devices that have passed attestation" ? Attestation from where? From who?

Volguus fucked around with this message at 02:48 on May 14, 2021

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
https://developer.android.com/training/safetynet/attestation

The general flow is your own server will be in charge of providing the decryption key, but you get to outsource the "check that the thing asking for it is an authentic version of your app running on an un-hosed-with device" step to someone else.

But keep in mind:

quote:

The API is not designed to fulfill the following use cases:
[...]
- Replace or implement strong DRM checks.
Again, it just makes the bored teenager need to work a little harder.

You could alternatively license a DRM system from somebody willing to sell it to you, and trust that their efficacy in practice matches up with their marketing copy.

Volguus
Mar 3, 2009
Cool, thanks, I'll report these findings. Yes, this could work, in my opinion, but I'm sure I'll hear: no servers, no online. Oh well...

FAT32 SHAMER
Aug 16, 2012



“Ok well I guess your IP is up for grabs then”

Volguus
Mar 3, 2009

FAT32 SHAMER posted:

“Ok well I guess your IP is up for grabs then”

Most likely they just won't push it to Play Store for everyone to download it. Just continue what they're doing now and give the APK (yes, with their thing up for grabs) to select people and companies. With NDAs or whatever signed. Personally, I'm happy to not be involved.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Jabor posted:

You could alternatively license a DRM system from somebody willing to sell it to you, and trust that their efficacy in practice matches up with their marketing copy.

s/trust/pretend/

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Volguus posted:

Most likely they just won't push it to Play Store for everyone to download it. Just continue what they're doing now and give the APK (yes, with their thing up for grabs) to select people and companies. With NDAs or whatever signed. Personally, I'm happy to not be involved.

Distributing it manually basically just means "we trust that you won't let anyone else touch this," which is fine if you're subtly watermarking it, can trace the leak, and then sue the offending company into oblivion, but realistically you ought to have some kind of licensing service for clients here. Not using the play store just helps prevent total randos from getting a copy vs a (friend of a?) disgruntled employee who was told "download the APK from here"

Volguus
Mar 3, 2009

Volmarias posted:

Distributing it manually basically just means "we trust that you won't let anyone else touch this," which is fine if you're subtly watermarking it, can trace the leak, and then sue the offending company into oblivion, but realistically you ought to have some kind of licensing service for clients here. Not using the play store just helps prevent total randos from getting a copy vs a (friend of a?) disgruntled employee who was told "download the APK from here"

They should ... a lot of things they should. But, their business model is not to sell the app per-se, the app is just a "demo". What they want to sell is their library with their model. The client company is to make their own app, which makes use of the image recognition stuff and then they sell it. I presume they could ask them then to ... do whatever to protect the model, like those people would care. This is why manual distribution for now works because is not like there are a billion companies out there interested in this. I assume they wanted to make it easier to distribute, and probably to reach a larger audience with their model.

As I said, I'm very happy to not be involved.

Glimm
Jul 27, 2005

Time is only gonna pass you by

Volguus posted:

Cool, thanks, I'll report these findings. Yes, this could work, in my opinion, but I'm sure I'll hear: no servers, no online. Oh well...


You could use something like Firebase Remote Config to send your decryption key down.

Folks can still sniff the network traffic and find it though.

Of course, you could encrypt the key before sending it, but then you've got to store the decryption key in the client...

It's a tough problem

kitten smoothie
Dec 29, 2001

Glimm posted:

Of course, you could encrypt the key before sending it, but then you've got to store the decryption key in the client...

It's a tough problem
Modern Android devices have hardware backed keystore, essentially anything with a fingerprint reader is mandated by Android CDD to have a means of storing keys in hardware.

Another thing you can do is use key attestation (this is different than Safetynet attestation), this works on devices that shipped with 7.0 and later.

If you create a public/private keypair you get metadata in the public key certificate that gives you some important data: the application ID of the app that created the key, and the SHA256 of the app signature, so you can verify the key was created by your app. It also indicates whether the private key is in hardware and not accessible to the Android side of the house. Finally you can plant a piece of user metadata into the keypair when you create it, like a timestamp value to prevent replay attacks. That whole shebang is signed by a key burned into the hardware, which is then chained back to a Google root certificate, so you can verify that the key was actually generated on device in the hardware encryption environment, and not replaying from a previous user.

So if you're okay with online access once at first load, you could create a keypair on-device, send a backend of yours the public key. That looks at attestation data, if it's good, encrypts your data blob with the public key and sends it down. At that point then you've got an encrypted data blob that can only be decrypted by that one phone because the private key to decrypt it is in hardware.

This might help you with storing the data encrypted at rest (and at least only require online access at first load) but you're still going to have to decrypt it to use it at runtime.

kitten smoothie fucked around with this message at 20:00 on May 15, 2021

mobby_6kl
Aug 9, 2009

by Fluffdaddy
First time trying android stuff in, uh, 10 years. I need my app to log sensor data until then user tells it not to, is a foreground service still the only way to accomplish that without android randomly killing it? I gave it s shot but it's kind of a pain in the rear end considering everything already works properly as long as the app is active.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Yes, a foreground service is the correct way to do this. The visible notification is a reminder to the user that your application is still doing what they asked it to.

It shouldn't be particularly onerous to set up, everything's gonna be running in the same process so you can ignore all the aidl poo poo. Just call startService() when the user does the thing and have the service call startForeground().

Probably the biggest hassle is making sure your Activity cleans itself up properly instead of not bothering.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
And to follow up, Android went through a cracking down phase a few years back because there were a billion services in everyone's phone and it was taking forever to have anything happen since they were all clamoring for attention. If your service isn't a foreground service, at this point all bets are off regardless of what system bits it may be interacting with, or are interacting with you. If you get a broadcast intent, you have to start a foreground service if you want to handle it right away and it's not something you can just plop into a scheduled service run for later.

mobby_6kl
Aug 9, 2009

by Fluffdaddy
Thanks, I got it to work eventually. Lots of boilerplate but thankfully examples exist to copy &paste from even if I had to fix some stuff. Sometimes seems to fail after a few minutes but this could be down to the specific sensor stuff I'm trying to do.

Speaking of broadcasts, I'm only sending one from the service to the mothership with the collected sensor data to visualize it. This... Doesn't work very well, I'm getting dropped frames and laggy UI when this is enabled. I'll probably need to figure out binding because I'm guessing intents aren't supposed to push data at a few hundred Hz :v:

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

mobby_6kl posted:

Speaking of broadcasts, I'm only sending one from the service to the mothership with the collected sensor data to visualize it. This... Doesn't work very well, I'm getting dropped frames and laggy UI when this is enabled. I'll probably need to figure out binding because I'm guessing intents aren't supposed to push data at a few hundred Hz :v:

:staredog:

No, you should not be sending several hundred intents per second. I am now warily curious about your app architecture and what exactly you mean by "motherhood", is it a separate process? If so, you may in fact want to look into AIDL stuff after all.

Volmarias fucked around with this message at 00:21 on May 31, 2021

mobby_6kl
Aug 9, 2009

by Fluffdaddy
Yeah that's what I thought but it seems to actually work ok as long as I'm also not drawing anything. By mothership I just meant the main activity, though I suppose motherhood works too :)

All of this is just trying to work around the limitations android places on apps in the simplest way possible but this seem like the way to do it:



The main activity, when running, draws the data to show what's being collected. The way to return data isn't clear yet as you can tell, but I'll look into AIDL. Strictly speaking this functionality isn't really necessary, it's mostly for debugging so this half-assed solution might do the job.

Vesi
Jan 12, 2005

pikachu looking at?

mobby_6kl posted:

Yeah that's what I thought but it seems to actually work ok as long as I'm also not drawing anything. By mothership I just meant the main activity, though I suppose motherhood works too :)

All of this is just trying to work around the limitations android places on apps in the simplest way possible but this seem like the way to do it:



The main activity, when running, draws the data to show what's being collected. The way to return data isn't clear yet as you can tell, but I'll look into AIDL. Strictly speaking this functionality isn't really necessary, it's mostly for debugging so this half-assed solution might do the job.

If they're in the same package you don't need to bother with any IPC stuff you can get the data from the service any way you want to, you can think of it like as a singleton. just try to start the service from the activity in onCreate and it'll either start it from scratch if it's not running or just do nothing if it's already running

In onServiceConnected you'll get the definitive instance of the service, but you can also access any of its static fields anytime in the activity

If you want to use the latest practices you'll write the data into a a StateFlow/SharedFlow from the service then listen to it from the activity

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Ok, I thought this was something more complicated, like a data collection app and a separate, optional supervision app. You certainly do not need to worry about IPC stuff like AIDL then!

The service and the activity live in the same process, and run in the same jvm instance, so they have the same memory and references. If the service lifecycle is independent of the activity, then binding the service isn't even necessarily necessary! There's things like Stateflow/Shareflow, but it could honestly be as simple as calling something to add a listener, which gets a callback when something happens.

Adbot
ADBOT LOVES YOU

brand engager
Mar 23, 2011

We have a multi-process app, and recently we found out that a bunch of classes that implement Parcelable were being stored to the filesystem and in a database in the marshalled form. Don't do this, it really sucks to fix

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply