Skip to content

fix(webview): open a document picker for untyped file inputs - #248

Merged
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/webview-file-chooser
Aug 31, 2026
Merged

fix(webview): open a document picker for untyped file inputs#248
ErikBjare merged 1 commit into
ActivityWatch:masterfrom
TimeToBuildBob:fix/webview-file-chooser

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Problem

v0.14.0b2 user report (ActivityWatch/aw-android#247):

  • In-app "import categorization" gives no feedback after tapping the button.
  • The file picker that does appear is camera / picture, not a document picker.

Cause: WebUIFragment had a WebViewClient and download listener, but no WebChromeClient.onShowFileChooser. Android WebView's default file-input handler is camera/gallery. Category import uses <input type="file"> with no accept attribute (CategorizationSettings.vue).

Fix

  • Implement onShowFileChooser and launch ACTION_GET_CONTENT via the existing Activity Result API.
  • Untyped / */* inputs use a generic openable document picker so JSON category files can be selected.
  • Cancel a pending callback in onDestroyView so a destroyed fragment cannot leak a ValueCallback.

Testing

JAVA_HOME=/opt/android-studio/jbr ANDROID_HOME=/home/bob/Android/Sdk \
  ./gradlew :mobile:testDebugUnitTest \
  --tests net.activitywatch.android.fragments.WebUIFragmentTest --no-daemon

Passed. Added unit tests for untyped vs explicit accept-type resolution.

Does not fully close #247. Sync 401 is a separate aw-server-rust PR; category-save persistence and sync UX feedback still open.

Without WebChromeClient.onShowFileChooser, Android WebView's default
chooser is camera/gallery. Category import uses <input type=file> with
no accept attribute, so in-app import could not select JSON
(ActivityWatch#247).
@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds Android document-picker support for file inputs in the embedded dashboard and cancels outstanding WebView callbacks when the view is destroyed.

  • Resolves untyped and wildcard accept values to a generic MIME type.
  • Launches an openable ACTION_GET_CONTENT intent and returns selected URIs to the WebView.
  • Adds focused unit coverage for MIME-type resolution.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete changed-code failure established for the currently described untyped category-import input.

The new chooser maps the current untyped input to an openable generic document picker, returns selected URIs through the WebView callback, and clears pending callbacks during replacement, launch failure, and view destruction.

Important Files Changed

Filename Overview
mobile/src/main/java/net/activitywatch/android/fragments/WebUIFragment.kt Adds the WebChromeClient file-chooser bridge, intent and result helpers, and callback lifecycle cleanup; no concrete blocking defect was established.
mobile/src/test/java/net/activitywatch/android/fragments/WebUIFragmentTest.kt Adds unit coverage for wildcard fallback and preservation of explicit MIME accept types.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant W as Dashboard WebView
    participant F as WebUIFragment
    participant P as Android Document Picker
    U->>W: Tap file input
    W->>F: onShowFileChooser(callback, params)
    F->>P: Launch ACTION_GET_CONTENT
    P-->>F: Selected URI(s) or cancellation
    F-->>W: Deliver callback result
Loading

Reviews (1): Last reviewed commit: "fix(webview): open a document picker for..." | Re-trigger Greptile

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@ErikBjare
ErikBjare merged commit cd6d448 into ActivityWatch:master Aug 31, 2026
8 checks passed
Judemasic added a commit to Judemasic/aw-android that referenced this pull request Sep 2, 2026
Takes ActivityWatch#250 (shared DeviceHostname helper), ActivityWatch#242, ActivityWatch#234, ActivityWatch#244, ActivityWatch#248, ActivityWatch#245.

Deliberately NOT taken: ActivityWatch#249's Kotlin half. It declares
  private external fun setDataDir(path: String)
and calls it from SyncInterface's init block, but this fork's android.rs
exports no Java_..._SyncInterface_setDataDir - the constructor would throw
UnsatisfiedLinkError and SyncScheduler would disable itself, which is Blocker 6
verbatim. This fork already gets the same fix via XDG_DATA_HOME (step 1.0b),
which needs no new JNI symbol. The refusal is documented at the call site so
the next merge re-checks it.

Submodule pointer kept at our fork (c6f7df2); upstream's 2ded7d7 has none of
the aw-sync fixes from Phase 1.

getDeviceName() now delegates to upstream's deviceHostname(), which is
byte-for-byte equivalent to the implementation it replaces - no device
directory in the shared folder changes name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

User feedback on v0.14.02b

2 participants