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

Auto update on android 12 #20

Closed
Donkey-Doug opened this issue Oct 9, 2021 · 19 comments
Closed

Auto update on android 12 #20

Donkey-Doug opened this issue Oct 9, 2021 · 19 comments

Comments

@Donkey-Doug
Copy link

Google has updated Android’s PackageInstaller.SessionParams class with a new method called setRequireUserAction. This method indicates whether or not user action should be required before an app install is allowed. It defaults to true for any app that holds the REQUEST_INSTALL_PACKAGES permission, which is required for any app before they can initiate an install session to sideload an app outside of Google Play or whatever preinstalled app store is on the device.

Before you can sideload an app on Android, you have to grant the install unknown apps permission. Anytime you want to update an app from a source other than Google Play, you have to manually tap “update” on this prompt.

However, user action won’t be required for an app install/update if all of the following conditions are met:

  • The installer opts into the new behavior.
  • The app that’s being installed targets API level 29 (Android 10) or higher. (Google notes that the target API level requirement will advance in future Android versions, a policy that’s in line with Google Play policy on API target requirement.)
  • The installer is either updating itself or installing an update to an app it first installed.
  • The installer declares the UPDATE_PACKAGES_WITHOUT_USER_ACTION permission.
@Iamlooker
Copy link
Contributor

Thats very helpful.
Thanks for bringing this into my light, I did not find this anywhere.
It would be very helpful if you can send the Official Docs or source link to this data

@Donkey-Doug
Copy link
Author

Could not find enough info. Perhaps because android 12 is not officially released yet. Here is a little bit of info:

https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequireUserAction(boolean)

@dznsm
Copy link

dznsm commented Nov 1, 2021

This feature would be really nice to have.
Theres limited official documentation about it https://developer.android.com/about/versions/12/features#automatic-app-updates

I was thinking no other f-droid client, or other app store, had implemented this yet and was doing some research when a web search turned up this ffupdater issue Tobi823/ffupdater#88

I tested it and found that they are well on their way to fully automated browser updates- just need to tap on a button in a notification that an update is available, but I think likely not too difficult to change to fully automatic.

Something i noticed is that apps installed via ffupdater have it listed as their Installer App when looking at the bottom of the app info page in
https://github.com/MuntashirAkon/AppManager/
Apps installed using other app store apps (Aurora Store, F-Droid, Foxy Droid etc.) all list 'package installer' as their Installer App

Actually the app info page in Android Settings shows the correct installer app.

@Donkey-Doug
Copy link
Author

Donkey-Doug commented Nov 20, 2021

By the way, my preferred implementation is if my apps get updated automatically and I get a notofication after the updates are completed saying "VLC got updated. See changelog" or something.

@maximbaz
Copy link

I'm not sure if I'm doing something wrong, but I still simply get a notification with available updates, the apps don't get auto updated... Does it work for any of you?

@shibattor
Copy link

Same here, I only got a notification.

@machiav3lli machiav3lli reopened this Dec 17, 2021
@Donkey-Doug
Copy link
Author

Are you on android 12?

@machiav3lli
Copy link
Member

@shibattor @maximbaz for now there's only the traditional manual installation or automated root installation. I guess you both don't have root and using the manual. For future releases we'd consider changing this.

@shibattor
Copy link

Are you on android 12?

Yes, I have not-rooted Android 12.
Automatic updates (for devices without root) would be much appreciated.

@dznsm
Copy link

dznsm commented Dec 29, 2021

Droidify is closer to providing unattended app updates for me.
The new Android 12 feature allows an app with a targetSDK of 29 or later, to be updated without popping up the system UI window for the user to confirm the update.

This does happen if i keep droidify in the foreground after tapping on the button in droidify to start downloading the update. No other user interaction is required. As expected this does require 'app installed from Droidify' to be listed under 'Store' in the app info page in system settings. You get to this position if droidify was the last 'store' app to provide an update to the app, or if it installed the app- if the app has not been updated since.

The desired behaviour would be for any app where it is possible (SDK29+ and previously updated by droidify), to have their updates downloaded and applied, without any user interaction, as soon as Droidify notices that an update is available for them. Then for Droidify to post a notification that the app had been successfully updated. It would be amazing for this to all work. I am not aware of any app store that can do this yet using the new Android 12 feature. I am impressed with your work moving towards this @mcrossman 🤩

I also see a regression, in some (not always) situations which are currently not completely clear to me, which I think may be somewhat related to this. If I dont keep droidify in the foreground while it is downloading an update, i get a notification that the update is ready, but if I tap on that nothing happens. Going back to droidify I have to download the update again.

For anyone that Is interested to observe this I find Fairemail from the Izzyondroid repo useful as it gets updated with amazing regularity.

