Code Monkey home page Code Monkey logo

zipternet's People

Contributors

isnit0 avatar julianharty avatar

Stargazers

 avatar

Watchers

 avatar  avatar

zipternet's Issues

gradle fails to build the app until folder created

Gradle fails with an error when trying build the app e.g. ./gradlew installDebug until the folder app/src/main/res/mipmap-xxhdpi/ has been created. It'd be helpful if this folder is created if needed by the gradle build process.

For now, mkdir -p app/src/main/res/mipmap-xxhdpi/ run in the root of the project is enough.

Fix crash of the app when external URL selected in WebView

Currently the app crashes whenever an external link is selected in the content. The issue was detected by the pre-launch report Robo testing and also by humans :)

Here are extracts of 2 logcat files from devices used by Google for the pre-launch report testing of APK 6 of the app.

Pixel 2 crash extract from logcat:

07-08 02:57:50.891: I/Robo(9005): is_web_view_element: true
07-08 02:57:50.891: I/Robo(9005): text_label: "F\303\274rstentum Liechtenstein" with ActionParameters{}}.
07-08 02:57:50.932: D/ZIMT(9054): URL: http://www.liechtenstein.li/
07-08 02:57:50.932: W/System.err(9054): java.lang.IllegalStateException: response must not be null
07-08 02:57:50.932: W/System.err(9054): 	at app.zimternet.traveleurope.MainActivity$loadContent$1.shouldInterceptRequest(MainActivity.kt:199)
07-08 02:57:50.932: W/System.err(9054): 	at com.android.webview.chromium.WebViewContentsClientAdapter.shouldInterceptRequest(WebViewContentsClientAdapter.java:52)
07-08 02:57:50.932: W/System.err(9054): 	at org.chromium.android_webview.AwContents$BackgroundThreadClientImpl.shouldInterceptRequest(AwContents.java:9)
07-08 02:57:50.932: W/System.err(9054): 	at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(AwContentsBackgroundThreadClient.java:11)
07-08 02:57:50.933: A/chromium(9054): [FATAL:jni_android.cc(243)] Please include Java exception stack in crash report
07-08 02:57:50.933: A/chromium(9054): --------- beginning of crash
...

Xperia XZ1 Compact crash extract from logcat:

07-08 02:56:02.864: I/Robo(13923): input_type: <androidx.test.tools.crawler.proto.ElementDescription$InputType@432bfa7 number=1 name=NONE>
07-08 02:56:02.864: I/Robo(13923): is_web_view_element: true
07-08 02:56:02.864: I/Robo(13923): text_label: "Italy" with ActionParameters{}}.
07-08 02:56:02.896: D/ZIMT(13978): URL: http://www.italia.it/en/home.html
07-08 02:56:02.894: W/[email protected](881): type=1400 audit(0.0:2118): avc: denied { search } for name="proc" dev="debugfs" ino=10619 scontext=u:r:hal_memtrack_default:s0 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0 ppid=1 pcomm="init" pgid=1 pgcomm="init"
07-08 02:56:02.894: W/[email protected](881): type=1400 audit(0.0:2119): avc: denied { search } for name="proc" dev="debugfs" ino=10619 scontext=u:r:hal_memtrack_default:s0 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0 ppid=1 pcomm="init" pgid=1 pgcomm="init"
07-08 02:56:02.898: W/System.err(13978): java.lang.IllegalStateException: response must not be null
07-08 02:56:02.898: W/System.err(13978): 	at app.zimternet.traveleurope.MainActivity$loadContent$1.shouldInterceptRequest(MainActivity.kt:199)
07-08 02:56:02.898: W/System.err(13978): 	at uU.b(PG:149)
07-08 02:56:02.898: W/System.err(13978): 	at aIl.a(PG:9)
07-08 02:56:02.898: W/System.err(13978): 	at org.chromium.android_webview.AwContentsBackgroundThreadClient.shouldInterceptRequestFromNative(PG:2)
...

BTW: Oddly the stack trace for the Xperia has minified filenames e.g. uU.b rather than the names of the source classes. Any ideas why?

Config-based app generation

With zero manual tasks if possible.

