diff options
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java | 72 | ||||
| -rw-r--r-- | packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java | 7 |
2 files changed, 79 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index b15c5debc17d..41bc1b29075c 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -28,6 +28,9 @@ import static com.android.systemui.statusbar.StatusBarState.SHADE; import static com.android.systemui.statusbar.notification.NotificationAlertingManager.alertAgain; import android.annotation.Nullable; +import android.app.ActivityManager; +import android.app.ActivityTaskManager; +import android.app.IActivityTaskManager; import android.app.INotificationManager; import android.app.Notification; import android.app.PendingIntent; @@ -35,11 +38,13 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Point; import android.graphics.Rect; +import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.service.notification.StatusBarNotification; import android.util.Log; import android.util.StatsLog; +import android.view.Display; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.WindowManager; @@ -52,6 +57,8 @@ import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shared.system.ActivityManagerWrapper; +import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; @@ -60,6 +67,7 @@ import com.android.systemui.statusbar.notification.row.NotificationInflater; import com.android.systemui.statusbar.phone.StatusBarWindowController; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -93,6 +101,8 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe private final Context mContext; private final NotificationEntryManager mNotificationEntryManager; + private final IActivityTaskManager mActivityTaskManager; + private final BubbleTaskStackListener mTaskStackListener; private BubbleStateChangeListener mStateChangeListener; private BubbleExpandListener mExpandListener; private LayoutInflater mInflater; @@ -176,6 +186,10 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe mStatusBarWindowController = statusBarWindowController; mStatusBarStateListener = new StatusBarStateListener(); Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener); + + mActivityTaskManager = ActivityTaskManager.getService(); + mTaskStackListener = new BubbleTaskStackListener(); + ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); } /** @@ -533,6 +547,64 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe || autoBubbleAll; } + /** + * This task stack listener is responsible for responding to tasks moved to the front + * which are on the default (main) display. When this happens, expanded bubbles must be + * collapsed so the user may interact with the app which was just moved to the front. + * <p> + * This listener is registered with SystemUI's ActivityManagerWrapper which dispatches + * these calls via a main thread Handler. + */ + @MainThread + private class BubbleTaskStackListener extends TaskStackChangeListener { + + @Nullable + private ActivityManager.StackInfo findStackInfo(int taskId) throws RemoteException { + final List<ActivityManager.StackInfo> stackInfoList = + mActivityTaskManager.getAllStackInfos(); + // Iterate through stacks from top to bottom. + final int stackCount = stackInfoList.size(); + for (int stackIndex = 0; stackIndex < stackCount; stackIndex++) { + final ActivityManager.StackInfo stackInfo = stackInfoList.get(stackIndex); + // Iterate through tasks from top to bottom. + for (int taskIndex = stackInfo.taskIds.length - 1; taskIndex >= 0; taskIndex--) { + if (stackInfo.taskIds[taskIndex] == taskId) { + return stackInfo; + } + } + } + return null; + } + + @Override + public void onTaskMovedToFront(int taskId) { + ActivityManager.StackInfo stackInfo = null; + try { + stackInfo = findStackInfo(taskId); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + if (stackInfo != null && stackInfo.displayId == Display.DEFAULT_DISPLAY + && mStackView != null) { + mStackView.collapseStack(); + } + } + + /** + * This is a workaround for the case when the activity had to be created in a new task. + * Existing code in ActivityStackSupervisor checks the display where the activity + * ultimately ended up, displays an error message toast, and calls this method instead of + * onTaskMovedToFront. + */ + // TODO(b/124058588): add requestedDisplayId to this callback, ignore unless matches + @Override + public void onActivityLaunchOnSecondaryDisplayFailed() { + if (mStackView != null) { + mStackView.collapseStack(); + } + } + } + private static boolean shouldAutoBubbleMessages(Context context) { return Settings.Secure.getInt(context.getContentResolver(), ENABLE_AUTO_BUBBLE_MESSAGES, 0) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 305f86655fcd..f6f3fa646232 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -41,6 +41,7 @@ import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.LinearLayout; +import androidx.annotation.MainThread; import androidx.annotation.Nullable; import androidx.dynamicanimation.animation.DynamicAnimation; import androidx.dynamicanimation.animation.SpringAnimation; @@ -384,7 +385,10 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F /** * Collapses the stack of bubbles. + * <p> + * Must be called from the main thread. */ + @MainThread public void collapseStack() { if (mIsExpanded) { // TODO: Save opened bubble & move it to top of stack @@ -402,7 +406,10 @@ public class BubbleStackView extends FrameLayout implements BubbleTouchHandler.F /** * Expands the stack fo bubbles. + * <p> + * Must be called from the main thread. */ + @MainThread public void expandStack() { if (!mIsExpanded) { mExpandedBubble = getTopBubble(); |