diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_activity.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
similarity index 93%
rename from libs/WindowManager/Shell/res/layout/bubble_overflow_activity.xml
rename to libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
index 306061911f8dc..8224d95fd9adf 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_overflow_activity.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml
@@ -14,7 +14,7 @@
~ limitations under the License
-->
-
-
+
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index cb6b54321b5e3..67f4cd25c487e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -24,7 +24,6 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.wm.shell.bubbles.BubbleOverflowActivity.EXTRA_BUBBLE_CONTROLLER;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
@@ -37,14 +36,16 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Outline;
+import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.ShapeDrawable;
-import android.os.Bundle;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
@@ -77,6 +78,7 @@ public class BubbleExpandedView extends LinearLayout {
private AlphaOptimizedButton mSettingsIcon;
private TaskView mTaskView;
+ private BubbleOverflowContainerView mOverflowView;
private int mTaskId = INVALID_TASK_ID;
@@ -125,6 +127,7 @@ public class BubbleExpandedView extends LinearLayout {
if (mDestroyed || mInitialized) {
return;
}
+
// Custom options so there is no activity transition animation
ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
0 /* enterResId */, 0 /* exitResId */);
@@ -307,15 +310,25 @@ public class BubbleExpandedView extends LinearLayout {
* Initialize {@link BubbleController} and {@link BubbleStackView} here, this method must need
* to be called after view inflate.
*/
- void initialize(BubbleController controller, BubbleStackView stackView) {
+ void initialize(BubbleController controller, BubbleStackView stackView, boolean isOverflow) {
mController = controller;
mStackView = stackView;
-
- mTaskView = new TaskView(mContext, mController.getTaskOrganizer());
- mExpandedViewContainer.addView(mTaskView);
- bringChildToFront(mTaskView);
- mTaskView.setListener(mContext.getMainExecutor(), mTaskViewListener);
+ mIsOverflow = isOverflow;
mPositioner = mController.getPositioner();
+
+ if (mIsOverflow) {
+ mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate(
+ R.layout.bubble_overflow_container, null /* root */);
+ mOverflowView.setBubbleController(mController);
+ mExpandedViewContainer.addView(mOverflowView);
+ bringChildToFront(mOverflowView);
+ mSettingsIcon.setVisibility(GONE);
+ } else {
+ mTaskView = new TaskView(mContext, mController.getTaskOrganizer());
+ mTaskView.setListener(mContext.getMainExecutor(), mTaskViewListener);
+ mExpandedViewContainer.addView(mTaskView);
+ bringChildToFront(mTaskView);
+ }
}
void updateDimensions() {
@@ -390,6 +403,17 @@ public class BubbleExpandedView extends LinearLayout {
/** Return a GraphicBuffer with the contents of the task view surface. */
@Nullable
SurfaceControl.ScreenshotHardwareBuffer snapshotActivitySurface() {
+ if (mIsOverflow) {
+ // For now, just snapshot the view and return it as a hw buffer so that the animation
+ // code for both the tasks and overflow can be the same
+ Picture p = new Picture();
+ mOverflowView.draw(
+ p.beginRecording(mOverflowView.getWidth(), mOverflowView.getHeight()));
+ p.endRecording();
+ Bitmap snapshot = Bitmap.createBitmap(p);
+ return new SurfaceControl.ScreenshotHardwareBuffer(snapshot.getHardwareBuffer(),
+ snapshot.getColorSpace(), false /* containsSecureLayers */);
+ }
if (mTaskView == null || mTaskView.getSurfaceControl() == null) {
return null;
}
@@ -400,6 +424,11 @@ public class BubbleExpandedView extends LinearLayout {
}
int[] getTaskViewLocationOnScreen() {
+ if (mIsOverflow) {
+ // This is only used for animating away the surface when switching bubbles, just use the
+ // view location on screen for now to allow us to use the same animation code with tasks
+ return mOverflowView.getLocationOnScreen();
+ }
if (mTaskView != null) {
return mTaskView.getLocationOnScreen();
} else {
@@ -450,10 +479,7 @@ public class BubbleExpandedView extends LinearLayout {
final float alpha = visibility ? 1f : 0f;
mPointerView.setAlpha(alpha);
- if (mTaskView == null) {
- return;
- }
- if (alpha != mTaskView.getAlpha()) {
+ if (mTaskView != null) {
mTaskView.setAlpha(alpha);
}
}
@@ -467,19 +493,6 @@ public class BubbleExpandedView extends LinearLayout {
return mTaskId;
}
- public void setOverflow(boolean overflow) {
- mIsOverflow = overflow;
-
- Intent target = new Intent(mContext, BubbleOverflowActivity.class);
- target.addFlags(FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK);
- Bundle extras = new Bundle();
- extras.putBinder(EXTRA_BUBBLE_CONTROLLER, ObjectWrapper.wrap(mController));
- target.putExtras(extras);
- mPendingIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */,
- target, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
- mSettingsIcon.setVisibility(GONE);
- }
-
/**
* Sets the bubble used to populate this view.
*/
@@ -511,7 +524,8 @@ public class BubbleExpandedView extends LinearLayout {
if (isNew) {
mPendingIntent = mBubble.getBubbleIntent();
- if (mPendingIntent != null || mBubble.hasMetadataShortcutId()) {
+ if ((mPendingIntent != null || mBubble.hasMetadataShortcutId())
+ && mTaskView != null) {
setContentVisibility(false);
mTaskView.setVisibility(VISIBLE);
}
@@ -552,13 +566,19 @@ public class BubbleExpandedView extends LinearLayout {
desiredHeight = Math.max(desiredHeight, mMinHeight);
float height = Math.min(desiredHeight, getMaxExpandedHeight());
height = Math.max(height, mMinHeight);
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mTaskView.getLayoutParams();
+ FrameLayout.LayoutParams lp = mIsOverflow
+ ? (FrameLayout.LayoutParams) mOverflowView.getLayoutParams()
+ : (FrameLayout.LayoutParams) mTaskView.getLayoutParams();
mNeedsNewHeight = lp.height != height;
if (!mImeVisible) {
// If the ime is visible... don't adjust the height because that will cause
// a configuration change and the ime will be lost.
lp.height = (int) height;
- mTaskView.setLayoutParams(lp);
+ if (mIsOverflow) {
+ mOverflowView.setLayoutParams(lp);
+ } else {
+ mTaskView.setLayoutParams(lp);
+ }
mNeedsNewHeight = false;
}
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
@@ -602,6 +622,9 @@ public class BubbleExpandedView extends LinearLayout {
updateHeight();
mTaskView.onLocationChanged();
}
+ if (mIsOverflow) {
+ mOverflowView.show();
+ }
}
/**
@@ -637,8 +660,8 @@ public class BubbleExpandedView extends LinearLayout {
/**
* Cleans up anything related to the task and TaskView. If this view should be reused after this
- * method is called, then {@link #initialize(BubbleController, BubbleStackView)} must be invoked
- * first.
+ * method is called, then {@link #initialize(BubbleController, BubbleStackView, boolean)} must
+ * be invoked first.
*/
public void cleanUpExpandedState() {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
@@ -653,8 +676,6 @@ public class BubbleExpandedView extends LinearLayout {
}
if (mTaskView != null) {
mTaskView.release();
- }
- if (mTaskView != null) {
removeView(mTaskView);
mTaskView = null;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index 8ab2f6325d2ba..c7219089bffe3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -65,8 +65,7 @@ class BubbleOverflow(
/** Call before use and again if cleanUpExpandedState was called. */
fun initialize(controller: BubbleController) {
- getExpandedView()?.initialize(controller, controller.stackView)
- getExpandedView()?.setOverflow(true)
+ getExpandedView()?.initialize(controller, controller.stackView, true /* isOverflow */)
}
fun cleanUpExpandedState() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
similarity index 87%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index cfd0066e0fc3b..39e4e1a090197 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowActivity.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -29,16 +29,21 @@ import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Bundle;
import android.os.IBinder;
+import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -50,10 +55,9 @@ import java.util.List;
import java.util.function.Consumer;
/**
- * Activity for showing aged out bubbles.
- * Must be public to be accessible to androidx...AppComponentFactory
+ * Container view for showing aged out bubbles.
*/
-public class BubbleOverflowActivity extends Activity {
+public class BubbleOverflowContainerView extends LinearLayout {
static final String EXTRA_BUBBLE_CONTROLLER = "bubble_controller";
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES;
@@ -95,37 +99,55 @@ public class BubbleOverflowActivity extends Activity {
}
}
+ public BubbleOverflowContainerView(Context context) {
+ super(context);
+ }
+
+ public BubbleOverflowContainerView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public BubbleOverflowContainerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public BubbleOverflowContainerView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ public void setBubbleController(BubbleController controller) {
+ mController = controller;
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ updateOverflow();
+ }
+
+ public void hide() {
+ setVisibility(View.INVISIBLE);
+ }
+
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.bubble_overflow_activity);
+ protected void onFinishInflate() {
+ super.onFinishInflate();
mRecyclerView = findViewById(R.id.bubble_overflow_recycler);
mEmptyState = findViewById(R.id.bubble_overflow_empty_state);
mEmptyStateTitle = findViewById(R.id.bubble_overflow_empty_title);
mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle);
mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image);
-
- Intent intent = getIntent();
- if (intent != null && intent.getExtras() != null) {
- IBinder binder = intent.getExtras().getBinder(EXTRA_BUBBLE_CONTROLLER);
- if (binder instanceof ObjectWrapper) {
- mController = ((ObjectWrapper) binder).get();
- updateOverflow();
- }
- } else {
- Log.w(TAG, "Bubble overflow activity created without bubble controller!");
- }
}
void updateOverflow() {
Resources res = getResources();
final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
mRecyclerView.setLayoutManager(
- new NoScrollGridLayoutManager(getApplicationContext(), columns));
+ new NoScrollGridLayoutManager(getContext(), columns));
DisplayMetrics displayMetrics = new DisplayMetrics();
- getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
+ getContext().getDisplay().getMetrics(displayMetrics);
final int overflowPadding = res.getDimensionPixelSize(R.dimen.bubble_overflow_padding);
final int recyclerViewWidth = displayMetrics.widthPixels - (overflowPadding * 2);
@@ -137,7 +159,7 @@ public class BubbleOverflowActivity extends Activity {
- res.getDimensionPixelSize(R.dimen.bubble_overflow_padding);
final int viewHeight = recyclerViewHeight / rows;
- mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles,
+ mAdapter = new BubbleOverflowAdapter(getContext(), mOverflowBubbles,
mController::promoteBubbleFromOverflow,
mController.getPositioner(),
viewWidth, viewHeight);
@@ -146,6 +168,11 @@ public class BubbleOverflowActivity extends Activity {
mOverflowBubbles.clear();
mOverflowBubbles.addAll(mController.getOverflowBubbles());
mAdapter.notifyDataSetChanged();
+
+ // Currently BubbleExpandedView.mExpandedViewContainer is WRAP_CONTENT so use the same
+ // width we would use for the recycler view
+ LayoutParams lp = (LayoutParams) mEmptyState.getLayoutParams();
+ lp.width = recyclerViewWidth;
updateEmptyStateVisibility();
mController.setOverflowListener(mDataListener);
@@ -172,12 +199,12 @@ public class BubbleOverflowActivity extends Activity {
? res.getDrawable(R.drawable.bubble_ic_empty_overflow_dark)
: res.getDrawable(R.drawable.bubble_ic_empty_overflow_light));
- findViewById(android.R.id.content)
+ findViewById(R.id.bubble_overflow_container)
.setBackgroundColor(isNightMode
? res.getColor(R.color.bubbles_dark)
: res.getColor(R.color.bubbles_light));
- final TypedArray typedArray = getApplicationContext().obtainStyledAttributes(
+ final TypedArray typedArray = getContext().obtainStyledAttributes(
new int[]{android.R.attr.colorBackgroundFloating,
android.R.attr.textColorSecondary});
int bgColor = typedArray.getColor(0, isNightMode ? Color.BLACK : Color.WHITE);
@@ -222,36 +249,6 @@ public class BubbleOverflowActivity extends Activity {
}
}
};
-
- @Override
- public void onStart() {
- super.onStart();
- }
-
- @Override
- public void onRestart() {
- super.onRestart();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updateOverflow();
- }
-
- @Override
- public void onPause() {
- super.onPause();
- }
-
- @Override
- public void onStop() {
- super.onStop();
- }
-
- public void onDestroy() {
- super.onDestroy();
- }
}
class BubbleOverflowAdapter extends RecyclerView.Adapter {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index e21ba6392e95b..0e7e92d9554ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -138,7 +138,7 @@ public class BubbleViewInfoTask extends AsyncTask
-
-
-
-
-