This implements the APK Extension Files spec for finding, downloading, and
installing OBB files that are extension packs for APKs.
This needs WRITE_EXTERNAL_STORAGE since "installing" OBB files is just
copying them to a specific path on the external storage.
https://developer.android.com/google/play/expansion-files.html
By sending an Intent to F-Droid, it will reply with the full download URL
to the OBB file, if one exists for the currently installed version of the
requesting app.
This allows a designated app to read the install history from F-Droid via a
ContentProvider. The app is designated by the packageName defined in the
string install_history_reader_packageName.
The install and uninstall history has lots of uses, including displaying
to the user in the app itself, reporting to the Device Administrator to
enable tracking of installs/uninstalls from the admin's app repo, etc. It
can also be used as part of a "popularity contest" #396
* moves apk verification back inside the Installer class
* uses support libs FileProvider for content Uris
* move apk file caching and storage methods into
ApkCache class
InstalledAppCacheUpdater was a custom Service-like thing with some
threading issues. InstalledAppProviderService is an IntentService that
relies on the built-in queue and threading of the IntentService to make
sure that things are processed nicely in the background and one at a time.
This changes the announcing so that each app added/changed/deleted triggers
a new annoucement. This keeps the UI more updated, and makes the Installed
tab show something as soon as possible, rather than waiting for the all of
the install apps to be processed. This becomes more important as more
stuff is added to InstalledAppProvider, like the hash of the APK.
This also strips down and simplifies the related BroadcastReceivers.
BroadcastReceivers work on the UI thread, so they should do as little work
as possible. PackageManagerReceiver just rebadges the incoming Intent and
sends it off to InstalledAppProviderService for processing.
Since it takes a chunk of time to generate and write the app index.jar when
swapping apps, this service starts running in the background immediately
when SwapService starts. It first indexes the installed apps that were not
cached, then caches apps based PACKAGE_ADDED broadcasts. It does not index
system apps, since there are many and they are rarely swapped.
This makes it easy to tell which debug build a device is running, since the
versionName now automatically describes the exact commit that was built,
based on `git describe`, e.g.: 0.100-alpha7-33-gc2e8e8a
For release builds, i.e. builds from commits that are tagged as releases,
the versionName will be just the tag name: 0.100-alpha8
closes#664https://gitlab.com/fdroid/fdroidclient/issues/664
DownloaderService is structured to be as simple as possible, and as tightly
matched to the downloading lifecycle as possible, with a single queue for
all requests to avoid downloads competing for bandwidth. This does not
represent the possibilities of the whole install process. For example,
downloading can happen in parallel with checking the cache, and if an APK
is fully cached, there is no need for it to go through the DownloaderService
queue.
This also lays the groundwork towards simplifying DownloaderService even
more, by moving the Notification handling to InstallManagerService. That
will provide a single place to manage all aspects of the Notifications that
has a lifecycle that is longer than the Notifications, unlike an Activity
or DownloaderService.
Having the notification as its own Service is overkill and really only
serves to increase complexity. The notification stuff should not take much
time or resources at all.
This moves the cache file deletion to a dedicated IntentService that runs
at the lowest possible priority. The cache cleanup does not need to happen
with any kind of priority, so it shouldn't delay the app start or take any
resources away from foreground processes.
This also changes the logic around the "Cache packages" preference. The
downloader always saves APKs, then if "Cache packages" is disabled, those
APKs are deleted when they are older than an hour.
This also simplifies Utils.deleteFiles() since the endswith arg is no
longer needed.
Fixes for priv extension install
For now, disable install of privileged extension on Android >=5.1 until we found better methods.
Also, fix crash of dialogs on Android 6 using a workaround for transparent activities and some code simplifications.
See merge request !259
DownloaderService is based on IntentService to provide queued requests that
run in a background thread via the Handler and the HandlerThread. It began
as the IntentService code, but it could not be a subclass because the
downloading needs to be cancelable. IntentServices cannot be canceled and
they provide no visibility into their queue.
DownloaderService then announces relevant events via LocalBroadcastManager
and Intents with custom "action" Strings.
https://gitlab.com/fdroid/fdroidclient/issues/601#601
Unfortunately, this approach did not really work out. It would have been
really nice to rely on the provided DownloadManager stuff, but it has too
many issues, like not working with Tor or other proxies, and being
difficult to tightly integrate.
This makes it a lot easier to setup all the testing stuff. Mostly,
I'm tired of fighting Android Studio's fragility, so I want to remove
as much non-standardness as possible in the hopes of improving that
situation.
closes#534https://gitlab.com/fdroid/fdroidclient/issues/534