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

Commit 28aef0fe authored by Ivan Tkachenko's avatar Ivan Tkachenko Committed by Android (Google) Code Review
Browse files

Merge "Bubble bar user education" into main

parents 37429533 1b6a0e70
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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
  -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
  <path
      android:pathData="M4,18H20V6H4V18ZM22,18C22,19.1 21.1,20 20,20H4C2.9,20 2,19.1 2,18V6C2,4.9 2.9,4 4,4H20C21.1,4 22,4.9 22,6V18ZM13,8H18V14H13V8Z"
      android:fillColor="#455A64"
      android:fillType="evenOdd"/>
</vector>
+56 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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
  -->
<com.android.wm.shell.common.bubbles.BubblePopupView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="@dimen/bubble_popup_margin_horizontal"
    android:layout_marginBottom="120dp"
    android:elevation="@dimen/bubble_manage_menu_elevation"
    android:gravity="center_horizontal"
    android:orientation="vertical">

    <ImageView
        android:layout_width="32dp"
        android:layout_height="32dp"
        android:tint="?android:attr/colorAccent"
        android:contentDescription="@null"
        android:src="@drawable/ic_floating_landscape"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:maxWidth="@dimen/bubble_popup_content_max_width"
        android:maxLines="1"
        android:ellipsize="end"
        android:textAppearance="@android:style/TextAppearance.DeviceDefault.Headline"
        android:textColor="?android:attr/textColorPrimary"
        android:text="@string/bubble_bar_education_stack_title"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:maxWidth="@dimen/bubble_popup_content_max_width"
        android:textAppearance="@android:style/TextAppearance.DeviceDefault"
        android:textColor="?android:attr/textColorSecondary"
        android:textAlignment="center"
        android:text="@string/bubble_bar_education_stack_text"/>

</com.android.wm.shell.common.bubbles.BubblePopupView>
 No newline at end of file
+4 −0
Original line number Diff line number Diff line
@@ -163,6 +163,10 @@
    <!-- [CHAR LIMIT=NONE] Empty overflow subtitle -->
    <string name="bubble_overflow_empty_subtitle">Recent bubbles and dismissed bubbles will appear here</string>

    <!-- Title text for the bubble bar feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=60]-->
    <string name="bubble_bar_education_stack_title">Chat using bubbles</string>
    <!-- Descriptive text for the bubble bar feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=NONE] -->
    <string name="bubble_bar_education_stack_text">New conversations appear as icons in a bottom corner of your screen. Tap to expand them or drag to dismiss them.</string>
    <!-- Title text for the bubble bar "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=60]-->
    <string name="bubble_bar_education_manage_title">Control bubbles anytime</string>
    <!-- Descriptive text for the bubble bar "manage" button tool tip highlighting where users can go to control bubble settings. [CHAR LIMIT=80]-->
