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
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. This was introduced in 5f3dde4060f5d472c
#660
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
After much consternation and testing, it became apparant that there
was nothing really wrong with our PendingIntent setup or notification
setup. The only problem was the rapidness with which the notification
was being updated. There is something about rapidly updated notificaitons
which makes it not possible to hit the action button. This explains why
the button _would indeed work sometimes_, because the user may have hit
it just in that sweet spot.
This change increases the time between progress events from 100ms to 500ms
which seems to do the job on my Moto X 2nd gen. Perhaps this can be changed
to a larger number if required. When it was set to 300 ms, it _mostly_ worked,
but there was still a few times where hitting the button wouldn't work at all.
Fixes#652.
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.
#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)
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.
!291https://gitlab.com/fdroid/fdroidclient/merge_requests/291
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.
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.
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.
Lint says that only GET_META_DATA and GET_SHARED_LIBRARY_FILES are allowed.
This contradicts Android's documentation where GET_UNINSTALLED_PACKAGES
is also allowed.
Fixes#605
This was crashing when coming to SwapAppsView because some of the flow
changed related to the new DownloaderService and InstallManagerService.
Also, this lazy loading is a tiny optimization that we cannot afford right
now, there are far too many lifecycle bugs with swap.
This should fix the PMD error:
"Check the value returned by the skip() method of an InputStream to see if
the requested number of bytes has been skipped."
The check was set up to only cancel when the `AppDetails` for that app
was shown. This is the correct behaviour for the 'complete' event, but
not the cancel. The cancel event should always result in the relevant
notification being removed.
If we are capable of bailing earlier rather than later, then we should. This way,
if a hash doesn't match, the file will be removed and a new download will begin,
as expected. The alternative is to let the installer catch the unmatching hashes.
By then though, it is too late to really do anything meaningfull and it becomes
more difficult to recover in a way that the user would expect.
Due to the earlier refactoring of `getNotificationTitle()` (or something like that)
to `getAppName()`, it was still returning `getString(downloading_apk, appName)` instead
of just the app name.
I wrestled with this a bunch, it seems quite difficult to make the Cancel
button on the notification responsive. This collection of minor changes
made it more reliable, but its still kind of flaky. I think the problem
might be related to the fact that it is creating a whole new Notification
instance, with the accompanying Intent and PendingIntent instances, for
every single download progress update.
closes#652https://gitlab.com/fdroid/fdroidclient/issues/652
If an APK was queued to download but had not started downloading yet, it
was not able to be fully canceled because ACTION_INTERRUPTED was not sent.
That meant that the UI never got updated, even though the APK was removed
from the queue.
#652https://gitlab.com/fdroid/fdroidclient/issues/652