2822 Commits

Author SHA1 Message Date
Dominik Schürmann
c5ae43d66c Remove UI code from PrivilegedInstaller 2016-05-31 17:15:07 +02:00
Dominik Schürmann
9e0787f23d Add javadoc to installer classes 2016-05-31 17:15:07 +02:00
Dominik Schürmann
b994b1c895 Fix selection of ExtensionInstaller 2016-05-31 17:15:07 +02:00
Dominik Schürmann
13f2e30a40 Make InstallerService an IntentService
Because only one apk should be installed at a time
and no cancelation is required it is sufficient to
use an IntentService
2016-05-31 17:15:07 +02:00
Dominik Schürmann
d6803e1bf4 Remove scopes from switch statements
also change two-case switch statements to if-else
2016-05-31 17:15:07 +02:00
Dominik Schürmann
f860257826 Fix pmd errors and code style 2016-05-31 17:15:07 +02:00
Dominik Schürmann
d3a7107a0f Fix checkstyle errors 2016-05-31 17:15:07 +02:00
Dominik Schürmann
2776b86050 Redesign PrivilegedInstaller
* use new local broadcasts
* show permission screen before download
* display permission screen as dialog
2016-05-31 17:15:07 +02:00
Dominik Schürmann
592cd0424a Better error handling for priv installer 2016-05-31 17:14:31 +02:00
Dominik Schürmann
4e8e148029 Display install errors as notify/dialog 2016-05-31 17:14:31 +02:00
Dominik Schürmann
de1d310499 Move installation of extension into own Installer 2016-05-31 17:14:31 +02:00
Dominik Schürmann
c5f9070370 Better error handling in privileged installer 2016-05-31 17:14:31 +02:00
Dominik Schürmann
bb273cd2f5 Use Uris more often instead of File 2016-05-31 17:14:31 +02:00
Dominik Schürmann
a2356b05d6 Refactor installer package 2016-05-31 17:13:53 +02:00
Dominik Schürmann
6d2f2d20a8 InstallerService 2016-05-31 17:13:26 +02:00
Daniel Martí
d4bb97db72 checkstyle: bump to 6.19
Seems like they finally fixed the hanging throws indent issue.
2016-05-30 22:04:33 +01:00
Daniel Martí
cd1c213fb2 Bump minSdkVersion to 10, remove all compat code
Summary of changes:

* Remove compat apply()
* Remove compat setReadable()
* Remove pre-10 compat code in swap
* Remove pre-10 compat code in PRNGFixes

Fixes #663.
2016-05-30 19:25:06 +01:00
Hans-Christoph Steiner
a03629d29d SanitizedFileTest requires systems with "/" for a path separator
closes #622 https://gitlab.com/fdroid/fdroidclient/issues/622
2016-05-27 22:00:28 +02:00
Hans-Christoph Steiner
1914f5f3e1 remove unused app.uninstallable
app.uninstallable is only used in AppDetails.  It is only set when
generating App instances from installed APKs for the swap stuff. Since it
is initialized to false and used as !app.uninstallable, it is always true
when used.  So it was doing nothing.

This needs to be thought out more so this is not entirely complete for
#628. AppDetails needs to know whether its a system app to provide proper
feedback and swap needs to know whether its a system app with an update
installed, otherwise it should ignore it.
2016-05-27 22:00:28 +02:00
Hans-Christoph Steiner
f7688d7f9a convert App comments to javadoc so they can be read in popups, etc.
Decent Java editors have all sorts of nice ways to show javadoc comments,
whether they are for public or private APIs.  So comments should be in that
format whenever possible.
2016-05-27 22:00:28 +02:00
Hans-Christoph Steiner
1410a720c8 reorganize swap's App() constructor to prepare for database caching
To generate swap's index.jar, lots of information about all the installed
APKs needs to be parsed.  That can take a long time.  Some of that can be
stored in InstalledAppProvider.  This prepares for those changes.

Also, turns out that packageInfo.applicationInfo provides enough info, so
there is no need to use pm.getApplicationInfo().  And the metadata from
GET_META_DATA was not even being used.
2016-05-27 22:00:28 +02:00
Hans-Christoph Steiner
aca94bcb68 move Provider tests into same java package the Providers
This allows the tests to call more methods directly without having to use
`public` visibility.
2016-05-27 22:00:28 +02:00
Hans-Christoph Steiner
c947f24495 simple test for WifiStateChangeService.formatIpAddress()
94f79a6438c7021db9c02003865c17f3a0da1718 made me want to be sure
2016-05-27 16:15:15 +02:00
Hans-Christoph Steiner
68375163f5 only use swap header image on large screens
The previous logic was putting the header on some 4" screens while not
putting it on a 7" tablet.  Tested with:

