--- name: project-feedreader-emulator description: "Android emulator set up on tungsten for direct testing of the feedreader (\"Feeds\") app instead of relying only on Peter's phone" metadata: node_type: memory type: project originSessionId: 375c858e-e817-41e8-a076-7920d22eab2b --- An Android emulator is provisioned on tungsten (the doot/feedreader host) for testing the "Feeds" app directly: AVD name `feedreader_test`, API 34, google_apis, x86_64, pixel_6 profile. Launch headless: `-no-window -no-audio -no-boot-anim -gpu swiftshader_indirect`. KVM-accelerated (host has `/dev/kvm` + AMD SVM). Controlled via `adb shell input tap/swipe`, `adb shell screencap`, and `adb shell uiautomator dump` for exact element bounds (more reliable than estimating tap coordinates from screenshots). **Why:** Peter suggested this ("since you're on tungsten you should have enough resources to install an emulator") after a hard-to-reproduce "crash loop" bug report — sideload-to-phone-and-wait-for-feedback cycles were too slow for debugging. With the emulator, a real crash (WebView touched off the main thread during Readability-extraction cancellation) was reproduced directly via scripted rapid-swiping through articles, root-caused from an actual stack trace, and verified fixed under a heavier stress test — instead of guessing from code review alone. **How to apply:** For future feedreader bugs, prefer reproducing on this emulator (install APK, drive via adb, capture logcat) before making a fix, rather than shipping a guess and waiting on Peter's phone-based feedback. `adb exec-out run-as org.terst.feedreader sqlite3 /data/data/org.terst.feedreader/databases/feedreader.db "..."` can query the on-device Room DB directly to verify behavior (e.g. confirming isRead flips). The SDK at `/opt/android-sdk` isn't on PATH by default — export `PATH=$PATH:/opt/android-sdk/platform-tools:/opt/android-sdk/emulator` first, and check `adb devices` since the emulator is often already running. To test `ReaderExtractor` against an arbitrary URL not in a subscribed feed, fire a share intent at `ShareReceiverActivity` rather than adding a throwaway subscription: `adb shell am start -a android.intent.action.SEND -t text/plain --es android.intent.extra.TEXT "" -n org.terst.feedreader/.ui.ShareReceiverActivity` — it extracts and saves to the Saved list (isSaved=true), viewable afterward. **Caveat confirmed 2026-07-23:** extracting a heavy, ad/tracker-laden real-world page (e.g. an Ars Technica article) through this emulator is genuinely flaky — the same URL can time out, succeed fully, or succeed with less content (some page sections render in via client-side JS some time after `onPageFinished`, racing against when our extraction script runs) across back-to-back identical attempts with zero code changes in between. Retry 2-3 times (waiting the full ~20-30s) before concluding a code change broke extraction.