I think the basic info (app icon, etc) can be extracted from the Zim file itself

Fix compatibility warnings reported in pre-launch report

With version 6 of the app, the pre-launch report has 11 warnings about possible future incompatibilities. These might be for libraries that are included in the app rather than in our code.

10 of the 11 all have the line app.zimternet.traveleurope.MainActivity.onCreate(MainActivity.kt:47)

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z
	at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
	at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
	at java.lang.Class.getDeclaredMethodInternal(Native Method)
	at java.lang.Class.getMethod(Class.java:2064)
	at java.lang.Class.getDeclaredMethod(Class.java:2047)
	at android.support.v7.widget.ViewUtils.<clinit>(ViewUtils.java:44)
	at android.support.v7.widget.ViewUtils.makeOptionalFitsSystemWindows(Unknown Source:0)
	at android.support.v7.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:685)
	at android.support.v7.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:518)
	at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:466)
	at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
	at app.zimternet.traveleurope.MainActivity.onCreate(MainActivity.kt:47)
StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V
	at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
	at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
	at java.lang.Class.getDeclaredMethodInternal(Native Method)
	at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
	at java.lang.Class.getMethod(Class.java:2063)
	at java.lang.Class.getMethod(Class.java:1690)
	at android.support.v7.widget.ViewUtils.makeOptionalFitsSystemWindows(ViewUtils.java:84)
	at android.support.v7.app.AppCompatDelegateImpl.createSubDecor(AppCompatDelegateImpl.java:685)
	at android.support.v7.app.AppCompatDelegateImpl.ensureSubDecor(AppCompatDelegateImpl.java:518)
	at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:466)
	at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
	at app.zimternet.traveleurope.MainActivity.onCreate(MainActivity.kt:47)
StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;->selectionAction(III)Landroid/view/textclassifier/logging/SmartSelectionEventTracker$SelectionEvent;
	at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
	at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
	at java.lang.Class.getDeclaredMethodInternal(Native Method)
	at java.lang.Class.getPublicMethodRecursive(Class.java:2075)
	at java.lang.Class.getMethod(Class.java:2063)
	at java.lang.Class.getMethod(Class.java:1690)
	at cyw.a(PG:9)
	at cyE.a(PG:12)
	at org.chromium.content.browser.selection.SmartSelectionClient.<init>(PG:5)
	at czl.a(Unknown Source:7)
	at org.chromium.android_webview.AwContents.e(PG:243)
	at org.chromium.android_webview.AwContents.d(PG:210)
	at org.chromium.android_webview.AwContents.<init>(PG:81)
	at vE.run(PG:15)
	at aKc.a(PG:13)
	at aKd.run(Unknown Source:2)
	at org.chromium.base.task.PostTask.b(PG:13)
	at aKc.a(PG:7)
	at com.android.webview.chromium.WebViewChromiumFactoryProvider.b(PG:6)
	at com.android.webview.chromium.WebViewChromium.init(PG:107)
	at android.webkit.WebView.<init>(WebView.java:422)
	at android.webkit.WebView.<init>(WebView.java:348)
	at android.webkit.WebView.<init>(WebView.java:331)
	at android.webkit.WebView.<init>(WebView.java:318)
	at java.lang.reflect.Constructor.newInstance0(Native Method)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
	at android.view.LayoutInflater.createView(LayoutInflater.java:647)
	at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
	at android.view.LayoutInflater.onCreateView(LayoutInflater.java:720)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:788)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
	at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
	at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
	at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
	at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
	at app.zimternet.traveleurope.MainActivity.onCreate(MainActivity.kt:47)

The 11th warning is for:

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Landroid/content/Context;->bindServiceAsUser(Landroid/content/Intent;Landroid/content/ServiceConnection;ILandroid/os/Handler;Landroid/os/UserHandle;)Z
	at android.os.StrictMode.lambda$static$1(StrictMode.java:428)
	at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
	at java.lang.Class.getDeclaredMethodInternal(Native Method)
	at java.lang.Class.getMethod(Class.java:2064)
	at java.lang.Class.getDeclaredMethod(Class.java:2047)
	at aMq.a(PG:4)
	at aMK.a(PG:10)
	at aMr.a(PG:50)
	at cvB.<init>(PG:4)
	at cuV.run(PG:9)
	at android.os.Handler.handleCallback(Handler.java:873)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:193)
	at android.os.HandlerThread.run(HandlerThread.java:65)

