In order to avoid having null guards making the code ugly, use a "blank"
instance of Apk which will work for the various comparisons. This fixes
this crash:
fixes#688
java.lang.NullPointerException
at org.fdroid.fdroid.installer.InstallManagerService$4.onReceive(InstallManagerService.java:243)
at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Improve order by/selection logic for database layer.
This was extracted from the postponed !311.
The order by stuff previously only allowed specifying a particular field. We should also be able to sort based on arbitrary expressions, and such expressions will require the ability to bind arguments using the "?" syntax. This change provides a Java abstraction for the order by, and improves the handling of selection arguments that need to bind to "?" so that both the selection (i.e. `WHERE` clause) and the `ORDER BY` clause can provide arguments as required.
See merge request !329
A previous commit accidentally pushed the code which queries the
`PackageManager` to a different method, but then still used the
`packageInfo` which was supposed to be populated by that code.
This change rectifies this, and in the process also clarifies/documents under
what circumstances the `PackageManager` needs to be queried, rather than
relying on the incoming intent.
Fixes#686.
This involved the typical Android design pattern of a "Base" style in
`values/styles.xml`, then the an empty normal style which uses that Base style
as a `parent` also in `values/styles.xml`, and finally any API specific
styles in another version of the normal style in a `values/styles-v17` folder.
Same was done for android:actionBarStyle moving it into into values-v11.
This time, didn't worry about the base style, because there was not much to be
gained. by doing so.
The order by stuff previously only allowed specifying a particular field.
We should also be able to sort based on arbitrary expressions, and such
expressions will require the ability to bind arguments using the "?" syntax.
This changes provides a Java abstraction for the order by, and improves
the handling of selection arguments that need to bind to "?" so that both
the selection (i.e. WHERE clause) and the ORDER BY clause can provide
arguments as required.
It is not a particularly expensive operation in the scheme of things. When we
are going to the database, the bottlneck is in disk access for the actual query
of the database tables. The difference between retrieving two columns or
all the columns when the query is for a handful of apps is inconsequential.
Thus, it is better to be safe than sorry and just ask for all the things so
that our value objects are correctly populated.
Translators:
Adrià García-Alzórriz Catalan
Daniel Martí Catalan
Enol Puente Asturian
ezjerry liao Traditional Chinese
Jonatan Swedish
Miss Min Persian
Nutchanon Wetchasit Thai
Sergio Oller Catalan
Permissions UI in AppDetails
* Removes the "m" prefix and some unnecessary TODOs
* Re-uses the permission list from the privileged installer for the list in AppDetails:

