summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/WindowManager/Shell/AndroidManifest.xml24
-rw-r--r--libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget.xml19
-rw-r--r--libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_background.xml24
-rw-r--r--libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_foreground.xml36
-rw-r--r--libs/WindowManager/Shell/res/values/strings.xml6
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java53
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/BubbleShortcutHelper.kt40
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt52
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt59
10 files changed, 316 insertions, 0 deletions
diff --git a/libs/WindowManager/Shell/AndroidManifest.xml b/libs/WindowManager/Shell/AndroidManifest.xml
index 7a986835359a..bcb1d292fce2 100644
--- a/libs/WindowManager/Shell/AndroidManifest.xml
+++ b/libs/WindowManager/Shell/AndroidManifest.xml
@@ -30,5 +30,29 @@
android:excludeFromRecents="true"
android:launchMode="singleInstance"
android:theme="@style/DesktopWallpaperTheme" />
+
+ <activity
+ android:name=".bubbles.shortcut.CreateBubbleShortcutActivity"
+ android:exported="true"
+ android:excludeFromRecents="true"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:label="Bubbles"
+ android:icon="@drawable/ic_bubbles_shortcut_widget">
+ <intent-filter>
+ <action android:name="android.intent.action.CREATE_SHORTCUT" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".bubbles.shortcut.ShowBubblesActivity"
+ android:exported="true"
+ android:excludeFromRecents="true"
+ android:theme="@android:style/Theme.NoDisplay" >
+ <intent-filter>
+ <action android:name="com.android.wm.shell.bubbles.action.SHOW_BUBBLES"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget.xml b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget.xml
new file mode 100644
index 000000000000..b208f2fea7b2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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.
+ -->
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@drawable/ic_bubbles_shortcut_widget_background" />
+ <foreground android:drawable="@drawable/ic_bubbles_shortcut_widget_foreground" />
+</adaptive-icon>
diff --git a/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_background.xml b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_background.xml
new file mode 100644
index 000000000000..510221fb2859
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_background.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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="108dp"
+ android:height="108dp"
+ android:viewportWidth="108"
+ android:viewportHeight="108">
+ <path
+ android:pathData="M0,0h108v108h-108z"
+ android:fillColor="#FFC20C"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_foreground.xml b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_foreground.xml
new file mode 100644
index 000000000000..a41b6a961bb2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_bubbles_shortcut_widget_foreground.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2024 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="108dp"
+ android:height="108dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/white">
+ <group android:scaleX="0.58"
+ android:scaleY="0.58"
+ android:translateX="5.04"
+ android:translateY="5.04">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M7.2,14.4m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14.8,18m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M15.2,8.8m-4.8,0a4.8,4.8 0,1 1,9.6 0a4.8,4.8 0,1 1,-9.6 0"/>
+ </group>
+</vector> \ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index bf654d979856..47846746b205 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -182,6 +182,12 @@
<!-- Content description to tell the user a bubble has been dismissed. -->
<string name="accessibility_bubble_dismissed">Bubble dismissed.</string>
+ <!-- Label used to for bubbles shortcut [CHAR_LIMIT=10] -->
+ <string name="bubble_shortcut_label">Bubbles</string>
+
+ <!-- Longer label used to for bubbles shortcut, shown if there is enough space [CHAR_LIMIT=25] -->
+ <string name="bubble_shortcut_long_label">Show Bubbles</string>
+
<!-- Description of the restart button in the hint of size compatibility mode. [CHAR LIMIT=NONE] -->
<string name="restart_button_description">Tap to restart this app for a better view</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index d9055fbba408..a86164a8ed7d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -86,6 +86,7 @@ import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.CollectionUtils;
import com.android.launcher3.icons.BubbleIconFactory;
import com.android.wm.shell.Flags;
import com.android.wm.shell.R;
@@ -93,6 +94,7 @@ import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.WindowManagerShellWrapper;
import com.android.wm.shell.bubbles.bar.BubbleBarLayerView;
import com.android.wm.shell.bubbles.properties.BubbleProperties;
+import com.android.wm.shell.bubbles.shortcut.BubbleShortcutHelper;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.ExternalInterfaceBinder;
import com.android.wm.shell.common.FloatingContentCoordinator;
@@ -511,6 +513,10 @@ public class BubbleController implements ConfigurationChangeListener,
}
mCurrentProfiles = userProfiles;
+ if (Flags.enableRetrievableBubbles()) {
+ registerShortcutBroadcastReceiver();
+ }
+
mShellController.addConfigurationChangeListener(this);
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BUBBLES,
this::createExternalInterface, this);
@@ -986,6 +992,25 @@ public class BubbleController implements ConfigurationChangeListener,
}
};
+ private void registerShortcutBroadcastReceiver() {
+ IntentFilter shortcutFilter = new IntentFilter();
+ shortcutFilter.addAction(BubbleShortcutHelper.ACTION_SHOW_BUBBLES);
+ ProtoLog.d(WM_SHELL_BUBBLES, "register broadcast receive for bubbles shortcut");
+ mContext.registerReceiver(mShortcutBroadcastReceiver, shortcutFilter,
+ Context.RECEIVER_NOT_EXPORTED);
+ }
+
+ private final BroadcastReceiver mShortcutBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "receive broadcast to show bubbles %s",
+ intent.getAction());
+ if (BubbleShortcutHelper.ACTION_SHOW_BUBBLES.equals(intent.getAction())) {
+ mMainExecutor.execute(() -> showBubblesFromShortcut());
+ }
+ }
+ };
+
/**
* Called by the BubbleStackView and whenever all bubbles have animated out, and none have been
* added in the meantime.
@@ -2221,6 +2246,34 @@ public class BubbleController implements ConfigurationChangeListener,
}
/**
+ * Show bubbles UI when triggered via shortcut.
+ *
+ * <p>When there are bubbles visible, expands the top-most bubble. When there are no bubbles
+ * visible, opens the bubbles overflow UI.
+ */
+ public void showBubblesFromShortcut() {
+ if (isStackExpanded()) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "showBubblesFromShortcut: stack visible, skip");
+ return;
+ }
+ if (mBubbleData.getSelectedBubble() != null) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "showBubblesFromShortcut: open selected bubble");
+ expandStackWithSelectedBubble();
+ return;
+ }
+ BubbleViewProvider bubbleToSelect = CollectionUtils.firstOrNull(mBubbleData.getBubbles());
+ if (bubbleToSelect == null) {
+ ProtoLog.v(WM_SHELL_BUBBLES, "showBubblesFromShortcut: no bubbles");
+ // make sure overflow bubbles are loaded
+ loadOverflowBubblesFromDisk();
+ bubbleToSelect = mBubbleData.getOverflow();
+ }
+ ProtoLog.v(WM_SHELL_BUBBLES, "showBubblesFromShortcut: select and open %s",
+ bubbleToSelect.getKey());
+ mBubbleData.setSelectedBubbleAndExpandStack(bubbleToSelect);
+ }
+
+ /**
* Description of current bubble state.
*/
private void dump(PrintWriter pw, String prefix) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 874102c20925..5f913f766164 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -912,6 +912,9 @@ public class BubbleData {
((Bubble) bubble).markAsAccessedAt(mTimeSource.currentTimeMillis());
}
mSelectedBubble = bubble;
+ if (isOverflow) {
+ mShowingOverflow = true;
+ }
mStateChange.selectedBubble = bubble;
mStateChange.selectionChanged = true;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/BubbleShortcutHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/BubbleShortcutHelper.kt
new file mode 100644
index 000000000000..efa12383f188
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/BubbleShortcutHelper.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.bubbles.shortcut
+
+import android.content.Context
+import android.content.pm.ShortcutInfo
+import android.graphics.drawable.Icon
+import com.android.wm.shell.R
+
+/** Helper class for creating a shortcut to open bubbles */
+object BubbleShortcutHelper {
+ const val SHORTCUT_ID = "bubbles_shortcut_id"
+ const val ACTION_SHOW_BUBBLES = "com.android.wm.shell.bubbles.action.SHOW_BUBBLES"
+
+ /** Create a shortcut that launches [ShowBubblesActivity] */
+ fun createShortcut(context: Context, icon: Icon): ShortcutInfo {
+ return ShortcutInfo.Builder(context, SHORTCUT_ID)
+ .setIntent(ShowBubblesActivity.createIntent(context))
+ .setActivity(ShowBubblesActivity.createComponent(context))
+ .setShortLabel(context.getString(R.string.bubble_shortcut_label))
+ .setLongLabel(context.getString(R.string.bubble_shortcut_long_label))
+ .setLongLived(true)
+ .setIcon(icon)
+ .build()
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
new file mode 100644
index 000000000000..a124f95d7431
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/CreateBubbleShortcutActivity.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.bubbles.shortcut
+
+import android.app.Activity
+import android.content.pm.ShortcutManager
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import com.android.wm.shell.Flags
+import com.android.wm.shell.R
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
+import com.android.wm.shell.util.KtProtoLog
+
+/** Activity to create a shortcut to open bubbles */
+class CreateBubbleShortcutActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ if (Flags.enableRetrievableBubbles()) {
+ KtProtoLog.d(WM_SHELL_BUBBLES, "Creating a shortcut for bubbles")
+ createShortcut()
+ }
+ finish()
+ }
+
+ private fun createShortcut() {
+ val icon = Icon.createWithResource(this, R.drawable.ic_bubbles_shortcut_widget)
+ // TODO(b/340337839): shortcut shows the sysui icon
+ val shortcutInfo = BubbleShortcutHelper.createShortcut(this, icon)
+ val shortcutManager = getSystemService(ShortcutManager::class.java)
+ val shortcutIntent = shortcutManager?.createShortcutResultIntent(shortcutInfo)
+ if (shortcutIntent != null) {
+ setResult(RESULT_OK, shortcutIntent)
+ } else {
+ setResult(RESULT_CANCELED)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
new file mode 100644
index 000000000000..ae7940ca1b65
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/shortcut/ShowBubblesActivity.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 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.wm.shell.bubbles.shortcut
+
+import android.app.Activity
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import com.android.wm.shell.Flags
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES
+import com.android.wm.shell.util.KtProtoLog
+
+/** Activity that sends a broadcast to open bubbles */
+class ShowBubblesActivity : Activity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ if (Flags.enableRetrievableBubbles()) {
+ val intent =
+ Intent().apply {
+ action = BubbleShortcutHelper.ACTION_SHOW_BUBBLES
+ // Set the package as the receiver is not exported
+ `package` = packageName
+ }
+ KtProtoLog.v(WM_SHELL_BUBBLES, "Sending broadcast to show bubbles")
+ sendBroadcast(intent)
+ }
+ finish()
+ }
+
+ companion object {
+ /** Create intent to launch this activity */
+ fun createIntent(context: Context): Intent {
+ return Intent(context, ShowBubblesActivity::class.java).apply {
+ action = BubbleShortcutHelper.ACTION_SHOW_BUBBLES
+ }
+ }
+
+ /** Create component for this activity */
+ fun createComponent(context: Context): ComponentName {
+ return ComponentName(context, ShowBubblesActivity::class.java)
+ }
+ }
+}