Rationale/approach

I'd like to make this project (app generator?) Have core feature parity with Kiwix custom apps, then refuse to add any of the other cruft.

We should minimise the number of things that can go wrong or out of date.

It would also be nice to have a fully automated MWO workflow to republish custom apps every month (even if the code has not changed)

Improve error detection and handing when content not available in ZIP content

There are several reasons why content may not be available. These include obscure paths and redirections in the content (which are not supported in ZIP file content).

2019-08-22 16:02:30.903 15709-15816/app.zipternet.custom D/ZIPT: openFile paths: -/s/css_modules/skins.minerva.base.reset|skins.minerva.content.styles|ext.cite.style|mobile.app.pagestyles.android|mediawiki.page.gallery.styles|mediawiki.skinning.content.parsoid.css:skins.minerva.base.reset|skins.minerva.content.styles|ext.cite.style|mobile.app.pagestyles.android|mediawiki.page.gallery.styles|mediawiki.skinning.content.parsoid.css
2019-08-22 16:02:34.432 15709-15816/app.zipternet.custom W/ContentUriUtils: Unknown content uri: content://app.zipternet.custom/-/s/css_modules/skins.minerva.base.reset%7Cskins.minerva.content.styles%7Cext.cite.style%7Cmobile.app.pagestyles.android%7Cmediawiki.page.gallery.styles%7Cmediawiki.skinning.content.parsoid.css
    java.lang.IllegalStateException: entry must not be null
        at app.zipternet.custom.ZipProvider.openFile(ZipProvider.kt:54)
        at android.content.ContentProvider.openAssetFile(ContentProvider.java:1545)
        at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1725)
        at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1791)
        at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:425)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1410)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1247)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1100)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1054)
        at org.chromium.base.ContentUriUtils.b(PG:46)
        at org.chromium.base.ContentUriUtils.openContentUriForRead(PG:7)
2019-08-22 16:02:34.451 15709-15816/app.zipternet.custom D/ZIPT: openFile paths: -/s/css_modules/content.parsoid.css:content.parsoid.css
2019-08-22 16:02:35.972 15709-15816/app.zipternet.custom W/ContentUriUtils: Unknown content uri: content://app.zipternet.custom/-/s/css_modules/content.parsoid.css
    java.lang.IllegalStateException: entry must not be null
        at app.zipternet.custom.ZipProvider.openFile(ZipProvider.kt:54)
        at android.content.ContentProvider.openAssetFile(ContentProvider.java:1545)
        at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1725)
        at android.content.ContentProvider.openTypedAssetFile(ContentProvider.java:1791)
        at android.content.ContentProvider$Transport.openTypedAssetFile(ContentProvider.java:425)
        at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1410)
        at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1247)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1100)
        at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1054)
        at org.chromium.base.ContentUriUtils.b(PG:46)
        at org.chromium.base.ContentUriUtils.openContentUriForRead(PG:7)
2019-08-22 16:02:36.010 15709-15709/app.zipternet.custom I/chromium: [INFO:CONSOLE(117)] "Uncaught ReferenceError: $ is not defined", source: content://app.zipternet.custom/A/index.html (117)

Handle insufficient space on device elegantly

When testing on a mid-range Android device (a Samsung Galaxy J2 Prime) which had only around 46MB available on internal storage, the app starts and then crashes almost immediately and before any splash screen appears.

It would be great if we can handle the problem in the app rather than leaving Android runtime to cope with the crash.

Note: I installed the app locally using gradle commands, I don't know whether the app store would allow the app to be installed with low free space so this may only be an issue in rare circumstances e.g. if a user deletes an OBB file somehow, then starts our app while there's not enough space for the OBB file to be reinstalled.

From the device's log we can see the following error and crash.

