Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 379ef492 authored by Bryce Lee's avatar Bryce Lee
Browse files

Move directional spacing logic out of ViewEntry.

This changelist delegates calculating the spacing between complications
to the DirectionGroup rather than the ViewEntry itself. By calculating
the margin up the hierarchy, more conditions can be accounted for
without passing the information down to the ViewEntries.

This changelist also renames complication margin to directional spacing
to better reflect how the value is used.

Test: atest ComplicationLayoutParamsTest
Bug: 280595239
Change-Id: I0a83ce98bcdd42d1100ebfe4ef2ab49bb2b95dc3
parent 1f1c22fc
Loading
Loading
Loading
Loading
+94 −45
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ package com.android.systemui.complication;

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_MARGIN_DEFAULT;
import static com.android.systemui.complication.dagger.ComplicationHostViewModule.COMPLICATION_DIRECTIONAL_SPACING_DEFAULT;
import static com.android.systemui.complication.dagger.ComplicationHostViewModule.SCOPED_COMPLICATIONS_LAYOUT;

import android.util.Log;
@@ -54,6 +54,37 @@ import javax.inject.Named;
public class ComplicationLayoutEngine implements Complication.VisibilityController {
    public static final String TAG = "ComplicationLayoutEng";

    /**
     * Container for storing and operating on a tuple of margin values.
     */
    public static class Margins {
        public final int start;
        public final int top;
        public final int end;
        public final int bottom;

        /**
         * Default constructor with all margins set to 0.
         */
        public Margins() {
            this(0, 0, 0, 0);
        }

        /**
         * Cosntructor to specify margin in each direction.
         * @param start start margin
         * @param top top margin
         * @param end end margin
         * @param bottom bottom margin
         */
        public Margins(int start, int top, int end, int bottom) {
            this.start = start;
            this.top = top;
            this.end = end;
            this.bottom = bottom;
        }
    }

    /**
     * {@link ViewEntry} is an internal container, capturing information necessary for working with
     * a particular {@link Complication} view.
@@ -65,15 +96,13 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
        private final Parent mParent;
        @Complication.Category
        private final int mCategory;
        private final int mDefaultMargin;

        /**
         * Default constructor. {@link Parent} allows for the {@link ViewEntry}'s surrounding
         * view hierarchy to be accessed without traversing the entire view tree.
         */
        ViewEntry(View view, ComplicationLayoutParams layoutParams,
                TouchInsetManager.TouchInsetSession touchSession, int category, Parent parent,
                int defaultMargin) {
                TouchInsetManager.TouchInsetSession touchSession, int category, Parent parent) {
            mView = view;
            // Views that are generated programmatically do not have a unique id assigned to them
            // at construction. A new id is assigned here to enable ConstraintLayout relative
@@ -84,7 +113,6 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            mTouchInsetSession = touchSession;
            mCategory = category;
            mParent = parent;
            mDefaultMargin = defaultMargin;

            touchSession.addViewToTracking(mView);
        }
@@ -192,23 +220,8 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
                        break;
                }

                if (!isRoot) {
                    final int margin = mLayoutParams.getMargin(mDefaultMargin);
                    switch(direction) {
                        case ComplicationLayoutParams.DIRECTION_DOWN:
                            params.setMargins(0, margin, 0, 0);
                            break;
                        case ComplicationLayoutParams.DIRECTION_UP:
                            params.setMargins(0, 0, 0, margin);
                            break;
                        case ComplicationLayoutParams.DIRECTION_END:
                            params.setMarginStart(margin);
                            break;
                        case ComplicationLayoutParams.DIRECTION_START:
                            params.setMarginEnd(margin);
                            break;
                    }
                }
                final Margins margins = mParent.getMargins(this);
                params.setMarginsRelative(margins.start, margins.top, margins.end, margins.bottom);
            });

            if (mLayoutParams.constraintSpecified()) {
@@ -275,7 +288,6 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            private final ComplicationLayoutParams mLayoutParams;
            private final int mCategory;
            private Parent mParent;
            private int mDefaultMargin;

            Builder(View view, TouchInsetManager.TouchInsetSession touchSession,
                    ComplicationLayoutParams lp, @Complication.Category int category) {
@@ -310,21 +322,11 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
                return this;
            }

            /**
             * Sets the margin that will be applied in the direction the complication is laid out
             * towards.
             */
            Builder setDefaultMargin(int margin) {
                mDefaultMargin = margin;
                return this;
            }

            /**
             * Builds and returns the resulting {@link ViewEntry}.
             */
            ViewEntry build() {
                return new ViewEntry(mView, mLayoutParams, mTouchSession, mCategory, mParent,
                        mDefaultMargin);
                return new ViewEntry(mView, mLayoutParams, mTouchSession, mCategory, mParent);
            }
        }

