Repository navigation
Merge upstream AnkiDroid main (2026-11-04) - #109
Merged
Merged
Conversation
The rule dropped what `ime enable` and `ime set` printed, so a failed switch only showed the two keyboard IDs. The restore and disable checks already include their command output. Android prints refusals to stderr, which `UiDevice.executeShellCommand` does not read, so an empty output means the switch was refused. Assisted-by: Claude Opus 5.5
When a command timed out, the test only saw "Test IME did not respond": an exception from the keyboard's process keeps only its message. The message now includes the stack of the keyboard's main thread. Assisted-by: Claude Opus 5.5
The cloze tabs only had the clozes in the fields, so a card whose cloze was removed wasn't listed, although it exists until 'Empty Cards' is used. In the template editor, which previews the first card, a 'Card 2' tab was then shown over 'No cloze 1 found'. The note's existing cards are now listed too, and a card without its cloze in the fields is marked as '(empty)'. Part of 20919 Assisted-by: Claude Opus 5.5
The template editor previews the first card of cloze note types, so 'No cloze 1 found' was shown under a 'Card 2' tab if 'Empty Cards' had deleted card 1. The note editor also requests card 1 if no cloze is left in the fields. If the requested card isn't one of the tabs, the first tab is shown. Fixes 20919 Assisted-by: Claude Opus 5.5
WebView storage was pointed at the profile before its folders were created. If loading then failed, AnkiDroid fell back to Default's data but kept the failed profile's WebView storage, and on older Android it also cleared the cookies. A failed load now sets the WebView up for Default instead, so Default never opens with another profile's cookies. Assisted-by: Claude Opus 5.5
Part of 18393 Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> Assisted-by: GPT-6.1-Sol xhigh
Part of 18393 Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> Assisted-by: GPT-6.1-Sol xhigh
Part of 18393 Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> Assisted-by: GPT-6.1-Sol xhigh
The deck list and card analysis widgets refresh every minute. If the collection could not be opened, for example while another AnkiDroid install held it locked, the refresh threw and crashed the app. The error is now logged and the widget keeps what it showed before. Part of 22838 Assisted-by: Claude Opus 5.5
Every widget update listed all of the device's storage folders just to decide whether the collection was usable, which can stall on Android's storage service (Issue 22825). Widgets now only wait until a storage location is chosen, and update straight away after that. Part of 22838 Assisted-by: Claude Opus 5.5
The Add Note widget only opens the note editor, which checks storage itself, so it no longer waits for the storage check. Its button works as soon as the widget is placed. Part of 22838 Assisted-by: Claude Opus 5.5
Every screen with the side drawer told the Add Note widget to refresh, in case storage access had just been granted, and ran the slow storage check on the main thread to decide. The widget no longer waits for storage, so the refresh has nothing left to do. Fixes 22838 Assisted-by: Claude Opus 5.5
This fix was based on principle of 'Treat tool changes as a third gesture ending path' And added setActiveTool() method in the viewModel to handle pending erase gestures before switching tools. Approach was like if the new tool cannot continue the active stroke erase gesture, finalize the pending erase before activating it. i.e If the new tool is also a stroke eraser allow the gesture to continue. All six existing activeTool.value sites have been routed through setActiveTool() and added the multiple tests as well Fixes ankidroid#22307 Assisted-by: Claude Opus 5
AGP 9.5 Compose Preview tasks were realized, and failed for variants without unit tests. Now: resole test tasks by name. Prep for AGP 9.5 PR 22859 Assisted-by: GPT-6.1-Sol xhigh
Use `anki-backend-core` (JVM) for local backend builds and test fixtures https://redirect.github.com/ankidroid/Anki-Android-Backend/pull/770 Assisted-by: GPT-6.1-Sol xhigh
Remove Android runtime dependencies from libanki and use SLF4J logging. Keep Android cursor adapters in anki-common and restrict FrameworkDatabase to the helpers used by its callers. Document moving shared cursor paging and conversion logic into anki-backend-core. Assisted-by: GPT-6.1-Sol xhigh
`JvmTest.runTest` now uses the coroutine test scheduler, allowing ViewModel/collection tests to move away from Robolectric. Same code as already used by Robolectric Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
InstantTaskExecutorRule (AndroidX) is used so we don't need an Android looper. Assisted-by: GPT-6.1-Sol xhigh
OnDiskJvmTest allows for these to execute using a temp directory for these tests. Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
Keeping the integration checks under the Android runner (WorkManager-related) Assisted-by: GPT-6.1-Sol xhigh
Run settings checks on the JVM and retain a Robolectric integration test that verifies the factory loads the saved action and display durations. Assisted-by: GPT-6.1-Sol xhigh
Typing a search before the deck list had loaded, or expanding or collapsing a deck in the results, brought back every deck while the search text was still there. The list now keeps the search applied. Assisted-by: Claude Opus 5.5
Adding or cloning a note type ran its collection work inside the dialog. It now runs in ManageNoteTypesViewModel, which adds the note type and reloads the list under one progress dialog, even if the screen is recreated meanwhile. Errors still go through launchCatchingTask, also on a recreated screen. Assisted-by: Claude Opus 5.5
Loading the column picker and the notes for Find and Replace now report progress from CardBrowserViewModel, so the browser's existing observer shows the dialog and blocks input while they load. Assisted-by: Claude Opus 5.5
Previously, `AnkiDroidApp.appResources` was required, even if all required preferences were overridden. Now, an in-memory SharedPreferences instance (SPMock) can be used Assisted-by: GPT-6.1-Sol xhigh
SharedPreferencesLastDeckIdRepository - use SharedPreferencesProvider Assisted-by: GPT-6.1-Sol xhigh
We previously leaked `BackendFactory.defaultLanguages` changes, which could apply to other tests Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
Moves 146 tests to the JVM Assisted-by: GPT-6.1-Sol xhigh
This avoids deck taps becoming long presses on a slow emulator. Fixes 22912 Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
So an exception caught outside an activity coroutine, for example in a ViewModel, can be shown the same way, with database corruption still opening the recovery dialog. Assisted-by: Claude Opus 5.5
The release smoke test can fail when ADB loses the emulator mid-run, even though the app is fine. Run it once more, but only if ADB reconnected and AGP's test results show the test never finished. A test that reported a failure is never retried, and a run that passes without any test result now fails. Assisted-by: Claude Opus 5.5
Assisted-by: GPT-6.1-Sol xhigh
Assisted-by: GPT-6.1-Sol xhigh
The deletion test clicked the "Other" deck as soon as the deck tree had loaded, but the rows are drawn a moment later, so on a slow runner the click could come before the row existed. It now waits until both decks are shown. Assisted-by: Claude Opus 5.5
PostRequestUri parses them, while AnkiServer only receives the requests, and is about to be replaced. Assisted-by: Claude Opus 5.5
Adds addWebMessageListener and addDocumentStartJavaScript, for PostRequestBridge. Callers must check that the WebView supports WEB_MESSAGE_LISTENER and DOCUMENT_START_SCRIPT. Assisted-by: Claude Opus 5.5
Android's WebView can intercept requests, but can't read their bodies, so AnkiServer listens on a localhost port to receive POST requests. Any app on the device can connect to that port. PostRequestBridge receives them without a server: `post-request-bridge.js` replaces fetch() before the page scripts run, and sends same-origin POST requests as binary web messages, which the bridge passes to a PostRequestHandler. Only frames from https://appassets.androidplatform.net get the script and the message object. That's the host WebViewAssetLoader uses: Google reserves it, so it doesn't resolve and nobody else can get a certificate for it. Unlike 127.0.0.1, where any app can listen on port 80 since Android 13 with kernel 5.15. Requests made with XMLHttpRequest, forms or from web workers aren't sent: the Anki pages and AnkiDroid's scripts only use fetch(). Claude Opus 5.5 implemented the bridge, the fetch() shim and their tests Assisted-by: Claude Opus 5.5
PostRequestBridge, which is replacing AnkiServer, needs WebViewFeature.WEB_MESSAGE_ARRAY_BUFFER: stable since WebView 116. DeckPicker and the importers show the outdated WebView dialog below it, or if the WebView lacks the features used by PostRequestBridge, as non-Google WebViews may. Assisted-by: Claude Opus 5.5
The importers enabled cancelling an import with Back from onLoadResource(), which WebView doesn't call for messages of PostRequestBridge. They now track the import progress from the POST requests they handle, which works with both AnkiServer and the bridge. The test is from David Allison's review. Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> Assisted-by: GPT-6 Assisted-by: Claude Opus 5.5
The Anki pages and the card viewers (the reviewer, the new study screen and the previewers) send their POST requests through PostRequestBridge, and AnkiServer is removed: AnkiDroid no longer listens on a localhost port. They're loaded from https://appassets.androidplatform.net/, whose assets the WebViewClients serve. Card templates may use http:// resources, like scripts, which an https page blocks by default, so the card viewers use MIXED_CONTENT_ALWAYS_ALLOW, as AnkiServer's http:// origin allowed them. The origin no longer changes, so localStorage persists for everyone, and the 'localStorage in Study Screen' setting has no effect. Data that templates stored under its fixed port isn't available from the new origin. The pages can't send requests without the bridge, so all of them show the outdated WebView dialog below version 116, instead of only the importers. The card viewers still load, but their requests fail. Unlike AnkiServer, a failed request without an error message returns status 500 with the exception name, instead of 200 with an empty body. Claude Opus 5.5 implemented this change and verified the Anki pages, the reviewer and the new study screen on an emulator Assisted-by: Claude Opus 5.5
AnkiServer was its only user in the app. ReviewerMediaErrorTest returns its failing responses from its WebViewClient, instead of a NanoHTTPD server. It fails its API request with an XMLHttpRequest, as same-origin fetch() POST requests go through PostRequestBridge. Assisted-by: Claude Opus 5.5
It made the reviewers' server use a fixed port, so templates kept their localStorage. Without the server, the origin is always https://appassets.androidplatform.net/ and localStorage persists for everyone. A preference upgrade removes its stored values. Assisted-by: Claude Opus 5.5
# Conflicts: # gradle/libs.versions.toml
|
Snapshot diff report vs
All 17 changed screenshotsCustomStudyScreenshotTest
DeckPickerScreenshotTest
DeckPickerTabletScreenshotTest
ExportDialogFragmentScreenshotTest
NavigationDrawerScreenshotTest
PreferencesScreenshotTest
ReviewRemindersScreenshotTest
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Merges the 62 commits on upstream AnkiDroid main since the last sync (up to
b9e492ddbf"feat: remove the 'localStorage in Study Screen' setting"). Supersedes #104.Conflicts
gradle/libs.versions.toml: both sides added a library entry on the same line afterandroidx-core. The fork addedandroidx-core-remoteviews, upstream addedandroidx-arch-core-testing. Kept both. Each one's version key (androidxCoreRemoteViews,androidxArchCore) merged cleanly.No other conflicts. Files changed on both sides that merged cleanly:
AnkiDroid/build.gradle.kts,AnkiDroid/src/main/AndroidManifest.xml,AnkiDroidApp.kt,DeckPickerTest.kt. Upstream deletedpages/AnkiServer.ktandNavigationDrawerActivityTest.kt, and nothing in the fork references either one.Checks run locally
:AnkiDroid:compilePlayDebugKotlin,:AnkiDroid:ktlintCheck:AnkiDroid:testPlayDebugUnitTest --tests 'com.ichi2.anki.ankiquest.*' --tests 'com.ichi2.anki.DeckPickerTest': 506 tests, 0 failures