* Samsung Galaxy Tab 3 7"
* Azpen A727 7"
* Xiaomi 4.5"
* Lenovo 4"
* emulators...
2016-05-27 16:15:15 +02:00
Hans-Christoph Steiner
1591851273 remove "Try to install" from swap UI
This should no longer be necessary since the local swap repo metadata now
includes the nativecode tag.

#30 https://gitlab.com/fdroid/fdroidclient/issues/30
2016-05-27 16:15:15 +02:00
Hans-Christoph Steiner
15005372a2 mark as compatible when App/Apk instances are from installed apps
By definition, an app that is already installed is compatible.
2016-05-27 12:26:17 +02:00
Peter Serwylo
810e8eae0d Use initLoader instead of resetartLoader. Call onResume after setting category.
While investigating the infamous issue #606, I noticed these two things which
were a little off. Firstly, we were doing more queries than required, because the
loader was being forceably recreated when it could instead be reused in onResume.

Also, the onResume method (which results in a cursor beign created) should be
called _after_ setting the selected category. This ensures that the query
which is run has the correct category the first time, and needn't be run again.

I am not confident that this fixes the issue, but it seems to help, and I believe
it is the correct thing to do even if it doesn't fix 606.
2016-05-26 10:58:17 +10:00
Hans-Christoph Steiner
94f79a6438 prevent crash caused by bad netmask given to WifiStateChangeService
My guess is that is from IPv6, but those should be filtered out in this
code before it gets to the crash point.  Here's the stacktrace:

java.lang.RuntimeException: An error occured while executing doInBackground()
	at android.os.AsyncTask$3.done(AsyncTask.java:300)
	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:841)
Caused by: java.lang.IllegalArgumentException: Value [64] not in range [0,32]
	at org.apache.commons.net.util.SubnetUtils.rangeCheck(SubnetUtils.java:339)
	at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:264)
	at org.apache.commons.net.util.SubnetUtils.<init>(SubnetUtils.java:51)
	at org.fdroid.fdroid.net.WifiStateChangeService.setIpInfoFromNetworkInterface(WifiStateChangeService.java:222)
	at org.fdroid.fdroid.net.WifiStateChangeService.access$300(WifiStateChangeService.java:37)
	at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:99)
	at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:71)
	at android.os.AsyncTask$2.call(AsyncTask.java:288)
	at java.util.concurrent.FutureTask.run(FutureTask.java:237)
	... 4 more
java.lang.IllegalArgumentException: Value [64] not in range [0,32]
	at org.apache.commons.net.util.SubnetUtils.rangeCheck(SubnetUtils.java:339)
	at org.apache.commons.net.util.SubnetUtils.calculate(SubnetUtils.java:264)
	at org.apache.commons.net.util.SubnetUtils.<init>(SubnetUtils.java:51)
	at org.fdroid.fdroid.net.WifiStateChangeService.setIpInfoFromNetworkInterface(WifiStateChangeService.java:222)
	at org.fdroid.fdroid.net.WifiStateChangeService.access$300(WifiStateChangeService.java:37)
	at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:99)
	at org.fdroid.fdroid.net.WifiStateChangeService$WaitForWifiAsyncTask.doInBackground(WifiStateChangeService.java:71)
	at android.os.AsyncTask$2.call(AsyncTask.java:288)
	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:841)
2016-05-24 21:47:45 +02:00
Hans-Christoph Steiner
2897dcb67e fix crash when InstallManager is killed while actively downloading
This is very related to #660 but this time, I can't see any other way to
solve it but a null guard.  I don't think it is possible to guarantee that
the Downloader.ACTION_INTERRUPTED receiver will be unregistered since
onDestroy() might not even be called.

java.lang.NullPointerException
	at org.fdroid.fdroid.installer.InstallManagerService.removeFromActive(InstallManagerService.java:328)
	at org.fdroid.fdroid.installer.InstallManagerService.access$400(InstallManagerService.java:58)
	at org.fdroid.fdroid.installer.InstallManagerService$4.onReceive(InstallManagerService.java:212)
	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:110)
	at android.os.Looper.loop(Looper.java:193)
	at android.app.ActivityThread.main(ActivityThread.java:5353)
	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:830)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:646)
	at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
	at dalvik.system.NativeStart.main(Native Method)
