This was implemented before because the main screen of the three tab
layout needed to update in response to the list of installed apps being
installed. When we scan the list of installed apps upon starting
F-Droid, we didn't want to have to requery for the list of installed
apps every time we found a new installed app. For this reason, we
"debounced" these requests (accumulated them for 1 second, and then let
go of a notification only after 1 second of inactivity).
This is no longer a feature, and so we can afford to fire the
notification instantly.
We were jumping the gun before, and asking to refresh the app details
adapter before the installed app service was able to notify us of a
change to the apps installed version.
This should be refactored to use broadcast receivers instead of
content observers (which are tied to the implementation of a content
provider). However this is currently a straight port from app details 1
to app details 2.
On newer devices, it takes the icon, removes colour, and uses that. This
looks weird because:
* The head and body look too close together once you remove the shading
from the launcher icon.
* The eyes dissapear because they are white (not transparent) in the
launcher icon.
Prior to this, it would still show the "Ready to update" list item.
Now it updatpes the description to say "successfully installed" and
removes the "Update" button.
If you open AppDetails, initiate a download + install, and then navigate
away, it still pops open the install dialog for you. This is because it
never deregisters the broadcast receiver.
This change maintains the behaviour of always having the broadcast
receiver. This is because it is only added when the download
completes, and would require further refactoring to change that.
Instead, we listen for the receiver, but we ask if the AppDetails view
for the apk in question is actually visible to the user. If not, we
don't try to initiate the package manager.
Previously it showed the number of things which were eligible for
update. This will become less and less important the more people we can
switch over to automatic updates. However, given the privext vs unknown
sources thing, we will always have a lot of users who need to be
notified that they need to take further action to complete an install.
Prior to this, they were in whatever order they came from the metadata.
This resulted in weidrness because the repo which was updated last will
have its apps shown last. We are trying to move away from the repo
update order being important.
In the future, this sort order should take into account better
heuristics, but for now this is at least deterministic.
The database still treats repos with a _low_ number as _low_ priority.
This means it sounds weird when you say "Repo with priority 1 is the
least important", but other than that, everything works as expected now.
Technically we could recreate the query to update the repo metadata
within DBHelper, but that is difficult because it is sort of build into
the content providers. Unfortunately, we are unable to access content
providers from the DBHelper.
In the future if we are able to migrate away from content providers to a
more dumb data access layer, then we could reuse the query to update the
metadata priorities in the DBHelper. However that is a tomorrow problem.
To limit the possible oddness of having the installer package being
something different than F-Droid, only set it to priv ext on android-24
and newer, since its required there.
There is still quite a bit to figure out in the data format of the
per-package "What's New" entries, and its breaking the tests, so move
the placeholder code to the one spot where the placeholder whatsNew
entry is used.
App.getAllScreenshots() works nicely here, but its probably a temporary
measure until we figure out how to handle the various kinds of
screenshots (TV, Wear, etc).
This is based on @pserwlyo's work. The App and Apk classes currently
need just the public instance variables auto-filled by Jackson, so
everything else is considered opt-in, via @JsonProperty declarations.
This is currently only used for setLocalized(), setUsesPermission(),
and setUsesPermissionSdk23().
# Conflicts:
# app/src/test/java/org/fdroid/fdroid/updater/IndexV1UpdaterTest.java
The parser should accept additional elements to each
uses-permission entry, in case more XML attributes is added to
<uses-permission>. <uses-permission> has had two attributes
since the beginning.
Other changes to this JSON data structure are bad index-v1
format, and will cause crashes:
* Removing an element e.g. null from a uses-permission entry
would be invalid index-v1 JSON, since that structure mirrors
the uses-permission AndroidManifest.xml element, which has a
long standing fixed definition of name/maxSdkVersion. That
should crash so that fdroidserver authors know they are
generating invalid index-v1.
* setting versionCode to anything but an int is invalid index-v1
JSON, and should crash. versionCode has been defined as an
32-bit signed integer value since the beginning of Android.
* <uses-permission android:name=""> has been defined as a string
since the beginning of Android.
https://developer.android.com/guide/topics/manifest/uses-permission-element.html
repoId is used in Repo, App, and Apk instances to point to the Repo data
in the database. It does not come from the index files, but rather the
client database.
An important security protection is erroring when the index-v1.jar is
older than what is currently in the database. If the current or older
jar is allowed to be parsed, then a malicious server or
Man-In-The-Middle could replay old version of the index-v1.jar to
prevent the clients from learning about updates that fix security issues
The image loading code for the app cards was presuming that the icon
returned did indeed exist. In this case, it crashed due to trying to
decode a `null` image.
I noticed that when returning to the settings fragment (e.g. by closing
then reopening F-Droid while viewing), it will attempt to re-remove the
priviledged preference. This causes a crash, so we check to see that we
still have the preference before deciding to remove it.
index-v1 does not send empty values. The description was historically
set to "No description available" on the server side, and in
index.xml. The database then inherited this behavior, and does not
support no description. In the long run, it would be good to sync up
the database with the index-v1 metadata, but perhasp then we'd have to
add a million null guards, which wouldn't be worth it.
Tell the Jackson JSON parser to ignore App/Apk fields that should never
come from the index, but instead are set locally to keep track of the
current state of things on the device.
There are two forms of tests to enforce that the proper things get
ignored. It is not possible to do this with decorators alone, so I
chose to use @JsonIgnore and leave the variables we want filled in
undecorated. Also, all of the instance variables in Apk/App/Repo
should come directly from the index metadata so that they are pure
data classes. Currently some state info is stored in them, those are
decorated with @JsonIgnore.
The tests then include lists of accepted and ignored properties, and
anything that is not in those lists will cause the tests to fail. So
if someone is adding a new instance variable, they will get a fail
until the tests are updated. One set of tests actually writes blank
instances out as JSON since that's the easiest test to write, and
Jackson treats @JsonIgnore the same in both directions. Then there is
another test that reads a JSON file with added, unsupported values to
make sure that they are properly ignored.
Having Jackson set to ignore unknown fields in the incoming JSON data,
instead of throwing an Exception, means that we can add any fields to the
JSON without having to rev the index version, and older clients will still
parse it fine. This is basically the same as in index.xml.
This sets the App instance variables using the localized index-v1 fields.
It trys to fill as many fields as possible, falling back to locales of the
same language, then finally English.
This is based on the Jackson JSON parser's ability to map a JSON key to a
method, e.g. @JsonProperty("localized")
This adds support for parsing the new index-v1.json data as defined in
fdroidserver!221. This new index metadata format is required to
support localization, graphics, screenshots, etc.
refs #15
This adds support for the index fields: uses-permission and
uses-permission-sdk-23. For most index fields, Jackson handles directly
mapping the incoming data to the instance vars based on the matching
field/var names. For uses-permission*, methods are declared for
handling those properties in the incoming index.
These fields will be ignored when using the v0 index.xml format.
* Move the privileged extension installed check above
the check whether the apk to be installed is privext.
* This lets privext updates work when it is already installed.
* The new PackageInstaller APIs, being used by the privext on Android
7.0 and above aren't happy with uninstall being done by an app
other than the original installer.
* Set it to the privileged extension if that is enabled and being used,
to make uninstalling work
This notification is kind of weird, because the only ways it can be
dismissed is by:
* Swiping a notification away from the notification drawer.
* Closing and reopening F-Droid.
However I think the UX is still pretty nice:
* Tells the user that it worked.
* Allows them to navigate to it if desired.
In a future MR I will remove this class completely, but this just
ensures that touching a notification will not send the user to the old
AppDetails (instead sending them to AppDetails2).
Default padding specified is 12dp which is not very generous.
This reduces it to 2dp for seemingly good effect. Yet to see what it
looks like with longer translations of other languages, but time will
tell.