See merge request !332
include targetSdkVersion in Apk
In order to work well with the Android 6.0+ permissions, the client needs to know whether an APK has been built against android-23 or higher.
@pserwylo @dschuermann how does this look?
See merge request !323
Check permissions for unattended installer
This PR introduces the class ``ApkVerifier`` which checks the permissions of the downloaded apk file against the expected permissions from the F-Droid listing (``Apk`` class).
* I removed ``AndroidXMLDecompress`` because everything which it has been used for can also be done with ``PackageManager.getPackageArchiveInfo()``, to the best of my knowledge. I even asked in at a similar project why ``PackageManager.getPackageArchiveInfo()``may not be enough: https://github.com/jaredrummler/APKParser/issues/3 It turns out in our case it should do everything we need.
* The code responsible for sanitizing the local apk file and making it world readable has also been moved into ``ApkVerifier`` for now. This can change in a later PR when I introduce the FileProvider for downloaded apks.
We still need to check the target sdk version (see TODO in ``ApkVerifier``). This depends on https://gitlab.com/fdroid/fdroidclient/merge_requests/323
See merge request !322
Remove first-time dialogs for extension installer
The root mechanism will not be useful in 5.1 and later and has been shown to be error prone.
See merge request !330
Like PMD, we also had to add a concession to allow static imports.
This time, it was achieved by moving the assertions to a more generally
named `Assert` class, and then allowing static imports from that.
To appease PMD, we now have a three rulesets in `config/pmd/*.xml`:
* `rules.xml`: The bulk of the rules, used by both main and test code.
* `rules-main.xml`: Rules specific to the andoid client code.
* `rules-test.xml`: Rules specific to test code.
The rationale is because checkstyle by default checks for "too many static
imports", which is a fair call. However in JUnit4 code, it is common to
import many `assert*` static methods.
The tests pass, but there is a lingering message that gets logged:
```
Jun 08, 2016 7:31:13 AM com.almworks.sqlite4java.Internal log
WARNING: [sqlite] [DETACH DATABASE temp_update_db]DB[1][C]: exception when clearing
com.almworks.sqlite4java.SQLiteException: [1] DB[1] reset [no such database: temp_update_db]
at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1309)
at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1282)
at com.almworks.sqlite4java.SQLiteConnection.cacheStatementHandle(SQLiteConnection.java:1211)
at com.almworks.sqlite4java.SQLiteConnection.access$900(SQLiteConnection.java:54)
at com.almworks.sqlite4java.SQLiteConnection$CachedController.dispose(SQLiteConnection.java:1606)
at com.almworks.sqlite4java.SQLiteStatement.dispose(SQLiteStatement.java:187)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections$4.call(ShadowSQLiteConnection.java:421)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:449)
at org.robolectric.shadows.ShadowSQLiteConnection$Connections$6.call(ShadowSQLiteConnection.java:443)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
```
The `temp_update_db` is the one used for repo updates, but I thought that it
correctly gets dropped/detached by the `TempAppProvider` when required. In fact,
given the nature of the error message (no such database: temp_update_db), that
hints at the fact that it is indeed dropped. I'm struggling to figure out what
causes this, but it should not be harmful to the running of the tests. If a test
actually fails, then it is picked up correctly by JUnit.
Many of the `Mock*` classes are there to deal with idiosyncrosies of
the Android SDK, including `final`/package local/`@Hide` annotations/etc.
They are no longer required with robolectric tests.
Get around silly `final` methods in `ContentResolver` with Mockito and `delegatesTo`.
The Robolectric library presumes that people always want to test content providers by
manually invoking the `query`/`update`/`delete` methods on the `ShadowContentResolver`.
While that is a great feature for testing, we have helper methods that require testing,
and these methods accept either a _real_ `ContentResolver` or `Context`. Robolectric
did some cool magic in terms of intercepting runtime calls to content resolvers and
forwarding them to the "shadow" verison, to deal with final/package private/etc methods.
However, as a side effect, the `ShadowContentProvider` _is not a `ContentProvider` as
far as the Java compiler is concerned.
By utilising Mockito + `delegatesTo` method, we are able to achieve what is required:
* An actual `ContentProvider` instance.
* It forwards calls to the `ShadowContentProvider` provided by Robolectric.
Robolectric provides testing support for Android via the JVM, including testing
of content providers. In order to get these tests to work, we need to avoid
the default behaviour of starting up FDroidApp.onCreate(). This method has a lot
of static state which fails if set multiple times. Instead of trying to ensure
we correctly zero out that state each test, it is preferable to instead never
bother with that in the first place. Expecially when that is not what is under
test (as is the case with content provider tests).
This makes testing of the function easier, as the method previously expected
a real file to exist on disk for which it could then hash. This instead allows
mock hash values to be inserted when under test.
Other than this, the semantics remain exactly the same as before, and the
expensive hashing is still done on a worker thread as part of the `IntentService`.
Translators:
Ab Arabic
Adrià García-Alzórriz Catalan
Adrià García-Alzórriz Spanish
ageru French
Ajeje Brazorf Sardinian
ezjerry liao Traditional Chinese
Francesco Giordano Italian
Frank Ludviksson Spanish
Helder Santana Portuguese (Brazil)
Kristoffer Grundström Swedish
Licaon Kter Romanian
Marian Hanzel Slovak
Massimiliano Caniparoli Italian
Mladen Pejaković Serbian
Mutante Citta Italian
naofum Japanese
Olexandr Nesterenko Ukrainian
Prasanna Venkadesh Tamil
Sérgio Marques Portuguese (Portugal)
Tobias Bannert German
Verdulo Esperanto
Verdulo Polish
Service crash fixes
3 relatively simple crash fixes. The two related to `WifiStateChangeService` have already be included in `stable-0.100`, 7385d320b42af960be63c9c179e1cbf186c1398a should be cherry-picked into `stable-0.100` after this is merged.
I already have 198ad843c1fabc8cf57ffe85c77230288cd6d7a4 ready in my stable-0.100 branch
See merge request !317
Historically the providers were responsible for notifying about inserts/deletes
for this table. However this is no longer the case with the new service responsible
for throttling the rate with which these notifications occur.
The `parseApp` method was previously accepting an `Intent`, which could
have been anything. Given it was only used once, this now pushed the
creation of that `Intent` into the `parseApp` method, and also reduced the
visibility of the method as it is only used once at time of writing.
This should not be a particularly expensive opperation,. Also, at time of
writing it is only used in a background thread, and only used once in that
thread (i.e. not in a loop or anything like that).
Now that we have RX as a dependency, it can be used as a nice concise way to
achieve certain tasks. Rate limiting is one thing it does well - via the
`debounce` mechanism:
http://reactivex.io/documentation/operators/debounce.html
The semantics of this code is the same as before, limiting content change notifications
to one per second.
Since refactoring the installed app cache stuff, these methods are no longer
required for testing purposes. This is because the tests directly ask the
content provider to insert relevant apps, rather than testing the broadcast
receiving functionality.