2016-05-24 21:47:45 +02:00
Hans-Christoph Steiner
fb3dcb293d fix crash with Bluetooth on android-10
android.bluetooth.BluetoothSocket.isConnected() is only 14+

java.lang.NoSuchMethodError: android.bluetooth.BluetoothSocket.isConnected
  at org.fdroid.fdroid.net.bluetooth.BluetoothConnection.open(BluetoothConnection.java:37)
  at org.fdroid.fdroid.net.bluetooth.BluetoothClient.openConnection(BluetoothClient.java:31)
  at org.fdroid.fdroid.net.BluetoothDownloader.<init>(BluetoothDownloader.java:30)
  at org.fdroid.fdroid.net.DownloaderFactory.create(DownloaderFactory.java:56)
  at org.fdroid.fdroid.RepoUpdater.downloadIndex(RepoUpdater.java:97)
  at org.fdroid.fdroid.RepoUpdater.update(RepoUpdater.java:131)
  at org.fdroid.fdroid.UpdateService.onHandleIntent(UpdateService.java:377)
  at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:59)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:130)
  at android.os.HandlerThread.run(HandlerThread.java:60)
2016-05-24 21:47:45 +02:00
Hans-Christoph Steiner
5f623e0c4a after downloading is complete, update notification to "Tap to install"
f9a30d2e1c9d95302e8f4dd0e733d019f70bed66 broke the "Tap to install" aspect.
2016-05-24 09:25:11 +02:00
Hans-Christoph Steiner
f08f8cb53d only parse <uses-sdk> once when looking for min/max SDK version
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.
2016-05-24 09:25:11 +02:00
Hans-Christoph Steiner
02d98826a9 when parsing APKs for the local repo, correctly set 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
2016-05-24 09:25:11 +02:00
Hans-Christoph Steiner
d54748ff39 SuppressLint("ParcelCreator") on MockApplicationInfo
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
2016-05-24 09:24:25 +02:00
F-Droid Translatebot
f631d16828 Pull translation updates from Weblate
Translators:

Ajeje Brazorf         Sardinian
Allan Nordhøy         Norwegian Bokmål
Enol P                Asturian
ezjerry liao          Traditional Chinese
Olexandr Nesterenko   Ukrainian
Tijmen Ennik          Dutch
2016-05-23 15:35:27 +01:00
Hans-Christoph Steiner
f9a30d2e1c reuse Notification.Builder instances
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.
2016-05-23 16:13:17 +02:00
Hans-Christoph Steiner
478538690e fix issue where first time installs do not work
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
2016-05-23 13:58:50 +02:00
Hans-Christoph Steiner
d4d5fb1908 Merge branch 'check-repo-index-timestamps' into 'master'
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
2016-05-21 19:56:49 +00:00
Hans-Christoph Steiner
e1f65cab62 prevent divide-by-zero errors when showing update download progress 2016-05-20 21:35:06 +02:00
Hans-Christoph Steiner
0ab80e4c6a delete the APK copy that Installer instances make
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
2016-05-20 21:35:06 +02:00
Hans-Christoph Steiner
c35d327fa4 include all needed data in install Intents
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 #660 https://gitlab.com/fdroid/fdroidclient/issues/660
2016-05-20 21:35:06 +02:00
Hans-Christoph Steiner
086ff54b5f move versionCode to app/build.gradle to match versionName
on @mvdan's request
2016-05-20 12:19:17 +02:00
Hans-Christoph Steiner
f1a31a7fe3 RepoUpdaterTest: convert writable test to JUnit assumption
This will mark the test as ignored rather then succeeded if it cannot find
a writable dir.
2016-05-20 12:04:36 +02:00
Hans-Christoph Steiner
02b2090e53 check repo index timestamps to prevent rollback attacks
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.
2016-05-20 12:04:36 +02:00
Hans-Christoph Steiner
014ab2d2b6 use Environment.getRootDirectory() instead of /system
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.
2016-05-20 12:04:34 +02:00
Hans-Christoph Steiner
f7c043b3fc set versionName based on git release tag
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 #664 https://gitlab.com/fdroid/fdroidclient/issues/664
2016-05-20 08:42:28 +02:00
Nico Alt
e91ba13601 Set default subject in e-mails
Fixes #600.
2016-05-19 15:26:12 +02:00
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