ankidroid / Anki-Android

AnkiDroid: Anki flashcards on Android. Your secret trick to achieve superhuman information retention.
GNU General Public License v3.0
8.74k stars 2.24k forks source link

`PermissionsUntil29Fragment`: PermissionsActivity cannot be cast to `com.ichi2.anki.DeckPicker` #17372

Open david-allison opened 2 weeks ago

david-allison commented 2 weeks ago

https://ankidroid.org/acra/app/1/bug/254139/report/9a9b9d55-923c-4799-95f3-5330c19a26c0

java.lang.ClassCastException: com.ichi2.anki.ui.windows.permissions.PermissionsActivity cannot be cast to com.ichi2.anki.DeckPicker
    at com.ichi2.anki.dialogs.DatabaseErrorDialog$UninstallListItem._init_$lambda$3(DatabaseErrorDialog.kt:425)
    at com.ichi2.anki.ui.windows.permissions.AndroidPermanentlyRevokedPermissionsDialog.show$lambda$2$lambda$1(AndroidPermanentlyRevokedPermissionsDialog.kt:59)
    at com.ichi2.utils.AlertDialogFacadeKt.listItemsAndMessage$lambda$14(AlertDialogFacade.kt:356)
    at android.widget.AdapterView.performItemClick(AdapterView.java:330)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1199)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3213)
    at android.widget.AbsListView.onTouchUp(AbsListView.java:4195)
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:3932)
    at android.view.View.dispatchTouchEvent(View.java:15103)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3178)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2820)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3184)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2834)
    at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:571)
    at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1899)
    at android.app.Dialog.dispatchTouchEvent(Dialog.java:920)
    at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
    at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:529)
    at android.view.View.dispatchPointerEvent(View.java:15383)
    at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:7112)
    at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6880)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6295)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6352)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6318)
    at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:6483)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6326)
    at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:6540)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6299)
    at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:6352)
    at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:6318)
    at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:6326)
    at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:6299)
    at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:9535)
    at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:9486)
    at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:9441)
    at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:9683)
    at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:296)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:341)
    at android.os.Looper.loopOnce(Looper.java:169)
    at android.os.Looper.loop(Looper.java:300)
    at android.app.ActivityThread.main(ActivityThread.java:8232)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1028)
--------- beginning of main
11-07 07:33:15.375 I/AnkiDroid(31545): DeckPicker: postponing startup code - permission screen shown
11-07 07:33:15.394 I/AnkiDroid(31545): isLegacyStorage(): current dir: /storage/emulated/0/AnkiDroid
11-07 07:33:15.394 I/AnkiDroid(31545): scoped external dirs: /storage/emulated/0/Android/data/com.ichi2.anki/files
11-07 07:33:15.394 I/AnkiDroid(31545): scoped internal dir: /data/user/0/com.ichi2.anki/files
11-07 07:33:15.395 I/AnkiDroid(31545): isLegacyStorage(): true
11-07 07:33:15.398 W/AnkiDroid(31545): DeckPicker/ No storage access, not enabling shortcuts
11-07 07:33:15.402 I/AnkiDroid(31545): DeckPicker::onStart
11-07 07:33:15.421 I/AnkiDroid(31545): DeckPicker::onResume
11-07 07:33:15.425 I/AnkiDroid(31545): isLegacyStorage(): current dir: /storage/emulated/0/AnkiDroid
11-07 07:33:15.425 I/AnkiDroid(31545): scoped external dirs: /storage/emulated/0/Android/data/com.ichi2.anki/files
11-07 07:33:15.425 I/AnkiDroid(31545): scoped internal dir: /data/user/0/com.ichi2.anki/files
11-07 07:33:15.426 I/AnkiDroid(31545): isLegacyStorage(): true
11-07 07:33:15.445 I/AnkiDroid(31545): DeckPicker::onPause
11-07 07:33:15.662 I/AnkiDroid(31545): Setting theme to BLACK
11-07 07:33:15.665 I/AnkiDroid(31545): PermissionsActivity::onCreate
11-07 07:33:15.666 I/AnkiDroid(31545): Setting theme to BLACK
11-07 07:33:15.681 I/AnkiDroid(31545): PermissionsActivity::onStart
11-07 07:33:15.682 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onAttach
11-07 07:33:15.682 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onCreate
11-07 07:33:15.697 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onViewCreated
11-07 07:33:15.697 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onStart
11-07 07:33:15.701 I/AnkiDroid(31545): PermissionsActivity::onResume
11-07 07:33:15.704 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onResume
11-07 07:33:15.860 I/AnkiDroid(31545): DeckPicker::onStop
11-07 07:33:15.864 I/AnkiDroid(31545): DeckPicker::onSaveInstanceState
11-07 07:33:15.865 I/AnkiDroid(31545): IntentHandler::onDestroy
11-07 07:33:20.074 I/AnkiDroid(31545): permission switch pressed
11-07 07:33:34.445 I/AnkiDroid(31545): PermissionsActivity::onPause
11-07 07:33:34.445 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onPause
11-07 07:33:35.069 I/AnkiDroid(31545): PermissionsActivity::onStop
11-07 07:33:35.069 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onStop
11-07 07:33:35.072 I/AnkiDroid(31545): PermissionsActivity::onSaveInstanceState
11-07 07:33:35.073 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onSaveInstanceState
11-07 07:33:48.459 I/AnkiDroid(31545): PermissionsActivity::onStart
11-07 07:33:48.459 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onStart
11-07 07:33:48.466 I/AnkiDroid(31545): PermissionsActivity::onResume
11-07 07:33:48.468 I/AnkiDroid(31545): PermissionsActivity::PermissionsUntil29Fragment::onResume
11-07 07:34:00.003 W/AnkiDroid(31545): W3/ could not check/update day rollover: collection not open
11-07 07:34:00.004 W/AnkiDroid(31545): W3/ could not check/update day rollover: collection not open
lukstbit commented 2 weeks ago

This is a duplicate of the old #5075 issue.

mikehardy commented 2 days ago

No, this is a new one

https://ankidroid.org/acra/app/1/bug/260958/report/6e1af9a6-646f-45ed-8480-70f738dea58e

The problem is that now if permissions for storage are revoked we start PermissionsActivity, and it opens the DatabaseErrorDialog, and the onClick listeners there will try to (for instance) "restore from backup", which is a method that lives on DeckPicker (vs, say, AnkiActivity)

So a user that has lost access to their collection tries to restore from backup and crashes - that's a pretty bad experience

Perhaps this method could throw an Intent to DeckPicker and start it, vs assuming it already was DeckPicker and then crashing on cast?

https://github.com/ankidroid/Anki-Android/blob/76aae32f5c7ee8876381179bc3dbcc643a1342c6/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt#L407-L429