3601 Commits

Author SHA1 Message Date
Peter Serwylo
9680ba1694 Merge branch 'enable-pmd-java-basic' into 'master'
Enable PMD java-basic

This is the fixes necessary to enable PMD's `java-basic` ruleset.  I think there will be a few rules in there that will largely be annoying, so we'll need to ultimately decide whether to use `// NOPMD` or just specify the rules we want from `java-basic`.

See merge request !280
2016-05-12 08:32:24 +00:00
Hans-Christoph Steiner
7fbdfaaae7 enable PMD's java-basic ruleset
* CollapsibleIfStatements is pedantic
* that one NOPMD is for debug logging, it'll go away

closes #623 https://gitlab.com/fdroid/fdroidclient/issues/623
2016-05-12 09:36:08 +02:00
Hans-Christoph Steiner
93433cff05 equals() and hashCode() should always be overridden together
This addressed the PMD error:
"Ensure you override both equals() and hashCode()"

#623 https://gitlab.com/fdroid/fdroidclient/issues/623
2016-05-12 09:25:04 +02:00
Hans-Christoph Steiner
23dad31426 make AndroidXMLDecompress a little less kludgey
#623 https://gitlab.com/fdroid/fdroidclient/issues/623
2016-05-12 09:25:04 +02:00
Hans-Christoph Steiner
103b2265ee make sure HTTP servers are able to skip the right amount
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."
2016-05-12 09:25:04 +02:00
Hans-Christoph Steiner
a0c20a35c3 Merge branch 'installer-manager-fixes' into 'master'
Installer manager fixes

Builds on the recently merged `InstallManagerService` to fix a few minor UX bugs:
 * Cancellation of pending downloads now removes notifications.
 * No longer shows "Downloading Downloading {AppName}" in notification, just "Downloading {AppName}"
 * If cached file is same size but corrupted, remove it and then continue with the process of downloading + installing

See merge request !281
2016-05-12 07:22:35 +00:00
Peter Serwylo
0967b79763 Remove notification correctly upon cancellation of download.
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.
2016-05-12 16:54:14 +10:00
Peter Serwylo
5c4d23d2d6 Do full verification of apk before talking to installer.
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.
2016-05-12 16:54:14 +10:00
Peter Serwylo
63807a688d Return app name correctly from getAppName().
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.
2016-05-12 16:54:14 +10:00
Peter Serwylo
7389315dfa Merge branch 'InstallManagerService' into 'master'
InstallManagerService

This provides an over-arching `Service` for managing the whole install process, from checking the cache, downloading files, handling the notification.  Ultimately, it should probably also handle starting and tracking progress of the final installation steps.

Note: this does undo some of the `Notification` handling stuff, putting it back to one notification per APK. I did that to get that part working OK for the short term, giving us time to figure out what the whole picture should look like.  I think @pserwylo has it pretty well sketched out in #592.  But I have no strong feelings about the notification stuff for 0.100, so I'm happy to shape this MR accordingly, provided its only a little work.


See merge request !278
2016-05-12 06:52:54 +00:00
Hans-Christoph Steiner
43be8f3fd1 delete temp files created by DownloaderFactory#create(Context, String) 2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
81f13279fe some tricks to get Cancel working on the download Notification
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 #652 https://gitlab.com/fdroid/fdroidclient/issues/652
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
62295b72b4 send ACTION_INTERRUPTED when APK is canceled from queue
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.

#652 https://gitlab.com/fdroid/fdroidclient/issues/652
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
78c0416c84 clear notification for app once it has been successfully installed
This logic is pretty basic for now, it'll have to be expanded a lot to
support the different UX between priv and non-priv installs.  For example,
priv updates will be able to happen entirely in the background.  Those will
then require leaving a notification to tell the user that the app was
updated so nothing can transparently install updates without the user
knowing.  When the user is an active part of each install, like the
non-priv experience requires, then keeping the "app installed" notification
feels like just extra noise.
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
e75143530f track AppDetails visibility to improve Notification UX
If AppDetails is visible, then it'll automatically launch the install
process, and there is no need to put up a "Tap to install" notification.

And of course, whenever I search stackoverflow, I find an answer from
@commonsguy :)
https://stackoverflow.com/questions/18038399/how-to-check-if-activity-is-in-foreground-or-in-visible-background/18469643#18469643
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
2080d77e6b temporary notification user experience to get something workable
this represents the current state of things until we can overhaul the whole
notifications and update UX as outlined in #592