07-16 18:04:37.554   701   783 D StatusBarManagerService: manageDisableList userId=0 what=0x0 pkg=Window{e18725e u0 d0 p8725 app.zimternet.traveleurope/app.zimternet.traveleurope.MainActivity}
07-16 18:04:37.564   701  1483 D VoldConnector: SND -> {9 volume mkdirs /storage/emulated/0/Android/obb/app.zimternet.traveleurope/}
07-16 18:04:37.564   216   291 D VoldCmdListener: volume mkdirs /storage/emulated/0/Android/obb/app.zimternet.traveleurope/
07-16 18:04:37.564   216   291 D VoldCmdListener: CommandListener::runCommand() cmd:mkdirs
07-16 18:04:37.564   216   291 D epmd    : Added EPM Instance (PID:216)
07-16 18:04:37.574   216   291 D epmd    : Terminated seperator: 1
07-16 18:04:37.574   232   232 D GraphicBuffer: free, handle(0xb58a0b40) (w:507 h:930 s:512 f:0x1 u:0x000b00)
07-16 18:04:37.574   232   232 I [MALI][Gralloc]: [-]hnd(0xb58a0b40), client(30), share_fd(50)
07-16 18:04:37.574   232   232 I BufferQueueProducer: [FrameBufferSurface_0](this:0xb3216000,id:0,api:1,p:232,c:232) queueBuffer: fps=11.96 dur=1505.31 max=1020.56 min=14.35
07-16 18:04:37.574   216   291 E cutils  : Failed to mkdirat(/storage/emulated/0/Android/obb/app.zimternet.traveleurope): No space left on device
07-16 18:04:37.574  8725  8725 W ContextImpl: Failed to ensure /storage/emulated/0/Android/obb/app.zimternet.traveleurope: 400
07-16 18:04:37.574  8725  8725 D AndroidRuntime: Shutting down VM
07-16 18:04:37.574   216   291 D SocketClient: SocketClient sendData done: 400 9 Command failed
07-16 18:04:37.574   701  1033 D VoldConnector: RCV <- {400 9 Command failed}
07-16 18:04:37.614  8725  8725 E AndroidRuntime: FATAL EXCEPTION: main
07-16 18:04:37.614  8725  8725 E AndroidRuntime: Process: app.zimternet.traveleurope, PID: 8725
07-16 18:04:37.614  8725  8725 E AndroidRuntime: java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {app.zimternet.traveleurope/app.zimternet.traveleurope.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File[] java.io.File.listFiles()' on a null object reference
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread.deliverResults(ActivityThread.java:5004)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread.handleSendResult(ActivityThread.java:5047)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread.access$1600(ActivityThread.java:229)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:102)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:148)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7406)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File[] java.io.File.listFiles()' on a null object reference
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at app.zimternet.traveleurope.MainActivity.loadContent(MainActivity.kt:146)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at app.zimternet.traveleurope.MainActivity.onRequestPermissionsResult(MainActivity.kt:118)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7291)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.Activity.dispatchActivityResult(Activity.java:7169)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	at android.app.ActivityThread.deliverResults(ActivityThread.java:5000)
07-16 18:04:37.614  8725  8725 E AndroidRuntime: 	... 9 more
07-16 18:04:37.624   701  3992 D InputDispatcher: Focused application set to: xxxx
07-16 18:04:37.624   701  3992 W ActivityManager:   Force finishing activity app.zimternet.traveleurope/.MainActivity

Search

We should be able to search for article titles (probably full text won't be much harder)

Retain last opened article

We should at least store the last viewed article.

This should stay when closing/opening the app, but also when rotating the app

Maybe we should store other navigation history too...

Refactor and tidy code

A few features have been hacked in recently, we should tidy up the code before doing too much more development

Provide reliable way to load homepage

In implementing the onRotation support (see #1) I discovered when testing with the testing_heuristics content that we sometimes end up with a bank screen and no easy way for end users to get back to a usable article. A homepage button #3 is one approach, there may be others. For example, to add better support for using the Android back button; as sometimes (after onRotation) the Android back button causes the app to go into the background rather than returning to the previous page.

Note: perhaps we need a more elegant and robust method of storing and restoring the last viewed page.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.