Merge "Per-bubble updates for overflow"
This commit is contained in:
@@ -694,6 +694,7 @@ class Bubble implements BubbleViewProvider {
|
|||||||
pw.print(" showInShade: "); pw.println(showInShade());
|
pw.print(" showInShade: "); pw.println(showInShade());
|
||||||
pw.print(" showDot: "); pw.println(showDot());
|
pw.print(" showDot: "); pw.println(showDot());
|
||||||
pw.print(" showFlyout: "); pw.println(showFlyout());
|
pw.print(" showFlyout: "); pw.println(showFlyout());
|
||||||
|
pw.print(" lastActivity: "); pw.println(getLastActivity());
|
||||||
pw.print(" desiredHeight: "); pw.println(getDesiredHeightString());
|
pw.print(" desiredHeight: "); pw.println(getDesiredHeightString());
|
||||||
pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification());
|
pw.print(" suppressNotif: "); pw.println(shouldSuppressNotification());
|
||||||
pw.print(" autoExpand: "); pw.println(shouldAutoExpand());
|
pw.print(" autoExpand: "); pw.println(shouldAutoExpand());
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
private INotificationManager mINotificationManager;
|
private INotificationManager mINotificationManager;
|
||||||
|
|
||||||
// Callback that updates BubbleOverflowActivity on data change.
|
// Callback that updates BubbleOverflowActivity on data change.
|
||||||
@Nullable private Runnable mOverflowCallback = null;
|
@Nullable private BubbleData.Listener mOverflowListener = null;
|
||||||
|
|
||||||
// Only load overflow data from disk once
|
// Only load overflow data from disk once
|
||||||
private boolean mOverflowDataLoaded = false;
|
private boolean mOverflowDataLoaded = false;
|
||||||
@@ -722,8 +722,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
mInflateSynchronously = inflateSynchronously;
|
mInflateSynchronously = inflateSynchronously;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOverflowCallback(Runnable updateOverflow) {
|
void setOverflowListener(BubbleData.Listener listener) {
|
||||||
mOverflowCallback = updateOverflow;
|
mOverflowListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1327,9 +1327,10 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
|
|
||||||
// Lazy load overflow bubbles from disk
|
// Lazy load overflow bubbles from disk
|
||||||
loadOverflowBubblesFromDisk();
|
loadOverflowBubblesFromDisk();
|
||||||
|
|
||||||
// Update bubbles in overflow.
|
// Update bubbles in overflow.
|
||||||
if (mOverflowCallback != null) {
|
if (mOverflowListener != null) {
|
||||||
mOverflowCallback.run();
|
mOverflowListener.applyUpdate(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collapsing? Do this first before remaining steps.
|
// Collapsing? Do this first before remaining steps.
|
||||||
@@ -1438,21 +1439,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
|||||||
cb.invalidateNotifications("BubbleData.Listener.applyUpdate");
|
cb.invalidateNotifications("BubbleData.Listener.applyUpdate");
|
||||||
}
|
}
|
||||||
updateStack();
|
updateStack();
|
||||||
|
|
||||||
if (DEBUG_BUBBLE_CONTROLLER) {
|
|
||||||
Log.d(TAG, "\n[BubbleData] bubbles:");
|
|
||||||
Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getBubbles(),
|
|
||||||
mBubbleData.getSelectedBubble()));
|
|
||||||
|
|
||||||
if (mStackView != null) {
|
|
||||||
Log.d(TAG, "\n[BubbleStackView]");
|
|
||||||
Log.d(TAG, BubbleDebugConfig.formatBubblesString(mStackView.getBubblesOnScreen(),
|
|
||||||
mStackView.getExpandedBubble()));
|
|
||||||
}
|
|
||||||
Log.d(TAG, "\n[BubbleData] overflow:");
|
|
||||||
Log.d(TAG, BubbleDebugConfig.formatBubblesString(mBubbleData.getOverflowBubbles(),
|
|
||||||
null) + "\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ public class BubbleData {
|
|||||||
@Nullable Bubble selectedBubble;
|
@Nullable Bubble selectedBubble;
|
||||||
@Nullable Bubble addedBubble;
|
@Nullable Bubble addedBubble;
|
||||||
@Nullable Bubble updatedBubble;
|
@Nullable Bubble updatedBubble;
|
||||||
|
@Nullable Bubble addedOverflowBubble;
|
||||||
|
@Nullable Bubble removedOverflowBubble;
|
||||||
// Pair with Bubble and @DismissReason Integer
|
// Pair with Bubble and @DismissReason Integer
|
||||||
final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>();
|
final List<Pair<Bubble, Integer>> removedBubbles = new ArrayList<>();
|
||||||
|
|
||||||
@@ -93,10 +95,12 @@ public class BubbleData {
|
|||||||
|| addedBubble != null
|
|| addedBubble != null
|
||||||
|| updatedBubble != null
|
|| updatedBubble != null
|
||||||
|| !removedBubbles.isEmpty()
|
|| !removedBubbles.isEmpty()
|
||||||
|
|| addedOverflowBubble != null
|
||||||
|
|| removedOverflowBubble != null
|
||||||
|| orderChanged;
|
|| orderChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) {
|
void bubbleRemoved(Bubble bubbleToRemove, @DismissReason int reason) {
|
||||||
removedBubbles.add(new Pair<>(bubbleToRemove, reason));
|
removedBubbles.add(new Pair<>(bubbleToRemove, reason));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,8 +490,9 @@ public class BubbleData {
|
|||||||
b.stopInflation();
|
b.stopInflation();
|
||||||
}
|
}
|
||||||
mLogger.logOverflowRemove(b, reason);
|
mLogger.logOverflowRemove(b, reason);
|
||||||
mStateChange.bubbleRemoved(b, reason);
|
|
||||||
mOverflowBubbles.remove(b);
|
mOverflowBubbles.remove(b);
|
||||||
|
mStateChange.bubbleRemoved(b, reason);
|
||||||
|
mStateChange.removedOverflowBubble = b;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -532,6 +537,7 @@ public class BubbleData {
|
|||||||
}
|
}
|
||||||
mLogger.logOverflowAdd(bubble, reason);
|
mLogger.logOverflowAdd(bubble, reason);
|
||||||
mOverflowBubbles.add(0, bubble);
|
mOverflowBubbles.add(0, bubble);
|
||||||
|
mStateChange.addedOverflowBubble = bubble;
|
||||||
bubble.stopInflation();
|
bubble.stopInflation();
|
||||||
if (mOverflowBubbles.size() == mMaxOverflowBubbles + 1) {
|
if (mOverflowBubbles.size() == mMaxOverflowBubbles + 1) {
|
||||||
// Remove oldest bubble.
|
// Remove oldest bubble.
|
||||||
@@ -542,6 +548,7 @@ public class BubbleData {
|
|||||||
mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED);
|
mStateChange.bubbleRemoved(oldest, BubbleController.DISMISS_OVERFLOW_MAX_REACHED);
|
||||||
mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
|
mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_MAX_REACHED);
|
||||||
mOverflowBubbles.remove(oldest);
|
mOverflowBubbles.remove(oldest);
|
||||||
|
mStateChange.removedOverflowBubble = oldest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,11 +828,19 @@ public class BubbleData {
|
|||||||
: "null");
|
: "null");
|
||||||
pw.print("expanded: ");
|
pw.print("expanded: ");
|
||||||
pw.println(mExpanded);
|
pw.println(mExpanded);
|
||||||
pw.print("count: ");
|
|
||||||
|
pw.print("stack bubble count: ");
|
||||||
pw.println(mBubbles.size());
|
pw.println(mBubbles.size());
|
||||||
for (Bubble bubble : mBubbles) {
|
for (Bubble bubble : mBubbles) {
|
||||||
bubble.dump(fd, pw, args);
|
bubble.dump(fd, pw, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pw.print("overflow bubble count: ");
|
||||||
|
pw.println(mOverflowBubbles.size());
|
||||||
|
for (Bubble bubble : mOverflowBubbles) {
|
||||||
|
bubble.dump(fd, pw, args);
|
||||||
|
}
|
||||||
|
|
||||||
pw.print("summaryKeys: ");
|
pw.print("summaryKeys: ");
|
||||||
pw.println(mSuppressedGroupKeys.size());
|
pw.println(mSuppressedGroupKeys.size());
|
||||||
for (String key : mSuppressedGroupKeys.keySet()) {
|
for (String key : mSuppressedGroupKeys.keySet()) {
|
||||||
|
|||||||
@@ -108,14 +108,10 @@ public class BubbleOverflowActivity extends Activity {
|
|||||||
mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle);
|
mEmptyStateSubtitle = findViewById(R.id.bubble_overflow_empty_subtitle);
|
||||||
mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image);
|
mEmptyStateImage = findViewById(R.id.bubble_overflow_empty_state_image);
|
||||||
|
|
||||||
updateDimensions();
|
updateOverflow();
|
||||||
onDataChanged(mBubbleController.getOverflowBubbles());
|
|
||||||
mBubbleController.setOverflowCallback(() -> {
|
|
||||||
onDataChanged(mBubbleController.getOverflowBubbles());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateDimensions() {
|
void updateOverflow() {
|
||||||
Resources res = getResources();
|
Resources res = getResources();
|
||||||
final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
|
final int columns = res.getInteger(R.integer.bubbles_overflow_columns);
|
||||||
mRecyclerView.setLayoutManager(
|
mRecyclerView.setLayoutManager(
|
||||||
@@ -137,6 +133,22 @@ public class BubbleOverflowActivity extends Activity {
|
|||||||
mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles,
|
mAdapter = new BubbleOverflowAdapter(getApplicationContext(), mOverflowBubbles,
|
||||||
mBubbleController::promoteBubbleFromOverflow, viewWidth, viewHeight);
|
mBubbleController::promoteBubbleFromOverflow, viewWidth, viewHeight);
|
||||||
mRecyclerView.setAdapter(mAdapter);
|
mRecyclerView.setAdapter(mAdapter);
|
||||||
|
|
||||||
|
mOverflowBubbles.clear();
|
||||||
|
mOverflowBubbles.addAll(mBubbleController.getOverflowBubbles());
|
||||||
|
mAdapter.notifyDataSetChanged();
|
||||||
|
updateEmptyStateVisibility();
|
||||||
|
|
||||||
|
mBubbleController.setOverflowListener(mDataListener);
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateEmptyStateVisibility() {
|
||||||
|
if (mOverflowBubbles.isEmpty()) {
|
||||||
|
mEmptyState.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
mEmptyState.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,22 +180,40 @@ public class BubbleOverflowActivity extends Activity {
|
|||||||
mEmptyStateSubtitle.setTextColor(textColor);
|
mEmptyStateSubtitle.setTextColor(textColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onDataChanged(List<Bubble> bubbles) {
|
private final BubbleData.Listener mDataListener = new BubbleData.Listener() {
|
||||||
mOverflowBubbles.clear();
|
|
||||||
mOverflowBubbles.addAll(bubbles);
|
|
||||||
mAdapter.notifyDataSetChanged();
|
|
||||||
|
|
||||||
if (mOverflowBubbles.isEmpty()) {
|
@Override
|
||||||
mEmptyState.setVisibility(View.VISIBLE);
|
public void applyUpdate(BubbleData.Update update) {
|
||||||
} else {
|
|
||||||
mEmptyState.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DEBUG_OVERFLOW) {
|
Bubble toRemove = update.removedOverflowBubble;
|
||||||
Log.d(TAG, "Updated overflow bubbles:\n" + BubbleDebugConfig.formatBubblesString(
|
if (toRemove != null) {
|
||||||
mOverflowBubbles, /*selected*/ null));
|
if (DEBUG_OVERFLOW) {
|
||||||
|
Log.d(TAG, "remove: " + toRemove);
|
||||||
|
}
|
||||||
|
toRemove.cleanupViews();
|
||||||
|
final int i = mOverflowBubbles.indexOf(toRemove);
|
||||||
|
mOverflowBubbles.remove(toRemove);
|
||||||
|
mAdapter.notifyItemRemoved(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bubble toAdd = update.addedOverflowBubble;
|
||||||
|
if (toAdd != null) {
|
||||||
|
if (DEBUG_OVERFLOW) {
|
||||||
|
Log.d(TAG, "add: " + toAdd);
|
||||||
|
}
|
||||||
|
mOverflowBubbles.add(0, toAdd);
|
||||||
|
mAdapter.notifyItemInserted(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateEmptyStateVisibility();
|
||||||
|
|
||||||
|
if (DEBUG_OVERFLOW) {
|
||||||
|
Log.d(TAG, BubbleDebugConfig.formatBubblesString(
|
||||||
|
mBubbleController.getOverflowBubbles(),
|
||||||
|
null));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
@@ -198,8 +228,7 @@ public class BubbleOverflowActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
updateDimensions();
|
updateOverflow();
|
||||||
updateTheme();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -276,6 +276,10 @@ public class BubbleStackView extends FrameLayout
|
|||||||
/** Description of current animation controller state. */
|
/** Description of current animation controller state. */
|
||||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||||
pw.println("Stack view state:");
|
pw.println("Stack view state:");
|
||||||
|
|
||||||
|
String bubblesOnScreen = BubbleDebugConfig.formatBubblesString(
|
||||||
|
getBubblesOnScreen(), getExpandedBubble());
|
||||||
|
pw.print(" bubbles on screen: "); pw.println(bubblesOnScreen);
|
||||||
pw.print(" gestureInProgress: "); pw.println(mIsGestureInProgress);
|
pw.print(" gestureInProgress: "); pw.println(mIsGestureInProgress);
|
||||||
pw.print(" showingDismiss: "); pw.println(mDismissView.isShowing());
|
pw.print(" showingDismiss: "); pw.println(mDismissView.isShowing());
|
||||||
pw.print(" isExpansionAnimating: "); pw.println(mIsExpansionAnimating);
|
pw.print(" isExpansionAnimating: "); pw.println(mIsExpansionAnimating);
|
||||||
|
|||||||
Reference in New Issue
Block a user