https://gitlab.com/fdroid/fdroidclient/issues/592
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
4a9ed54f42 use simplified ProgressListener in Downloader and DownloaderService
Now the simplified ProgressListener works as the generic listener again,
enforcing the concept of URL as unique ID throughout the code base.
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
7f10be18c6 fix index update progress using simplified ProgressListener
The Event class is no longer needed once there is specific ProgressListener
instances for each type of progress update.  The sourceUrl serves as the
unique ID, like with DownloaderService and InstallManagerService.

fixes #633 https://gitlab.com/fdroid/fdroidclient/issues/633
2016-05-11 21:56:00 +02:00
Hans-Christoph Steiner
96c36d85c4 keep App instances for each active APK in the install process
This allows the install process to have consistent data, even if the index
database changes while an APK is making its way through this process.

This also provides a set of packageNames to be easily queried.
2016-05-11 15:11:05 +02:00
Hans-Christoph Steiner
f195c34a8b make Apk the common internal data type
Standardizing on Apk as the internal data type means that most of the data
that is needed for the whole lifecycle of a given APK going through this
process will be available regardless of the database changes.  Once App
instances are also included, then all of the data should be available
separately from the database.  This is important to support parallel
operation.  The index could be updated and an app could disappear while an
APK of that app is being downloaded.  In that case, it should not show
blank notifications.

Also, in AppDetail, the Apk instance is completely loaded from the db, so
there should not be any nulls on the essential bits like packageName and
download URL.
2016-05-11 15:11:05 +02:00
Hans-Christoph Steiner
dded004321 use standard URL ID int for Intents used in Notifications
This keeps the IDs standard throughout the code: either urlString when it
should be a String, or urlString.hashCode() when it should be an int. It
also follows the naming convention in DownloaderService helper methods,
e.g. getIntentFilter().  "create" to me doesn't necessarily mean also "get"

Using @NonNull or @Nullable is fine when it is actually useful, like the
compiler can catch errors, but it also adds a lot of noise when reading the
code.  For example, @NonNull here will just make people avoid thinking.
Context can never be null anywhere in Android, that's a given throughout
the Android API.  And in this code, urlString is the unique ID used
throughout the process, so if its ever null, nothing works.
2016-05-11 15:11:05 +02:00
Hans-Christoph Steiner
08988f2369 move all downloading notifications to InstallManagerService
This keeps DownloaderService tightly focused on downloading, and makes it a
lot easier to manage Notifications since InstallManagerService's lifecycle
lasts as long as the Notifications, unlike DownloaderService.
2016-05-11 15:11:05 +02:00
Hans-Christoph Steiner
67e66a7b0c InstallManagerService skeleton which checks cache before installing
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.
2016-05-11 15:11:05 +02:00
Peter Serwylo
37ba565f5b Make logging more informative.
Before it said:

>  "doDownload for http://... false"

Now it says:

> "Starting download for http://... (is resumable: false)"
2016-05-11 13:49:07 +02:00
Peter Serwylo
2c7033e367 Ask for active downloading url in on resume.
Fixes #624.

The `AppDetails` activity was not correctly asking for the active
download url string when being resumed. This change recalculates the
value when being resumed now.
2016-05-11 13:49:07 +02:00
Peter Serwylo
3a1fcfd226 Move Utils#getApkUrl(String repoAddress, Apk apk) to Apk#getUrl()
Added assertions that both apkName and repoAddress need to be populated
in order to call `getUrl()`. Also verified that this is the case for all
usages of this method, which it should be. All `Apk` objects which currently
have `getUrl()` called on them are loaded using the `ApkProvider.Helper.findById()`
method without specifying which columns to load (which defaults to all).
2016-05-11 13:49:07 +02:00
Peter Serwylo
e72ba25fe5 Call stopService to ensure notification goes away. Always show download notifications.
Addresses a bug found in MR !273 whereby removing `stopForeground` results
in a persistent "Downloading ..." notification even though it was cancelled.

In the process of doing this, it also addresses / Fixes #621 by ensuring
that all downloads of apks are done in a foreground service, regardless
of the preference used for foreground updater service updating.
2016-05-11 13:18:18 +02:00
Peter Serwylo
169346ce76 Merge branch 'downloaderservice-fixes' into 'master'
DownloaderService fixes

This aims to simplify the `DownloaderService` a bunch to make it easier to understand.  It also fixes some bugs with the download queue and related progress reports.

This is groundwork for the upcoming `InstallManagerService` which will manage the whole process of installing an app, from checking the cache, to downloading, to running the install process.

See merge request !273
2016-05-10 21:00:54 +00:00
Hans-Christoph Steiner
c66b6c52b7 fix bug with enabling NetCipher on the wrong domains breaks SNI
I messed this up in f2621dcb558b12a4430b6301b4af4a824d57eb6d