@mcrossman
Copy link
Contributor

mcrossman commented Dec 29, 2021

A really small app you can reinstall fairly quickly is a good test case. A recently updated example would be SaveTo.... Install an earlier version, hit update, then escape to someplace else to reproduce this issue.

The behaviour I've been observing while using Droidify has been that auto-updates are only triggered within the app info page where you started the download. Another issue is that the intent to open MainActivity doesn't seem to work - tapping the notification should be opening Droidify. I'll continue to look into it further.

@mcrossman
Copy link
Contributor

mcrossman commented Dec 30, 2021

Current progress (not published since I need to properly merge it with new database commits that were causing crashes):

  • Fixed the install notification by replacing the broadcast receiver in DownloadService with the more direct use of startActivity (receiver seems unable to start an activity)
  • I moved install notifications to InstallerService since that's where we determine whether we need user action to proceed
    • Currently using MainActivity to extract and start the package manager intent that was originally given to InstallerService, but I'm working on making MainActivity invoke InstallerService to stop the UI from freezing.
    • On Android 9 and earlier, you'll get an installer prompt rather than a notification (potentially many prompts, spaced out over time). Android 10+ blocks background activity launching so you'll need to tap a notification to proceed.
  • If an update requires no user action, it proceeds silently then provides an "installed" notification on completion
    • Still have to look into what happens with an app that takes a really long time to update after downloading completes.

The desired behaviour would be for any app where it is possible (SDK29+ and previously updated by droidify), to have their updates downloaded and applied, without any user interaction, as soon as Droidify notices that an update is available for them. Then for Droidify to post a notification that the app had been successfully updated. It would be amazing for this to all work. I am not aware of any app store that can do this yet using the new Android 12 feature.

That's certainly doable if we chain updates to the end of a repo sync. I believe that subsequent updates in a batch wait for the first one to download, so you would see a stack of pending downloads then a stack of "installed" once they're all done.

This should also have a preference in settings. Maybe enabled by default on Android 12+.

For implementation, we can try and run startUpdate in some intermediary function between handleNextTask and displayUpdateNotification. We skip to notifications depending on your preferences.

@machiav3lli
Copy link
Member

@mcrossman thanks for your work. On the DBS migration topic:

  • I would suggest that you use the git-tree before the merge (and maybe cherry-picking the commits afterwards) as this migration is a part of a huge rewrite that will takes sometime but I can assure you to not touch the installer classes for that.

  • All classes with the -x suffix will replace their older ones (fragments and activities). But you shouldn't have to worry about this I'll re-apply your fixes on the new classes (specially MainActivity(X)) after merging your PR.

@mcrossman
Copy link
Contributor

Got auto-update working after repo sync in #159. It seems to work well from my testing. Updates will trigger after repo sync completes. If the repos are already up to date, any pending updates will be installed anyway (sort of like an update all button).

It's set up enabled by default on Android 12+. There's a toggle for it in settings, though it's important to note that since it can run after manual syncs, it operates independently of the auto sync setting above it.

On Android 9 and earlier, you'll get an installer prompt rather than a notification (potentially many prompts, spaced out over time). Android 10+ blocks background activity launching so you'll need to tap a notification to proceed.

I've reverted this. I don't trust that background activity starts are going to be reliable in any way. If you want it back it's a pretty simple change to make:

if (Utils.inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
// to this
if ((!Android.sdk(29) || Utils.inForeground()) && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {

I've run into and caught some strange fringe cases in DefaultInstaller. These exceptions get logged as warnings and while I'm fairly certain I've caught all of the possible crashes, you might still run into yet another edge case.

@Offerel
Copy link

Offerel commented Jan 25, 2022

Do i need root privileges to make auto-update working or is this also working, when installing the apk the standard way?

@machiav3lli
Copy link
Member

@Offerel auto-update without root works only for A12 and for the apps installed by Droid-ify at the first place (restriction of Android)

@Offerel
Copy link

Offerel commented Jan 26, 2022

Ok, since I'm having A12 installed, i have to re-install all application, i have installed previously with standard f-drod client now again with Droid-ify?

Then i will do so... many thx.

@dznsm
Copy link

dznsm commented Jan 29, 2022

@Offerel you don't need to install them with droidify, just have to update them once with it, where you'll have to manually confirm the update. After that they should update without any user interaction

Note however that there hasn't been a release since this feature was implemented, so it will not work until the next release.

I've been hopefully watching out for a Droid-ify update for a few weeks now.

@machiav3lli
Copy link
Member

@dznsm we have already announced that we're working on a deep re-writing & re-design of the app and therefore it'll be a while till we do a stable release.

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

8 participants