summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Coco Duan <cocod@google.com> 2025-02-05 10:10:52 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-05 10:10:52 -0800
commit5555f7c85b1867d523cb41d5cdbe6c5be290f985 (patch)
tree69a8c2e373bee00ec2b4e138751f22f9256de47c
parent91830b2447c6fbb489757cdd18cd02c033f97d49 (diff)
parent0ffc4fc6ff9a7432b5ebc59ca2cb4d5440346273 (diff)
Merge "Adjust dream overlay margins for mobile" into main
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResponsiveLazyHorizontalGrid.kt9
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationHostViewControllerTest.java41
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/complication/ComplicationLayoutEngineTest.java87
-rw-r--r--packages/SystemUI/res/values/dimens.xml10
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/util/WindowSizeUtils.kt45
-rw-r--r--packages/SystemUI/src/com/android/systemui/complication/ComplicationHostViewController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/complication/ComplicationLayoutEngine.java85
-rw-r--r--packages/SystemUI/src/com/android/systemui/complication/dagger/ComplicationHostViewModule.java58
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)
+ );
}
/**