diff options
author | 2025-02-05 10:10:52 -0800 | |
---|---|---|
committer | 2025-02-05 10:10:52 -0800 | |
commit | 5555f7c85b1867d523cb41d5cdbe6c5be290f985 (patch) | |
tree | 69a8c2e373bee00ec2b4e138751f22f9256de47c | |
parent | 91830b2447c6fbb489757cdd18cd02c033f97d49 (diff) | |
parent | 0ffc4fc6ff9a7432b5ebc59ca2cb4d5440346273 (diff) |
Merge "Adjust dream overlay margins for mobile" into main
8 files changed, 258 insertions, 93 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt index 44c375d6ac5e..62aa31b49870 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt @@ -48,6 +48,9 @@ import androidx.compose.ui.unit.coerceAtMost import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.times import androidx.window.layout.WindowMetricsCalculator +import com.android.systemui.communal.util.WindowSizeUtils.COMPACT_HEIGHT +import com.android.systemui.communal.util.WindowSizeUtils.COMPACT_WIDTH +import com.android.systemui.communal.util.WindowSizeUtils.MEDIUM_WIDTH /** * Renders a responsive [LazyHorizontalGrid] with dynamic columns and rows. Each cell will maintain @@ -266,14 +269,14 @@ fun calculateWindowSize(): DpSize { private fun calculateNumCellsWidth(width: Dp) = // See https://developer.android.com/develop/ui/views/layout/use-window-size-classes when { - width >= 840.dp -> 3 - width >= 600.dp -> 2 + width >= MEDIUM_WIDTH -> 3 + width >= COMPACT_WIDTH -> 2 else -> 1 } private fun calculateNumCellsHeight(height: Dp) = when { height >= 1000.dp -> 3 - height >= 480.dp -> 2 + height >= COMPACT_HEIGHT -> 2 else -> 1 } diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java index 2ae611d236e9..3e5e72deb208 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java @@ -22,8 +22,12 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.content.res.Configuration; +import android.graphics.Rect; import android.os.UserHandle; import android.provider.Settings; +import android.testing.TestableLooper; +import android.testing.ViewUtils; import android.view.View; import androidx.constraintlayout.widget.ConstraintLayout; @@ -35,6 +39,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.kosmos.KosmosJavaAdapter; import com.android.systemui.util.settings.FakeSettings; import com.android.systemui.util.settings.SecureSettings; @@ -52,8 +57,8 @@ import java.util.HashSet; @SmallTest @RunWith(AndroidJUnit4.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) public class ComplicationHostViewControllerTest extends SysuiTestCase { - @Mock ConstraintLayout mComplicationHostView; @Mock @@ -99,6 +104,10 @@ public class ComplicationHostViewControllerTest extends SysuiTestCase { private SecureSettings mSecureSettings; + private KosmosJavaAdapter mKosmos; + + private TestableLooper mLooper; + private static final int CURRENT_USER_ID = UserHandle.USER_SYSTEM; @Before @@ -113,9 +122,12 @@ public class ComplicationHostViewControllerTest extends SysuiTestCase { when(mViewHolder.getLayoutParams()).thenReturn(mComplicationLayoutParams); when(mComplicationView.getParent()).thenReturn(mComplicationHostView); + mLooper = TestableLooper.get(this); + mKosmos = new KosmosJavaAdapter(this); mSecureSettings = new FakeSettings(); + mComplicationHostView = new ConstraintLayout(getContext()); mSecureSettings.putFloatForUser( - Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f, CURRENT_USER_ID); + Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f, CURRENT_USER_ID); mController = new ComplicationHostViewController( mComplicationHostView, @@ -123,12 +135,35 @@ public class ComplicationHostViewControllerTest extends SysuiTestCase { mDreamOverlayStateController, mLifecycleOwner, mViewModel, - mSecureSettings); + mSecureSettings, + mKosmos.getConfigurationInteractor(), + mKosmos.getTestDispatcher() + ); mController.init(); } /** + * Ensures layout engine update is called on configuration change. + */ + @Test + public void testUpdateLayoutEngineOnConfigurationChange() { + mController.onViewAttached(); + // Attach the complication host view so flows collecting on it start running. + ViewUtils.attachView(mComplicationHostView); + mLooper.processAllMessages(); + + // emit configuration change + Rect bounds = new Rect(0, 0, 2000, 2000); + Configuration config = new Configuration(); + config.windowConfiguration.setMaxBounds(bounds); + mKosmos.getConfigurationRepository().onConfigurationChange(config); + mKosmos.getTestScope().getTestScheduler().runCurrent(); + + verify(mLayoutEngine).updateLayoutEngine(bounds); + } + + /** * Ensures the lifecycle of complications is properly handled. */ @Test diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java index 383e0fab73ff..35eb2527bd1d 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java @@ -18,10 +18,12 @@ package com.android.systemui.complication; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.graphics.Rect; import android.view.View; import androidx.constraintlayout.widget.ConstraintLayout; @@ -56,12 +58,14 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Mock TouchInsetManager.TouchInsetSession mTouchSession; + Margins mMargins = new Margins(0, 0, 0, 0); + ComplicationLayoutEngine createComplicationLayoutEngine() { return createComplicationLayoutEngine(0); } ComplicationLayoutEngine createComplicationLayoutEngine(int spacing) { - return new ComplicationLayoutEngine(mLayout, spacing, 0, 0, 0, 0, mTouchSession, 0, 0); + return new ComplicationLayoutEngine(mLayout, spacing, () -> mMargins, mTouchSession, 0, 0); } @Before @@ -84,7 +88,7 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { ConstraintLayout layout) { this.lp = params; this.category = category; - this.view = Mockito.mock(View.class); + this.view = mock(View.class); this.id = sFactory.getNextId(); when(view.getId()).thenReturn(sNextId++); when(view.getParent()).thenReturn(layout); @@ -131,15 +135,10 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testComplicationMarginPosition() { final Random rand = new Random(); - final int startMargin = rand.nextInt(); - final int topMargin = rand.nextInt(); - final int endMargin = rand.nextInt(); - final int bottomMargin = rand.nextInt(); final int spacing = rand.nextInt(); - - final ComplicationLayoutEngine engine = new ComplicationLayoutEngine(mLayout, spacing, - startMargin, topMargin, endMargin, bottomMargin, mTouchSession, 0, 0); - + mMargins = new Margins(rand.nextInt(), rand.nextInt(), rand.nextInt(), + rand.nextInt()); + final ComplicationLayoutEngine engine = createComplicationLayoutEngine(spacing); final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -167,17 +166,67 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { addComplication(engine, secondViewInfo); - // The first added view should have margins from both directions from the corner position. verifyChange(firstViewInfo, false, lp -> { - assertThat(lp.topMargin).isEqualTo(topMargin); - assertThat(lp.getMarginEnd()).isEqualTo(endMargin); + assertThat(lp.topMargin).isEqualTo(mMargins.top); + assertThat(lp.getMarginEnd()).isEqualTo(mMargins.end); }); // The second view should be spaced below the first view and have the side end margin. verifyChange(secondViewInfo, false, lp -> { assertThat(lp.topMargin).isEqualTo(spacing); - assertThat(lp.getMarginEnd()).isEqualTo(endMargin); + assertThat(lp.getMarginEnd()).isEqualTo(mMargins.end); + }); + } + + @Test + public void testComplicationMarginsOnScreenSizeChange() { + final Random rand = new Random(); + final int spacing = rand.nextInt(); + final ComplicationLayoutEngine engine = createComplicationLayoutEngine(spacing); + final ViewInfo firstViewInfo = new ViewInfo( + new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_END, + ComplicationLayoutParams.DIRECTION_DOWN, + 0), + Complication.CATEGORY_SYSTEM, + mLayout); + + addComplication(engine, firstViewInfo); + + final ViewInfo secondViewInfo = new ViewInfo( + new ComplicationLayoutParams( + 100, + 100, + ComplicationLayoutParams.POSITION_TOP + | ComplicationLayoutParams.POSITION_END, + ComplicationLayoutParams.DIRECTION_DOWN, + 0), + Complication.CATEGORY_STANDARD, + mLayout); + + addComplication(engine, secondViewInfo); + + firstViewInfo.clearInvocations(); + secondViewInfo.clearInvocations(); + + // Triggers an update to the layout engine with new margins. + final int newTopMargin = rand.nextInt(); + final int newEndMargin = rand.nextInt(); + mMargins = new Margins(0, newTopMargin, newEndMargin, 0); + engine.updateLayoutEngine(new Rect(0, 0, 800, 1000)); + + // Ensure complication view have new margins + verifyChange(firstViewInfo, false, lp -> { + assertThat(lp.topMargin).isEqualTo(newTopMargin); + assertThat(lp.getMarginEnd()).isEqualTo(newEndMargin); + }); + verifyChange(secondViewInfo, false, lp -> { + assertThat(lp.topMargin).isEqualTo(spacing); + assertThat(lp.getMarginEnd()).isEqualTo(newEndMargin); }); } @@ -241,7 +290,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testDirectionLayout() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -289,7 +337,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testPositionLayout() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -376,7 +423,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { public void testDefaultMargin() { final int margin = 5; final ComplicationLayoutEngine engine = createComplicationLayoutEngine(margin); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -452,7 +498,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { final int defaultMargin = 5; final int complicationMargin = 10; final ComplicationLayoutEngine engine = createComplicationLayoutEngine(defaultMargin); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -518,7 +563,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { public void testWidthConstraint() { final int maxWidth = 20; final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo viewStartDirection = new ViewInfo( new ComplicationLayoutParams( 100, @@ -566,7 +610,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { public void testHeightConstraint() { final int maxHeight = 20; final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo viewUpDirection = new ViewInfo( new ComplicationLayoutParams( 100, @@ -613,7 +656,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testConstraintNotSetWhenNotSpecified() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo view = new ViewInfo( new ComplicationLayoutParams( 100, @@ -641,7 +683,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testRemoval() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -687,7 +728,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testDoubleRemoval() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo firstViewInfo = new ViewInfo( new ComplicationLayoutParams( 100, @@ -716,7 +756,6 @@ public class ComplicationLayoutEngineTest extends SysuiTestCase { @Test public void testGetViews() { final ComplicationLayoutEngine engine = createComplicationLayoutEngine(); - final ViewInfo topEndView = new ViewInfo( new ComplicationLayoutParams( 100, diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index fcd3a51d5bb3..220d8a99d130 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1993,10 +1993,14 @@ </item> <!-- The padding applied to the dream overlay container --> - <dimen name="dream_overlay_container_padding_start">0dp</dimen> - <dimen name="dream_overlay_container_padding_end">0dp</dimen> + <dimen name="dream_overlay_container_padding_start">40dp</dimen> + <dimen name="dream_overlay_container_padding_end">40dp</dimen> <dimen name="dream_overlay_container_padding_top">0dp</dimen> - <dimen name="dream_overlay_container_padding_bottom">0dp</dimen> + <dimen name="dream_overlay_container_padding_bottom">40dp</dimen> + <dimen name="dream_overlay_container_small_padding_start">32dp</dimen> + <dimen name="dream_overlay_container_small_padding_end">32dp</dimen> + <dimen name="dream_overlay_container_small_padding_top">0dp</dimen> + <dimen name="dream_overlay_container_small_padding_bottom">32dp</dimen> <!-- The margin applied between complications --> <dimen name="dream_overlay_complication_margin">0dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/WindowSizeUtils.kt b/packages/SystemUI/src/com/android/systemui/communal/util/WindowSizeUtils.kt new file mode 100644 index 000000000000..7e62f0fdc821 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/util/WindowSizeUtils.kt @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2025 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.util + +import android.content.Context +import androidx.compose.ui.unit.dp +import androidx.window.layout.WindowMetricsCalculator + +/** + * [WindowSizeUtils] defines viewport breakpoints that helps create responsive mobile layout. + * + * @see https://developer.android.com/develop/ui/views/layout/use-window-size-classes + */ +object WindowSizeUtils { + /** Compact screen width breakpoint. */ + val COMPACT_WIDTH = 600.dp + /** Medium screen width breakpoint. */ + val MEDIUM_WIDTH = 840.dp + /** Compact screen height breakpoint. */ + val COMPACT_HEIGHT = 480.dp + /** Expanded screen height breakpoint. */ + val EXPANDED_HEIGHT = 900.dp + + /** Whether the window size is compact, which reflects most mobile sizes in portrait. */ + @JvmStatic + fun isCompactWindowSize(context: Context): Boolean { + val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context) + val width = metrics.bounds.width() + return width / metrics.density < COMPACT_WIDTH.value + } +} diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationHostViewController.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationHostViewController.java index 35592a5d87d9..ee98a06371e9 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationHostViewController.java +++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationHostViewController.java @@ -18,6 +18,7 @@ package com.android.systemui.complication; import static com.android.systemui.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT; import static com.android.systemui.complication.dagger.ComplicationModule.SCOPED_COMPLICATIONS_MODEL; +import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import android.graphics.Rect; import android.graphics.Region; @@ -32,10 +33,14 @@ import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.Observer; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.util.ViewController; import com.android.systemui.util.settings.SecureSettings; +import kotlinx.coroutines.CoroutineDispatcher; + import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -77,7 +82,9 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay DreamOverlayStateController dreamOverlayStateController, LifecycleOwner lifecycleOwner, @Named(SCOPED_COMPLICATIONS_MODEL) ComplicationCollectionViewModel viewModel, - SecureSettings secureSettings) { + SecureSettings secureSettings, + ConfigurationInteractor configurationInteractor, + @Main CoroutineDispatcher mainDispatcher) { super(view); mLayoutEngine = layoutEngine; mLifecycleOwner = lifecycleOwner; @@ -87,6 +94,13 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay // Whether animations are enabled. mIsAnimationEnabled = secureSettings.getFloatForUser( Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f, UserHandle.USER_CURRENT) != 0.0f; + // Update layout on configuration change like rotation, fold etc. + collectFlow( + view, + configurationInteractor.getMaxBounds(), + mLayoutEngine::updateLayoutEngine, + mainDispatcher + ); } /** diff --git a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java index 15ec4d463163..d91fbab04f64 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java +++ b/packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java @@ -27,16 +27,15 @@ import static com.android.systemui.complication.ComplicationLayoutParams.POSITIO import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_IN_DURATION; import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATIONS_FADE_OUT_DURATION; import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_DIRECTIONAL_SPACING_DEFAULT; -import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN_POSITION_BOTTOM; -import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN_POSITION_END; -import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN_POSITION_START; -import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGIN_POSITION_TOP; +import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_MARGINS; import static com.android.systemui.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT; +import android.graphics.Rect; import android.util.Log; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.NonNull; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.Constraints; @@ -52,11 +51,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.function.Consumer; import java.util.stream.Collectors; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; /** * {@link ComplicationLayoutEngine} arranges a collection of {@link ComplicationViewModel} based on @@ -401,6 +402,16 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll return mDirectionGroups.get(direction).add(entryBuilder); } + public void updateDirectionalMargins(Map<Integer, Margins> directionalMargins) { + // the new map should have the same set of directional keys as the old map + if (!(directionalMargins.keySet()) + .containsAll(mDirectionalMargins.keySet())) { + Log.e(TAG, "Directional margins map does not have the same keys"); + return; + } + mDirectionalMargins.replaceAll((direction, v) -> directionalMargins.get(direction)); + } + @Override public void onEntriesChanged() { // Whenever an entry is added/removed from a child {@link DirectionGroup}, it is vital @@ -584,42 +595,36 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll private final TouchInsetManager.TouchInsetSession mSession; private final int mFadeInDuration; private final int mFadeOutDuration; - private final HashMap<Integer, HashMap<Integer, Margins>> mPositionDirectionMarginMapping; - + private final HashMap<Integer, HashMap<Integer, Margins>> mPositionDirectionMarginMapping = + new HashMap<>(); + private final Provider<Margins> mComplicationMarginsProvider; + private Rect mScreenBounds = new Rect(); /** */ @Inject public ComplicationLayoutEngine(@Named(SCOPED_COMPLICATIONS_LAYOUT) ConstraintLayout layout, @Named(COMPLICATION_DIRECTIONAL_SPACING_DEFAULT) int defaultDirectionalSpacing, - @Named(COMPLICATION_MARGIN_POSITION_START) int complicationMarginPositionStart, - @Named(COMPLICATION_MARGIN_POSITION_TOP) int complicationMarginPositionTop, - @Named(COMPLICATION_MARGIN_POSITION_END) int complicationMarginPositionEnd, - @Named(COMPLICATION_MARGIN_POSITION_BOTTOM) int complicationMarginPositionBottom, + @Named(COMPLICATION_MARGINS) Provider<Margins> complicationMarginsProvider, TouchInsetManager.TouchInsetSession session, @Named(COMPLICATIONS_FADE_IN_DURATION) int fadeInDuration, - @Named(COMPLICATIONS_FADE_OUT_DURATION) int fadeOutDuration) { + @Named(COMPLICATIONS_FADE_OUT_DURATION) int fadeOutDuration + ) { mLayout = layout; mDefaultDirectionalSpacing = defaultDirectionalSpacing; mSession = session; mFadeInDuration = fadeInDuration; mFadeOutDuration = fadeOutDuration; - mPositionDirectionMarginMapping = generatePositionDirectionalMarginsMapping( - complicationMarginPositionStart, - complicationMarginPositionTop, - complicationMarginPositionEnd, - complicationMarginPositionBottom); + mComplicationMarginsProvider = complicationMarginsProvider; + updatePositionDirectionalMarginsMapping(mPositionDirectionMarginMapping, + mComplicationMarginsProvider.get()); } - private static HashMap<Integer, HashMap<Integer, Margins>> - generatePositionDirectionalMarginsMapping(int complicationMarginPositionStart, - int complicationMarginPositionTop, - int complicationMarginPositionEnd, - int complicationMarginPositionBottom) { - HashMap<Integer, HashMap<Integer, Margins>> mapping = new HashMap<>(); - - final Margins startMargins = new Margins(complicationMarginPositionStart, 0, 0, 0); - final Margins topMargins = new Margins(0, complicationMarginPositionTop, 0, 0); - final Margins endMargins = new Margins(0, 0, complicationMarginPositionEnd, 0); - final Margins bottomMargins = new Margins(0, 0, 0, complicationMarginPositionBottom); + private static void updatePositionDirectionalMarginsMapping( + Map<Integer, HashMap<Integer, Margins>> mapping, + Margins complicationMargins) { + final Margins startMargins = new Margins(complicationMargins.start, 0, 0, 0); + final Margins topMargins = new Margins(0, complicationMargins.top, 0, 0); + final Margins endMargins = new Margins(0, 0, complicationMargins.end, 0); + final Margins bottomMargins = new Margins(0, 0, 0, complicationMargins.bottom); addToMapping(mapping, POSITION_START | POSITION_TOP, DIRECTION_END, topMargins); addToMapping(mapping, POSITION_START | POSITION_TOP, DIRECTION_DOWN, startMargins); @@ -632,11 +637,9 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll addToMapping(mapping, POSITION_END | POSITION_BOTTOM, DIRECTION_START, bottomMargins); addToMapping(mapping, POSITION_END | POSITION_BOTTOM, DIRECTION_UP, endMargins); - - return mapping; } - private static void addToMapping(HashMap<Integer, HashMap<Integer, Margins>> mapping, + private static void addToMapping(Map<Integer, HashMap<Integer, Margins>> mapping, @Position int position, @Direction int direction, Margins margins) { if (!mapping.containsKey(position)) { mapping.put(position, new HashMap<>()); @@ -644,6 +647,28 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll mapping.get(position).put(direction, margins); } + /** + * Update margins on screen dimension change. + */ + public void updateLayoutEngine(@NonNull Rect bounds) { + if (bounds.width() == mScreenBounds.width() && bounds.height() == mScreenBounds.height()) { + return; + } + mScreenBounds = bounds; + updatePositionDirectionalMarginsMapping(mPositionDirectionMarginMapping, + mComplicationMarginsProvider.get()); + + // update each position group and layout of entries + for (Integer position : mPositions.keySet()) { + PositionGroup positionGroup = mPositions.get(position); + positionGroup.updateDirectionalMargins(mPositionDirectionMarginMapping + .get(position)); + positionGroup.onEntriesChanged(); + } + Log.d(TAG, "Updated margins for complications as screen size changed to width = " + + bounds.width() + "px, height = " + bounds.height() + "px."); + } + @Override public void setVisibility(int visibility) { if (visibility == View.VISIBLE) { diff --git a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java index 9dd48eaa7551..e446fbf35543 100644 --- a/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java @@ -16,12 +16,15 @@ package com.android.systemui.complication.dagger; +import android.content.Context; import android.content.res.Resources; import android.view.LayoutInflater; import androidx.constraintlayout.widget.ConstraintLayout; import com.android.internal.util.Preconditions; +import com.android.systemui.communal.util.WindowSizeUtils; +import com.android.systemui.complication.ComplicationLayoutEngine; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.res.R; @@ -42,14 +45,7 @@ public abstract class ComplicationHostViewModule { public static final String COMPLICATIONS_FADE_IN_DURATION = "complications_fade_in_duration"; public static final String COMPLICATIONS_RESTORE_TIMEOUT = "complication_restore_timeout"; public static final String COMPLICATIONS_FADE_OUT_DELAY = "complication_fade_out_delay"; - public static final String COMPLICATION_MARGIN_POSITION_START = - "complication_margin_position_start"; - public static final String COMPLICATION_MARGIN_POSITION_TOP = - "complication_margin_position_top"; - public static final String COMPLICATION_MARGIN_POSITION_END = - "complication_margin_position_end"; - public static final String COMPLICATION_MARGIN_POSITION_BOTTOM = - "complication_margin_position_bottom"; + public static final String COMPLICATION_MARGINS = "complication_margins"; /** * Generates a {@link ConstraintLayout}, which can host @@ -72,28 +68,32 @@ public abstract class ComplicationHostViewModule { return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin); } + /** + * Use small margins for compact window width (mobile portrait), and regular margins for + * medium and expanded width (mobile landscape, tablet and large unfolded). + */ @Provides - @Named(COMPLICATION_MARGIN_POSITION_START) - static int providesComplicationMarginPositionStart(@Main Resources resources) { - return resources.getDimensionPixelSize(R.dimen.dream_overlay_container_padding_start); - } - - @Provides - @Named(COMPLICATION_MARGIN_POSITION_TOP) - static int providesComplicationMarginPositionTop(@Main Resources resources) { - return resources.getDimensionPixelSize(R.dimen.dream_overlay_container_padding_top); - } - - @Provides - @Named(COMPLICATION_MARGIN_POSITION_END) - static int providesComplicationMarginPositionEnd(@Main Resources resources) { - return resources.getDimensionPixelSize(R.dimen.dream_overlay_container_padding_end); - } - - @Provides - @Named(COMPLICATION_MARGIN_POSITION_BOTTOM) - static int providesComplicationMarginPositionBottom(@Main Resources resources) { - return resources.getDimensionPixelSize(R.dimen.dream_overlay_container_padding_bottom); + @Named(COMPLICATION_MARGINS) + static ComplicationLayoutEngine.Margins providesComplicationMargins(@Main Resources resources, + Context context) { + return WindowSizeUtils.isCompactWindowSize(context) + ? new ComplicationLayoutEngine.Margins(resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_small_padding_start), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_small_padding_top), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_small_padding_end), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_small_padding_bottom)) : + new ComplicationLayoutEngine.Margins(resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_padding_start), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_padding_top), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_padding_end), + resources.getDimensionPixelSize( + R.dimen.dream_overlay_container_padding_bottom) + ); } /** |