fixes #629 https://gitlab.com/fdroid/fdroidclient/issues/629
2016-05-10 16:14:49 +02:00
Hans-Christoph Steiner
d73dac73ad delete DownloaderServiceTest stub, it is now crashing
DownloaderServiceTest is just a stub of a test that doesn't really test
anything yet.  It is now causing a NullPointerException, so its a problem:

 java.lang.NullPointerException
 	at org.fdroid.fdroid.net.DownloaderService.notifyDownloadComplete(DownloaderService.java:313)
 	at org.fdroid.fdroid.net.DownloaderService.handleIntent(DownloaderService.java:287)
 	at org.fdroid.fdroid.net.DownloaderService$ServiceHandler.handleMessage(DownloaderService.java:104)
 	at android.os.Handler.dispatchMessage(Handler.java:99)
 	at android.os.Looper.loop(Looper.java:137)
 	at android.os.HandlerThread.run(HandlerThread.java:60)
2016-05-10 15:38:27 +02:00
Hans-Christoph Steiner
0214e9e447 remove pointless method: DownloaderService.getPackageNameFromIntent()
This method provides the exact same results as the underlying method it
uses, intent.getStringExtra()

This was added in 0163d6efa6013181c2e6554760e5fa6e67a6daf9
2016-05-10 15:38:27 +02:00
Hans-Christoph Steiner
44b703a7d2 replace QUEUE_WHATS hack with urlString.hashCode() as ID
There is already a method for reproducibly generating an int based on
a the contents of a String, thanks to @pserwylo for finding it! So
urlString.hashCode() is used as the ID for Notifications and the
DownloaderService queue (msg.what).  This entirely replaces the
QUEUE_WHATS hack.  Both requestCode and msg.what just need to be
unique int, and that value can always be generated by the urlString.

This also fixes a bug preventing removing correct URL from Downloader queue.
b66810944fec802aa119c0e5ec8b7875930a2c22 made a change that breaks removing
the correct item from the queue. The `what` value must be fetched based on
urlString and fed to serviceHandler.removeMessages(what). The commit made
it use the `what` value from the last item that was queued. Those will
often be different things.

This also removes all stopForeground(true) calls except for the one in
onDestroy().  The nature of an IntentService, which DownloaderService
is basically a copy of, is to quit running once it is no longer
processing Intents.  That is also the time to remove the notification.
2016-05-10 15:38:27 +02:00
Hans-Christoph Steiner
18b3a05806 always cancel APK download progress reports
Before, these were not being reliably canceled before the final COMPLETE or
INTERRUPTED notification went out.  This moves closing the progress Timer
to a finally block after the Timer is setup, which should hopefully
guarantee the progress reports are always stopped.

This prevents any more progress reports from being sent, in case there is
one pending anywhere. downloaderProgressListener needs to be volatile to
ensure that the two threads are seeing the same values.

This was an omission on my part when putting together the DownloaderService
in !248
2016-05-10 15:38:27 +02:00
Hans-Christoph Steiner
3ee64b1bc0 fold DownloadCompleteService into 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.
2016-05-10 15:38:27 +02:00
Daniel Martí
ac151716c9 Merge branch 'latest-android-testing-support' into 'master'
use latest android testing support setup

With 2.0 of Android Studio and gradle pluging coming out shortly, I wanted to start trying to use the improved testing setup.  So this is a place to track that stuff until it stabilizes.

See merge request !252
2016-05-10 13:31:31 +00:00
Hans-Christoph Steiner
cff807e191 include useful output logs for failing tests
This helps when tests fail on the gitlab-ci builds.
2016-05-10 14:34:15 +02:00
Hans-Christoph Steiner
d6ed2a5e8a simplify downloadUninterruptedTests to improve reliability
Test downloads with actual files, not dynamically generated things.

Testing with the progress reports is really hard with multiple URLs, so
just test progress with a single URL for now, and multiple URLs can still
be tested without the progress check.

