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).
Move logic which parses intent and forceably sets the text of our search
input to onCreate(), not onResume(). onCreate() is invoked each time a
new intent is sent to open up this activity. That is, each time a new
category is opened or a new search request is received. onResume() is
called much more often than this, including when the user is directed to
a new activity and then returns to the search screen after hitting back.
In this case we don't want to remove the search query the user had and
replace it with the data in the original intent.
Locale.getDefault() returns the default for the current JVM (or whatever
runtime Android calls it these days). By asking the configuration, we
will get the Locale that the user has selected from within the F-Droid
preferences.
Replicant is committed to follow the GNU Free System Distribution
Guidelines (FSDG)[1]. Apps with certain anti-feature flags in F-Droid
violate these guidelines and thus shouldn't be available in the
F-Droid client on Replicant[2].
Issue #564 discusses this, although only the case of having apps with
anti-features optionally filtered. To be compliant with the FSDG
guidelines, all violating apps must not be accessible and there
shouldn't be a setting to make them visible. Not all anti-features in
F-Droid violate the FSDG guidelines, so no need to filter all of them.
Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
[1] https://www.gnu.org/distros/free-system-distribution-guidelines.html
[2] https://redmine.replicant.us/issues/1629
The previous dependency extended the support library bottom nav. It did
this at the expense of lots of reflection. This is pretty brittle and
likely to break in future releases as the support lib gets updated. In
the mean time we need to have a fully working bottom nav, so this commit
includes a different dependency.
Most 3rd party bottom navigation panes look great. All that I found
require at least API 11, mostly API 14 (due to animations I suspect).
I've forked one of the most popular ones on GitHub and made it support
back down to API 10. My fork is added as a dependency until upstream
accepts the PR.
If they don't ever, then we can reconsider what our options are.
The two times I've swapped the bottom nav implementation have both been
trivial. The code generally only touches the MainActivity and its
layout.
Shows a red badge over the "Updates" menu item.
The updates badge is a bit hacky. There are indeed libraries which
implement a bottom nav which have support for badges built into
them. However they target API 14. There are also other badge
libraries which just deal with rendering, but for the cost of
another dependency, it is not particularly difficult to create a
`TextView` with a background and position it ourselves.
* Show selectable background behind "Show/Hide apps" button.
* Scroll to the relevant place in the list when showing/hiding apps.
* Only show one line (ellipsized) of the apps to update in header.
This will read downloaded .apk files from the disk cache in the background.
For each apk that corresponds to an app which can be updated, the status
manager is notified.
Alows for more flexibility in what we are able to display, including:
* Prompting users to donate to frequently updated apps
* Showing messages from package maintainers to users
* Marking apps for later installation when offline
Most of these are not yet implemented, but will be able to when
required, whereas they were not able to in the previous UI.
Doing this required tweaking our `IconDownloader` which we give to the
UIL init method in FDroidApp. It only knew how to load from HTTP, but we
needed it to fetch `drawable://` images too (which the library
supports). In addition, it has been renamed `ImageDownloader` as it also
is now used for screenshots/feature images.
This is currently needed for screenshot placeholders, but might be
useful in the future as well. Note that the default BaseImageDownloaded
supports this, as well as content:// and drawable:// protocols.
This was not updating the versions expand icon correctly when the user
clicked on it. It was working when they scrolled away and returned to
the versions list. Now it works for both.