Describe the bug
The app crashes when switching tabs (ViewPager2 pages) in the browser.
The crash is caused by a ViewGroup using LayoutTransition (or animateLayoutChanges="true"), which conflicts with ViewPager2's internal scrolling animation and results in an IllegalStateException.
This issue occurs during normal UI interaction and is not specific to test frameworks.
How to Reproduce
Steps to reproduce the behavior:
- Launch the DuckDuckGo app
- Open multiple tabs in the browser
- Trigger a tab switch (e.g., via tab manager or programmatic navigation)
- Observe crash
I found this crash by automated testing tool.
Logcat shows:
--------- beginning of crash
03-30 01:21:50.933 20810 20810 E AndroidRuntime: FATAL EXCEPTION: main
03-30 01:21:50.933 20810 20810 E AndroidRuntime: Process: com.duckduckgo.mobile.android.debug, PID: 20810
03-30 01:21:50.933 20810 20810 E AndroidRuntime: java.lang.IllegalStateException: Page(s) contain a ViewGroup with a LayoutTransition (or animateLayoutChanges="true"), which interferes with the scrolling animation. Make sure to call getLayoutTransition().setAnimateParentHierarchy(false) on all ViewGroups with a LayoutTransition before an animation is started.
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ScrollEventAdapter.updateScrollEventValues(ScrollEventAdapter.java:271)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ScrollEventAdapter.getRelativeScrollPosition(ScrollEventAdapter.java:406)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ViewPager2.setCurrentItemInternal(ViewPager2.java:654)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ViewPager2.setCurrentItem(ViewPager2.java:614)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity.onMoveToTabRequested$lambda$51(BrowserActivity.kt:1470)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity.$r8$lambda$JCC60xI_JcBNHNTavCcUC05kgBA(Unknown Source:0)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity$$ExternalSyntheticLambda5.run(D8$$SyntheticClass:0)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:873)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6669)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
03-30 01:21:51.908 2603 18416 E ActivityThread: Failed to find provider info for com.google.android.apps.gsa.testing.ui.audio.recorded
the action sequence before the crash
action: 9@back
action: 3@click resource-id=com.duckduckgo.mobile.android.debug:id/aiChatIconMenu :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 10@scroll direction=down
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 2@edit resource-id=com.duckduckgo.mobile.android.debug:id/omnibarTextInput :android.widget.EditText@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/backIcon :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 9@click className=android.widget.Button,instance=0 :android.widget.Button@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 4@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 2@click resource-id=com.duckduckgo.mobile.android.debug:id/duckAIToolbarButton :android.widget.Button@
action: 11@scroll direction=up
action: 4@click resource-id=com.duckduckgo.mobile.android.debug:id/fireIconImageView :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 5@back
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 5@clickLong className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 16@edit resource-id=com.duckduckgo.mobile.android.debug:id/omnibarTextInput :android.widget.EditText@weather forecast today
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/fireIconImageView :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/leadingIcon :android.widget.ImageView@
Expected behavior
Switching tabs should work smoothly without crashing, regardless of layout animations inside child views.
Environment
- DDG App Version:5.274.0 (debug intern build)
- Device:Android Emulator (medium phone)
- OS: Android 9
Describe the bug
The app crashes when switching tabs (ViewPager2 pages) in the browser.
The crash is caused by a
ViewGroupusingLayoutTransition(oranimateLayoutChanges="true"), which conflicts with ViewPager2's internal scrolling animation and results in anIllegalStateException.This issue occurs during normal UI interaction and is not specific to test frameworks.
How to Reproduce
Steps to reproduce the behavior:
I found this crash by automated testing tool.
Logcat shows:
--------- beginning of crash
03-30 01:21:50.933 20810 20810 E AndroidRuntime: FATAL EXCEPTION: main
03-30 01:21:50.933 20810 20810 E AndroidRuntime: Process: com.duckduckgo.mobile.android.debug, PID: 20810
03-30 01:21:50.933 20810 20810 E AndroidRuntime: java.lang.IllegalStateException: Page(s) contain a ViewGroup with a LayoutTransition (or animateLayoutChanges="true"), which interferes with the scrolling animation. Make sure to call getLayoutTransition().setAnimateParentHierarchy(false) on all ViewGroups with a LayoutTransition before an animation is started.
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ScrollEventAdapter.updateScrollEventValues(ScrollEventAdapter.java:271)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ScrollEventAdapter.getRelativeScrollPosition(ScrollEventAdapter.java:406)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ViewPager2.setCurrentItemInternal(ViewPager2.java:654)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at androidx.viewpager2.widget.ViewPager2.setCurrentItem(ViewPager2.java:614)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity.onMoveToTabRequested$lambda$51(BrowserActivity.kt:1470)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity.$r8$lambda$JCC60xI_JcBNHNTavCcUC05kgBA(Unknown Source:0)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.duckduckgo.app.browser.BrowserActivity$$ExternalSyntheticLambda5.run(D8$$SyntheticClass:0)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:873)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.os.Looper.loop(Looper.java:193)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6669)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
03-30 01:21:50.933 20810 20810 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
03-30 01:21:51.908 2603 18416 E ActivityThread: Failed to find provider info for com.google.android.apps.gsa.testing.ui.audio.recorded
the action sequence before the crash
action: 9@back
action: 3@click resource-id=com.duckduckgo.mobile.android.debug:id/aiChatIconMenu :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 10@scroll direction=down
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 2@edit resource-id=com.duckduckgo.mobile.android.debug:id/omnibarTextInput :android.widget.EditText@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/backIcon :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 9@click className=android.widget.Button,instance=0 :android.widget.Button@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 4@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 2@click resource-id=com.duckduckgo.mobile.android.debug:id/duckAIToolbarButton :android.widget.Button@
action: 11@scroll direction=up
action: 4@click resource-id=com.duckduckgo.mobile.android.debug:id/fireIconImageView :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 5@back
action: 3@click className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 5@clickLong className=android.widget.TextView,instance=0 :android.widget.TextView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 16@edit resource-id=com.duckduckgo.mobile.android.debug:id/omnibarTextInput :android.widget.EditText@weather forecast today
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/fireIconImageView :android.widget.ImageView@recycler items_com.duckduckgo.app.browser.BrowserActivity_000000000
action: 1@click resource-id=com.duckduckgo.mobile.android.debug:id/leadingIcon :android.widget.ImageView@
Expected behavior
Switching tabs should work smoothly without crashing, regardless of layout animations inside child views.
Environment