2225 Commits

Author SHA1 Message Date
Hans-Christoph Steiner
c862eb0bd3 safely handle nulls that start InstallManagerService
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 #660 https://gitlab.com/fdroid/fdroidclient/issues/660
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
507f17e19e always set App.icon when instantiating from installed app
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.
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
2038b7e1cb only generate basic swap index.jar if none exists
Let's keep the index.jar around as a cache of parsed information.

LocalRepoManager.getApps() was totally unused
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
897ed989b1 fixes #633 update download progress regression
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
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
23ab7046bc parse APK for <nativecode> info in local repos
This parses the APKs for swapping, looking for what kinds of native code it
includes.  This is used in the compatibility check.

closes #30 https://gitlab.com/fdroid/fdroidclient/issues/30
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
4224d6df81 only update static WiFi settings var from WifiInfoThread
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 #589 https://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)
2016-05-18 21:25:41 +02:00
Hans-Christoph Steiner
16a36f212c fix download progress when installing apps via swap
fixes issue that came from all the #601 !278 changes
2016-05-18 21:25:41 +02:00
Peter Serwylo
8d742b7e30 Correctly expand list of nearby people to the entire height of the screen.
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.
2016-05-17 13:27:49 +02:00
Peter Serwylo
c7b6313907 Ensure FLAG_AUTO_REQUERY is used for main app list adapters.
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.
2016-05-16 23:53:06 +10:00
Daniel Martí
611db650d5 Merge branch 'fix-661--prevent-notification-swiping' into 'master'
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
2016-05-15 12:52:20 +00:00
Peter Serwylo
f184c97354 Don't allow download notifications to be cancelled, other than our "Cancel" action on them.
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.
2016-05-15 11:53:04 +10:00
Peter Serwylo
da8a142510 Fix Android Studio warnings.
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.
2016-05-15 08:33:29 +10:00
Peter Serwylo
ef75f30701 Ignore intents other than ACTION_INSTALL 2016-05-15 08:31:53 +10:00
Peter Serwylo
4f6910fca7 Rename 'startDownload' to 'initiateInstall'.
This is more apt given the change from `DownloaderService` to `InstallManagerService`.
2016-05-15 08:31:53 +10:00
Hans-Christoph Steiner
5bb73999ad more javadoc about how the download URL is used as a unique ID 2016-05-13 12:52:48 +02:00
Hans-Christoph Steiner
426e03a649 switch out swap Repo instance all at once
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.
2016-05-13 12:52:48 +02:00
Hans-Christoph Steiner
26d173acdc convert WifiStateChangeService to IntentService
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.
2016-05-13 12:52:48 +02:00
Hans-Christoph Steiner
7eeab77aaf in ACRA process, do not run everything in FDroidApp.onCreate()
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.
2016-05-13 12:52:48 +02:00
Daniel Martí
9b96282cbf Bump to 0.100-alpha7 2016-05-12 23:12:10 +01:00
F-Droid Translatebot
c7f92d2ee6 Pull translation updates from Weblate
Translators:

Boris Timofeev           Russian
ezjerry liao             Traditional Chinese
Kristoffer Grundström    Swedish
Licaon Kter              Romanian
2016-05-12 23:06:13 +01:00
Daniel Martí
d9f1215142 Merge branch 'install-lint' into 'master'
Ignore lint for GET_UNINSTALLED_PACKAGES



See merge request !287
2016-05-12 22:04:34 +00:00
Daniel Martí
d1d0f13a41 Merge branch 'priv-stub' into 'master'
Use IPrivilegedCallback.Stub()



See merge request !288
2016-05-12 21:55:18 +00:00
Dominik Schürmann
0984a93133 Ignore lint for GET_UNINSTALLED_PACKAGES
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
2016-05-13 00:53:20 +03:00
Dominik Schürmann
6c84c79397 Use IPrivilegedCallback.Stub() 2016-05-13 00:44:24 +03:00
Dominik Schürmann
69e2546821 Workaround for Android N2 preview bug with EXTRA_RETURN_RESULT 2016-05-13 00:20:08 +03:00
Hans-Christoph Steiner
768b3d7688 register event receivers for SwapAppsView when Apk is available
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.
2016-05-12 19:05:26 +02:00
Hans-Christoph Steiner
cad7a9687d manage InstallManagerService queue with methods
This should hopefully make it a bit clearer how the list of active APKs is
managed.
2016-05-12 19:05:19 +02:00
Hans-Christoph Steiner
80ed1e7180 prevent crash when starting swap in Android 6.0+
This just stops the crash for now, it does not yet request the permission.
That'll be part of the big UX overhaul.

#656 https://gitlab.com/fdroid/fdroidclient/issues/656
2016-05-12 19:05:19 +02:00
Daniel Martí
c432bf1ea0 PMD: Enable most empty code rules 2016-05-12 13:34:20 +01:00
Daniel Martí
65e2931fe8 PMD: Enable UnnecessaryWrapperObjectCreation 2016-05-12 13:34:20 +01: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
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
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