The date/time written to index.xml and index-v1.json should always be in
UTC format. These formats are often in the form of just a date, e.g.
2019-04-28. Those are then converted to UNIX seconds, which includes the
time. In the date only case, the time is assumed to be 00:00, which will
be different per time zone.
index-v1.json is better since it mostly uses Java-style UNIX time in millis
but the dates/times are parsed then stored in the local database in the old
format yyyy-MM-dd_HH:mm:ss which will result in different UNIX times when
the device is in different time zones.
fdroid/fdroidclient#1757
This also converts old Repo.lastUpdated values rather than just failing.
index.xml handling used to store the Repo "Last Updated" date used to store
the value as just an ISO date (2019-04-29), then the time was added. So if
date/time parsing fails, this falls back to trying to parse just the date.
null is returned when parsing fails, and the Latest Tab shows nothing if
the Last Updated is null.
Some related tests were also tweaked.
Hopefully:
closesfdroid/fdroidclient#1757
Throwable includes Errors and Exceptions. Fixes stacktraces like these:
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:32)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 3 more
java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:32)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
When auto-updates are enabled, the app should update itself last, to ensure
that all of the other apps are completely updated before this app is killed
as part of the update process.
closes#1556
java.lang.NoSuchMethodError: No virtual method toPath()Ljava/nio/file/Path; in class Ljava/io/File; or its super classes (declaration of 'java.io.File' appears in /system/framework/core-oj.jar)
at org.apache.commons.io.FileUtils.isSymlink(FileUtils.java:3107)
at org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:1616)
at org.fdroid.fdroid.DeleteCacheService.onHandleWork(DeleteCacheService.java:30)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:391)
at android.support.v4.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:382)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.e(Log.java:232)
at org.fdroid.fdroid.net.DownloaderService.handleIntent(DownloaderService.java:232)
at org.fdroid.fdroid.net.DownloaderService.access$000(DownloaderService.java:88)
at org.fdroid.fdroid.net.DownloaderService$ServiceHandler.handleMessage(DownloaderService.java:108)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
This is needed since this affects the onProgress broadcasts, and sending
too many can peg the device's CPU. 1k was just too small. ANd 8k works
fine for Bluetooth.
fdroid/fdroidclient#1590
In some cases (e.g. when using Firefox Klar) and copying the URL
(of a link), then only the uri is set and not the text. This
prevented (before this commit) the autofill of the
add package source dialog in such cases.
java.lang.NullPointerException: Attempt to read from field 'java.lang.String org.fdroid.fdroid.data.App.packageName' on a null object reference
at org.fdroid.fdroid.views.swap.SwapAppsView$AppListAdapter$ViewHolder$2.onChange(SwapAppsView.java:294)
at android.database.ContentObserver.onChange(ContentObserver.java:130)
at android.database.ContentObserver.onChange(ContentObserver.java:145)
at android.database.ContentObserver$NotificationRunnable.run(ContentObserver.java:216)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:5497)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Normally, WifiStateChangeService finds the SSID when F-Droid starts. But if
the user hasn't granted location permissions yet, then WifiStateChangeService
won't have been able to read the SSID yet.
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File java.io.File.getCanonicalFile()' on a null object reference
at android.os.storage.StorageManager.getStorageVolume(StorageManager.java:844)
at android.os.storage.StorageManager.getStorageVolume(StorageManager.java:838)
at android.os.Environment.isExternalStorageRemovable(Environment.java:725)
at org.fdroid.fdroid.views.main.NearbyViewBinder.<init>(NearbyViewBinder.java:85)
at org.fdroid.fdroid.views.main.MainViewController.bindSwapView(MainViewController.java:64)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:94)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:47)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6685)
java.lang.IllegalArgumentException: Failed to find storage device at null
at android.os.Environment.isExternalStorageRemovable(Environment.java:859)
at org.fdroid.fdroid.views.main.NearbyViewBinder.<init>(NearbyViewBinder.java:85)
at org.fdroid.fdroid.views.main.MainViewController.bindSwapView(MainViewController.java:64)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:94)
at org.fdroid.fdroid.views.main.MainViewAdapter.onCreateViewHolder(MainViewAdapter.java:47)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6685)
java.lang.ArrayIndexOutOfBoundsException: length=13; index=42
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2340)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2740)
at java.util.Calendar.updateTime(Calendar.java:2589)
at java.util.Calendar.getTimeInMillis(Calendar.java:1101)
at java.util.Calendar.getTime(Calendar.java:1074)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1518)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1413)
at java.text.DateFormat.parse(DateFormat.java:356)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.Apk.<init>(Apk.java:178)
java.lang.NumberFormatException: Not a number:
at android.icu.math.BigDecimal.bad(BigDecimal.java:3349)
at android.icu.math.BigDecimal.<init>(BigDecimal.java:526)
at android.icu.math.BigDecimal.<init>(BigDecimal.java:910)
at android.icu.text.DigitList.getBigDecimalICU(DigitList.java:278)
at android.icu.text.DecimalFormat.parse(DecimalFormat.java:2058)
at android.icu.text.DecimalFormat.parse(DecimalFormat.java:1931)
at java.text.DecimalFormat.parse(DecimalFormat.java:804)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2353)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1615)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1528)
at java.text.DateFormat.parse(DateFormat.java:360)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.App.<init>(App.java:311)
at org.fdroid.fdroid.views.whatsnew.WhatsNewAdapter.onBindViewHolder(WhatsNewAdapter.java:95)
at org.fdroid.fdroid.views.whatsnew.WhatsNewAdapter.onBindViewHolder(WhatsNewAdapter.java:19)
java.lang.ArrayIndexOutOfBoundsException: length=13; index=36
at sun.util.calendar.BaseCalendar.getCalendarDateFromFixedDate(BaseCalendar.java:454)
at java.util.GregorianCalendar.computeFields(GregorianCalendar.java:2411)
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2813)
at java.util.Calendar.updateTime(Calendar.java:3397)
at java.util.Calendar.getTimeInMillis(Calendar.java:1761)
at java.util.Calendar.getTime(Calendar.java:1734)
at java.text.SimpleDateFormat.parseInternal(SimpleDateFormat.java:1633)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1528)
at java.text.DateFormat.parse(DateFormat.java:360)
at org.fdroid.fdroid.Utils.parseDateFormat(Utils.java:577)
at org.fdroid.fdroid.Utils.parseDate(Utils.java:592)
at org.fdroid.fdroid.data.App.<init>(App.java:314)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onCanUpdateLoadFinished(UpdatesAdapter.java:241)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onLoadFinished(UpdatesAdapter.java:224)
at org.fdroid.fdroid.views.updates.UpdatesAdapter.onLoadFinished(UpdatesAdapter.java:67)
java.lang.NumberFormatException: For input string: "@2131034146"
at java.lang.Integer.parseInt(Integer.java:615)
at java.lang.Integer.parseInt(Integer.java:650)
at org.fdroid.fdroid.data.App.getMinTargetMaxSdkVersions(App.java:1092)
at org.fdroid.fdroid.data.App.initInstalledApk(App.java:769)
at org.fdroid.fdroid.data.App.getInstance(App.java:395)
at
org.fdroid.fdroid.localrepo.CacheSwapAppsService.onHandleIntent(CacheSwapAppsService.java:77)
at
android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:76)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:65)