fixes #650 https://gitlab.com/fdroid/fdroidclient/issues/650
2016-05-09 20:00:28 +02:00
Hans-Christoph Steiner
00c6db81a7 gitlab-ci: add missing semi-colon in failure script
It was echoing 'cat "$log" instead of cat'ing the log.
2016-05-09 20:00:27 +02:00
Hans-Christoph Steiner
3112ba75c9 gitlab-ci: improve caching of gradle stuff 2016-05-09 20:00:27 +02:00
Hans-Christoph Steiner
d8c87c3d4b gitlab-ci: switch glibc to a memory conserving mode 2016-05-09 20:00:27 +02:00
Hans-Christoph Steiner
a4161aeb73 gitlab-ci: run adb shell input keyevent 82 in the background
This is the common pattern I've seen in travis-ci builds.  It should
speed things up a little bit since the adb connection process will
happen in parallel with waiting for the screen lock to be dismissed.
2016-05-09 19:59:51 +02:00
Hans-Christoph Steiner
41b2e175c9 improve build server performance by allowing disabling of pre-dexing
It seems that Google is finally paying some attention to CI builds with the
emulator, they issued a recommendation:
http://tools.android.com/tech-docs/new-build-system/tips#TOC-Improving-Build-Server-performance
2016-05-09 19:58:05 +02:00
F-Droid Translatebot
aaf5bfe1db Pull translation updates from Weblate
Translators:

Adrià García-Alzórriz  Catalan
Oliver Zehm            German
Tobias Bannert         German
2016-05-09 11:14:58 +01:00
Hans-Christoph Steiner
a96eeccea9 Merge branch 'crash-fixes' into 'master'
Two NPE fixes, cleanup

@eighthave I couldn't find why `setExecutable()` isn't used anymore. The fact that it is now unused code begs the question: why don't we need to set the APK download folder as executable anymore?

See merge request !279
2016-05-09 10:10:32 +00:00
Daniel Martí
5f6762f543 Remove some dead code found by Studio 2016-05-07 23:14:20 +01:00
Daniel Martí
98130de4ae Apply a few weaker access suggestions from Studio 2016-05-07 23:14:20 +01:00
Daniel Martí
0baf443b63 Remove now unused cache_downloaded_on string
We now use a list of time durations to keep the files for.
2016-05-07 23:14:20 +01:00
Daniel Martí
d847f2caef AppDetails: Also check null View in header
Mirror the check already being done in the other fragment. As reported
via ACRA:

	ANDROID_VERSION=4.4.4
	APP_VERSION_NAME=0.100-alpha6
	STACK_TRACE=java.lang.NullPointerException
		at org.fdroid.fdroid.AppDetails$AppDetailsHeaderFragment.updateViews(AppDetails.java:1524)
		at org.fdroid.fdroid.AppDetails$AppDetailsHeaderFragment.updateViews(AppDetails.java:1519)
		at org.fdroid.fdroid.AppDetails.refreshHeader(AppDetails.java:624)
		at org.fdroid.fdroid.AppDetails.onAppChanged(AppDetails.java:549)
		at org.fdroid.fdroid.AppDetails.access$000(AppDetails.java:100)
		at org.fdroid.fdroid.AppDetails$AppObserver.onChange(AppDetails.java:141)
		at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:180)
		at android.os.Handler.handleCallback(Handler.java:733)
		at android.os.Handler.dispatchMessage(Handler.java:95)
		at android.os.Looper.loop(Looper.java:136)
		at android.app.ActivityThread.main(ActivityThread.java:5146)
		at java.lang.reflect.Method.invokeNative(Native Method)
		at java.lang.reflect.Method.invoke(Method.java:515)
		at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
		at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
		at dalvik.system.NativeStart.main(Native Method)
2016-05-07 22:38:33 +01:00
Daniel Martí
1a94c46e87 Fix NPE crash when clearing files in a directory
This was very probably introduced with the new CleanCacheService stuff.
Reported via ACRA:

	ANDROID_VERSION=6.0.1
	APP_VERSION_NAME=0.100-alpha6
	STACK_TRACE=java.lang.NullPointerException: Attempt to get length of null array
		at org.fdroid.fdroid.Utils.clearOldFiles(Utils.java:349)
		at org.fdroid.fdroid.Utils.clearOldFiles(Utils.java:351)
		at org.fdroid.fdroid.Utils.clearOldFiles(Utils.java:351)
		at org.fdroid.fdroid.CleanCacheService.onHandleIntent(CleanCacheService.java:54)
		at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
		at android.os.Handler.dispatchMessage(Handler.java:102)
		at android.os.Looper.loop(Looper.java:148)
		at android.os.HandlerThread.run(HandlerThread.java:61)

There is nothing to clear if the directory could not be obtained for
some reason, so this seems like a reasonable fix. Anything is better
than a crash anyway.
2016-05-07 22:30:31 +01:00
Daniel Martí
ee696b4737 Merge branch 'fix-ellipsize' into 'master'
Fix ellipsizing on 2.X, other minor updates



See merge request !276
2016-05-07 20:44:57 +00:00