Merge "Adds an overflow bubble to the bubble bar." into udc-qpr-dev

This commit is contained in:
Treehugger Robot
2023-06-07 22:09:31 +00:00
committed by Android (Google) Code Review
6 changed files with 105 additions and 15 deletions

View File

@@ -363,6 +363,7 @@
<dimen name="bubblebar_icon_size">50dp</dimen>
<dimen name="bubblebar_badge_size">24dp</dimen>
<dimen name="bubblebar_icon_overlap">12dp</dimen>
<dimen name="bubblebar_overflow_inset">24dp</dimen>
<dimen name="bubblebar_icon_spacing">3dp</dimen>
<dimen name="bubblebar_icon_elevation">1dp</dimen>

View File

@@ -38,11 +38,15 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Path;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.os.Bundle;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -51,6 +55,8 @@ import android.util.Log;
import android.util.PathParser;
import android.view.LayoutInflater;
import androidx.appcompat.content.res.AppCompatResources;
import com.android.internal.graphics.ColorUtils;
import com.android.launcher3.R;
import com.android.launcher3.icons.BitmapInfo;
@@ -113,7 +119,8 @@ public class BubbleBarController extends IBubblesListener.Stub {
private final LauncherApps mLauncherApps;
private final BubbleIconFactory mIconFactory;
private BubbleBarBubble mSelectedBubble;
private BubbleBarItem mSelectedBubble;
private BubbleBarOverflow mOverflowBubble;
private BubbleBarViewController mBubbleBarViewController;
private BubbleStashController mBubbleStashController;
@@ -178,6 +185,16 @@ public class BubbleBarController extends IBubblesListener.Stub {
mBubbleBarViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
mBubbleStashedHandleViewController.setHiddenForBubbles(!BUBBLE_BAR_ENABLED);
});
BUBBLE_STATE_EXECUTOR.execute(() -> {
if (mOverflowBubble == null) {
BubbleBarOverflow overflow = createOverflow(mContext);
mMainExecutor.execute(() -> {
mBubbleBarViewController.addBubble(overflow);
mOverflowBubble = overflow;
});
}
});
}
/**
@@ -329,7 +346,7 @@ public class BubbleBarController extends IBubblesListener.Stub {
* WMShell that the selection has changed, that should go through
* {@link SystemUiProxy#showBubble}.
*/
public void setSelectedBubble(BubbleBarBubble b) {
public void setSelectedBubble(BubbleBarItem b) {
if (!Objects.equals(b, mSelectedBubble)) {
if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey());
mSelectedBubble = b;
@@ -424,7 +441,6 @@ public class BubbleBarController extends IBubblesListener.Stub {
dotColor = ColorUtils.blendARGB(badgeBitmapInfo.color,
Color.WHITE, WHITE_SCRIM_ALPHA);
LayoutInflater inflater = LayoutInflater.from(context);
BubbleView bubbleView = (BubbleView) inflater.inflate(
R.layout.bubblebar_item_view, bbv, false /* attachToRoot */);
@@ -434,4 +450,37 @@ public class BubbleBarController extends IBubblesListener.Stub {
bubbleView.setBubble(bubble);
return bubble;
}
private BubbleBarOverflow createOverflow(Context context) {
Bitmap bitmap = createOverflowBitmap(context);
LayoutInflater inflater = LayoutInflater.from(context);
BubbleView bubbleView = (BubbleView) inflater.inflate(
R.layout.bubblebar_item_view, mBarView, false /* attachToRoot */);
BubbleBarOverflow overflow = new BubbleBarOverflow(bubbleView);
bubbleView.setOverflow(overflow, bitmap);
return overflow;
}
private Bitmap createOverflowBitmap(Context context) {
Drawable iconDrawable = AppCompatResources.getDrawable(mContext,
R.drawable.bubble_ic_overflow_button);
final TypedArray ta = mContext.obtainStyledAttributes(
new int[]{
com.android.internal.R.attr.materialColorOnPrimaryFixed,
com.android.internal.R.attr.materialColorPrimaryFixed
});
int overflowIconColor = ta.getColor(0, Color.WHITE);
int overflowBackgroundColor = ta.getColor(1, Color.BLACK);
ta.recycle();
iconDrawable.setTint(overflowIconColor);
int inset = context.getResources().getDimensionPixelSize(R.dimen.bubblebar_overflow_inset);
Drawable foreground = new InsetDrawable(iconDrawable, inset);
Drawable drawable = new AdaptiveIconDrawable(new ColorDrawable(overflowBackgroundColor),
foreground);
return mIconFactory.createBadgedIconBitmap(drawable).icon;
}
}

View File

@@ -19,16 +19,19 @@ import android.graphics.Bitmap
import android.graphics.Path
import com.android.wm.shell.common.bubbles.BubbleInfo
/** An entity in the bubble bar. */
sealed class BubbleBarItem(open val key: String, open val view: BubbleView)
/** Contains state info about a bubble in the bubble bar as well as presentation information. */
data class BubbleBarBubble(
val info: BubbleInfo,
val view: BubbleView,
override val view: BubbleView,
val badge: Bitmap,
val icon: Bitmap,
val dotColor: Int,
val dotPath: Path,
val appName: String
) {
) : BubbleBarItem(info.key, view)
val key: String = info.key
}
/** Represents the overflow bubble in the bubble bar. */
data class BubbleBarOverflow(override val view: BubbleView) : BubbleBarItem("overflow", view)

View File

@@ -101,7 +101,7 @@ public class BubbleBarViewController {
}
private void onBubbleClicked(View v) {
BubbleBarBubble bubble = ((BubbleView) v).getBubble();
BubbleBarItem bubble = ((BubbleView) v).getBubble();
if (bubble == null) {
Log.e(TAG, "bubble click listener, bubble was null");
}
@@ -236,7 +236,7 @@ public class BubbleBarViewController {
/**
* Removes the provided bubble from the bubble bar.
*/
public void removeBubble(BubbleBarBubble b) {
public void removeBubble(BubbleBarItem b) {
if (b != null) {
mBarView.removeView(b.getView());
} else {
@@ -247,7 +247,7 @@ public class BubbleBarViewController {
/**
* Adds the provided bubble to the bubble bar.
*/
public void addBubble(BubbleBarBubble b) {
public void addBubble(BubbleBarItem b) {
if (b != null) {
mBarView.addView(b.getView(), 0, new FrameLayout.LayoutParams(mIconSize, mIconSize));
b.getView().setOnClickListener(mBubbleClickListener);
@@ -268,7 +268,7 @@ public class BubbleBarViewController {
/**
* Updates the selected bubble.
*/
public void updateSelectedBubble(BubbleBarBubble newlySelected) {
public void updateSelectedBubble(BubbleBarItem newlySelected) {
mBarView.setSelectedBubble(newlySelected.getView());
}

View File

@@ -32,6 +32,7 @@ import com.android.launcher3.icons.IconNormalizer;
// TODO: (b/276978250) This is will be similar to WMShell's BadgedImageView, it'd be nice to share.
// TODO: (b/269670235) currently this doesn't show the 'update dot'
/**
* View that displays a bubble icon, along with an app badge on either the left or
* right side of the view.
@@ -48,7 +49,7 @@ public class BubbleView extends ConstraintLayout {
// TODO: (b/273310265) handle RTL
private boolean mOnLeft = false;
private BubbleBarBubble mBubble;
private BubbleBarItem mBubble;
public BubbleView(Context context) {
this(context, null);
@@ -97,15 +98,27 @@ public class BubbleView extends ConstraintLayout {
mAppIcon.setImageBitmap(bubble.getBadge());
}
void setOverflow(BubbleBarOverflow overflow, Bitmap bitmap) {
mBubble = overflow;
mBubbleIcon.setImageBitmap(bitmap);
hideBadge();
}
/** Returns the bubble being rendered in this view. */
@Nullable
BubbleBarBubble getBubble() {
BubbleBarItem getBubble() {
return mBubble;
}
/** Shows the app badge on this bubble. */
void showBadge() {
Bitmap appBadgeBitmap = mBubble.getBadge();
if (mBubble instanceof BubbleBarOverflow) {
// The overflow bubble does not have a badge, so just bail.
return;
}
BubbleBarBubble bubble = (BubbleBarBubble) mBubble;
Bitmap appBadgeBitmap = bubble.getBadge();
if (appBadgeBitmap == null) {
mAppIcon.setVisibility(GONE);
return;
@@ -113,7 +126,7 @@ public class BubbleView extends ConstraintLayout {
int translationX;
if (mOnLeft) {
translationX = -(mBubble.getIcon().getWidth() - appBadgeBitmap.getWidth());
translationX = -(bubble.getIcon().getWidth() - appBadgeBitmap.getWidth());
} else {
translationX = 0;
}

View File

@@ -0,0 +1,24 @@
<!--
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:viewportWidth="24"
android:viewportHeight="24"
android:width="24dp"
android:height="24dp">
<path
android:fillColor="#1A73E8"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>