From 99157ead88379cb76bd0fe72e2c2dcd3582ab436 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 27 Apr 2022 11:18:48 -0400 Subject: [PATCH] Fix RTL changes in PagedTileLayout This change fixes two RTL issues with PagedTileLayout: * When RTL happens we had a race condition between the following: * onConfigurationChanged * onRtlPropertiesChanged * QSFragment recreation due to InterestingConfigChanges This was causing that the page that was set after RTL changed when QS was open (for example, by using the Development tile) would sometimes not be correct. In order to fix this, we do two things: * Remove LAYOUT_DIRECTION from InterestingConfigChanges so QSFragment is not recreated * Cached the last known direction in PagedTileLayout so we can use that to get the page when the change happens, even if it has already propagated internally due to onConfigurationChanged. * When PagedTileLayout has never measured and laid out page 0 (because it was recreated in a different page), getTilesHeight returned 0. To prevent this, make sure that we always measure and lay out page 0 (explicitly if not attached to PagedTileLayout). Test: manual Fixes: 227231905 Change-Id: I453606937f275b8fe3255f3e2c666cb912229b1a --- .../fragments/FragmentHostManager.java | 2 +- .../android/systemui/qs/PagedTileLayout.java | 48 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java index 3ae11ff283456..9c7411bf36499 100644 --- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java +++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java @@ -54,7 +54,7 @@ public class FragmentHostManager { private final View mRootView; private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges( ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE - | ActivityInfo.CONFIG_LAYOUT_DIRECTION | ActivityInfo.CONFIG_ASSETS_PATHS); + | ActivityInfo.CONFIG_ASSETS_PATHS); private final FragmentService mManager; private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 34f771ce04310..ce50ddff7b0f5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -39,6 +39,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { private static final boolean DEBUG = false; private static final String CURRENT_PAGE = "current_page"; + private static final int NO_PAGE = -1; private static final String TAG = "PagedTileLayout"; private static final int REVEAL_SCROLL_DURATION_MILLIS = 750; @@ -109,13 +110,14 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { } public void saveInstanceState(Bundle outState) { - outState.putInt(CURRENT_PAGE, getCurrentItem()); + int resolvedPage = mPageToRestore != NO_PAGE ? mPageToRestore : getCurrentPageNumber(); + outState.putInt(CURRENT_PAGE, resolvedPage); } public void restoreInstanceState(Bundle savedInstanceState) { // There's only 1 page at this point. We want to restore the correct page once the // pages have been inflated - mPageToRestore = savedInstanceState.getInt(CURRENT_PAGE, -1); + mPageToRestore = savedInstanceState.getInt(CURRENT_PAGE, NO_PAGE); } @Override @@ -151,12 +153,15 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { @Override public void onRtlPropertiesChanged(int layoutDirection) { + // The configuration change will change the flag in the view (that's returned in + // isLayoutRtl). As we detect the change, we use the cached direction to store the page + // before setting it. + final int page = getPageNumberForDirection(mLayoutDirection == LAYOUT_DIRECTION_RTL); super.onRtlPropertiesChanged(layoutDirection); if (mLayoutDirection != layoutDirection) { mLayoutDirection = layoutDirection; setAdapter(mAdapter); - setCurrentItem(0, false); - mPageToRestore = 0; + setCurrentItem(page, false); } } @@ -172,8 +177,12 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { * Obtains the current page number respecting RTL */ private int getCurrentPageNumber() { + return getPageNumberForDirection(isLayoutRtl()); + } + + private int getPageNumberForDirection(boolean isLayoutRTL) { int page = getCurrentItem(); - if (mLayoutDirection == LAYOUT_DIRECTION_RTL) { + if (isLayoutRTL) { page = mPages.size() - 1 - page; } return page; @@ -388,9 +397,9 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { mPageIndicator.setNumPages(mPages.size()); setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); - if (mPageToRestore != -1) { + if (mPageToRestore != NO_PAGE) { setCurrentItem(mPageToRestore, false); - mPageToRestore = -1; + mPageToRestore = NO_PAGE; } } @@ -479,9 +488,27 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { maxHeight = height; } } + if (mPages.get(0).getParent() == null) { + // Measure page 0 so we know how tall it is if it's not attached to the pager. + mPages.get(0).measure(widthMeasureSpec, heightMeasureSpec); + int height = mPages.get(0).getMeasuredHeight(); + if (height > maxHeight) { + maxHeight = height; + } + } setMeasuredDimension(getMeasuredWidth(), maxHeight + getPaddingBottom()); } + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + super.onLayout(changed, l, t, r, b); + if (mPages.get(0).getParent() == null) { + // Layout page 0, so we can get the bottom of the tiles. We only do this if the page + // is not attached. + mPages.get(0).layout(l, t, r, b); + } + } + public int getColumnCount() { if (mPages.size() == 0) return 0; return mPages.get(0).mColumns; @@ -625,8 +652,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { if (mPageIndicator == null) return; if (mPageListener != null) { int pageNumber = isLayoutRtl() ? mPages.size() - 1 - position : position; - mPageListener.onPageChanged(isLayoutRtl() ? position == mPages.size() - 1 - : position == 0, pageNumber); + mPageListener.onPageChanged(pageNumber == 0, pageNumber); } } @@ -645,8 +671,8 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { mPageIndicator.setLocation(mPageIndicatorPosition); if (mPageListener != null) { int pageNumber = isLayoutRtl() ? mPages.size() - 1 - position : position; - mPageListener.onPageChanged(positionOffsetPixels == 0 && - (isLayoutRtl() ? position == mPages.size() - 1 : position == 0), + mPageListener.onPageChanged( + positionOffsetPixels == 0 && pageNumber == 0, // Send only valid page number on integer pages positionOffsetPixels == 0 ? pageNumber : PageListener.INVALID_PAGE );