summaryrefslogtreecommitdiff
path: root/packages/SystemUI/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src')
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleTaskView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt75
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java211
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt165
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java6
34 files changed, 700 insertions, 376 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
index fc29f5cddb26..2f103940f3e4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardViewController.java
@@ -57,27 +57,27 @@ public interface KeyguardViewController {
/**
* Called when the device started going to sleep.
*/
- void onStartedGoingToSleep();
+ default void onStartedGoingToSleep() {};
/**
* Called when the device has finished going to sleep.
*/
- void onFinishedGoingToSleep();
+ default void onFinishedGoingToSleep() {};
/**
* Called when the device started waking up.
*/
- void onStartedWakingUp();
+ default void onStartedWakingUp() {};
/**
* Called when the device started turning on.
*/
- void onScreenTurningOn();
+ default void onScreenTurningOn() {};
/**
* Called when the device has finished turning on.
*/
- void onScreenTurnedOn();
+ default void onScreenTurnedOn() {};
/**
* Sets whether the Keyguard needs input.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index cc4ee89f2208..f6368c466e91 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -109,7 +109,7 @@ public class AssistManager {
protected static final String CONSTRAINED_KEY = "should_constrain";
public static final int INVOCATION_TYPE_GESTURE = 1;
- public static final int INVOCATION_TYPE_ACTIVE_EDGE = 2;
+ public static final int INVOCATION_TYPE_OTHER = 2;
public static final int INVOCATION_TYPE_VOICE = 3;
public static final int INVOCATION_TYPE_QUICK_SEARCH_BAR = 4;
public static final int INVOCATION_HOME_BUTTON_LONG_PRESS = 5;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 5c66462f2a5b..496456deccee 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -125,6 +125,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
// Custom options so there is no activity transition animation
ActivityOptions options = ActivityOptions.makeCustomAnimation(getContext(),
0 /* enterResId */, 0 /* exitResId */);
+ options.setTaskAlwaysOnTop(true);
// Post to keep the lifecycle normal
post(() -> {
if (DEBUG_BUBBLE_EXPANDED_VIEW) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index fee33dcd7677..6a7b0da0d8d8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -1441,7 +1441,7 @@ public class BubbleStackView extends FrameLayout {
/** Expands the clicked bubble. */
public void expandBubble(Bubble bubble) {
- if (bubble.equals(mBubbleData.getSelectedBubble())) {
+ if (bubble != null && bubble.equals(mBubbleData.getSelectedBubble())) {
// If the bubble we're supposed to expand is the selected bubble, that means the
// overflow bubble is currently expanded. Don't tell BubbleData to set this bubble as
// selected, since it already is. Just call the stack's setSelectedBubble to expand it.
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTaskView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTaskView.java
index 0d6d137491a9..06205c5c1c41 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTaskView.java
@@ -23,8 +23,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.PendingIntent;
-import android.app.TaskEmbedder;
-import android.app.TaskOrganizerTaskEmbedder;
+import android.window.TaskEmbedder;
+import android.window.TaskOrganizerTaskEmbedder;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ShortcutInfo;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 3bed3384c91f..f7f9afdd2928 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -16,6 +16,9 @@
package com.android.systemui.doze;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+
import android.annotation.MainThread;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Trace;
@@ -368,8 +371,8 @@ public class DozeMachine {
case DOZE_PULSE_DONE:
final State nextState;
@Wakefulness int wakefulness = mWakefulnessLifecycle.getWakefulness();
- if (wakefulness == WakefulnessLifecycle.WAKEFULNESS_AWAKE
- || wakefulness == WakefulnessLifecycle.WAKEFULNESS_WAKING) {
+ if (state != State.INITIALIZED && (wakefulness == WAKEFULNESS_AWAKE
+ || wakefulness == WAKEFULNESS_WAKING)) {
nextState = State.FINISH;
} else if (mDockManager.isDocked()) {
nextState = mDockManager.isHidden() ? State.DOZE : State.DOZE_AOD_DOCKED;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index c40e9c08d44f..15c9dbad1680 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -41,8 +41,8 @@ import android.os.RemoteException;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceControl;
-import android.window.ITaskOrganizer;
-import android.window.IWindowContainer;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
@@ -60,7 +60,7 @@ import java.util.function.Consumer;
/**
* Manages PiP tasks such as resize and offset.
*
- * This class listens on {@link ITaskOrganizer} callbacks for windowing mode change
+ * This class listens on {@link TaskOrganizer} callbacks for windowing mode change
* both to and from PiP and issues corresponding animation if applicable.
* Normally, we apply series of {@link SurfaceControl.Transaction} when the animator is running
* and files a final {@link WindowContainerTransaction} at the end of the transition.
@@ -68,7 +68,7 @@ import java.util.function.Consumer;
* This class is also responsible for general resize/offset PiP operations within SysUI component,
* see also {@link com.android.systemui.pip.phone.PipMotionHelper}.
*/
-public class PipTaskOrganizer extends ITaskOrganizer.Stub {
+public class PipTaskOrganizer extends TaskOrganizer {
private static final String TAG = PipTaskOrganizer.class.getSimpleName();
private static final int MSG_RESIZE_IMMEDIATE = 1;
@@ -182,7 +182,7 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
};
private ActivityManager.RunningTaskInfo mTaskInfo;
- private IWindowContainer mToken;
+ private WindowContainerToken mToken;
private SurfaceControl mLeash;
private boolean mInPip;
private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
@@ -234,13 +234,9 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
* @param animationDurationMs duration in millisecond for the exiting PiP transition
*/
public void dismissPip(int animationDurationMs) {
- try {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
- WindowOrganizer.applyTransaction(wct);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to apply container transaction", e);
- }
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.setActivityWindowingMode(mToken, WINDOWING_MODE_FULLSCREEN);
+ WindowOrganizer.applyTransaction(wct);
final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
TRANSITION_DIRECTION_TO_FULLSCREEN, animationDurationMs,
@@ -258,11 +254,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
mTaskInfo = info;
mToken = mTaskInfo.token;
mInPip = true;
- try {
- mLeash = mToken.getLeash();
- } catch (RemoteException e) {
- throw new RuntimeException("Unable to get leash", e);
- }
+ mLeash = mToken.getLeash();
+
final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
mBoundsToRestore.put(mToken.asBinder(), currentBounds);
if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
@@ -290,8 +283,8 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
*/
@Override
public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
- IWindowContainer token = info.token;
- Objects.requireNonNull(token, "Requires valid IWindowContainer");
+ WindowContainerToken token = info.token;
+ Objects.requireNonNull(token, "Requires valid WindowContainerToken");
if (token.asBinder() != mToken.asBinder()) {
Log.wtf(TAG, "Unrecognized token: " + token);
return;
@@ -502,30 +495,26 @@ public class PipTaskOrganizer extends ITaskOrganizer.Stub {
+ "directly");
}
mLastReportedBounds.set(destinationBounds);
- try {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- final Rect taskBounds;
- if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
- // If we are animating to fullscreen, then we need to reset the override bounds
- // on the task to ensure that the task "matches" the parent's bounds, this applies
- // also to the final windowing mode, which should be reset to undefined rather than
- // fullscreen.
- taskBounds = null;
- wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
- .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
- } else {
- taskBounds = destinationBounds;
- }
- if (direction == TRANSITION_DIRECTION_TO_PIP) {
- wct.scheduleFinishEnterPip(mToken, taskBounds);
- } else {
- wct.setBounds(mToken, taskBounds);
- }
- wct.setBoundsChangeTransaction(mToken, tx);
- WindowOrganizer.applyTransaction(wct);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to apply container transaction", e);
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+ final Rect taskBounds;
+ if (direction == TRANSITION_DIRECTION_TO_FULLSCREEN) {
+ // If we are animating to fullscreen, then we need to reset the override bounds
+ // on the task to ensure that the task "matches" the parent's bounds, this applies
+ // also to the final windowing mode, which should be reset to undefined rather than
+ // fullscreen.
+ taskBounds = null;
+ wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED)
+ .setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+ } else {
+ taskBounds = destinationBounds;
+ }
+ if (direction == TRANSITION_DIRECTION_TO_PIP) {
+ wct.scheduleFinishEnterPip(mToken, taskBounds);
+ } else {
+ wct.setBounds(mToken, taskBounds);
}
+ wct.setBoundsChangeTransaction(mToken, tx);
+ WindowOrganizer.applyTransaction(wct);
}
private void animateResizePip(Rect currentBounds, Rect destinationBounds,
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 8a25f4d441d3..99d6df517224 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -18,7 +18,6 @@ package com.android.systemui.pip.phone;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.window.WindowOrganizer.TaskOrganizer;
import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
@@ -234,7 +233,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
try {
- TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED);
+ mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
if (stackInfo != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index c6e6da16652f..52c8960d1ccf 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -19,7 +19,6 @@ package com.android.systemui.pip.tv;
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
@@ -294,7 +293,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
try {
WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener);
- TaskOrganizer.registerOrganizer(mPipTaskOrganizer, WINDOWING_MODE_PINNED);
+ mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
} catch (RemoteException | UnsupportedOperationException e) {
Log.e(TAG, "Failed to register pinned stack listener", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
index f710f7fc47e2..448531a132df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/DoubleLineTileLayout.kt
@@ -25,13 +25,18 @@ import com.android.systemui.qs.TileLayout.exactly
class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTileLayout {
+ companion object {
+ private const val NUM_LINES = 2
+ }
+
protected val mRecords = ArrayList<QSPanel.TileRecord>()
private var _listening = false
private var smallTileSize = 0
private val twoLineHeight
- get() = smallTileSize * 2 + cellMarginVertical
+ get() = smallTileSize * NUM_LINES + cellMarginVertical * (NUM_LINES - 1)
private var cellMarginHorizontal = 0
private var cellMarginVertical = 0
+ private var tilesToShow = 0
init {
isFocusableInTouchMode = true
@@ -68,7 +73,7 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
override fun updateResources(): Boolean {
with(mContext.resources) {
smallTileSize = getDimensionPixelSize(R.dimen.qs_quick_tile_size)
- cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal)
+ cellMarginHorizontal = getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal_two_line)
cellMarginVertical = getDimensionPixelSize(R.dimen.new_qs_vertical_margin)
}
requestLayout()
@@ -83,11 +88,12 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
}
}
- override fun getNumVisibleTiles() = mRecords.size
+ override fun getNumVisibleTiles() = tilesToShow
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
updateResources()
+ postInvalidate()
}
override fun onFinishInflate() {
@@ -95,39 +101,58 @@ class DoubleLineTileLayout(context: Context) : ViewGroup(context), QSPanel.QSTil
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
- var previousView: View = this
- var tiles = 0
mRecords.forEach {
- val tileView = it.tileView
- if (tileView.visibility != View.GONE) {
- tileView.updateAccessibilityOrder(previousView)
- previousView = tileView
- tiles++
- tileView.measure(exactly(smallTileSize), exactly(smallTileSize))
- }
+ it.tileView.measure(exactly(smallTileSize), exactly(smallTileSize))
}
val height = twoLineHeight
- val columns = tiles / 2
- val width = paddingStart + paddingEnd +
- columns * smallTileSize +
- (columns - 1) * cellMarginHorizontal
- setMeasuredDimension(width, height)
+ setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), height)
+ }
+
+ private fun calculateMaxColumns(availableWidth: Int): Int {
+ if (smallTileSize + cellMarginHorizontal == 0) {
+ return 0
+ } else {
+ return (availableWidth - smallTileSize) / (smallTileSize + cellMarginHorizontal) + 1
+ }
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
- val tiles = mRecords.filter { it.tileView.visibility != View.GONE }
- tiles.forEachIndexed {
- index, tile ->
- val column = index % (tiles.size / 2)
- val left = getLeftForColumn(column)
- val top = if (index < tiles.size / 2) 0 else getTopBottomRow()
- tile.tileView.layout(left, top, left + smallTileSize, top + smallTileSize)
+ val availableWidth = r - l - paddingLeft - paddingRight
+ val maxColumns = calculateMaxColumns(availableWidth)
+ val actualColumns = Math.min(maxColumns, mRecords.size / NUM_LINES)
+ if (actualColumns == 0) {
+ // No tileSize or horizontal margin
+ return
+ }
+ tilesToShow = actualColumns * NUM_LINES
+
+ val interTileSpace = if (actualColumns <= 2) {
+ // Extra "column" of padding to be distributed on each end
+ (availableWidth - actualColumns * smallTileSize) / actualColumns
+ } else {
+ (availableWidth - actualColumns * smallTileSize) / (actualColumns - 1)
+ }
+
+ for (index in 0 until mRecords.size) {
+ val tileView = mRecords[index].tileView
+ if (index >= tilesToShow) {
+ tileView.visibility = View.GONE
+ } else {
+ tileView.visibility = View.VISIBLE
+ if (index > 0) tileView.updateAccessibilityOrder(mRecords[index - 1].tileView)
+ val column = index % actualColumns
+ val left = getLeftForColumn(column, interTileSpace, actualColumns <= 2)
+ val top = if (index < actualColumns) 0 else getTopBottomRow()
+ tileView.layout(left, top, left + smallTileSize, top + smallTileSize)
+ }
}
}
- private fun getLeftForColumn(column: Int) = column * (smallTileSize + cellMarginHorizontal)
+ private fun getLeftForColumn(column: Int, interSpace: Int, sideMargin: Boolean): Int {
+ return (if (sideMargin) interSpace / 2 else 0) + column * (smallTileSize + interSpace)
+ }
private fun getTopBottomRow() = smallTileSize + cellMarginVertical
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 66e321145701..b71c4ebb5930 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -20,7 +20,6 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.window.WindowOrganizer.TaskOrganizer;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -33,11 +32,12 @@ import android.os.Handler;
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Slog;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerToken;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
-import android.window.IWindowContainer;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
@@ -181,14 +181,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
private boolean mPausedTargetAdjusted = false;
private boolean getSecondaryHasFocus(int displayId) {
- try {
- IWindowContainer imeSplit = TaskOrganizer.getImeTarget(displayId);
- return imeSplit != null
- && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed to get IME target", e);
- }
- return false;
+ WindowContainerToken imeSplit = TaskOrganizer.getImeTarget(displayId);
+ return imeSplit != null
+ && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder());
}
private void updateDimTargets() {
@@ -270,10 +265,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
wct.setScreenSizeDp(mSplits.mSecondary.token,
SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED);
}
- try {
- WindowOrganizer.applyTransaction(wct);
- } catch (RemoteException e) {
- }
+
+ WindowOrganizer.applyTransaction(wct);
// Update all the adjusted-for-ime states
if (!mPaused) {
@@ -506,12 +499,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
int midPos = mSplitLayout.getSnapAlgorithm().getMiddleTarget().position;
final WindowContainerTransaction tct = new WindowContainerTransaction();
mSplitLayout.resizeSplits(midPos, tct);
- try {
- WindowOrganizer.applyTransaction(tct);
- } catch (RemoteException e) {
- }
- } else if (mRotateSplitLayout != null
- && mSplitLayout.mDisplayLayout.rotation()
+ WindowOrganizer.applyTransaction(tct);
+ } else if (mSplitLayout.mDisplayLayout.rotation()
== mRotateSplitLayout.mDisplayLayout.rotation()) {
mSplitLayout.mPrimary = new Rect(mRotateSplitLayout.mPrimary);
mSplitLayout.mSecondary = new Rect(mRotateSplitLayout.mSecondary);
@@ -653,7 +642,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
}
}
updateTouchable();
- WindowManagerProxy.applyContainerTransaction(wct);
+ WindowOrganizer.applyTransaction(wct);
}
void setAdjustedForIme(boolean adjustedForIme) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index a6f67412fa50..91d638e70677 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -22,7 +22,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.window.WindowOrganizer.TaskOrganizer;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration;
@@ -32,11 +31,11 @@ import android.util.Log;
import android.view.Display;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import android.window.ITaskOrganizer;
+import android.window.TaskOrganizer;
import java.util.ArrayList;
-class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
+class SplitScreenTaskOrganizer extends TaskOrganizer {
private static final String TAG = "SplitScreenTaskOrganizer";
private static final boolean DEBUG = Divider.DEBUG;
@@ -56,8 +55,8 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
}
void init(SurfaceSession session) throws RemoteException {
- TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
- TaskOrganizer.registerOrganizer(this, WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+ registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ registerOrganizer(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
try {
mPrimary = TaskOrganizer.createRootTask(Display.DEFAULT_DISPLAY,
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
@@ -65,9 +64,9 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
mPrimarySurface = mPrimary.token.getLeash();
mSecondarySurface = mSecondary.token.getLeash();
- } catch (RemoteException e) {
+ } catch (Exception e) {
// teardown to prevent callbacks
- TaskOrganizer.unregisterOrganizer(this);
+ unregisterOrganizer();
throw e;
}
mSplitScreenSupported = true;
@@ -99,14 +98,6 @@ class SplitScreenTaskOrganizer extends ITaskOrganizer.Stub {
}
@Override
- public void onTaskAppeared(RunningTaskInfo taskInfo) {
- }
-
- @Override
- public void onTaskVanished(RunningTaskInfo taskInfo) {
- }
-
- @Override
public void onTaskInfoChanged(RunningTaskInfo taskInfo) {
if (taskInfo.displayId != DEFAULT_DISPLAY) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index 6ed7afe152df..85dcbb6316d0 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -20,7 +20,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.window.WindowOrganizer.TaskOrganizer;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -30,7 +29,8 @@ import android.os.RemoteException;
import android.util.Log;
import android.view.Display;
import android.view.WindowManagerGlobal;
-import android.window.IWindowContainer;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
import android.window.WindowOrganizer;
@@ -112,27 +112,21 @@ public class WindowManagerProxy {
static void applyResizeSplits(int position, SplitDisplayLayout splitLayout) {
WindowContainerTransaction t = new WindowContainerTransaction();
splitLayout.resizeSplits(position, t);
- try {
- WindowOrganizer.applyTransaction(t);
- } catch (RemoteException e) {
- }
+ WindowOrganizer.applyTransaction(t);
}
- private static boolean getHomeAndRecentsTasks(List<IWindowContainer> out,
- IWindowContainer parent) {
+ private static boolean getHomeAndRecentsTasks(List<WindowContainerToken> out,
+ WindowContainerToken parent) {
boolean resizable = false;
- try {
- List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
- ? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
- : TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
- for (int i = 0, n = rootTasks.size(); i < n; ++i) {
- final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
- out.add(ti.token);
- if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
- resizable = ti.isResizable();
- }
+ List<ActivityManager.RunningTaskInfo> rootTasks = parent == null
+ ? TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS)
+ : TaskOrganizer.getChildTasks(parent, HOME_AND_RECENTS);
+ for (int i = 0, n = rootTasks.size(); i < n; ++i) {
+ final ActivityManager.RunningTaskInfo ti = rootTasks.get(i);
+ out.add(ti.token);
+ if (ti.topActivityType == ACTIVITY_TYPE_HOME) {
+ resizable = ti.isResizable();
}
- } catch (RemoteException e) {
}
return resizable;
}
@@ -142,11 +136,11 @@ public class WindowManagerProxy {
* split is minimized. This actually "sticks out" of the secondary split area, but when in
* minimized mode, the secondary split gets a 'negative' crop to expose it.
*/
- static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent,
+ static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, WindowContainerToken parent,
@NonNull WindowContainerTransaction wct) {
// Resize the home/recents stacks to the larger minimized-state size
final Rect homeBounds;
- final ArrayList<IWindowContainer> homeStacks = new ArrayList<>();
+ final ArrayList<WindowContainerToken> homeStacks = new ArrayList<>();
boolean isHomeResizable = getHomeAndRecentsTasks(homeStacks, parent);
if (isHomeResizable) {
homeBounds = layout.calcMinimizedHomeStackBounds();
@@ -170,36 +164,31 @@ public class WindowManagerProxy {
* @return whether the home stack is resizable
*/
static boolean applyEnterSplit(SplitScreenTaskOrganizer tiles, SplitDisplayLayout layout) {
- try {
- // Set launchtile first so that any stack created after
- // getAllStackInfos and before reparent (even if unlikely) are placed
- // correctly.
- TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
- List<ActivityManager.RunningTaskInfo> rootTasks =
- TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
- WindowContainerTransaction wct = new WindowContainerTransaction();
- if (rootTasks.isEmpty()) {
- return false;
+ // Set launchtile first so that any stack created after
+ // getAllStackInfos and before reparent (even if unlikely) are placed
+ // correctly.
+ TaskOrganizer.setLaunchRoot(DEFAULT_DISPLAY, tiles.mSecondary.token);
+ List<ActivityManager.RunningTaskInfo> rootTasks =
+ TaskOrganizer.getRootTasks(DEFAULT_DISPLAY, null /* activityTypes */);
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ if (rootTasks.isEmpty()) {
+ return false;
+ }
+ tiles.mHomeAndRecentsSurfaces.clear();
+ for (int i = rootTasks.size() - 1; i >= 0; --i) {
+ final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
+ if (isHomeOrRecentTask(rootTask)) {
+ tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash());
}
- tiles.mHomeAndRecentsSurfaces.clear();
- for (int i = rootTasks.size() - 1; i >= 0; --i) {
- final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i);
- if (isHomeOrRecentTask(rootTask)) {
- tiles.mHomeAndRecentsSurfaces.add(rootTask.token.getLeash());
- }
- if (rootTask.configuration.windowConfiguration.getWindowingMode()
- != WINDOWING_MODE_FULLSCREEN) {
- continue;
- }
- wct.reparent(rootTask.token, tiles.mSecondary.token, true /* onTop */);
+ if (rootTask.configuration.windowConfiguration.getWindowingMode()
+ != WINDOWING_MODE_FULLSCREEN) {
+ continue;
}
- boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
- WindowOrganizer.applyTransaction(wct);
- return isHomeResizable;
- } catch (RemoteException e) {
- Log.w(TAG, "Error moving fullscreen tasks to secondary split: " + e);
+ wct.reparent(rootTask.token, tiles.mSecondary.token, true /* onTop */);
}
- return false;
+ boolean isHomeResizable = applyHomeTasksMinimized(layout, null /* parent */, wct);
+ WindowOrganizer.applyTransaction(wct);
+ return isHomeResizable;
}
private static boolean isHomeOrRecentTask(ActivityManager.RunningTaskInfo ti) {
@@ -214,82 +203,70 @@ public class WindowManagerProxy {
* fullscreen. {@code false} resolves the other way.
*/
static void applyDismissSplit(SplitScreenTaskOrganizer tiles, boolean dismissOrMaximize) {
- try {
- // Set launch root first so that any task created after getChildContainers and
- // before reparent (pretty unlikely) are put into fullscreen.
- TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
- tiles.mHomeAndRecentsSurfaces.clear();
- // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
- // plus specific APIs to clean this up.
- List<ActivityManager.RunningTaskInfo> primaryChildren =
- TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
- List<ActivityManager.RunningTaskInfo> secondaryChildren =
- TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
- // In some cases (eg. non-resizable is launched), system-server will leave split-screen.
- // as a result, the above will not capture any tasks; yet, we need to clean-up the
- // home task bounds.
- List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
- TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
- if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
- && freeHomeAndRecents.isEmpty()) {
- return;
+ // Set launch root first so that any task created after getChildContainers and
+ // before reparent (pretty unlikely) are put into fullscreen.
+ TaskOrganizer.setLaunchRoot(Display.DEFAULT_DISPLAY, null);
+ tiles.mHomeAndRecentsSurfaces.clear();
+ // TODO(task-org): Once task-org is more complete, consider using Appeared/Vanished
+ // plus specific APIs to clean this up.
+ List<ActivityManager.RunningTaskInfo> primaryChildren =
+ TaskOrganizer.getChildTasks(tiles.mPrimary.token, null /* activityTypes */);
+ List<ActivityManager.RunningTaskInfo> secondaryChildren =
+ TaskOrganizer.getChildTasks(tiles.mSecondary.token, null /* activityTypes */);
+ // In some cases (eg. non-resizable is launched), system-server will leave split-screen.
+ // as a result, the above will not capture any tasks; yet, we need to clean-up the
+ // home task bounds.
+ List<ActivityManager.RunningTaskInfo> freeHomeAndRecents =
+ TaskOrganizer.getRootTasks(Display.DEFAULT_DISPLAY, HOME_AND_RECENTS);
+ if (primaryChildren.isEmpty() && secondaryChildren.isEmpty()
+ && freeHomeAndRecents.isEmpty()) {
+ return;
+ }
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ if (dismissOrMaximize) {
+ // Dismissing, so move all primary split tasks first
+ for (int i = primaryChildren.size() - 1; i >= 0; --i) {
+ wct.reparent(primaryChildren.get(i).token, null /* parent */,
+ true /* onTop */);
}
- WindowContainerTransaction wct = new WindowContainerTransaction();
- if (dismissOrMaximize) {
- // Dismissing, so move all primary split tasks first
- for (int i = primaryChildren.size() - 1; i >= 0; --i) {
- wct.reparent(primaryChildren.get(i).token, null /* parent */,
- true /* onTop */);
- }
- // Don't need to worry about home tasks because they are already in the "proper"
- // order within the secondary split.
- for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
- final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
- wct.reparent(ti.token, null /* parent */, true /* onTop */);
- if (isHomeOrRecentTask(ti)) {
- wct.setBounds(ti.token, null);
- }
- }
- } else {
- // Maximize, so move non-home secondary split first
- for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
- if (isHomeOrRecentTask(secondaryChildren.get(i))) {
- continue;
- }
- wct.reparent(secondaryChildren.get(i).token, null /* parent */,
- true /* onTop */);
+ // Don't need to worry about home tasks because they are already in the "proper"
+ // order within the secondary split.
+ for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+ final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
+ wct.reparent(ti.token, null /* parent */, true /* onTop */);
+ if (isHomeOrRecentTask(ti)) {
+ wct.setBounds(ti.token, null);
}
- // Find and place home tasks in-between. This simulates the fact that there was
- // nothing behind the primary split's tasks.
- for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
- final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
- if (isHomeOrRecentTask(ti)) {
- wct.reparent(ti.token, null /* parent */, true /* onTop */);
- // reset bounds too
- wct.setBounds(ti.token, null);
- }
+ }
+ } else {
+ // Maximize, so move non-home secondary split first
+ for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+ if (isHomeOrRecentTask(secondaryChildren.get(i))) {
+ continue;
}
- for (int i = primaryChildren.size() - 1; i >= 0; --i) {
- wct.reparent(primaryChildren.get(i).token, null /* parent */,
- true /* onTop */);
+ wct.reparent(secondaryChildren.get(i).token, null /* parent */,
+ true /* onTop */);
+ }
+ // Find and place home tasks in-between. This simulates the fact that there was
+ // nothing behind the primary split's tasks.
+ for (int i = secondaryChildren.size() - 1; i >= 0; --i) {
+ final ActivityManager.RunningTaskInfo ti = secondaryChildren.get(i);
+ if (isHomeOrRecentTask(ti)) {
+ wct.reparent(ti.token, null /* parent */, true /* onTop */);
+ // reset bounds too
+ wct.setBounds(ti.token, null);
}
}
- for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
- wct.setBounds(freeHomeAndRecents.get(i).token, null);
+ for (int i = primaryChildren.size() - 1; i >= 0; --i) {
+ wct.reparent(primaryChildren.get(i).token, null /* parent */,
+ true /* onTop */);
}
- // Reset focusable to true
- wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
- WindowOrganizer.applyTransaction(wct);
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to remove stack: " + e);
}
- }
-
- static void applyContainerTransaction(WindowContainerTransaction wct) {
- try {
- WindowOrganizer.applyTransaction(wct);
- } catch (RemoteException e) {
- Log.w(TAG, "Error setting focusability: " + e);
+ for (int i = freeHomeAndRecents.size() - 1; i >= 0; --i) {
+ wct.setBounds(freeHomeAndRecents.get(i).token, null);
}
+ // Reset focusable to true
+ wct.setFocusable(tiles.mPrimary.token, true /* focusable */);
+ WindowOrganizer.applyTransaction(wct);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index a978cad1127a..fd44f04a0d80 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -32,6 +32,7 @@ import com.android.systemui.Dumpable
import com.android.systemui.Interpolators
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator
import com.android.systemui.statusbar.phone.BiometricUnlockController
import com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK
import com.android.systemui.statusbar.phone.NotificationShadeWindowController
@@ -39,7 +40,6 @@ import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.policy.KeyguardStateController
import java.io.FileDescriptor
import java.io.PrintWriter
-import java.lang.IllegalArgumentException
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
@@ -69,11 +69,41 @@ class NotificationShadeDepthController @Inject constructor(
private var notificationAnimator: Animator? = null
private var updateScheduled: Boolean = false
private var shadeExpansion = 0f
+ private var ignoreShadeBlurUntilHidden: Boolean = false
@VisibleForTesting
var shadeSpring = DepthAnimation()
@VisibleForTesting
var globalActionsSpring = DepthAnimation()
+ @VisibleForTesting
+ var brightnessMirrorSpring = DepthAnimation()
+ var brightnessMirrorVisible: Boolean = false
+ set(value) {
+ field = value
+ brightnessMirrorSpring.animateTo(if (value) blurUtils.blurRadiusOfRatio(1f)
+ else 0)
+ }
+
+ /**
+ * When launching an app from the shade, the animations progress should affect how blurry the
+ * shade is, overriding the expansion amount.
+ */
+ var notificationLaunchAnimationParams: ActivityLaunchAnimator.ExpandAnimationParameters? = null
+ set(value) {
+ field = value
+ if (value != null) {
+ scheduleUpdate()
+ return
+ }
+
+ if (shadeSpring.radius == 0) {
+ return
+ }
+ ignoreShadeBlurUntilHidden = true
+ shadeSpring.animateTo(0)
+ shadeSpring.finishIfRunning()
+ }
+
/**
* Blur radius of the wake-up animation on this frame.
*/
@@ -91,7 +121,19 @@ class NotificationShadeDepthController @Inject constructor(
val updateBlurCallback = Choreographer.FrameCallback {
updateScheduled = false
- val blur = max(max(shadeSpring.radius, wakeAndUnlockBlurRadius), globalActionsSpring.radius)
+ var shadeRadius = max(shadeSpring.radius, wakeAndUnlockBlurRadius).toFloat()
+ shadeRadius *= 1f - brightnessMirrorSpring.ratio
+ val launchProgress = notificationLaunchAnimationParams?.linearProgress ?: 0f
+ shadeRadius *= (1f - launchProgress) * (1f - launchProgress)
+
+ if (ignoreShadeBlurUntilHidden) {
+ if (shadeRadius == 0f) {
+ ignoreShadeBlurUntilHidden = false
+ } else {
+ shadeRadius = 0f
+ }
+ }
+ val blur = max(shadeRadius.toInt(), globalActionsSpring.radius)
blurUtils.applyBlur(blurRoot?.viewRootImpl ?: root.viewRootImpl, blur)
try {
wallpaperManager.setWallpaperZoomOut(root.windowToken,
@@ -148,6 +190,7 @@ class NotificationShadeDepthController @Inject constructor(
if (isDozing) {
shadeSpring.finishIfRunning()
globalActionsSpring.finishIfRunning()
+ brightnessMirrorSpring.finishIfRunning()
}
}
}
@@ -176,7 +219,6 @@ class NotificationShadeDepthController @Inject constructor(
if (statusBarStateController.state == StatusBarState.SHADE) {
newBlur = blurUtils.blurRadiusOfRatio(shadeExpansion)
}
-
shadeSpring.animateTo(newBlur)
}
@@ -199,7 +241,11 @@ class NotificationShadeDepthController @Inject constructor(
it.increaseIndent()
it.println("shadeRadius: ${shadeSpring.radius}")
it.println("globalActionsRadius: ${globalActionsSpring.radius}")
+ it.println("brightnessMirrorRadius: ${brightnessMirrorSpring.radius}")
it.println("wakeAndUnlockBlur: $wakeAndUnlockBlurRadius")
+ it.println("notificationLaunchAnimationProgress: " +
+ "${notificationLaunchAnimationParams?.linearProgress}")
+ it.println("ignoreShadeBlurUntilHidden: $ignoreShadeBlurUntilHidden")
}
}
@@ -212,7 +258,12 @@ class NotificationShadeDepthController @Inject constructor(
* Blur radius visible on the UI, in pixels.
*/
var radius = 0
- private set
+
+ /**
+ * Depth ratio of the current blur radius.
+ */
+ val ratio
+ get() = blurUtils.ratioOfBlurRadius(radius)
/**
* Radius that we're animating to.
@@ -239,7 +290,7 @@ class NotificationShadeDepthController @Inject constructor(
init {
springAnimation.spring = SpringForce(0.0f)
springAnimation.spring.dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
- springAnimation.spring.stiffness = SpringForce.STIFFNESS_MEDIUM
+ springAnimation.spring.stiffness = SpringForce.STIFFNESS_HIGH
springAnimation.addEndListener { _, _, _, _ -> pendingRadius = -1 }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
index 564d8bc14c8c..3f74aaf3abf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
@@ -38,10 +38,12 @@ public class NotificationUiAdjustment {
public final String key;
public final List<Notification.Action> smartActions;
public final List<CharSequence> smartReplies;
+ public final boolean isConversation;
@VisibleForTesting
NotificationUiAdjustment(
- String key, List<Notification.Action> smartActions, List<CharSequence> smartReplies) {
+ String key, List<Notification.Action> smartActions, List<CharSequence> smartReplies,
+ boolean isConversation) {
this.key = key;
this.smartActions = smartActions == null
? Collections.emptyList()
@@ -49,12 +51,14 @@ public class NotificationUiAdjustment {
this.smartReplies = smartReplies == null
? Collections.emptyList()
: smartReplies;
+ this.isConversation = isConversation;
}
public static NotificationUiAdjustment extractFromNotificationEntry(
NotificationEntry entry) {
return new NotificationUiAdjustment(
- entry.getKey(), entry.getSmartActions(), entry.getSmartReplies());
+ entry.getKey(), entry.getSmartActions(), entry.getSmartReplies(),
+ entry.getRanking().isConversation());
}
public static boolean needReinflate(
@@ -63,6 +67,9 @@ public class NotificationUiAdjustment {
if (oldAdjustment == newAdjustment) {
return false;
}
+ if (oldAdjustment.isConversation != newAdjustment.isConversation) {
+ return true;
+ }
if (areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions)) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index 7c061574f19c..6aef6b407f37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -34,6 +34,7 @@ import android.view.View;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
@@ -57,6 +58,7 @@ public class ActivityLaunchAnimator {
private final NotificationListContainer mNotificationContainer;
private final float mWindowCornerRadius;
private final NotificationShadeWindowViewController mNotificationShadeWindowViewController;
+ private final NotificationShadeDepthController mDepthController;
private Callback mCallback;
private final Runnable mTimeoutRunnable = () -> {
setAnimationPending(false);
@@ -70,9 +72,11 @@ public class ActivityLaunchAnimator {
NotificationShadeWindowViewController notificationShadeWindowViewController,
Callback callback,
NotificationPanelViewController notificationPanel,
+ NotificationShadeDepthController depthController,
NotificationListContainer container) {
mNotificationPanel = notificationPanel;
mNotificationContainer = container;
+ mDepthController = depthController;
mNotificationShadeWindowViewController = notificationShadeWindowViewController;
mCallback = callback;
mWindowCornerRadius = ScreenDecorationsUtils
@@ -212,7 +216,7 @@ public class ActivityLaunchAnimator {
mWindowCornerRadius, progress);
applyParamsToWindow(primary);
applyParamsToNotification(mParams);
- applyParamsToNotificationList(mParams);
+ applyParamsToNotificationShade(mParams);
}
});
anim.addListener(new AnimatorListenerAdapter() {
@@ -256,14 +260,15 @@ public class ActivityLaunchAnimator {
if (!running) {
mCallback.onExpandAnimationFinished(mIsFullScreenLaunch);
applyParamsToNotification(null);
- applyParamsToNotificationList(null);
+ applyParamsToNotificationShade(null);
}
}
- private void applyParamsToNotificationList(ExpandAnimationParameters params) {
+ private void applyParamsToNotificationShade(ExpandAnimationParameters params) {
mNotificationContainer.applyExpandAnimationParams(params);
mNotificationPanel.applyExpandAnimationParams(params);
+ mDepthController.setNotificationLaunchAnimationParams(params);
}
private void applyParamsToNotification(ExpandAnimationParameters params) {
@@ -295,7 +300,7 @@ public class ActivityLaunchAnimator {
};
public static class ExpandAnimationParameters {
- float linearProgress;
+ public float linearProgress;
int[] startPosition;
float startTranslationZ;
int left;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt
deleted file mode 100644
index 6be0fff38f2b..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotificationProcessor.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2020 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.systemui.statusbar.notification
-
-import android.app.Notification
-import android.content.pm.LauncherApps
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import javax.inject.Inject
-
-class ConversationNotificationProcessor @Inject constructor(
- private val launcherApps: LauncherApps
-) {
- fun processNotification(entry: NotificationEntry, recoveredBuilder: Notification.Builder) {
- val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return
- messagingStyle.conversationType =
- if (entry.ranking.channel.isImportantConversation)
- Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT
- else
- Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL
- entry.ranking.shortcutInfo?.let { shortcutInfo ->
- messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo)
- shortcutInfo.shortLabel?.let { shortLabel ->
- messagingStyle.conversationTitle = shortLabel
- }
- }
- }
-} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
new file mode 100644
index 000000000000..7ef1d0eba3f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2020 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.systemui.statusbar.notification
+
+import android.app.Notification
+import android.content.Context
+import android.content.pm.LauncherApps
+import android.service.notification.NotificationListenerService.Ranking
+import android.service.notification.NotificationListenerService.RankingMap
+import com.android.internal.statusbar.NotificationVisibility
+import com.android.internal.widget.ConversationLayout
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.NotificationContentView
+import java.util.concurrent.ConcurrentHashMap
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/** Populates additional information in conversation notifications */
+class ConversationNotificationProcessor @Inject constructor(
+ private val launcherApps: LauncherApps,
+ private val conversationNotificationManager: ConversationNotificationManager
+) {
+ fun processNotification(entry: NotificationEntry, recoveredBuilder: Notification.Builder) {
+ val messagingStyle = recoveredBuilder.style as? Notification.MessagingStyle ?: return
+ messagingStyle.conversationType =
+ if (entry.ranking.channel.isImportantConversation)
+ Notification.MessagingStyle.CONVERSATION_TYPE_IMPORTANT
+ else
+ Notification.MessagingStyle.CONVERSATION_TYPE_NORMAL
+ entry.ranking.shortcutInfo?.let { shortcutInfo ->
+ messagingStyle.shortcutIcon = launcherApps.getShortcutIcon(shortcutInfo)
+ shortcutInfo.shortLabel?.let { shortLabel ->
+ messagingStyle.conversationTitle = shortLabel
+ }
+ }
+ messagingStyle.unreadMessageCount =
+ conversationNotificationManager.getUnreadCount(entry, recoveredBuilder)
+ }
+}
+
+/**
+ * Tracks state related to conversation notifications, and updates the UI of existing notifications
+ * when necessary.
+ */
+@Singleton
+class ConversationNotificationManager @Inject constructor(
+ private val notificationEntryManager: NotificationEntryManager,
+ private val context: Context
+) {
+ // Need this state to be thread safe, since it's accessed from the ui thread
+ // (NotificationEntryListener) and a bg thread (NotificationContentInflater)
+ private val states = ConcurrentHashMap<String, ConversationState>()
+
+ private var notifPanelCollapsed = true
+
+ init {
+ notificationEntryManager.addNotificationEntryListener(object : NotificationEntryListener {
+
+ override fun onNotificationRankingUpdated(rankingMap: RankingMap) {
+ fun getLayouts(view: NotificationContentView) =
+ sequenceOf(view.contractedChild, view.expandedChild, view.headsUpChild)
+ val ranking = Ranking()
+ states.keys.asSequence()
+ .mapNotNull { notificationEntryManager.getActiveNotificationUnfiltered(it) }
+ .forEach { entry ->
+ if (rankingMap.getRanking(entry.sbn.key, ranking) &&
+ ranking.isConversation) {
+ val important = ranking.channel.isImportantConversation
+ entry.row?.layouts?.asSequence()
+ ?.flatMap(::getLayouts)
+ ?.mapNotNull { it as? ConversationLayout }
+ ?.forEach { it.setIsImportantConversation(important) }
+ }
+ }
+ }
+
+ override fun onEntryInflated(entry: NotificationEntry) {
+ if (!entry.ranking.isConversation) return
+ fun updateCount(isExpanded: Boolean) {
+ if (isExpanded && !notifPanelCollapsed) {
+ resetCount(entry.key)
+ entry.row?.let(::resetBadgeUi)
+ }
+ }
+ entry.row?.setOnExpansionChangedListener(::updateCount)
+ updateCount(entry.row?.isExpanded == true)
+ }
+
+ override fun onEntryReinflated(entry: NotificationEntry) = onEntryInflated(entry)
+
+ override fun onEntryRemoved(
+ entry: NotificationEntry,
+ visibility: NotificationVisibility?,
+ removedByUser: Boolean,
+ reason: Int
+ ) = removeTrackedEntry(entry)
+ })
+ }
+
+ fun getUnreadCount(entry: NotificationEntry, recoveredBuilder: Notification.Builder): Int =
+ states.compute(entry.key) { _, state ->
+ val newCount = state?.run {
+ val old = Notification.Builder.recoverBuilder(context, notification)
+ val increment = Notification
+ .areStyledNotificationsVisiblyDifferent(old, recoveredBuilder)
+ if (increment) unreadCount + 1 else unreadCount
+ } ?: 1
+ ConversationState(newCount, entry.sbn.notification)
+ }!!.unreadCount
+
+ fun onNotificationPanelExpandStateChanged(isCollapsed: Boolean) {
+ notifPanelCollapsed = isCollapsed
+ if (isCollapsed) return
+
+ // When the notification panel is expanded, reset the counters of any expanded
+ // conversations
+ val expanded = states
+ .asSequence()
+ .mapNotNull { (key, _) ->
+ notificationEntryManager.getActiveNotificationUnfiltered(key)
+ ?.let { entry ->
+ if (entry.row?.isExpanded == true) key to entry
+ else null
+ }
+ }
+ .toMap()
+ states.replaceAll { key, state ->
+ if (expanded.contains(key)) state.copy(unreadCount = 0)
+ else state
+ }
+ // Update UI separate from the replaceAll call, since ConcurrentHashMap may re-run the
+ // lambda if threads are in contention.
+ expanded.values.asSequence().mapNotNull { it.row }.forEach(::resetBadgeUi)
+ }
+
+ private fun resetCount(key: String) {
+ states.compute(key) { _, state -> state?.copy(unreadCount = 0) }
+ }
+
+ private fun removeTrackedEntry(entry: NotificationEntry) {
+ states.remove(entry.key)
+ }
+
+ private fun resetBadgeUi(row: ExpandableNotificationRow): Unit =
+ (row.layouts?.asSequence() ?: emptySequence())
+ .mapNotNull { layout -> layout.contractedChild as? ConversationLayout }
+ .forEach { convoLayout -> convoLayout.setUnreadCount(0) }
+
+ private data class ConversationState(val unreadCount: Int, val notification: Notification)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index b90cfa8ae25e..c9cc67009399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -249,6 +249,7 @@ public class NotifCollection implements Dumpable {
stats.notificationVisibility);
} catch (RemoteException e) {
// system process is dead if we're here.
+ mLogger.logRemoteExceptionOnNotificationClear(entry.getKey(), e);
}
}
}
@@ -277,6 +278,7 @@ public class NotifCollection implements Dumpable {
mStatusBarService.onClearAllNotifications(userId);
} catch (RemoteException e) {
// system process is dead if we're here.
+ mLogger.logRemoteExceptionOnClearAllNotifications(e);
}
final List<NotificationEntry> entries = new ArrayList<>(getAllNotifs());
@@ -743,6 +745,6 @@ public class NotifCollection implements Dumpable {
@Retention(RetentionPolicy.SOURCE)
public @interface CancellationReason {}
- public static final int REASON_NOT_CANCELED = -1;
+ static final int REASON_NOT_CANCELED = -1;
public static final int REASON_UNKNOWN = 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
index 8675cca3cffe..ef302f682df8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
@@ -16,11 +16,13 @@
package com.android.systemui.statusbar.notification.collection.notifcollection
+import android.os.RemoteException
import android.service.notification.NotificationListenerService.RankingMap
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogLevel.DEBUG
import com.android.systemui.log.LogLevel.INFO
import com.android.systemui.log.LogLevel.WARNING
+import com.android.systemui.log.LogLevel.WTF
import com.android.systemui.log.dagger.NotificationLog
import javax.inject.Inject
@@ -92,6 +94,23 @@ class NotifCollectionLogger @Inject constructor(
buffer.log(TAG, DEBUG, { str1 = entry }, { " $str1" })
}
}
+
+ fun logRemoteExceptionOnNotificationClear(key: String, e: RemoteException) {
+ buffer.log(TAG, WTF, {
+ str1 = key
+ str2 = e.toString()
+ }, {
+ "RemoteException while attempting to clear $str1:\n$str2"
+ })
+ }
+
+ fun logRemoteExceptionOnClearAllNotifications(e: RemoteException) {
+ buffer.log(TAG, WTF, {
+ str1 = e.toString()
+ }, {
+ "RemoteException while attempting to clear all notifications:\n$str1"
+ })
+ }
}
-private const val TAG = "NotifCollection" \ No newline at end of file
+private const val TAG = "NotifCollection"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 7deabf79a6dd..19b5f5c79ea2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -107,6 +107,7 @@ import com.android.systemui.statusbar.policy.InflatedSmartReplies.SmartRepliesAn
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
@@ -136,7 +137,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
*/
public interface LayoutListener {
void onLayout();
+ }
+ /** Listens for changes to the expansion state of this row. */
+ public interface OnExpansionChangedListener {
+ void onExpansionChanged(boolean isExpanded);
}
private StatusBarStateController mStatusbarStateController;
@@ -323,6 +328,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private boolean mWasChildInGroupWhenRemoved;
private NotificationInlineImageResolver mImageResolver;
private NotificationMediaManager mMediaManager;
+ @Nullable private OnExpansionChangedListener mExpansionChangedListener;
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
new SystemNotificationAsyncTask();
@@ -351,6 +357,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return isSystemNotification;
}
+ public NotificationContentView[] getLayouts() {
+ return Arrays.copyOf(mLayouts, mLayouts.length);
+ }
+
@Override
public boolean isGroupExpansionChanging() {
if (isChildInGroup()) {
@@ -1659,8 +1669,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
- mChildrenContainer.getHeaderView().showAppOpsIcons(activeOps);
+ if (mIsSummaryWithChildren) {
+ mChildrenContainer.showAppOpsIcons(activeOps);
}
mPrivateLayout.showAppOpsIcons(activeOps);
mPublicLayout.showAppOpsIcons(activeOps);
@@ -1687,8 +1697,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private final Runnable mExpireRecentlyAlertedFlag = () -> applyAudiblyAlertedRecently(false);
private void applyAudiblyAlertedRecently(boolean audiblyAlertedRecently) {
- if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
- mChildrenContainer.getHeaderView().setRecentlyAudiblyAlerted(audiblyAlertedRecently);
+ if (mIsSummaryWithChildren) {
+ mChildrenContainer.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
mPrivateLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
mPublicLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
@@ -2911,9 +2921,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
if (mIsSummaryWithChildren) {
mChildrenContainer.onExpansionChanged();
}
+ if (mExpansionChangedListener != null) {
+ mExpansionChangedListener.onExpansionChanged(nowExpanded);
+ }
}
}
+ public void setOnExpansionChangedListener(@Nullable OnExpansionChangedListener listener) {
+ mExpansionChangedListener = listener;
+ }
+
@Override
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfoInternal(info);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 9b9225e0bde0..8efdc1b56e8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -1468,27 +1468,27 @@ public class NotificationContentView extends FrameLayout {
}
public void showAppOpsIcons(ArraySet<Integer> activeOps) {
- if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
- mContractedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ if (mContractedChild != null) {
+ mContractedWrapper.showAppOpsIcons(activeOps);
}
- if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
- mExpandedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ if (mExpandedChild != null) {
+ mExpandedWrapper.showAppOpsIcons(activeOps);
}
- if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
- mHeadsUpWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
+ if (mHeadsUpChild != null) {
+ mHeadsUpWrapper.showAppOpsIcons(activeOps);
}
}
/** Sets whether the notification being displayed audibly alerted the user. */
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
- if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
- mContractedWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
+ if (mContractedChild != null) {
+ mContractedWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
- if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
- mExpandedWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
+ if (mExpandedChild != null) {
+ mExpandedWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
- if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
- mHeadsUpWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
+ if (mHeadsUpChild != null) {
+ mHeadsUpWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
index 82e5f0a3b130..8d675f86c343 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/StackScrollerDecorView.java
@@ -47,6 +47,18 @@ public abstract class StackScrollerDecorView extends ExpandableView {
}
};
+ private boolean mSecondaryAnimating = false;
+ private final Runnable mSecondaryVisibilityEndRunnable = () -> {
+ mSecondaryAnimating = false;
+ // If we were on screen, become GONE to avoid touches
+ if (mSecondaryView == null) return;
+ if (getVisibility() != View.GONE
+ && mSecondaryView.getVisibility() != View.GONE
+ && !mIsSecondaryVisible) {
+ mSecondaryView.setVisibility(View.GONE);
+ }
+ };
+
public StackScrollerDecorView(Context context, AttributeSet attrs) {
super(context, attrs);
setClipChildren(false);
@@ -88,9 +100,11 @@ public abstract class StackScrollerDecorView extends ExpandableView {
private void setContentVisible(boolean contentVisible, boolean animate) {
if (mContentVisible != contentVisible) {
mContentAnimating = animate;
- setViewVisible(mContent, contentVisible, animate, mContentVisibilityEndRunnable);
mContentVisible = contentVisible;
- } if (!mContentAnimating) {
+ setViewVisible(mContent, contentVisible, animate, mContentVisibilityEndRunnable);
+ }
+
+ if (!mContentAnimating) {
mContentVisibilityEndRunnable.run();
}
}
@@ -136,8 +150,13 @@ public abstract class StackScrollerDecorView extends ExpandableView {
*/
public void setSecondaryVisible(boolean nowVisible, boolean animate) {
if (mIsSecondaryVisible != nowVisible) {
- setViewVisible(mSecondaryView, nowVisible, animate, null /* endRunnable */);
+ mSecondaryAnimating = animate;
mIsSecondaryVisible = nowVisible;
+ setViewVisible(mSecondaryView, nowVisible, animate, mSecondaryVisibilityEndRunnable);
+ }
+
+ if (!mSecondaryAnimating) {
+ mSecondaryVisibilityEndRunnable.run();
}
}
@@ -170,6 +189,12 @@ public abstract class StackScrollerDecorView extends ExpandableView {
if (view == null) {
return;
}
+
+ // Make sure we're visible so animations work
+ if (view.getVisibility() != View.VISIBLE) {
+ view.setVisibility(View.VISIBLE);
+ }
+
// cancel any previous animations
view.animate().cancel();
float endValue = nowVisible ? 1.0f : 0.0f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 7808a4b2dc74..0c311b403c48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.row.wrapper;
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
+import android.annotation.NonNull;
+import android.app.AppOpsManager;
import android.app.Notification;
import android.content.Context;
import android.util.ArraySet;
@@ -60,6 +62,11 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
protected NotificationHeaderView mNotificationHeader;
private TextView mHeaderText;
private ImageView mWorkProfileImage;
+ private View mCameraIcon;
+ private View mMicIcon;
+ private View mOverlayIcon;
+ private View mAppOps;
+ private View mAudiblyAlertedIcon;
private boolean mIsLowPriority;
private boolean mTransformLowPriorityTitle;
@@ -107,6 +114,11 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
+ mCameraIcon = mView.findViewById(com.android.internal.R.id.camera);
+ mMicIcon = mView.findViewById(com.android.internal.R.id.mic);
+ mOverlayIcon = mView.findViewById(com.android.internal.R.id.overlay);
+ mAppOps = mView.findViewById(com.android.internal.R.id.app_ops);
+ mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon);
if (mNotificationHeader != null) {
mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
mColor = mNotificationHeader.getOriginalIconColor();
@@ -114,8 +126,35 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
+ View.OnClickListener listener = row.getAppOpsOnClickListener();
if (mNotificationHeader != null) {
- mNotificationHeader.setAppOpsOnClickListener(row.getAppOpsOnClickListener());
+ mNotificationHeader.setAppOpsOnClickListener(listener);
+ }
+ mAppOps.setOnClickListener(listener);
+ mCameraIcon.setOnClickListener(listener);
+ mMicIcon.setOnClickListener(listener);
+ mOverlayIcon.setOnClickListener(listener);
+ }
+
+ /**
+ * Shows or hides 'app op in use' icons based on app usage.
+ */
+ @Override
+ public void showAppOpsIcons(ArraySet<Integer> appOps) {
+ if (appOps == null) {
+ return;
+ }
+ if (mOverlayIcon != null) {
+ mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
+ ? View.VISIBLE : View.GONE);
+ }
+ if (mCameraIcon != null) {
+ mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
+ ? View.VISIBLE : View.GONE);
+ }
+ if (mMicIcon != null) {
+ mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
+ ? View.VISIBLE : View.GONE);
}
}
@@ -184,6 +223,18 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
mHeaderText);
}
+ if (mCameraIcon != null) {
+ mTransformationHelper.addViewTransformingToSimilar(mCameraIcon);
+ }
+ if (mMicIcon != null) {
+ mTransformationHelper.addViewTransformingToSimilar(mMicIcon);
+ }
+ if (mOverlayIcon != null) {
+ mTransformationHelper.addViewTransformingToSimilar(mOverlayIcon);
+ }
+ if (mAudiblyAlertedIcon != null) {
+ mTransformationHelper.addViewTransformingToSimilar(mAudiblyAlertedIcon);
+ }
}
@Override
@@ -195,6 +246,13 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
@Override
+ public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
+ if (mAudiblyAlertedIcon != null) {
+ mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? View.VISIBLE : View.GONE);
+ }
+ }
+
+ @Override
public NotificationHeaderView getNotificationHeader() {
return mNotificationHeader;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index e4fb2f7c42d4..fa7f282be74a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.util.ArraySet;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
@@ -95,6 +96,14 @@ public abstract class NotificationViewWrapper implements TransformableView {
public void onContentUpdated(ExpandableNotificationRow row) {
}
+ /**
+ * Show a set of app opp icons in the layout.
+ *
+ * @param appOps which app ops to show
+ */
+ public void showAppOpsIcons(ArraySet<Integer> appOps) {
+ }
+
public void onReinflated() {
if (shouldClearBackgroundOnReapply()) {
mBackgroundColor = 0;
@@ -362,4 +371,10 @@ public abstract class NotificationViewWrapper implements TransformableView {
public int getExtraMeasureHeight() {
return 0;
}
+
+ /**
+ * Set the view to have recently visibly alerted.
+ */
+ public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 3d0bf3f4c1c6..400e794b820b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.service.notification.StatusBarNotification;
+import android.util.ArraySet;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.NotificationHeaderView;
@@ -1265,4 +1266,27 @@ public class NotificationChildrenContainer extends ViewGroup {
mHeaderVisibleAmount = headerVisibleAmount;
mCurrentHeaderTranslation = (int) ((1.0f - headerVisibleAmount) * mTranslationForHeader);
}
+
+ /**
+ * Show a set of app opp icons in the layout.
+ *
+ * @param appOps which app ops to show
+ */
+ public void showAppOpsIcons(ArraySet<Integer> appOps) {
+ if (mNotificationHeaderWrapper != null) {
+ mNotificationHeaderWrapper.showAppOpsIcons(appOps);
+ }
+ if (mNotificationHeaderWrapperLowPriority != null) {
+ mNotificationHeaderWrapperLowPriority.showAppOpsIcons(appOps);
+ }
+ }
+
+ public void setRecentlyAudiblyAlerted(boolean audiblyAlertedRecently) {
+ if (mNotificationHeaderWrapper != null) {
+ mNotificationHeaderWrapper.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
+ }
+ if (mNotificationHeaderWrapperLowPriority != null) {
+ mNotificationHeaderWrapperLowPriority.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
index c05119de1e79..d6039af9232a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
-import android.util.ArraySet;
import android.util.Log;
import android.view.IWindowManager;
import android.view.MotionEvent;
@@ -27,8 +26,6 @@ import android.view.MotionEvent;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.AutoHideUiElement;
-import java.util.Set;
-
import javax.inject.Inject;
/** A controller to control all auto-hide things. Also see {@link AutoHideUiElement}. */
@@ -38,8 +35,9 @@ public class AutoHideController {
private final IWindowManager mWindowManagerService;
private final Handler mHandler;
- private final Set<AutoHideUiElement> mElements;
+ private AutoHideUiElement mStatusBar;
+ private AutoHideUiElement mNavigationBar;
private int mDisplayId;
private boolean mAutoHideSuspended;
@@ -55,28 +53,24 @@ public class AutoHideController {
IWindowManager iWindowManager) {
mHandler = handler;
mWindowManagerService = iWindowManager;
- mElements = new ArraySet<>();
mDisplayId = context.getDisplayId();
}
/**
- * Adds an {@link AutoHideUiElement} whose behavior should be controlled by the
+ * Sets a {@link AutoHideUiElement} status bar that should be controlled by the
* {@link AutoHideController}.
*/
- public void addAutoHideUiElement(AutoHideUiElement element) {
- if (element != null) {
- mElements.add(element);
- }
+ public void setStatusBar(AutoHideUiElement element) {
+ mStatusBar = element;
}
/**
- * Remove an {@link AutoHideUiElement} that was previously added.
+ * Sets a {@link AutoHideUiElement} navigation bar that should be controlled by the
+ * {@link AutoHideController}.
*/
- public void removeAutoHideUiElement(AutoHideUiElement element) {
- if (element != null) {
- mElements.remove(element);
- }
+ public void setNavigationBar(AutoHideUiElement element) {
+ mNavigationBar = element;
}
private void hideTransientBars() {
@@ -86,8 +80,12 @@ public class AutoHideController {
Log.w(TAG, "Cannot get WindowManager");
}
- for (AutoHideUiElement element : mElements) {
- element.hide();
+ if (mStatusBar != null) {
+ mStatusBar.hide();
+ }
+
+ if (mNavigationBar != null) {
+ mNavigationBar.hide();
}
}
@@ -121,15 +119,13 @@ public class AutoHideController {
}
private Runnable getCheckBarModesRunnable() {
- if (mElements.isEmpty()) {
+ if (mStatusBar != null) {
+ return () -> mStatusBar.synchronizeState();
+ } else if (mNavigationBar != null) {
+ return () -> mNavigationBar.synchronizeState();
+ } else {
return null;
}
-
- return () -> {
- for (AutoHideUiElement element : mElements) {
- element.synchronizeState();
- }
- };
}
private void cancelAutoHide() {
@@ -147,8 +143,11 @@ public class AutoHideController {
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar.
&& event.getX() == 0 && event.getY() == 0;
- for (AutoHideUiElement element : mElements) {
- shouldHide &= element.shouldHideOnTouch();
+ if (mStatusBar != null) {
+ shouldHide &= mStatusBar.shouldHideOnTouch();
+ }
+ if (mNavigationBar != null) {
+ shouldHide &= mNavigationBar.shouldHideOnTouch();
}
if (shouldHide) {
@@ -162,11 +161,14 @@ public class AutoHideController {
}
private boolean isAnyTransientBarShown() {
- for (AutoHideUiElement element : mElements) {
- if (element.isVisible()) {
- return true;
- }
+ if (mStatusBar != null && mStatusBar.isVisible()) {
+ return true;
}
+
+ if (mNavigationBar != null && mNavigationBar.isVisible()) {
+ return true;
+ }
+
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 31266db9e144..6fd3bb2c8222 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -1075,12 +1075,9 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
/** Sets {@link AutoHideController} to the navigation bar. */
public void setAutoHideController(AutoHideController autoHideController) {
- if (mAutoHideController != null) {
- mAutoHideController.removeAutoHideUiElement(mAutoHideUiElement);
- }
mAutoHideController = autoHideController;
if (mAutoHideController != null) {
- mAutoHideController.addAutoHideUiElement(mAutoHideUiElement);
+ mAutoHideController.setNavigationBar(mAutoHideUiElement);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 98ba6e5b88a0..31797d1faa61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.phone;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
+import static java.lang.Float.isNaN;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -86,6 +88,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.AnimatableProperty;
+import com.android.systemui.statusbar.notification.ConversationNotificationManager;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -238,6 +241,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final PulseExpansionHandler mPulseExpansionHandler;
private final KeyguardBypassController mKeyguardBypassController;
private final KeyguardUpdateMonitor mUpdateMonitor;
+ private final ConversationNotificationManager mConversationNotificationManager;
private KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@@ -451,7 +455,8 @@ public class NotificationPanelViewController extends PanelViewController {
ActivityManager activityManager, ZenModeController zenModeController,
ConfigurationController configurationController,
FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
- StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ ConversationNotificationManager conversationNotificationManager) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -509,6 +514,7 @@ public class NotificationPanelViewController extends PanelViewController {
mShadeController = shadeController;
mLockscreenUserManager = notificationLockscreenUserManager;
mEntryManager = notificationEntryManager;
+ mConversationNotificationManager = conversationNotificationManager;
mView.setBackgroundColor(Color.TRANSPARENT);
OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -2005,7 +2011,12 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
protected float getOverExpansionAmount() {
- return mNotificationStackScroller.getCurrentOverScrollAmount(true /* top */);
+ float result = mNotificationStackScroller.getCurrentOverScrollAmount(true /* top */);
+ if (isNaN(result)) {
+ Log.wtf(TAG, "OverExpansionAmount is NaN!");
+ }
+
+ return result;
}
@Override
@@ -2143,6 +2154,7 @@ public class NotificationPanelViewController extends PanelViewController {
super.onExpandingFinished();
mNotificationStackScroller.onExpansionStopped();
mHeadsUpManager.onExpandingFinished();
+ mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
mIsExpanding = false;
if (isFullyCollapsed()) {
DejankUtils.postAfterTraversal(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 83cc4e33e2db..f7d403f667cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static java.lang.Float.isNaN;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -638,6 +640,9 @@ public abstract class PanelViewController {
}
public void setExpandedHeightInternal(float h) {
+ if (isNaN(h)) {
+ Log.wtf(TAG, "ExpandedHeight set to NaN");
+ }
if (mExpandLatencyTracking && h != 0f) {
DejankUtils.postAfterTraversal(
() -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index d343090900a1..fa55b74606c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -176,6 +176,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
@@ -589,6 +590,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private ActivityLaunchAnimator mActivityLaunchAnimator;
protected StatusBarNotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
+ private Lazy<NotificationShadeDepthController> mNotificationShadeDepthControllerLazy;
private final BubbleController mBubbleController;
private final BubbleController.BubbleExpandListener mBubbleExpandListener;
@@ -679,6 +681,7 @@ public class StatusBar extends SystemUI implements DemoMode,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
DismissCallbackRegistry dismissCallbackRegistry,
+ Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
super(context);
mNotificationsController = notificationsController;
@@ -735,6 +738,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mScreenPinningRequest = screenPinningRequest;
mDozeScrimController = dozeScrimController;
mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
+ mNotificationShadeDepthControllerLazy = notificationShadeDepthControllerLazy;
mVolumeComponent = volumeComponent;
mCommandQueue = commandQueue;
mRecentsOptional = recentsOptional;
@@ -1073,7 +1077,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
});
- mAutoHideController.addAutoHideUiElement(new AutoHideUiElement() {
+ mAutoHideController.setStatusBar(new AutoHideUiElement() {
@Override
public void synchronizeState() {
checkBarModes();
@@ -1135,6 +1139,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mBrightnessMirrorController = new BrightnessMirrorController(
mNotificationShadeWindowView,
mNotificationPanelViewController,
+ mNotificationShadeDepthControllerLazy.get(),
(visible) -> {
mBrightnessMirrorVisible = visible;
updateScrimController();
@@ -1230,6 +1235,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// Set up the initial notification state.
mActivityLaunchAnimator = new ActivityLaunchAnimator(
mNotificationShadeWindowViewController, this, mNotificationPanelViewController,
+ mNotificationShadeDepthControllerLazy.get(),
(NotificationListContainer) mStackScroller);
// TODO: inject this.
@@ -3333,12 +3339,12 @@ public class StatusBar extends SystemUI implements DemoMode,
Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
Trace.beginSection("StatusBar#updateDozingState");
- boolean sleepingFromKeyguard =
- mStatusBarKeyguardViewManager.isGoingToSleepVisibleNotOccluded();
+ boolean visibleNotOccluded = mStatusBarKeyguardViewManager.isShowing()
+ && !mStatusBarKeyguardViewManager.isOccluded();
boolean wakeAndUnlock = mBiometricUnlockController.getMode()
== BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup() && !wakeAndUnlock)
- || (mDozing && mDozeServiceHost.shouldAnimateScreenOff() && sleepingFromKeyguard);
+ || (mDozing && mDozeServiceHost.shouldAnimateScreenOff() && visibleNotOccluded);
mNotificationPanelViewController.setDozing(mDozing, animate, mWakeUpTouchLocation);
updateQsExpansionEnabled();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 31db8eb404a9..45719c7f3936 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -168,7 +168,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private boolean mLastIsDocked;
private boolean mLastPulsing;
private int mLastBiometricMode;
- private boolean mGoingToSleepVisibleNotOccluded;
private boolean mLastLockVisible;
private OnDismissAction mAfterKeyguardGoneAction;
@@ -450,37 +449,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
}
- public boolean isGoingToSleepVisibleNotOccluded() {
- return mGoingToSleepVisibleNotOccluded;
- }
-
- @Override
- public void onStartedGoingToSleep() {
- mGoingToSleepVisibleNotOccluded = isShowing() && !isOccluded();
- }
-
@Override
public void onFinishedGoingToSleep() {
- mGoingToSleepVisibleNotOccluded = false;
mBouncer.onScreenTurnedOff();
}
@Override
- public void onStartedWakingUp() {
- // TODO: remove
- }
-
- @Override
- public void onScreenTurningOn() {
- // TODO: remove
- }
-
- @Override
- public void onScreenTurnedOn() {
- // TODO: remove
- }
-
- @Override
public void onRemoteInputActive(boolean active) {
mRemoteInputActive = active;
updateStates();
@@ -999,7 +973,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
pw.println(" mOccluded: " + mOccluded);
pw.println(" mRemoteInputActive: " + mRemoteInputActive);
pw.println(" mDozing: " + mDozing);
- pw.println(" mGoingToSleepVisibleNotOccluded: " + mGoingToSleepVisibleNotOccluded);
pw.println(" mAfterKeyguardGoneAction: " + mAfterKeyguardGoneAction);
pw.println(" mAfterKeyguardGoneRunnables: " + mAfterKeyguardGoneRunnables);
pw.println(" mPendingWakeupAction: " + mPendingWakeupAction);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index bbc7e7ab8c06..b81a5198b498 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
@@ -197,6 +198,7 @@ public interface StatusBarPhoneModule {
UserInfoControllerImpl userInfoControllerImpl,
PhoneStatusBarPolicy phoneStatusBarPolicy,
KeyguardIndicationController keyguardIndicationController,
+ Lazy<NotificationShadeDepthController> notificationShadeDepthController,
DismissCallbackRegistry dismissCallbackRegistry,
StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
return new StatusBar(
@@ -276,6 +278,7 @@ public interface StatusBarPhoneModule {
phoneStatusBarPolicy,
keyguardIndicationController,
dismissCallbackRegistry,
+ notificationShadeDepthController,
statusBarTouchableRegionManager);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index d62da10de3d5..78111fb61fd0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -24,6 +24,7 @@ import android.view.View;
import android.widget.FrameLayout;
import com.android.systemui.R;
+import com.android.systemui.statusbar.NotificationShadeDepthController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
@@ -39,16 +40,19 @@ public class BrightnessMirrorController
private final NotificationShadeWindowView mStatusBarWindow;
private final Consumer<Boolean> mVisibilityCallback;
private final NotificationPanelViewController mNotificationPanel;
+ private final NotificationShadeDepthController mDepthController;
private final ArraySet<BrightnessMirrorListener> mBrightnessMirrorListeners = new ArraySet<>();
private final int[] mInt2Cache = new int[2];
private View mBrightnessMirror;
public BrightnessMirrorController(NotificationShadeWindowView statusBarWindow,
NotificationPanelViewController notificationPanelViewController,
+ NotificationShadeDepthController notificationShadeDepthController,
@NonNull Consumer<Boolean> visibilityCallback) {
mStatusBarWindow = statusBarWindow;
mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
mNotificationPanel = notificationPanelViewController;
+ mDepthController = notificationShadeDepthController;
mNotificationPanel.setPanelAlphaEndAction(() -> {
mBrightnessMirror.setVisibility(View.INVISIBLE);
});
@@ -59,11 +63,13 @@ public class BrightnessMirrorController
mBrightnessMirror.setVisibility(View.VISIBLE);
mVisibilityCallback.accept(true);
mNotificationPanel.setPanelAlpha(0, true /* animate */);
+ mDepthController.setBrightnessMirrorVisible(true);
}
public void hideMirror() {
mVisibilityCallback.accept(false);
mNotificationPanel.setPanelAlpha(255, true /* animate */);
+ mDepthController.setBrightnessMirrorVisible(false);
}
public void setLocation(View original) {