diff options
5 files changed, 69 insertions, 33 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java index 044ea54e89f6..24ee969526cc 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java @@ -321,20 +321,6 @@ class Bubble { return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0; } - /** - * Whether this bubble was explicitly created by the user via a SysUI affordance. - */ - boolean isUserCreated() { - return mIsUserCreated; - } - - /** - * Set whether this bubble was explicitly created by the user via a SysUI affordance. - */ - void setUserCreated(boolean isUserCreated) { - mIsUserCreated = isUserCreated; - } - float getDesiredHeight(Context context) { Notification.BubbleMetadata data = mEntry.getBubbleMetadata(); boolean useRes = data.getDesiredHeightResId() != 0; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index db1185fb96f9..ed21e141c12d 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -31,6 +31,7 @@ import static android.view.View.VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER; +import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.systemui.statusbar.StatusBarState.SHADE; @@ -92,6 +93,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import javax.inject.Inject; @@ -145,6 +147,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi // Saves notification keys of active bubbles when users are switched. private final SparseSetArray<String> mSavedBubbleKeysPerUser; + // Saves notification keys of user created "fake" bubbles so that we can allow notifications + // like these to bubble by default. Doesn't persist across reboots, not a long-term solution. + private final HashSet<String> mUserCreatedBubbles; + // Bubbles get added to the status bar view private final StatusBarWindowController mStatusBarWindowController; private final ZenModeController mZenModeController; @@ -312,6 +318,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi restoreBubbles(newUserId); mCurrentUserId = newUserId; }); + + mUserCreatedBubbles = new HashSet<>(); } /** @@ -535,10 +543,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * @param entry the notification to show as a bubble. */ public void onUserCreatedBubbleFromNotification(NotificationEntry entry) { + if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) { + Log.d(TAG, "onUserCreatedBubble: " + entry.getKey()); + } mShadeController.get().collapsePanel(true); entry.setFlagBubble(true); updateBubble(entry, true /* suppressFlyout */, false /* showInShade */); - mBubbleData.getBubbleWithKey(entry.getKey()).setUserCreated(true); + mUserCreatedBubbles.add(entry.getKey()); } /** @@ -548,8 +559,19 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * @param entry the notification to no longer show as a bubble. */ public void onUserDemotedBubbleFromNotification(NotificationEntry entry) { + if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) { + Log.d(TAG, "onUserDemotedBubble: " + entry.getKey()); + } entry.setFlagBubble(false); removeBubble(entry.getKey(), DISMISS_BLOCKED); + mUserCreatedBubbles.remove(entry.getKey()); + } + + /** + * Whether this bubble was explicitly created by the user via a SysUI affordance. + */ + boolean isUserCreatedBubble(String key) { + return mUserCreatedBubbles.contains(key); } /** @@ -616,7 +638,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mNotificationEntryManager.updateNotifications( "BubbleController.onNotificationRemoveRequested"); return true; - } else if (!userRemovedNotif && entry != null && !bubble.isUserCreated()) { + } else if (!userRemovedNotif && entry != null + && !isUserCreatedBubble(bubble.getKey())) { // This wasn't a user removal so we should remove the bubble as well mBubbleData.notificationEntryRemoved(entry, DISMISS_NOTIF_CANCEL); return false; @@ -676,8 +699,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationEntryListener mEntryListener = new NotificationEntryListener() { @Override public void onPendingEntryAdded(NotificationEntry entry) { - Bubble b = mBubbleData.getBubbleWithKey(entry.getKey()); - BubbleExperimentConfig.adjustForExperiments(mContext, entry, b); + boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey()); + BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated); if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry) && canLaunchInActivityView(mContext, entry)) { @@ -687,8 +710,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi @Override public void onPreEntryUpdated(NotificationEntry entry) { - Bubble b = mBubbleData.getBubbleWithKey(entry.getKey()); - BubbleExperimentConfig.adjustForExperiments(mContext, entry, b); + boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey()); + BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated); boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry) && canLaunchInActivityView(mContext, entry); diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java index b702d06ca7cd..a912eccd4d5e 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java @@ -37,5 +37,6 @@ public class BubbleDebugConfig { static final boolean DEBUG_BUBBLE_DATA = false; static final boolean DEBUG_BUBBLE_STACK_VIEW = false; static final boolean DEBUG_BUBBLE_EXPANDED_VIEW = false; + static final boolean DEBUG_EXPERIMENTS = true; } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java index ea51f4af7fe3..512b38e895bb 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java @@ -189,12 +189,10 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList + " mActivityViewStatus=" + mActivityViewStatus + " bubble=" + getBubbleKey()); } - if (mBubble != null && !mBubble.isUserCreated()) { - if (mBubble != null) { - // Must post because this is called from a binder thread. - post(() -> mBubbleController.removeBubble(mBubble.getKey(), - BubbleController.DISMISS_TASK_FINISHED)); - } + if (mBubble != null && !mBubbleController.isUserCreatedBubble(mBubble.getKey())) { + // Must post because this is called from a binder thread. + post(() -> mBubbleController.removeBubble(mBubble.getKey(), + BubbleController.DISMISS_TASK_FINISHED)); } } }; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java index 6eeb5c396cfc..17d6737b04d6 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java @@ -22,6 +22,9 @@ import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED; import static com.android.systemui.bubbles.BubbleController.canLaunchIntentInActivityView; +import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS; +import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; +import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME; import android.app.Notification; import android.app.PendingIntent; @@ -35,6 +38,7 @@ import android.os.Bundle; import android.os.Parcelable; import android.os.UserHandle; import android.provider.Settings; +import android.util.Log; import com.android.internal.util.ArrayUtils; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -47,6 +51,7 @@ import java.util.List; * Common class for experiments controlled via secure settings. */ public class BubbleExperimentConfig { + private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES; private static final String SHORTCUT_DUMMY_INTENT = "bubble_experiment_shortcut_intent"; private static PendingIntent sDummyShortcutIntent; @@ -104,8 +109,7 @@ public class BubbleExperimentConfig { * the notification has necessary info for BubbleMetadata. */ static void adjustForExperiments(Context context, NotificationEntry entry, - Bubble previousBubble) { - + boolean previouslyUserCreated) { Notification.BubbleMetadata metadata = null; boolean addedMetadata = false; @@ -118,6 +122,19 @@ public class BubbleExperimentConfig { boolean useShortcutInfo = useShortcutInfoToBubble(context); String shortcutId = entry.getSbn().getNotification().getShortcutId(); + boolean hasMetadata = entry.getBubbleMetadata() != null; + if ((!hasMetadata && (previouslyUserCreated || bubbleNotifForExperiment)) + || useShortcutInfo) { + if (DEBUG_EXPERIMENTS) { + Log.d(TAG, "Adjusting " + entry.getKey() + " for bubble experiment." + + " allowMessages=" + allowMessageNotifsToBubble(context) + + " isMessage=" + isMessage + + " allowNotifs=" + allowAnyNotifToBubble(context) + + " useShortcutInfo=" + useShortcutInfo + + " previouslyUserCreated=" + previouslyUserCreated); + } + } + if (useShortcutInfo && shortcutId != null) { // We don't actually get anything useful from ShortcutInfo so just check existence ShortcutInfo info = getShortcutInfo(context, entry.getSbn().getPackageName(), @@ -127,26 +144,37 @@ public class BubbleExperimentConfig { } // Replace existing metadata with shortcut, or we're bubbling for experiment - boolean shouldBubble = entry.getBubbleMetadata() != null || bubbleNotifForExperiment; - + boolean shouldBubble = entry.getBubbleMetadata() != null + || bubbleNotifForExperiment + || previouslyUserCreated; if (shouldBubble && metadata != null) { + if (DEBUG_EXPERIMENTS) { + Log.d(TAG, "Adding experimental shortcut bubble for: " + entry.getKey()); + } entry.setBubbleMetadata(metadata); addedMetadata = true; } } // Didn't get metadata from a shortcut & we're bubbling for experiment - if (entry.getBubbleMetadata() == null && bubbleNotifForExperiment) { + if (entry.getBubbleMetadata() == null + && (bubbleNotifForExperiment || previouslyUserCreated)) { metadata = createFromNotif(context, entry); if (metadata != null) { + if (DEBUG_EXPERIMENTS) { + Log.d(TAG, "Adding experimental notification bubble for: " + entry.getKey()); + } entry.setBubbleMetadata(metadata); addedMetadata = true; } } - if (previousBubble != null && addedMetadata) { - // Update to a previously bubble, set its flag now so the update goes + if (previouslyUserCreated && addedMetadata) { + // Update to a previous bubble, set its flag now so the update goes // to the bubble. + if (DEBUG_EXPERIMENTS) { + Log.d(TAG, "Setting FLAG_BUBBLE for: " + entry.getKey()); + } entry.setFlagBubble(true); } } |