When building APK instances from installed apps, the minSdkVersion and
maxSdkVersion needs to be parsed directly from the APK's Android Manifest,
since PackageManager does not provide a method to get it how we need it.
Previously, the whole AndroidManifest.xml file was parsed entirely twice,
once for minSdkVersion then for maxSdkVersion.
The original logic had maxSdkVersion=0 meaning infinity. That was changed
to be a very large value SDK_VERSION_MAX_VALUE, but getMinMaxSdkVersion()
was still returning 0 for APKs where maxSdkVersion was not set.
This is a follow up on fc0df0dcf4dd0d5f13de82d7cd9254b2b48cb62d
Apparently, the CREATOR field is not (yet?) needed in the tests, since
they work without it. This gets us closer to making lint errors fail
the CI builds.
closes#580
notification update improvements
Ok, I made a mistake in c35d327fa4c503425c629d49778c001b08ecb833 / !301 that messed up installing. Turns out it was a simple fix: 0838a15792fd70afde4e3743296ce88c961a299e This also removes the _Cancel_ button from the one active download notification to provide a working, albeit verbose, notification UX for 0.100.
After this commit, these commits and the ones from !301 should be included in `stable-0.100` and a new alpha tagged :)
See merge request !306
This is the recommended way to deal with updating Notifications. Each new
update should be a new Notification, but the same Builder instance should
be used to generate each new Notification instance.
New installs where being caught up in the logic to check whether a download
is still in progress after InstallManagerService got killed. Also checking
whether Intent was just redelivered lets the new installs through while
screening out the inactive Intents that were redelivered. This logic also
cancels the notification for any download that was in progress when the
InstallManagerService was killed.
#660
Check repo index timestamps
The Update Framework documents provide a [nice discussion of possible attacks](https://github.com/theupdateframework/tuf/blob/develop/SECURITY.md) against update systems. One example is a "rollback attack", where the attacker just serves the old signed `index.jar` to keep all clients from updating their apps. That allows the attacker to exploit known vulnerabilities in those un-updated apps.
While this is a reasonably hard attack, this fix is an important step towards removing the requirement for trusting the web server operator. Ultimately, it should be able trusting the index signing key only. Then it doesn't matter were the files come from, it just matters that they are verifiably signed by the index signing key.
This does not address "freeze attacks" since it allows an index update with the same timestamp. I did that deliberately to slowly ramp up the security checks in order to avoid problems along the way. Code-wise, blocking freeze-attacks is mostly a matter of changing the timestamp check from `<` to `<=`.
See merge request !302
Couple more 0.100 fixes
This is a couple more bug fixes towards finally releasing 0.100. These should be cherry-picked into `stable-0.100`.
See merge request !301
Installer instances always copy the APK to a safe place to run the install
from. That copy needs to be deleted. Until we have the whole lifecycle in
InstallManagerService, we need this hack. It should be handled on the
broadcast from InstallerService to say that its complete.
#611!300
Including the App and Apk instances in the Intent that starts
InstallManagerService ensures that the needed data is present in the
Service no matter what happens outside of the Service. For example, if the
index is updated or cleared while an install is in progress, the install
process still needs to know the name and packageName of the app to update
the Notification.
A cleaner but more labor-intensive way to implement this would be to make
App and Apk properly implement the full Parcelable interface. That would
require tests to check that the Parcelable methods have all the same fields
as toContentValues() and the database.
closes#660https://gitlab.com/fdroid/fdroidclient/issues/660
A hacked fdroid server could "replay" old index.jar files known to have
apps with vulnerabilities in it. That provides a long window of time for
exploiting that vulnerability. By checking that the timestamp of an update
is never older than the current index, this attack is prevented.
Its officially possible to have the ROM's filesystem with any name. While I
have never seen that in practice, Android does provide an easy method to
get the real name. Plus this should help avoid typos and the like, and
make it easy to track things that rely on that filesystem path.
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
For some odd reason, something is sending a URL to be downloaded that then
results in a null Apk instance. My first guess was because it was being
canceled, but the interrupted receiver is not even registered yet. My
second thought is that something is sending a download and cancel Intent at
the same time. In any case, its something to keep in mind when reworking
InstallManagerService once InstallerService comes along.
closes#660https://gitlab.com/fdroid/fdroidclient/issues/660
The App(Context context, PackageManager pm, String packageName) constructor
was not setting App.icon, which is required for lots of things. This makes
it always get set, since its just a standard file name, and it does not
have to even exist yet.
When reworking this in 7f10be18c6dd0b69e2fdbae98d09b197e60af443, I confused
the "Processing" with the "Downloading", probably because I thought those
steps were combined, but they are not. Also, I forgot that Downloader
instances do not broadcast status. So its just a matter of setting up the
right ProgressListeners.
https://gitlab.com/fdroid/fdroidclient/issues/633
Since Intents can come in any time, whether WifiInfoThread is running or
not, the global static vars for storing the WiFi settings info should only
be updated from the WifiInfoThread. Otherwise, the WiFi settings could be
nulled out between the time of the null guard and the execution in code
like this:
if (!TextUtils.isEmpty(FDroidApp.ipAddressString) && netmask != null) {
FDroidApp.subnetInfo = new SubnetUtils(FDroidApp.ipAddressString, netmask).getInfo();
fixes#589https://gitlab.com/fdroid/fdroidclient/issues/589
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalArgumentException: Could not parse [null/24]
at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:275)
at org.apache.commons.net.util.SubnetUtils.<init>(SubnetUtils.java:62)
at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:89)
at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:70)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more
java.lang.IllegalArgumentException: Could not parse [null/24]
at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:275)
at org.apache.commons.net.util.SubnetUtils.<init>(SubnetUtils.java:62)
at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:89)
at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:70)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Correctly expand list of nearby people to the entire height of the screen.
NOTE: To be cherry-picked into stable-v0.100
If the device is small, then the "Conenct and trade apps with people
near you" header takes up too much space and we end up not being able
to see any nearby people at all, even if they are in the list. As
such, this also removes that header for "small" and "ldpi"
devices. During testing I found that "small" was not enough, because a
240x400 screen is considered "medium" and there is not enough
space. ldpi seems to be a reasonable metric for "that header is going
to be taking valuable space and should not be shown then".
All larger devices retain the header and seem to look nice.
This also pushes the "Can't find what you're looking for?" message and
associated buttons right to the bottom of the screen. This is more in
line with the original design.
Fixes#604.
Screenshots
No good
The image below shows a 240x400 device. This falls into the "medium"
screen size, and so would include the header if I only used
"layout-small". As such, I also removed the header for
"layout-ldpi". It doesn't look absolutely terrible, but remember that
this is an emulator without Bluetooth, and as such it is missing a UI
element for enablign Bluetooth which would take up the remaining real
estate:
emu-240x400
Good
Large devices work well now, with all of the empty space below
available for the "Nearby Devices":
large_device
Also, small devices should exclude the header and provide just enough
space for the list of pears (as shon by this 240x320 device):
emu-240x320dp
Here is a more normal sized phone (my Moto X 2nd gen with normal DPI
settings):
moto_x_2nd_gen__largish_
closes!291
See merge request !291
If the device is small, then the "Conenct and trade apps with people near you"
header takes up too much space and we end up not being able to see any nearby
people at all, even if they are in the list. As such, this also removes that
header for "small" and "ldpi" devices. During testing I found that "small" was
not enough, because a 240x400 screen is considered "medium" and there is not
enough space. ldpi seems to be a reasonable metric for "that header is going to
be taking valuable space and should not be shown then".
All larger devices retain the header and seem to look nice.
This also pushes the "Can't find what you're looking for?" message and associated
buttons right to the bottom of the screen. This is more in line with the original
design.
Fixes#604.
CI: Add android-10 connectedCheck task
GitLab doesn't currently support any kind of build or env matrix, so we
have to duplicate this code. This is due to change in upcoming releases,
at which point I'll fix this.
See merge request !293
Ensure `FLAG_AUTO_REQUERY` is used for main app list adapters.
**NOTE: This has a sister MR which is targeting the `stable-v0.100` and thus should *not* be cherry-picked across to that branch.**
Although this is deprecated, and will result in queries being run on the main thread, it is required to fix#606. In the future, `LoaderManagers` should be used to address the concerns of querying on the main thread.
See merge request !294
Although this is deprecated, and will result in queries being run on the
main thread, it is required to fix#606. In the future, `LoaderManagers`
should be used to address the concerns of querying on the main thread.
GitLab doesn't currently support any kind of build or env matrix, so we
have to duplicate this code. This is due to change in upcoming releases,
at which point I'll fix this.
Don't allow download notifications to be cancelled, other than our "Cancel" action on them.
*NOTE: To be cherry-picked into stable-v0.100*
As a user, I expect removing a notification of a pending action to cancel that pending action. This change makes the pending notifications uncancellable, unless users use our cancel action added to the events by @paresh. If the user is on an older device that doesn't support these type of rich notifications, then they will need to touch the pending download notification, which will take them to the `AppDetails` activity for that app. From there, they can cancel the install, which will remove the app from the pending download queue.
Until the notifications are reworked, this is the simplest solution. In the near future, the notifications will likely be combined into one more intelligent notification with better defined semantics.
See merge request !292
Until the notifications are reworked, this is the simplest solution.
In the near future, the notifications will likely be combined into one
more intelligent notification with better defined semantics.
Installer manager cosmetic changes
This branch as some cosmetic code changes related to the `InstallManagerService`. I have a few more that I'll be throwing in here too as I go along. By and large, it is renaming, annotating, minor refactoring. The semantics should not change at all with this change, any fixes to the `InstallManagerService` will be done through separate MRs. They are from issues listed in [this comment](https://gitlab.com/fdroid/fdroidclient/merge_requests/278#note_11762414) during my CR and testing of !278.
I realise that cosmetic changes often come with baggage because we all have slightly different ideas of what Java code should look like, but in general, I will strive to only make changes if I believe strongly that they will:
* Improve understanding of the code (i.e. renaming, extracting methods)
* Prevent future errors by new contributors (e.g. @NonNull/@Nullable annotations, extracting classes to encapsulate logic which requires developers to know they need to change multiple things at once)
I try not to make changes because:
* I have a different opinion about formatting.
* Hopefully any other unreasonable or disagreeable reason.
See merge request !282
Type parameters can be ommited if defined and declared in same statement.
`onStart()` is deprecated and not required, as we target APIs > 5.
`Intent.FLAG_ACTIVITY_CLEAR_TASK` is not supported on APIs < 11 but we target 8.
WifiStateChangeService fixes
`WifiStateChangeService` had a number of issues, including being run often when there was no change, and being run twice at start-up. Also, its _complete_ broadcast was being sent twice, in effect. That made for a lot of flaky behavior for the things that rely on that information, namely wifi swap.
See merge request !289
Before, it would change fields in a final Repo instance, which means that
things could be out of sync when accessed. Now it swaps out the old one
with a new Repo instance in one step.
The local repo variables are now declared volatile so that they are more
predictable when accessed from various threads (WifiStateChangeService,
SwapService, etc.)
askServerToSwapWithUs(NewRepoConfig) was unused, so I removed it.
The IntentService provides the nice incoming Intent queue. It also runs
the Intent in a thread, so even the initial check is now in a very low
priority thread. The queuing prevents the incoming Intents from competing.
This also simplifies the code since the lifecycle is more automatic now.
The `android:process` statement in AndroidManifest.xml causes another
process to be created to run CrashReportActivity. This was causing lots of
things to be started/run twice including CleanCacheService and
WifiStateChangeService.