@@ -336,6 +338,11 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
             * Indicates the {@link ViewEntry} requests removal.
             */
            void removeEntry(ViewEntry entry);

            /**
             * Returns the margins to be applied to the entry
             */
            Margins getMargins(ViewEntry entry);
        }
    }

@@ -347,6 +354,12 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
    private static class PositionGroup implements DirectionGroup.Parent {
        private final HashMap<Integer, DirectionGroup> mDirectionGroups = new HashMap<>();

        private final int mDefaultDirectionalSpacing;

        PositionGroup(int defaultDirectionalSpacing) {
            mDefaultDirectionalSpacing = defaultDirectionalSpacing;
        }

        /**
         * Invoked by the {@link PositionGroup} holder to introduce a {@link Complication} view to
         * this group. It is assumed that the caller has correctly identified this
@@ -356,7 +369,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
        public ViewEntry add(ViewEntry.Builder entryBuilder) {
            final int direction = entryBuilder.getLayoutParams().getDirection();
            if (!mDirectionGroups.containsKey(direction)) {
                mDirectionGroups.put(direction, new DirectionGroup(this));
                mDirectionGroups.put(direction, new DirectionGroup(this, direction));
            }

            return mDirectionGroups.get(direction).add(entryBuilder);
@@ -370,6 +383,11 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            updateViews();
        }

        @Override
        public int getDefaultDirectionalSpacing() {
            return mDefaultDirectionalSpacing;
        }

        private void updateViews() {
            ViewEntry head = null;

@@ -417,17 +435,22 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
             * {@link DirectionGroup}.
             */
            void onEntriesChanged();

            /**
             * Returns the default spacing between elements.
             */
            int getDefaultDirectionalSpacing();
        }
        private final ArrayList<ViewEntry> mViews = new ArrayList<>();
        private final Parent mParent;
        private final int mDirection;

        /**
         * Creates a new {@link DirectionGroup} with the specified parent. Note that the
         * {@link DirectionGroup} does not store its own direction. It is the responsibility of the
         * {@link DirectionGroup.Parent} to maintain this association.
         * Creates a new {@link DirectionGroup} with the specified parent.
         */
        DirectionGroup(Parent parent) {
        DirectionGroup(Parent parent, int direction) {
            mParent = parent;
            mDirection = direction;
        }

        /**
@@ -463,6 +486,33 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            mParent.onEntriesChanged();
        }

        @Override
        public Margins getMargins(ViewEntry entry) {
            int directionalSpacing = entry.getLayoutParams().getDirectionalSpacing(
                    mParent.getDefaultDirectionalSpacing());

            Margins margins = new Margins();

            if (getHead() != entry) {
                switch (mDirection) {
                    case ComplicationLayoutParams.DIRECTION_START:
                        margins = new Margins(0, 0, directionalSpacing, 0);
                        break;
                    case ComplicationLayoutParams.DIRECTION_UP:
                        margins = new Margins(0, 0, 0, directionalSpacing);
                        break;
                    case ComplicationLayoutParams.DIRECTION_END:
                        margins = new Margins(directionalSpacing, 0, 0, 0);
                        break;
                    case ComplicationLayoutParams.DIRECTION_DOWN:
                        margins = new Margins(0, directionalSpacing, 0, 0);
                        break;
                }
            }

            return margins;
        }

        /**
         * Invoked by {@link Parent} to update the layout of all children {@link ViewEntry} with
         * the specified head. Note that the head might not be in this group and instead part of a
@@ -484,7 +534,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
    }

    private final ConstraintLayout mLayout;
    private final int mDefaultMargin;
    private final int mDefaultDirectionalSpacing;
    private final HashMap<ComplicationId, ViewEntry> mEntries = new HashMap<>();
    private final HashMap<Integer, PositionGroup> mPositions = new HashMap<>();
    private final TouchInsetManager.TouchInsetSession mSession;
@@ -494,12 +544,12 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
    /** */
    @Inject
    public ComplicationLayoutEngine(@Named(SCOPED_COMPLICATIONS_LAYOUT) ConstraintLayout layout,
            @Named(COMPLICATION_MARGIN_DEFAULT) int defaultMargin,
            @Named(COMPLICATION_DIRECTIONAL_SPACING_DEFAULT) int defaultDirectionalSpacing,
            TouchInsetManager.TouchInsetSession session,
            @Named(COMPLICATIONS_FADE_IN_DURATION) int fadeInDuration,
            @Named(COMPLICATIONS_FADE_OUT_DURATION) int fadeOutDuration) {
        mLayout = layout;
        mDefaultMargin = defaultMargin;
        mDefaultDirectionalSpacing = defaultDirectionalSpacing;
        mSession = session;
        mFadeInDuration = fadeInDuration;
        mFadeOutDuration = fadeOutDuration;
@@ -537,13 +587,12 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
            removeComplication(id);
        }

        final ViewEntry.Builder entryBuilder = new ViewEntry.Builder(view, mSession, lp, category)
                .setDefaultMargin(mDefaultMargin);
        final ViewEntry.Builder entryBuilder = new ViewEntry.Builder(view, mSession, lp, category);

        // Add position group if doesn't already exist
        final int position = lp.getPosition();
        if (!mPositions.containsKey(position)) {
            mPositions.put(position, new PositionGroup());
            mPositions.put(position, new PositionGroup(mDefaultDirectionalSpacing));
        }

        // Insert entry into group
+22 −19
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
    private static final int FIRST_POSITION = POSITION_TOP;
    private static final int LAST_POSITION = POSITION_END;

    private static final int MARGIN_UNSPECIFIED = 0xFFFFFFFF;
    private static final int DIRECTIONAL_SPACING_UNSPECIFIED = 0xFFFFFFFF;
    private static final int CONSTRAINT_UNSPECIFIED = 0xFFFFFFFF;

    @Retention(RetentionPolicy.SOURCE)
@@ -80,7 +80,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {

    private final int mWeight;

    private final int mMargin;
    private final int mDirectionalSpacing;

    private final int mConstraint;

@@ -113,8 +113,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight) {
        this(width, height, position, direction, weight, MARGIN_UNSPECIFIED, CONSTRAINT_UNSPECIFIED,
                false);
        this(width, height, position, direction, weight, DIRECTIONAL_SPACING_UNSPECIFIED,
                CONSTRAINT_UNSPECIFIED, false);
    }

    /**
@@ -127,11 +127,12 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     * @param weight The weight that should be considered for this view when compared to other
     *               views. This has an impact on the placement of the view but not the rendering of
     *               the view.
     * @param margin The margin to apply between complications.
     * @param directionalSpacing The spacing to apply between complications.
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight, int margin) {
        this(width, height, position, direction, weight, margin, CONSTRAINT_UNSPECIFIED, false);
            @Direction int direction, int weight, int directionalSpacing) {
        this(width, height, position, direction, weight, directionalSpacing, CONSTRAINT_UNSPECIFIED,
                false);
    }

    /**
@@ -144,14 +145,14 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     * @param weight The weight that should be considered for this view when compared to other
     *               views. This has an impact on the placement of the view but not the rendering of
     *               the view.
     * @param margin The margin to apply between complications.
     * @param directionalSpacing The spacing to apply between complications.
     * @param constraint The max width or height the complication is allowed to spread, depending on
     *                   its direction. For horizontal directions, this would be applied on width,
     *                   and for vertical directions, height.
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight, int margin, int constraint) {
        this(width, height, position, direction, weight, margin, constraint, false);
            @Direction int direction, int weight, int directionalSpacing, int constraint) {
        this(width, height, position, direction, weight, directionalSpacing, constraint, false);
    }

    /**
@@ -172,8 +173,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight, boolean snapToGuide) {
        this(width, height, position, direction, weight, MARGIN_UNSPECIFIED, CONSTRAINT_UNSPECIFIED,
                snapToGuide);
        this(width, height, position, direction, weight, DIRECTIONAL_SPACING_UNSPECIFIED,
                CONSTRAINT_UNSPECIFIED, snapToGuide);
    }

    /**
@@ -186,7 +187,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     * @param weight The weight that should be considered for this view when compared to other
     *               views. This has an impact on the placement of the view but not the rendering of
     *               the view.
     * @param margin The margin to apply between complications.
     * @param directionalSpacing The spacing to apply between complications.
     * @param constraint The max width or height the complication is allowed to spread, depending on
     *                   its direction. For horizontal directions, this would be applied on width,
     *                   and for vertical directions, height.
@@ -197,7 +198,8 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
     *                    from the end of the parent to the guide.
     */
    public ComplicationLayoutParams(int width, int height, @Position int position,
            @Direction int direction, int weight, int margin, int constraint, boolean snapToGuide) {
            @Direction int direction, int weight, int directionalSpacing, int constraint,
            boolean snapToGuide) {
        super(width, height);

        if (!validatePosition(position)) {
@@ -213,7 +215,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {

        mWeight = weight;

        mMargin = margin;
        mDirectionalSpacing = directionalSpacing;

        mConstraint = constraint;

@@ -228,7 +230,7 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
        mPosition = source.mPosition;
        mDirection = source.mDirection;
        mWeight = source.mWeight;
        mMargin = source.mMargin;
        mDirectionalSpacing = source.mDirectionalSpacing;
        mConstraint = source.mConstraint;
        mSnapToGuide = source.mSnapToGuide;
    }
@@ -300,11 +302,12 @@ public class ComplicationLayoutParams extends ViewGroup.LayoutParams {
    }

    /**
     * Returns the margin to apply between complications, or the given default if no margin is
     * Returns the spacing to apply between complications, or the given default if no spacing is
     * specified.
     */
    public int getMargin(int defaultMargin) {
        return mMargin == MARGIN_UNSPECIFIED ? defaultMargin : mMargin;
    public int getDirectionalSpacing(int defaultSpacing) {
        return mDirectionalSpacing == DIRECTIONAL_SPACING_UNSPECIFIED
                ? defaultSpacing : mDirectionalSpacing;
    }

    /**
+3 −2
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ import javax.inject.Named;
@Module
public abstract class ComplicationHostViewModule {
    public static final String SCOPED_COMPLICATIONS_LAYOUT = "scoped_complications_layout";
    public static final String COMPLICATION_MARGIN_DEFAULT = "complication_margin_default";
    public static final String COMPLICATION_DIRECTIONAL_SPACING_DEFAULT =
            "complication_directional_spacing_default";
    public static final String COMPLICATIONS_FADE_OUT_DURATION = "complications_fade_out_duration";
    public static final String COMPLICATIONS_FADE_IN_DURATION = "complications_fade_in_duration";
    public static final String COMPLICATIONS_RESTORE_TIMEOUT = "complication_restore_timeout";
@@ -58,7 +59,7 @@ public abstract class ComplicationHostViewModule {
    }

    @Provides
    @Named(COMPLICATION_MARGIN_DEFAULT)
    @Named(COMPLICATION_DIRECTIONAL_SPACING_DEFAULT)
    static int providesComplicationPadding(@Main Resources resources) {
        return resources.getDimensionPixelSize(R.dimen.dream_overlay_complication_margin);
    }
+4 −4
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase {
                ComplicationLayoutParams.POSITION_TOP,
                ComplicationLayoutParams.DIRECTION_DOWN,
                3);
        assertThat(params.getMargin(10) == 10).isTrue();
        assertThat(params.getDirectionalSpacing(10) == 10).isTrue();
    }

    /**
@@ -127,7 +127,7 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase {
                ComplicationLayoutParams.DIRECTION_DOWN,
                3,
                10);
        assertThat(params.getMargin(5) == 10).isTrue();
        assertThat(params.getDirectionalSpacing(5) == 10).isTrue();
    }

    /**
@@ -148,7 +148,7 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase {
        assertThat(copy.getDirection() == params.getDirection()).isTrue();
        assertThat(copy.getPosition() == params.getPosition()).isTrue();
        assertThat(copy.getWeight() == params.getWeight()).isTrue();
        assertThat(copy.getMargin(0) == params.getMargin(1)).isTrue();
        assertThat(copy.getDirectionalSpacing(0) == params.getDirectionalSpacing(1)).isTrue();
        assertThat(copy.getConstraint() == params.getConstraint()).isTrue();
        assertThat(copy.height == params.height).isTrue();
        assertThat(copy.width == params.width).isTrue();
@@ -171,7 +171,7 @@ public class ComplicationLayoutParamsTest extends SysuiTestCase {
        assertThat(copy.getDirection() == params.getDirection()).isTrue();
        assertThat(copy.getPosition() == params.getPosition()).isTrue();
        assertThat(copy.getWeight() == params.getWeight()).isTrue();
        assertThat(copy.getMargin(1) == params.getMargin(1)).isTrue();
        assertThat(copy.getDirectionalSpacing(1) == params.getDirectionalSpacing(1)).isTrue();
        assertThat(copy.height == params.height).isTrue();
        assertThat(copy.width == params.width).isTrue();
    }