Merge "Save usercreated bubbles and re-bubble next time; add experiment debug logs"
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user