+28 −1
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.content.pm.ShortcutInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Binder;
@@ -1063,6 +1064,15 @@ public class BubbleController implements ConfigurationChangeListener,
        }
    }

    /**
     * Show bubble bar user education relative to the reference position.
     * @param position the reference position in Screen coordinates.
     */
    public void showUserEducation(Point position) {
        if (mLayerView == null) return;
        mLayerView.showUserEducation(position);
    }

    @VisibleForTesting
    public boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey) {
        boolean isSuppressedBubble = (mBubbleData.hasAnyBubbleWithKey(key)
@@ -1114,6 +1124,16 @@ public class BubbleController implements ConfigurationChangeListener,
        }
    }

    /**
     * Expands the stack if the selected bubble is present. This is currently used when user
     * education view is clicked to expand the selected bubble.
     */
    public void expandStackWithSelectedBubble() {
        if (mBubbleData.getSelectedBubble() != null) {
            mBubbleData.setExpanded(true);
        }
    }

    /**
     * Expands and selects the provided bubble as long as it already exists in the stack or the
     * overflow. This is currently used when opening a bubble via clicking on a conversation widget.
@@ -1730,7 +1750,8 @@ public class BubbleController implements ConfigurationChangeListener,
                        + " expandedChanged=" + update.expandedChanged
                        + " selectionChanged=" + update.selectionChanged
                        + " suppressed=" + (update.suppressedBubble != null)
                        + " unsuppressed=" + (update.unsuppressedBubble != null));
                        + " unsuppressed=" + (update.unsuppressedBubble != null)
                        + " shouldShowEducation=" + update.shouldShowEducation);
            }

            ensureBubbleViewsAndWindowCreated();
@@ -2155,6 +2176,12 @@ public class BubbleController implements ConfigurationChangeListener,
        public void onBubbleDrag(String bubbleKey, boolean isBeingDragged) {
            mMainExecutor.execute(() -> mController.onBubbleDrag(bubbleKey, isBeingDragged));
        }

        @Override
        public void showUserEducation(int positionX, int positionY) {
            mMainExecutor.execute(() ->
                    mController.showUserEducation(new Point(positionX, positionY)));
        }
    }

    private class BubblesImpl implements Bubbles {
+10 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ public class BubbleData {
        boolean orderChanged;
        boolean suppressedSummaryChanged;
        boolean expanded;
        boolean shouldShowEducation;
        @Nullable BubbleViewProvider selectedBubble;
        @Nullable Bubble addedBubble;
        @Nullable Bubble updatedBubble;
@@ -126,6 +127,7 @@ public class BubbleData {

            bubbleBarUpdate.expandedChanged = expandedChanged;
            bubbleBarUpdate.expanded = expanded;
            bubbleBarUpdate.shouldShowEducation = shouldShowEducation;
            if (selectionChanged) {
                bubbleBarUpdate.selectedBubbleKey = selectedBubble != null
                        ? selectedBubble.getKey()
@@ -165,6 +167,7 @@ public class BubbleData {
         */
        BubbleBarUpdate getInitialState() {
            BubbleBarUpdate bubbleBarUpdate = new BubbleBarUpdate();
            bubbleBarUpdate.shouldShowEducation = shouldShowEducation;
            for (int i = 0; i < bubbles.size(); i++) {
                bubbleBarUpdate.currentBubbleList.add(bubbles.get(i).asBubbleBarBubble());
            }
@@ -187,6 +190,7 @@ public class BubbleData {

    private final Context mContext;
    private final BubblePositioner mPositioner;
    private final BubbleEducationController mEducationController;
    private final Executor mMainExecutor;
    /** Bubbles that are actively in the stack. */
    private final List<Bubble> mBubbles;
@@ -233,10 +237,11 @@ public class BubbleData {
    private HashMap<String, String> mSuppressedGroupKeys = new HashMap<>();

    public BubbleData(Context context, BubbleLogger bubbleLogger, BubblePositioner positioner,
            Executor mainExecutor) {
            BubbleEducationController educationController, Executor mainExecutor) {
        mContext = context;
        mLogger = bubbleLogger;
        mPositioner = positioner;
        mEducationController = educationController;
        mMainExecutor = mainExecutor;
        mOverflow = new BubbleOverflow(context, positioner);
        mBubbles = new ArrayList<>();
@@ -447,6 +452,7 @@ public class BubbleData {
        if (bubble.shouldAutoExpand()) {
            bubble.setShouldAutoExpand(false);
            setSelectedBubbleInternal(bubble);

            if (!mExpanded) {
                setExpandedInternal(true);
            }
@@ -877,6 +883,9 @@ public class BubbleData {

    private void dispatchPendingChanges() {
        if (mListener != null && mStateChange.anythingChanged()) {
            mStateChange.shouldShowEducation = mSelectedBubble != null
                    && mEducationController.shouldShowStackEducation(mSelectedBubble)
                    && !mExpanded;
            mListener.applyUpdate(mStateChange);
        }
        mStateChange = new Update(mBubbles, mOverflowBubbles);
Loading