Merge "Fix smart reply lifetime extension" into sc-v2-dev
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 86cf28f..e08b913 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -54,6 +54,10 @@
/** @hide */
public static final String SETTINGS_SUPPORT_LARGE_SCREEN = "settings_support_large_screen";
+ /** @hide */
+ public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS =
+ "settings_enable_monitor_phantom_procs";
+
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -76,6 +80,7 @@
DEFAULT_FLAGS.put(SETTINGS_USE_NEW_BACKUP_ELIGIBILITY_RULES, "true");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_SECURITY_HUB, "true");
DEFAULT_FLAGS.put(SETTINGS_SUPPORT_LARGE_SCREEN, "true");
+ DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
}
private static final Set<String> PERSISTENT_FLAGS;
@@ -83,6 +88,7 @@
PERSISTENT_FLAGS = new HashSet<>();
PERSISTENT_FLAGS.add(SETTINGS_PROVIDER_MODEL);
PERSISTENT_FLAGS.add(SETTINGS_SUPPORT_LARGE_SCREEN);
+ PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
}
/**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 721260e..1244d75 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -3682,14 +3682,14 @@
if (!mEdgeGlowBottom.isFinished()) {
mEdgeGlowBottom.onRelease();
}
- invalidateTopGlow();
+ invalidateEdgeEffects();
} else if (incrementalDeltaY < 0) {
mEdgeGlowBottom.onPullDistance((float) overscroll / getHeight(),
1.f - (float) x / getWidth());
if (!mEdgeGlowTop.isFinished()) {
mEdgeGlowTop.onRelease();
}
- invalidateBottomGlow();
+ invalidateEdgeEffects();
}
}
}
@@ -3729,7 +3729,7 @@
if (!mEdgeGlowBottom.isFinished()) {
mEdgeGlowBottom.onRelease();
}
- invalidateTopGlow();
+ invalidateEdgeEffects();
} else if (rawDeltaY < 0) {
mEdgeGlowBottom.onPullDistance(
(float) -overScrollDistance / getHeight(),
@@ -3737,7 +3737,7 @@
if (!mEdgeGlowTop.isFinished()) {
mEdgeGlowTop.onRelease();
}
- invalidateBottomGlow();
+ invalidateEdgeEffects();
}
}
}
@@ -3783,17 +3783,21 @@
// First allow releasing existing overscroll effect:
float consumed = 0;
if (mEdgeGlowTop.getDistance() != 0) {
- consumed = mEdgeGlowTop.onPullDistance((float) deltaY / getHeight(),
- (float) x / getWidth());
- if (consumed != 0f) {
- invalidateTopGlow();
+ if (canScrollUp()) {
+ mEdgeGlowTop.onRelease();
+ } else {
+ consumed = mEdgeGlowTop.onPullDistance((float) deltaY / getHeight(),
+ (float) x / getWidth());
}
+ invalidateEdgeEffects();
} else if (mEdgeGlowBottom.getDistance() != 0) {
- consumed = -mEdgeGlowBottom.onPullDistance((float) -deltaY / getHeight(),
- 1f - (float) x / getWidth());
- if (consumed != 0f) {
- invalidateBottomGlow();
+ if (canScrollDown()) {
+ mEdgeGlowBottom.onRelease();
+ } else {
+ consumed = -mEdgeGlowBottom.onPullDistance((float) -deltaY / getHeight(),
+ 1f - (float) x / getWidth());
}
+ invalidateEdgeEffects();
}
int pixelsConsumed = Math.round(consumed * getHeight());
return deltaY - pixelsConsumed;
@@ -3803,30 +3807,16 @@
* @return <code>true</code> if either the top or bottom edge glow is currently active or
* <code>false</code> if it has no value to release.
*/
- private boolean isGlowActive() {
- return mEdgeGlowBottom.getDistance() != 0 || mEdgeGlowTop.getDistance() != 0;
+ private boolean doesTouchStopStretch() {
+ return (mEdgeGlowBottom.getDistance() != 0 && !canScrollDown())
+ || (mEdgeGlowTop.getDistance() != 0 && !canScrollUp());
}
- private void invalidateTopGlow() {
+ private void invalidateEdgeEffects() {
if (!shouldDisplayEdgeEffects()) {
return;
}
- final boolean clipToPadding = getClipToPadding();
- final int top = clipToPadding ? mPaddingTop : 0;
- final int left = clipToPadding ? mPaddingLeft : 0;
- final int right = clipToPadding ? getWidth() - mPaddingRight : getWidth();
- invalidate(left, top, right, top + mEdgeGlowTop.getMaxHeight());
- }
-
- private void invalidateBottomGlow() {
- if (!shouldDisplayEdgeEffects()) {
- return;
- }
- final boolean clipToPadding = getClipToPadding();
- final int bottom = clipToPadding ? getHeight() - mPaddingBottom : getHeight();
- final int left = clipToPadding ? mPaddingLeft : 0;
- final int right = clipToPadding ? getWidth() - mPaddingRight : getWidth();
- invalidate(left, bottom - mEdgeGlowBottom.getMaxHeight(), right, bottom);
+ invalidate();
}
@Override
@@ -4469,7 +4459,7 @@
final int edgeY = Math.min(0, scrollY + mFirstPositionDistanceGuess) + translateY;
canvas.translate(translateX, edgeY);
if (mEdgeGlowTop.draw(canvas)) {
- invalidateTopGlow();
+ invalidateEdgeEffects();
}
canvas.restoreToCount(restoreCount);
}
@@ -4483,7 +4473,7 @@
canvas.translate(edgeX, edgeY);
canvas.rotate(180, width, 0);
if (mEdgeGlowBottom.draw(canvas)) {
- invalidateBottomGlow();
+ invalidateEdgeEffects();
}
canvas.restoreToCount(restoreCount);
}
@@ -4573,7 +4563,7 @@
mActivePointerId = ev.getPointerId(0);
int motionPosition = findMotionRow(y);
- if (isGlowActive()) {
+ if (doesTouchStopStretch()) {
// Pressed during edge effect, so this is considered the same as a fling catch.
touchMode = mTouchMode = TOUCH_MODE_FLING;
} else if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) {
@@ -6579,7 +6569,7 @@
*/
public void setBottomEdgeEffectColor(@ColorInt int color) {
mEdgeGlowBottom.setColor(color);
- invalidateBottomGlow();
+ invalidateEdgeEffects();
}
/**
@@ -6593,7 +6583,7 @@
*/
public void setTopEdgeEffectColor(@ColorInt int color) {
mEdgeGlowTop.setColor(color);
- invalidateTopGlow();
+ invalidateEdgeEffects();
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index f0f78748..19d513f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -346,6 +346,9 @@
* bubble is dragged back into the row.
*/
public void dragBubbleOut(View bubbleView, float x, float y) {
+ if (mMagnetizedBubbleDraggingOut == null) {
+ return;
+ }
if (mSpringToTouchOnNextMotionEvent) {
springBubbleTo(mMagnetizedBubbleDraggingOut.getUnderlyingObject(), x, y);
mSpringToTouchOnNextMotionEvent = false;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
index b65a2e4..8e6c05d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java
@@ -151,7 +151,13 @@
final Rect rightHitRegion = new Rect();
final Rect rightDrawRegion = bottomOrRightBounds;
- displayRegion.splitVertically(leftHitRegion, rightHitRegion);
+ // If we have existing split regions use those bounds, otherwise split it 50/50
+ if (inSplitScreen) {
+ leftHitRegion.set(topOrLeftBounds);
+ rightHitRegion.set(bottomOrRightBounds);
+ } else {
+ displayRegion.splitVertically(leftHitRegion, rightHitRegion);
+ }
mTargets.add(new Target(TYPE_SPLIT_LEFT, leftHitRegion, leftDrawRegion));
mTargets.add(new Target(TYPE_SPLIT_RIGHT, rightHitRegion, rightDrawRegion));
@@ -162,8 +168,13 @@
final Rect bottomHitRegion = new Rect();
final Rect bottomDrawRegion = bottomOrRightBounds;
- displayRegion.splitHorizontally(
- topHitRegion, bottomHitRegion);
+ // If we have existing split regions use those bounds, otherwise split it 50/50
+ if (inSplitScreen) {
+ topHitRegion.set(topOrLeftBounds);
+ bottomHitRegion.set(bottomOrRightBounds);
+ } else {
+ displayRegion.splitHorizontally(topHitRegion, bottomHitRegion);
+ }
mTargets.add(new Target(TYPE_SPLIT_TOP, topHitRegion, topDrawRegion));
mTargets.add(new Target(TYPE_SPLIT_BOTTOM, bottomHitRegion, bottomDrawRegion));
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
index 67f9062..fd3be2b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java
@@ -17,7 +17,9 @@
package com.android.wm.shell.draganddrop;
import static android.app.StatusBarManager.DISABLE_NONE;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import android.animation.Animator;
@@ -32,11 +34,11 @@
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Insets;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
import android.view.DragEvent;
import android.view.SurfaceControl;
-import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowInsets.Type;
import android.widget.LinearLayout;
@@ -73,6 +75,7 @@
private DropZoneView mDropZoneView2;
private int mDisplayMargin;
+ private int mDividerSize;
private Insets mInsets = Insets.NONE;
private boolean mIsShowing;
@@ -89,13 +92,15 @@
mDisplayMargin = context.getResources().getDimensionPixelSize(
R.dimen.drop_layout_display_margin);
+ mDividerSize = context.getResources().getDimensionPixelSize(
+ R.dimen.split_divider_bar_width);
mDropZoneView1 = new DropZoneView(context);
mDropZoneView2 = new DropZoneView(context);
- addView(mDropZoneView1, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT));
- addView(mDropZoneView2, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT));
+ addView(mDropZoneView1, new LinearLayout.LayoutParams(MATCH_PARENT,
+ MATCH_PARENT));
+ addView(mDropZoneView2, new LinearLayout.LayoutParams(MATCH_PARENT,
+ MATCH_PARENT));
((LayoutParams) mDropZoneView1.getLayoutParams()).weight = 1;
((LayoutParams) mDropZoneView2.getLayoutParams()).weight = 1;
updateContainerMargins();
@@ -165,44 +170,82 @@
mHasDropped = false;
mCurrentTarget = null;
- List<ActivityManager.RunningTaskInfo> tasks = null;
- // Figure out the splashscreen info for the existing task(s).
- try {
- tasks = ActivityTaskManager.getService().getTasks(2,
- false /* filterOnlyVisibleRecents */,
- false /* keepIntentExtra */);
- } catch (RemoteException e) {
- // don't show an icon / will just use the defaults
- }
- if (tasks != null && !tasks.isEmpty()) {
- ActivityManager.RunningTaskInfo taskInfo1 = tasks.get(0);
- Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
- int bgColor1 = getResizingBackgroundColor(taskInfo1);
-
- boolean alreadyInSplit = mSplitScreenController != null
- && mSplitScreenController.isSplitScreenVisible();
- if (alreadyInSplit && tasks.size() > 1) {
- ActivityManager.RunningTaskInfo taskInfo2 = tasks.get(1);
- Drawable icon2 = mIconProvider.getIcon(taskInfo2.topActivityInfo);
- int bgColor2 = getResizingBackgroundColor(taskInfo2);
-
- // figure out which task is on which side
- int splitPosition1 = mSplitScreenController.getSplitPosition(taskInfo1.taskId);
- boolean isTask1TopOrLeft = splitPosition1 == SPLIT_POSITION_TOP_OR_LEFT;
- if (isTask1TopOrLeft) {
- mDropZoneView1.setAppInfo(bgColor1, icon1);
- mDropZoneView2.setAppInfo(bgColor2, icon2);
- } else {
- mDropZoneView2.setAppInfo(bgColor1, icon1);
- mDropZoneView1.setAppInfo(bgColor2, icon2);
- }
- } else {
+ boolean alreadyInSplit = mSplitScreenController != null
+ && mSplitScreenController.isSplitScreenVisible();
+ if (!alreadyInSplit) {
+ List<ActivityManager.RunningTaskInfo> tasks = null;
+ // Figure out the splashscreen info for the existing task.
+ try {
+ tasks = ActivityTaskManager.getService().getTasks(1,
+ false /* filterOnlyVisibleRecents */,
+ false /* keepIntentExtra */);
+ } catch (RemoteException e) {
+ // don't show an icon / will just use the defaults
+ }
+ if (tasks != null && !tasks.isEmpty()) {
+ ActivityManager.RunningTaskInfo taskInfo1 = tasks.get(0);
+ Drawable icon1 = mIconProvider.getIcon(taskInfo1.topActivityInfo);
+ int bgColor1 = getResizingBackgroundColor(taskInfo1);
mDropZoneView1.setAppInfo(bgColor1, icon1);
mDropZoneView2.setAppInfo(bgColor1, icon1);
+ updateDropZoneSizes(null, null); // passing null splits the views evenly
}
+ } else {
+ // We're already in split so get taskInfo from the controller to populate icon / color.
+ ActivityManager.RunningTaskInfo topOrLeftTask =
+ mSplitScreenController.getTaskInfo(SPLIT_POSITION_TOP_OR_LEFT);
+ ActivityManager.RunningTaskInfo bottomOrRightTask =
+ mSplitScreenController.getTaskInfo(SPLIT_POSITION_BOTTOM_OR_RIGHT);
+ if (topOrLeftTask != null && bottomOrRightTask != null) {
+ Drawable topOrLeftIcon = mIconProvider.getIcon(topOrLeftTask.topActivityInfo);
+ int topOrLeftColor = getResizingBackgroundColor(topOrLeftTask);
+ Drawable bottomOrRightIcon = mIconProvider.getIcon(
+ bottomOrRightTask.topActivityInfo);
+ int bottomOrRightColor = getResizingBackgroundColor(bottomOrRightTask);
+ mDropZoneView1.setAppInfo(topOrLeftColor, topOrLeftIcon);
+ mDropZoneView2.setAppInfo(bottomOrRightColor, bottomOrRightIcon);
+ }
+
+ // Update the dropzones to match existing split sizes
+ Rect topOrLeftBounds = new Rect();
+ Rect bottomOrRightBounds = new Rect();
+ mSplitScreenController.getStageBounds(topOrLeftBounds, bottomOrRightBounds);
+ updateDropZoneSizes(topOrLeftBounds, bottomOrRightBounds);
}
}
+ /**
+ * Sets the size of the two drop zones based on the provided bounds. The divider sits between
+ * the views and its size is included in the calculations.
+ *
+ * @param bounds1 bounds to apply to the first dropzone view, null if split in half.
+ * @param bounds2 bounds to apply to the second dropzone view, null if split in half.
+ */
+ private void updateDropZoneSizes(Rect bounds1, Rect bounds2) {
+ final int orientation = getResources().getConfiguration().orientation;
+ final boolean isPortrait = orientation == Configuration.ORIENTATION_PORTRAIT;
+ final int halfDivider = mDividerSize / 2;
+ final LinearLayout.LayoutParams dropZoneView1 =
+ (LayoutParams) mDropZoneView1.getLayoutParams();
+ final LinearLayout.LayoutParams dropZoneView2 =
+ (LayoutParams) mDropZoneView2.getLayoutParams();
+ if (isPortrait) {
+ dropZoneView1.width = MATCH_PARENT;
+ dropZoneView2.width = MATCH_PARENT;
+ dropZoneView1.height = bounds1 != null ? bounds1.height() + halfDivider : MATCH_PARENT;
+ dropZoneView2.height = bounds2 != null ? bounds2.height() + halfDivider : MATCH_PARENT;
+ } else {
+ dropZoneView1.width = bounds1 != null ? bounds1.width() + halfDivider : MATCH_PARENT;
+ dropZoneView2.width = bounds2 != null ? bounds2.width() + halfDivider : MATCH_PARENT;
+ dropZoneView1.height = MATCH_PARENT;
+ dropZoneView2.height = MATCH_PARENT;
+ }
+ dropZoneView1.weight = bounds1 != null ? 0 : 1;
+ dropZoneView2.weight = bounds2 != null ? 0 : 1;
+ mDropZoneView1.setLayoutParams(dropZoneView1);
+ mDropZoneView2.setLayoutParams(dropZoneView2);
+ }
+
public void show() {
mIsShowing = true;
recomputeDropTargets();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
index 6d4773b..c0734e9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -112,11 +112,17 @@
default void showPictureInPictureMenu() {}
/**
- * Called by NavigationBar in order to listen in for PiP bounds change. This is mostly used
- * for times where the PiP bounds could conflict with SystemUI elements, such as a stashed
- * PiP and the Back-from-Edge gesture.
+ * Called by NavigationBar and TaskbarDelegate in order to listen in for PiP bounds change. This
+ * is mostly used for times where the PiP bounds could conflict with SystemUI elements, such as
+ * a stashed PiP and the Back-from-Edge gesture.
*/
- default void setPipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
+ default void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
+
+ /**
+ * Remove a callback added previously. This is used when NavigationBar is removed from the
+ * view hierarchy or destroyed.
+ */
+ default void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) { }
/**
* Dump the current state and information if need.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index e3674dc..b3558ad 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -38,6 +38,8 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
@@ -89,7 +91,7 @@
private @Nullable Runnable mOnMinimalSizeChangeCallback;
private @Nullable TriConsumer<Boolean, Integer, Boolean> mOnShelfVisibilityChangeCallback;
- private @Nullable Consumer<Rect> mOnPipExclusionBoundsChangeCallback;
+ private List<Consumer<Rect>> mOnPipExclusionBoundsChangeCallbacks = new ArrayList<>();
public PipBoundsState(@NonNull Context context) {
mContext = context;
@@ -108,8 +110,8 @@
/** Set the current PIP bounds. */
public void setBounds(@NonNull Rect bounds) {
mBounds.set(bounds);
- if (mOnPipExclusionBoundsChangeCallback != null) {
- mOnPipExclusionBoundsChangeCallback.accept(bounds);
+ for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) {
+ callback.accept(bounds);
}
}
@@ -407,17 +409,25 @@
}
/**
- * Set a callback to watch out for PiP bounds. This is mostly used by SystemUI's
+ * Add a callback to watch out for PiP bounds. This is mostly used by SystemUI's
* Back-gesture handler, to avoid conflicting with PiP when it's stashed.
*/
- public void setPipExclusionBoundsChangeCallback(
+ public void addPipExclusionBoundsChangeCallback(
@Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) {
- mOnPipExclusionBoundsChangeCallback = onPipExclusionBoundsChangeCallback;
- if (mOnPipExclusionBoundsChangeCallback != null) {
- mOnPipExclusionBoundsChangeCallback.accept(getBounds());
+ mOnPipExclusionBoundsChangeCallbacks.add(onPipExclusionBoundsChangeCallback);
+ for (Consumer<Rect> callback : mOnPipExclusionBoundsChangeCallbacks) {
+ callback.accept(getBounds());
}
}
+ /**
+ * Remove a callback that was previously added.
+ */
+ public void removePipExclusionBoundsChangeCallback(
+ @Nullable Consumer<Rect> onPipExclusionBoundsChangeCallback) {
+ mOnPipExclusionBoundsChangeCallbacks.remove(onPipExclusionBoundsChangeCallback);
+ }
+
/** Source of truth for the current bounds of PIP that may be in motion. */
public static class MotionBoundsState {
/** The bounds used when PIP is in motion (e.g. during a drag or animation) */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index 26fd962..a41fd84 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -843,9 +843,16 @@
}
@Override
- public void setPipExclusionBoundsChangeListener(Consumer<Rect> listener) {
+ public void addPipExclusionBoundsChangeListener(Consumer<Rect> listener) {
mMainExecutor.execute(() -> {
- mPipBoundsState.setPipExclusionBoundsChangeCallback(listener);
+ mPipBoundsState.addPipExclusionBoundsChangeCallback(listener);
+ });
+ }
+
+ @Override
+ public void removePipExclusionBoundsChangeListener(Consumer<Rect> listener) {
+ mMainExecutor.execute(() -> {
+ mPipBoundsState.removePipExclusionBoundsChangeCallback(listener);
});
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index cf4e56e..46c4a40 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -186,6 +186,15 @@
return mStageCoordinator.isSplitScreenVisible();
}
+ @Nullable
+ public ActivityManager.RunningTaskInfo getTaskInfo(@SplitPosition int splitPosition) {
+ if (isSplitScreenVisible()) {
+ int taskId = mStageCoordinator.getTaskId(splitPosition);
+ return mTaskOrganizer.getRunningTaskInfo(taskId);
+ }
+ return null;
+ }
+
public boolean isTaskInSplitScreen(int taskId) {
return isSplitScreenVisible()
&& mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index dd538dc..da78d5e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -522,6 +522,14 @@
return SplitLayout.reversePosition(mSideStagePosition);
}
+ int getTaskId(@SplitPosition int splitPosition) {
+ if (mSideStagePosition == splitPosition) {
+ return mSideStage.getTopVisibleChildTaskId();
+ } else {
+ return mMainStage.getTopVisibleChildTaskId();
+ }
+ }
+
void setSideStagePosition(@SplitPosition int sideStagePosition,
@Nullable WindowContainerTransaction wct) {
setSideStagePosition(sideStagePosition, true /* updateBounds */, wct);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
index 2b9bdce..335222e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -59,19 +59,21 @@
private int mStackOffset;
private PointF mExpansionPoint;
private BubblePositioner mPositioner;
- private BubbleStackView.StackViewState mStackViewState;
+ private BubbleStackView.StackViewState mStackViewState = new BubbleStackView.StackViewState();
@SuppressLint("VisibleForTests")
@Before
public void setUp() throws Exception {
super.setUp();
- BubbleStackView stackView = mock(BubbleStackView.class);
- when(stackView.getState()).thenReturn(getStackViewState());
mPositioner = new BubblePositioner(getContext(), mock(WindowManager.class));
mPositioner.updateInternal(Configuration.ORIENTATION_PORTRAIT,
Insets.of(0, 0, 0, 0),
new Rect(0, 0, mDisplayWidth, mDisplayHeight));
+
+ BubbleStackView stackView = mock(BubbleStackView.class);
+ when(stackView.getState()).thenReturn(getStackViewState());
+
mExpandedController = new ExpandedAnimationController(mPositioner,
mOnBubbleAnimatedOutAction,
stackView);
@@ -135,6 +137,12 @@
testBubblesInCorrectExpandedPositions();
}
+ @Test
+ public void testDragBubbleOutDoesntNPE() throws InterruptedException {
+ mExpandedController.onGestureFinished();
+ mExpandedController.dragBubbleOut(mViews.get(0), 1, 1);
+ }
+
/** Expand the stack and wait for animations to finish. */
private void expand() throws InterruptedException {
mExpandedController.expandFromStack(mock(Runnable.class));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
index a6215d3..8e30f65 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java
@@ -188,7 +188,7 @@
final Rect newBounds = new Rect(50, 50, 100, 75);
mPipBoundsState.setBounds(currentBounds);
- mPipBoundsState.setPipExclusionBoundsChangeCallback(callback);
+ mPipBoundsState.addPipExclusionBoundsChangeCallback(callback);
// Setting the listener immediately calls back with the current bounds.
verify(callback).accept(currentBounds);
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
index 066e169..f7a7603 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
@@ -299,6 +299,13 @@
fullscreenTransparentBackground.setOnClickListener { dialog.dismiss() }
dialogContentWithBackground.isClickable = true
+ // Make sure the transparent and dialog backgrounds are not focusable by accessibility
+ // features.
+ fullscreenTransparentBackground.importantForAccessibility =
+ View.IMPORTANT_FOR_ACCESSIBILITY_NO
+ dialogContentWithBackground.importantForAccessibility =
+ View.IMPORTANT_FOR_ACCESSIBILITY_NO
+
fullscreenTransparentBackground.addView(
dialogContentWithBackground,
FrameLayout.LayoutParams(
@@ -342,8 +349,10 @@
?.color
?.defaultColor ?: Color.BLACK
- // Make the background view invisible until we start the animation.
- dialogContentWithBackground.visibility = View.INVISIBLE
+ // Make the background view invisible until we start the animation. We use the transition
+ // visibility like GhostView does so that we don't mess up with the accessibility tree (see
+ // b/204944038#comment17).
+ dialogContentWithBackground.setTransitionVisibility(View.INVISIBLE)
// Make sure the dialog is visible instantly and does not do any window animation.
window.attributes.windowAnimations = R.style.Animation_LaunchAnimation
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
index 3ccf5e4..86cd357 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
@@ -186,7 +186,11 @@
// Making the ghost view invisible will make the ghosted view visible, so order is
// important here.
ghostView.visibility = View.INVISIBLE
- ghostedView.visibility = View.INVISIBLE
+
+ // Make the ghosted view invisible again. We use the transition visibility like
+ // GhostView does so that we don't mess up with the accessibility tree (see
+ // b/204944038#comment17).
+ ghostedView.setTransitionVisibility(View.INVISIBLE)
backgroundView.visibility = View.INVISIBLE
}
return
@@ -257,6 +261,10 @@
GhostView.removeGhost(ghostedView)
launchContainerOverlay.remove(backgroundView)
+
+ // Make sure that the view is considered VISIBLE by accessibility by first making it
+ // INVISIBLE then VISIBLE (see b/204944038#comment17 for more info).
+ ghostedView.visibility = View.INVISIBLE
ghostedView.visibility = View.VISIBLE
ghostedView.invalidate()
}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_slice_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_slice_view.xml
index 1863d11..7c5dbc2 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_slice_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_slice_view.xml
@@ -30,8 +30,6 @@
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="44dp"
- android:paddingEnd="44dp"
android:visibility="gone"
android:textColor="?attr/wallpaperTextColor"
android:theme="@style/TextAppearance.Keyguard"
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index b0bdc72..b8770e8 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -112,7 +112,7 @@
<style name="TextAppearance.Keyguard">
<item name="android:textSize">@dimen/widget_title_font_size</item>
<item name="android:lineHeight">@dimen/widget_title_line_height</item>
- <item name="android:gravity">center</item>
+ <item name="android:gravity">start</item>
<item name="android:ellipsize">end</item>
<item name="android:maxLines">2</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
@@ -131,6 +131,7 @@
<style name="TextAppearance.Keyguard.BottomArea">
<item name="android:textSize">14sp</item>
<item name="android:maxLines">1</item>
+ <item name="android:gravity">center</item>
<item name="android:textColor">?attr/wallpaperTextColor</item>
<item name="android:shadowColor">@color/keyguard_shadow_color</item>
<item name="android:shadowRadius">?attr/shadowRadius</item>
diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
index 275e0a5..baf5336 100644
--- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
+++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml
@@ -390,36 +390,34 @@
android:focusable="false">
<FrameLayout
- android:id="@+id/apm_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:clickable="true"
- android:focusable="true"
android:layout_gravity="start|center_vertical"
android:orientation="vertical">
<Button
+ android:id="@+id/apm_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/turn_off_airplane_mode"
android:ellipsize="end"
style="@style/Widget.Dialog.Button.BorderButton"
- android:clickable="false"/>
+ android:clickable="true"
+ android:focusable="true"/>
</FrameLayout>
<FrameLayout
- android:id="@+id/done_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:layout_gravity="end|center_vertical"
- android:clickable="true"
- android:focusable="true">
+ android:layout_gravity="end|center_vertical">
<Button
+ android:id="@+id/done_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/inline_done_button"
style="@style/Widget.Dialog.Button"
- android:clickable="false"/>
+ android:clickable="true"
+ android:focusable="true"/>
</FrameLayout>
</FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
index 78867f7..605d376 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/rotation/RotationButtonController.java
@@ -36,6 +36,7 @@
import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
+import android.view.HapticFeedbackConstants;
import android.view.IRotationWatcher;
import android.view.MotionEvent;
import android.view.Surface;
@@ -453,6 +454,7 @@
mUiEventLogger.log(RotationButtonEvent.ROTATION_SUGGESTION_ACCEPTED);
incrementNumAcceptedRotationSuggestionsIfNeeded();
setRotationLockedAtAngle(mLastRotationSuggestion);
+ v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
}
private boolean onRotateSuggestionHover(View v, MotionEvent event) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 38eded8..48fcbbd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -61,7 +61,7 @@
public class ActivityManagerWrapper {
private static final String TAG = "ActivityManagerWrapper";
-
+ private static final int NUM_RECENT_ACTIVITIES_REQUEST = 3;
private static final ActivityManagerWrapper sInstance = new ActivityManagerWrapper();
// Should match the values in PhoneWindowManager
@@ -113,6 +113,22 @@
}
/**
+ * We ask for {@link #NUM_RECENT_ACTIVITIES_REQUEST} activities because when in split screen,
+ * we'll get back 2 activities for each split app and one for launcher. Launcher might be more
+ * "recently" used than one of the split apps so if we only request 2 tasks, then we might miss
+ * out on one of the split apps
+ *
+ * @return an array of up to {@link #NUM_RECENT_ACTIVITIES_REQUEST} running tasks
+ * filtering only for tasks that can be visible in the recent tasks list.
+ */
+ public ActivityManager.RunningTaskInfo[] getRunningTasks(boolean filterOnlyVisibleRecents) {
+ // Note: The set of running tasks from the system is ordered by recency
+ List<ActivityManager.RunningTaskInfo> tasks =
+ mAtm.getTasks(NUM_RECENT_ACTIVITIES_REQUEST, filterOnlyVisibleRecents);
+ return tasks.toArray(new RunningTaskInfo[tasks.size()]);
+ }
+
+ /**
* @return a list of the recents tasks.
*/
public List<RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 324fae1..86b12d3c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -354,8 +354,6 @@
mKeyguardUnlockAnimationController.updateLockscreenSmartSpacePosition();
}
}
-
- mKeyguardSliceViewController.updatePosition(x, props, animate);
}
/** Sets an alpha value on every child view except for the smartspace. */
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
index d05cc4e..2af9244 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java
@@ -43,9 +43,6 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.statusbar.notification.AnimatableProperty;
-import com.android.systemui.statusbar.notification.PropertyAnimator;
-import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.ViewController;
@@ -203,13 +200,6 @@
Trace.endSection();
}
- /**
- * Update position of the view, with optional animation
- */
- void updatePosition(int x, AnimationProperties props, boolean animate) {
- PropertyAnimator.setProperty(mView, AnimatableProperty.TRANSLATION_X, x, props, animate);
- }
-
void showSlice(Slice slice) {
Trace.beginSection("KeyguardSliceViewController#showSlice");
if (slice == null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 237ca71..2789e27 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -830,7 +830,9 @@
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
lockedOutStateChanged |= !mFingerprintLockedOutPermanent;
mFingerprintLockedOutPermanent = true;
- requireStrongAuthIfAllLockedOut();
+ Log.d(TAG, "Fingerprint locked out - requiring strong auth");
+ mLockPatternUtils.requireStrongAuth(
+ STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, getCurrentUser());
}
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
@@ -840,6 +842,7 @@
if (isUdfpsEnrolled()) {
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
}
+ stopListeningForFace();
}
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1049,7 +1052,6 @@
if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
lockedOutStateChanged = !mFaceLockedOutPermanent;
mFaceLockedOutPermanent = true;
- requireStrongAuthIfAllLockedOut();
}
if (isHwUnavailable && cameraPrivacyEnabled) {
@@ -1163,19 +1165,6 @@
return faceAuthenticated;
}
- private void requireStrongAuthIfAllLockedOut() {
- final boolean faceLock =
- (mFaceLockedOutPermanent || !shouldListenForFace()) && !getIsFaceAuthenticated();
- final boolean fpLock =
- mFingerprintLockedOutPermanent || !shouldListenForFingerprint(isUdfpsEnrolled());
-
- if (faceLock && fpLock) {
- Log.d(TAG, "All biometrics locked out - requiring strong auth");
- mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
- getCurrentUser());
- }
- }
-
public boolean getUserCanSkipBouncer(int userId) {
return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
}
@@ -2373,6 +2362,9 @@
containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
|| containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+ // TODO: always disallow when fp is already locked out?
+ final boolean fpLockedout = mFingerprintLockedOut || mFingerprintLockedOutPermanent;
+
final boolean canBypass = mKeyguardBypassController != null
&& mKeyguardBypassController.canBypass();
// There's no reason to ask the HAL for authentication when the user can dismiss the
@@ -2407,7 +2399,8 @@
&& !mKeyguardGoingAway && biometricEnabledForUser && !mLockIconPressed
&& strongAuthAllowsScanning && mIsPrimaryUser
&& (!mSecureCameraLaunched || mOccludingAppRequestingFace)
- && !faceAuthenticated;
+ && !faceAuthenticated
+ && !fpLockedout;
// Aggregate relevant fields for debug logging.
if (DEBUG_FACE || DEBUG_SPEW) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 89a5d72..7a53fd1 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1025,7 +1025,10 @@
if (!mExternallyEnabled) {
hideLocked();
}
- } else if (mShowing) {
+ } else if (mShowing && !mKeyguardStateController.isKeyguardGoingAway()) {
+ // If we are going to sleep but the keyguard is showing (and will continue to be
+ // showing, not in the process of going away) then reset its state. Otherwise, let
+ // this fall through and explicitly re-lock the keyguard.
mPendingReset = true;
} else if (
(offReason == WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT
@@ -2090,15 +2093,6 @@
private final Runnable mKeyguardGoingAwayRunnable = new Runnable() {
@Override
public void run() {
- // If the keyguard is already going away, or it's about to because we are going to
- // trigger the going-away remote animation to show the surface behind, don't do it
- // again. That will cause the current animation to be cancelled unnecessarily.
- if (mKeyguardStateController.isKeyguardGoingAway()
- || mSurfaceBehindRemoteAnimationRequested
- || mSurfaceBehindRemoteAnimationRunning) {
- return;
- }
-
Trace.beginSection("KeyguardViewMediator.mKeyGuardGoingAwayRunnable");
if (DEBUG) Log.d(TAG, "keyguardGoingAway");
mKeyguardViewControllerLazy.get().keyguardGoingAway();
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 7a12ecc..963576b 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -628,7 +628,7 @@
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener);
- mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener);
+ mPipOptional.ifPresent(mNavigationBarView::addPipExclusionBoundsChangeListener);
prepareNavigationBarView();
checkNavBarModes();
@@ -699,6 +699,7 @@
mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
mHandler.removeCallbacks(mEnableLayoutTransitions);
mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
+ mPipOptional.ifPresent(mNavigationBarView::removePipExclusionBoundsChangeListener);
mFrame = null;
mNavigationBarView = null;
mOrientationHandle = null;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index bfabf71..a984974 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -59,9 +59,11 @@
import com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.wm.shell.pip.Pip;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Optional;
import javax.inject.Inject;
@@ -106,7 +108,8 @@
NavigationBar.Factory navigationBarFactory,
DumpManager dumpManager,
AutoHideController autoHideController,
- LightBarController lightBarController) {
+ LightBarController lightBarController,
+ Optional<Pip> pipOptional) {
mContext = context;
mHandler = mainHandler;
mNavigationBarFactory = navigationBarFactory;
@@ -118,7 +121,7 @@
mTaskbarDelegate = taskbarDelegate;
mTaskbarDelegate.setDependencies(commandQueue, overviewProxyService,
navBarHelper, navigationModeController, sysUiFlagsContainer,
- dumpManager, autoHideController, lightBarController);
+ dumpManager, autoHideController, lightBarController, pipOptional);
mIsTablet = isTablet(mContext);
dumpManager.registerDumpable(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
index 7c8c3e0..7adb7ac 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
@@ -75,12 +75,12 @@
import com.android.systemui.navigationbar.buttons.NearestTouchFrame;
import com.android.systemui.navigationbar.buttons.RotationContextButton;
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler;
-import com.android.systemui.shared.rotation.FloatingRotationButton;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
+import com.android.systemui.shared.rotation.FloatingRotationButton;
import com.android.systemui.shared.rotation.RotationButton.RotationButtonUpdatesCallback;
import com.android.systemui.shared.rotation.RotationButtonController;
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.SysUiStatsLog;
@@ -1386,8 +1386,12 @@
legacySplitScreen.registerInSplitScreenListener(mDockedListener);
}
- void registerPipExclusionBoundsChangeListener(Pip pip) {
- pip.setPipExclusionBoundsChangeListener(mPipListener);
+ void addPipExclusionBoundsChangeListener(Pip pip) {
+ pip.addPipExclusionBoundsChangeListener(mPipListener);
+ }
+
+ void removePipExclusionBoundsChangeListener(Pip pip) {
+ pip.removePipExclusionBoundsChangeListener(mPipListener);
}
private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
index 68f4aea..feda99f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/TaskbarDelegate.java
@@ -40,6 +40,7 @@
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
@@ -68,9 +69,12 @@
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightBarTransitionsController;
+import com.android.wm.shell.pip.Pip;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Optional;
+import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -91,6 +95,7 @@
private AutoHideController mAutoHideController;
private LightBarController mLightBarController;
private LightBarTransitionsController mLightBarTransitionsController;
+ private Optional<Pip> mPipOptional;
private int mDisplayId;
private int mNavigationIconHints;
private final NavBarHelper.NavbarTaskbarStateUpdater mNavbarTaskbarStateUpdater =
@@ -113,6 +118,7 @@
private Context mWindowContext;
private ScreenPinningNotify mScreenPinningNotify;
private int mNavigationMode;
+ private final Consumer<Rect> mPipListener;
/**
* Tracks the system calls for when taskbar should transiently show or hide so we can return
@@ -143,6 +149,7 @@
.create(context);
mContext = context;
mDisplayManager = mContext.getSystemService(DisplayManager.class);
+ mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds;
}
public void setDependencies(CommandQueue commandQueue,
@@ -151,7 +158,8 @@
NavigationModeController navigationModeController,
SysUiState sysUiState, DumpManager dumpManager,
AutoHideController autoHideController,
- LightBarController lightBarController) {
+ LightBarController lightBarController,
+ Optional<Pip> pipOptional) {
// TODO: adding this in the ctor results in a dagger dependency cycle :(
mCommandQueue = commandQueue;
mOverviewProxyService = overviewProxyService;
@@ -162,6 +170,7 @@
mAutoHideController = autoHideController;
mLightBarController = lightBarController;
mLightBarTransitionsController = createLightBarTransitionsController();
+ mPipOptional = pipOptional;
}
// Separated into a method to keep setDependencies() clean/readable.
@@ -207,6 +216,7 @@
updateSysuiFlags();
mAutoHideController.setNavigationBar(mAutoHideUiElement);
mLightBarController.setNavigationBar(mLightBarTransitionsController);
+ mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener);
mInitialized = true;
}
@@ -228,9 +238,18 @@
mAutoHideController.setNavigationBar(null);
mLightBarTransitionsController.destroy(mContext);
mLightBarController.setNavigationBar(null);
+ mPipOptional.ifPresent(this::removePipExclusionBoundsChangeListener);
mInitialized = false;
}
+ void addPipExclusionBoundsChangeListener(Pip pip) {
+ pip.addPipExclusionBoundsChangeListener(mPipListener);
+ }
+
+ void removePipExclusionBoundsChangeListener(Pip pip) {
+ pip.removePipExclusionBoundsChangeListener(mPipListener);
+ }
+
/**
* Returns {@code true} if this taskBar is {@link #init(int)}. Returns {@code false} if this
* taskbar has not yet been {@link #init(int)} or has been {@link #destroy()}.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
index 99eb5b6..544246e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetAdapter.java
@@ -53,7 +53,10 @@
private final InternetDialogController mInternetDialogController;
private List<WifiEntry> mWifiEntries;
- private int mWifiEntriesCount;
+ @VisibleForTesting
+ protected int mWifiEntriesCount;
+ @VisibleForTesting
+ protected int mMaxEntriesCount = InternetDialogController.MAX_WIFI_ENTRY_COUNT;
protected View mHolderView;
protected Context mContext;
@@ -87,7 +90,8 @@
*/
public void setWifiEntries(@Nullable List<WifiEntry> wifiEntries, int wifiEntriesCount) {
mWifiEntries = wifiEntries;
- mWifiEntriesCount = wifiEntriesCount;
+ mWifiEntriesCount =
+ (wifiEntriesCount < mMaxEntriesCount) ? wifiEntriesCount : mMaxEntriesCount;
}
/**
@@ -101,6 +105,20 @@
}
/**
+ * Sets the maximum number of Wi-Fi networks.
+ */
+ public void setMaxEntriesCount(int count) {
+ if (count < 0 || mMaxEntriesCount == count) {
+ return;
+ }
+ mMaxEntriesCount = count;
+ if (mWifiEntriesCount > count) {
+ mWifiEntriesCount = count;
+ notifyDataSetChanged();
+ }
+ }
+
+ /**
* ViewHolder for binding Wi-Fi view.
*/
static class InternetViewHolder extends RecyclerView.ViewHolder {
@@ -133,7 +151,8 @@
}
void onBind(@NonNull WifiEntry wifiEntry) {
- mWifiIcon.setImageDrawable(getWifiDrawable(wifiEntry));
+ mWifiIcon.setImageDrawable(
+ getWifiDrawable(wifiEntry.getLevel(), wifiEntry.shouldShowXLevelIcon()));
setWifiNetworkLayout(wifiEntry.getTitle(),
Html.fromHtml(wifiEntry.getSummary(false), Html.FROM_HTML_MODE_LEGACY));
@@ -170,12 +189,13 @@
mWifiSummaryText.setText(summary);
}
- Drawable getWifiDrawable(@NonNull WifiEntry wifiEntry) {
- if (wifiEntry.getLevel() == WifiEntry.WIFI_LEVEL_UNREACHABLE) {
+ Drawable getWifiDrawable(int level, boolean hasNoInternet) {
+ // If the Wi-Fi level is equal to WIFI_LEVEL_UNREACHABLE(-1), then a null drawable
+ // will be returned.
+ if (level == WifiEntry.WIFI_LEVEL_UNREACHABLE) {
return null;
}
- final Drawable drawable = mWifiIconInjector.getIcon(wifiEntry.shouldShowXLevelIcon(),
- wifiEntry.getLevel());
+ final Drawable drawable = mWifiIconInjector.getIcon(hasNoInternet, level);
if (drawable == null) {
return null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
index 2a39849..ef4d1ac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs.tiles.dialog;
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
+import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
import android.app.AlertDialog;
import android.content.Context;
@@ -40,6 +41,7 @@
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
+import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -79,6 +81,7 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
static final long PROGRESS_DELAY_MS = 1500L;
+ static final int MAX_NETWORK_COUNT = 4;
private final Handler mHandler;
private final Executor mBackgroundExecutor;
@@ -124,8 +127,8 @@
private Switch mMobileDataToggle;
private View mMobileToggleDivider;
private Switch mWiFiToggle;
- private FrameLayout mDoneLayout;
- private FrameLayout mAirplaneModeLayout;
+ private Button mDoneButton;
+ private Button mAirplaneModeButton;
private Drawable mBackgroundOn;
private Drawable mBackgroundOff = null;
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -138,7 +141,7 @@
@VisibleForTesting
protected int mWifiEntriesCount;
@VisibleForTesting
- protected boolean mHasMoreEntry;
+ protected boolean mHasMoreWifiEntries;
// Wi-Fi scanning progress bar
protected boolean mIsProgressBarVisible;
@@ -215,8 +218,8 @@
mWifiSettingsIcon = mDialogView.requireViewById(R.id.wifi_settings_icon);
mWifiRecyclerView = mDialogView.requireViewById(R.id.wifi_list_layout);
mSeeAllLayout = mDialogView.requireViewById(R.id.see_all_layout);
- mDoneLayout = mDialogView.requireViewById(R.id.done_layout);
- mAirplaneModeLayout = mDialogView.requireViewById(R.id.apm_layout);
+ mDoneButton = mDialogView.requireViewById(R.id.done_button);
+ mAirplaneModeButton = mDialogView.requireViewById(R.id.apm_button);
mSignalIcon = mDialogView.requireViewById(R.id.signal_icon);
mMobileTitleText = mDialogView.requireViewById(R.id.mobile_title);
mMobileSummaryText = mDialogView.requireViewById(R.id.mobile_summary);
@@ -238,7 +241,7 @@
setOnClickListener();
mTurnWifiOnLayout.setBackground(null);
- mAirplaneModeLayout.setVisibility(
+ mAirplaneModeButton.setVisibility(
mInternetDialogController.isAirplaneModeEnabled() ? View.VISIBLE : View.GONE);
mWifiRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
mWifiRecyclerView.setAdapter(mAdapter);
@@ -278,8 +281,8 @@
mConnectedWifListLayout.setOnClickListener(null);
mSeeAllLayout.setOnClickListener(null);
mWiFiToggle.setOnCheckedChangeListener(null);
- mDoneLayout.setOnClickListener(null);
- mAirplaneModeLayout.setOnClickListener(null);
+ mDoneButton.setOnClickListener(null);
+ mAirplaneModeButton.setOnClickListener(null);
mInternetDialogController.onStop();
mInternetDialogFactory.destroyDialog();
}
@@ -305,7 +308,7 @@
}
mInternetDialogTitle.setText(getDialogTitleText());
mInternetDialogSubTitle.setText(getSubtitleText());
- mAirplaneModeLayout.setVisibility(
+ mAirplaneModeButton.setVisibility(
mInternetDialogController.isAirplaneModeEnabled() ? View.VISIBLE : View.GONE);
updateEthernet();
@@ -353,8 +356,8 @@
buttonView.setChecked(isChecked);
mWifiManager.setWifiEnabled(isChecked);
});
- mDoneLayout.setOnClickListener(v -> dismiss());
- mAirplaneModeLayout.setOnClickListener(v -> {
+ mDoneButton.setOnClickListener(v -> dismiss());
+ mAirplaneModeButton.setOnClickListener(v -> {
mInternetDialogController.setAirplaneModeDisabled();
});
}
@@ -462,21 +465,36 @@
mSeeAllLayout.setVisibility(View.GONE);
return;
}
- mWifiRecyclerView.setMinimumHeight(mWifiNetworkHeight * getWifiListMaxCount());
+ final int wifiListMaxCount = getWifiListMaxCount();
+ if (mAdapter.getItemCount() > wifiListMaxCount) {
+ mHasMoreWifiEntries = true;
+ }
+ mAdapter.setMaxEntriesCount(wifiListMaxCount);
+ final int wifiListMinHeight = mWifiNetworkHeight * wifiListMaxCount;
+ if (mWifiRecyclerView.getMinimumHeight() != wifiListMinHeight) {
+ mWifiRecyclerView.setMinimumHeight(wifiListMinHeight);
+ }
mWifiRecyclerView.setVisibility(View.VISIBLE);
- mSeeAllLayout.setVisibility(mHasMoreEntry ? View.VISIBLE : View.INVISIBLE);
+ mSeeAllLayout.setVisibility(mHasMoreWifiEntries ? View.VISIBLE : View.INVISIBLE);
}
@VisibleForTesting
@MainThread
int getWifiListMaxCount() {
- int count = InternetDialogController.MAX_WIFI_ENTRY_COUNT;
+ // Use the maximum count of networks to calculate the remaining count for Wi-Fi networks.
+ int count = MAX_NETWORK_COUNT;
if (mEthernetLayout.getVisibility() == View.VISIBLE) {
count -= 1;
}
if (mMobileNetworkLayout.getVisibility() == View.VISIBLE) {
count -= 1;
}
+
+ // If the remaining count is greater than the maximum count of the Wi-Fi network, the
+ // maximum count of the Wi-Fi network is used.
+ if (count > MAX_WIFI_ENTRY_COUNT) {
+ count = MAX_WIFI_ENTRY_COUNT;
+ }
if (mConnectedWifListLayout.getVisibility() == View.VISIBLE) {
count -= 1;
}
@@ -654,14 +672,14 @@
@Override
@WorkerThread
public void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
- @Nullable WifiEntry connectedEntry, boolean hasMoreEntry) {
+ @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries) {
// Should update the carrier network layout when it is connected under airplane mode ON.
boolean shouldUpdateCarrierNetwork = mMobileNetworkLayout.getVisibility() == View.VISIBLE
&& mInternetDialogController.isAirplaneModeEnabled();
mHandler.post(() -> {
mConnectedWifiEntry = connectedEntry;
mWifiEntriesCount = wifiEntries == null ? 0 : wifiEntries.size();
- mHasMoreEntry = hasMoreEntry;
+ mHasMoreWifiEntries = hasMoreWifiEntries;
updateDialog(shouldUpdateCarrierNetwork /* shouldUpdateMobileNetwork */);
mAdapter.setWifiEntries(wifiEntries, mWifiEntriesCount);
mAdapter.notifyDataSetChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index 4908d4f..0d064af 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -18,6 +18,7 @@
import static com.android.settingslib.mobile.MobileMappings.getIconKey;
import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
+import static com.android.wifitrackerlib.WifiEntry.CONNECTED_STATE_CONNECTED;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -125,7 +126,7 @@
R.string.all_network_unavailable;
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- static final int MAX_WIFI_ENTRY_COUNT = 4;
+ static final int MAX_WIFI_ENTRY_COUNT = 3;
private WifiManager mWifiManager;
private Context mContext;
@@ -143,8 +144,6 @@
private AccessPointController mAccessPointController;
private IntentFilter mConnectionStateFilter;
private InternetDialogCallback mCallback;
- private WifiEntry mConnectedEntry;
- private int mWifiEntriesCount;
private UiEventLogger mUiEventLogger;
private BroadcastDispatcher mBroadcastDispatcher;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -156,6 +155,7 @@
private SignalDrawable mSignalDrawable;
private LocationController mLocationController;
private DialogLaunchAnimator mDialogLaunchAnimator;
+ private boolean mHasWifiEntries;
@VisibleForTesting
static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f;
@@ -177,6 +177,8 @@
protected KeyguardStateController mKeyguardStateController;
@VisibleForTesting
protected boolean mHasEthernet = false;
+ @VisibleForTesting
+ protected ConnectedWifiInternetMonitor mConnectedWifiInternetMonitor;
private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@@ -237,6 +239,7 @@
mSignalDrawable = new SignalDrawable(mContext);
mLocationController = locationController;
mDialogLaunchAnimator = dialogLaunchAnimator;
+ mConnectedWifiInternetMonitor = new ConnectedWifiInternetMonitor();
}
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
@@ -277,6 +280,7 @@
mAccessPointController.removeAccessPointCallback(this);
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
mConnectivityManager.unregisterNetworkCallback(mConnectivityManagerNetworkCallback);
+ mConnectedWifiInternetMonitor.unregisterCallback();
}
@VisibleForTesting
@@ -334,7 +338,7 @@
return mContext.getText(SUBTITLE_TEXT_UNLOCK_TO_VIEW_NETWORKS);
}
- if (mConnectedEntry != null || mWifiEntriesCount > 0) {
+ if (mHasWifiEntries) {
return mCanConfigWifi ? mContext.getText(SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT) : null;
}
@@ -875,43 +879,30 @@
return;
}
- if (accessPoints == null || accessPoints.size() == 0) {
- mConnectedEntry = null;
- mWifiEntriesCount = 0;
- mCallback.onAccessPointsChanged(null /* wifiEntries */, null /* connectedEntry */,
- false /* hasMoreEntry */);
- return;
- }
-
- boolean hasMoreEntry = false;
- int count = MAX_WIFI_ENTRY_COUNT;
- if (mHasEthernet) {
- count -= 1;
- }
- if (hasActiveSubId() || isCarrierNetworkActive()) {
- count -= 1;
- }
- final int wifiTotalCount = accessPoints.size();
- if (count > wifiTotalCount) {
- count = wifiTotalCount;
- } else if (count < wifiTotalCount) {
- hasMoreEntry = true;
- }
-
WifiEntry connectedEntry = null;
- final List<WifiEntry> wifiEntries = new ArrayList<>();
- for (int i = 0; i < count; i++) {
- WifiEntry entry = accessPoints.get(i);
- if (connectedEntry == null && entry.isDefaultNetwork() && entry.hasInternetAccess()) {
- connectedEntry = entry;
- } else {
- wifiEntries.add(entry);
+ List<WifiEntry> wifiEntries = null;
+ final int accessPointsSize = (accessPoints == null) ? 0 : accessPoints.size();
+ final boolean hasMoreWifiEntries = (accessPointsSize > MAX_WIFI_ENTRY_COUNT);
+ if (accessPointsSize > 0) {
+ wifiEntries = new ArrayList<>();
+ final int count = hasMoreWifiEntries ? MAX_WIFI_ENTRY_COUNT : accessPointsSize;
+ mConnectedWifiInternetMonitor.unregisterCallback();
+ for (int i = 0; i < count; i++) {
+ WifiEntry entry = accessPoints.get(i);
+ mConnectedWifiInternetMonitor.registerCallbackIfNeed(entry);
+ if (connectedEntry == null && entry.isDefaultNetwork()
+ && entry.hasInternetAccess()) {
+ connectedEntry = entry;
+ } else {
+ wifiEntries.add(entry);
+ }
}
+ mHasWifiEntries = true;
+ } else {
+ mHasWifiEntries = false;
}
- mConnectedEntry = connectedEntry;
- mWifiEntriesCount = wifiEntries.size();
- mCallback.onAccessPointsChanged(wifiEntries, mConnectedEntry, hasMoreEntry);
+ mCallback.onAccessPointsChanged(wifiEntries, connectedEntry, hasMoreWifiEntries);
}
@Override
@@ -987,6 +978,55 @@
}
/**
+ * Helper class for monitoring the Internet access of the connected WifiEntry.
+ */
+ @VisibleForTesting
+ protected class ConnectedWifiInternetMonitor implements WifiEntry.WifiEntryCallback {
+
+ private WifiEntry mWifiEntry;
+
+ public void registerCallbackIfNeed(WifiEntry entry) {
+ if (entry == null || mWifiEntry != null) {
+ return;
+ }
+ // If the Wi-Fi is not connected yet, or it's the connected Wi-Fi with Internet
+ // access. Then we don't need to listen to the callback to update the Wi-Fi entries.
+ if (entry.getConnectedState() != CONNECTED_STATE_CONNECTED
+ || (entry.isDefaultNetwork() && entry.hasInternetAccess())) {
+ return;
+ }
+ mWifiEntry = entry;
+ entry.setListener(this);
+ }
+
+ public void unregisterCallback() {
+ if (mWifiEntry == null) {
+ return;
+ }
+ mWifiEntry.setListener(null);
+ mWifiEntry = null;
+ }
+
+ @MainThread
+ @Override
+ public void onUpdated() {
+ if (mWifiEntry == null) {
+ return;
+ }
+ WifiEntry entry = mWifiEntry;
+ if (entry.getConnectedState() != CONNECTED_STATE_CONNECTED) {
+ unregisterCallback();
+ return;
+ }
+ if (entry.isDefaultNetwork() && entry.hasInternetAccess()) {
+ unregisterCallback();
+ // Trigger onAccessPointsChanged() to update the Wi-Fi entries.
+ scanWifiAccessPoints();
+ }
+ }
+ }
+
+ /**
* Return {@code true} If the Ethernet exists
*/
@MainThread
@@ -1061,7 +1101,7 @@
void dismissDialog();
void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries,
- @Nullable WifiEntry connectedEntry, boolean hasMoreEntry);
+ @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries);
}
void makeOverlayToast(int stringId) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
index 04c60fc..8909e9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/charging/WiredChargingRippleController.kt
@@ -93,9 +93,8 @@
nowPluggedIn: Boolean,
charging: Boolean
) {
- // Suppresses the ripple when it's disabled, or when the state change comes
- // from wireless charging.
- if (!rippleEnabled || batteryController.isPluggedInWireless) {
+ // Suppresses the ripple when the state change comes from wireless charging.
+ if (batteryController.isPluggedInWireless) {
return
}
val wasPluggedIn = pluggedIn
@@ -145,7 +144,7 @@
}
fun startRipple() {
- if (!rippleEnabled || rippleView.rippleInProgress || rippleView.parent != null) {
+ if (rippleView.rippleInProgress || rippleView.parent != null) {
// Skip if ripple is still playing, or not playing but already added the parent
// (which might happen just before the animation starts or right after
// the animation ends.)
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 b84e6e6..e788928 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -416,7 +416,7 @@
* dragging it and translation should be deferred {@see KeyguardBouncer#show(boolean, boolean)}
*/
public void showGenericBouncer(boolean scrimmed) {
- if (mAlternateAuthInterceptor != null) {
+ if (shouldShowAltAuth()) {
updateAlternateAuthShowing(mAlternateAuthInterceptor.showAlternateAuthBouncer());
return;
}
@@ -424,6 +424,11 @@
showBouncer(scrimmed);
}
+ private boolean shouldShowAltAuth() {
+ return mAlternateAuthInterceptor != null
+ && mKeyguardUpdateManager.isUnlockingWithBiometricAllowed(true);
+ }
+
/**
* Hides the input bouncer (pin/password/pattern).
*/
@@ -479,7 +484,7 @@
// If there is an an alternate auth interceptor (like the UDFPS), show that one instead
// of the bouncer.
- if (mAlternateAuthInterceptor != null) {
+ if (shouldShowAltAuth()) {
if (!afterKeyguardGone) {
mBouncer.setDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
mAfterKeyguardGoneAction = null;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ef9b850..70792cf 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -669,7 +669,7 @@
mKeyguardUpdateMonitor.mFingerprintAuthenticationCallback
.onAuthenticationError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT, "");
- verify(mLockPatternUtils, never()).requireStrongAuth(anyInt(), anyInt());
+ verify(mLockPatternUtils).requireStrongAuth(anyInt(), anyInt());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
index 9d2541c..3e8e874 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavigationBarControllerTest.java
@@ -47,6 +47,7 @@
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.wm.shell.pip.Pip;
import org.junit.After;
import org.junit.Before;
@@ -55,6 +56,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Optional;
+
/** atest NavigationBarControllerTest */
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -88,7 +91,8 @@
mNavigationBarFactory,
mock(DumpManager.class),
mock(AutoHideController.class),
- mock(LightBarController.class)));
+ mock(LightBarController.class),
+ Optional.of(mock(Pip.class))));
initializeNavigationBars();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
index 77946cf..d3bb241 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetAdapterTest.java
@@ -1,5 +1,7 @@
package com.android.systemui.qs.tiles.dialog;
+import static com.android.systemui.qs.tiles.dialog.InternetDialogController.MAX_WIFI_ENTRY_COUNT;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -83,7 +85,7 @@
@Test
public void getItemCount_returnWifiEntriesCount() {
- for (int i = 0; i < InternetDialogController.MAX_WIFI_ENTRY_COUNT; i++) {
+ for (int i = 0; i < MAX_WIFI_ENTRY_COUNT; i++) {
mInternetAdapter.setWifiEntries(mWifiEntries, i /* wifiEntriesCount */);
assertThat(mInternetAdapter.getItemCount()).isEqualTo(i);
@@ -141,6 +143,60 @@
}
@Test
+ public void setWifiEntries_wifiCountLessThenMaxCount_setWifiCount() {
+ final int wifiCount = MAX_WIFI_ENTRY_COUNT - 1;
+ mInternetAdapter.mMaxEntriesCount = MAX_WIFI_ENTRY_COUNT;
+
+ mInternetAdapter.setWifiEntries(mWifiEntries, wifiCount);
+
+ assertThat(mInternetAdapter.mWifiEntriesCount).isEqualTo(wifiCount);
+ }
+
+ @Test
+ public void setWifiEntries_wifiCountGreaterThenMaxCount_setMaxCount() {
+ final int wifiCount = MAX_WIFI_ENTRY_COUNT;
+ mInternetAdapter.mMaxEntriesCount = MAX_WIFI_ENTRY_COUNT - 1;
+
+ mInternetAdapter.setWifiEntries(mWifiEntries, wifiCount);
+
+ assertThat(mInternetAdapter.mWifiEntriesCount).isEqualTo(mInternetAdapter.mMaxEntriesCount);
+ }
+
+ @Test
+ public void setMaxEntriesCount_maxCountLessThenZero_doNothing() {
+ mInternetAdapter.mMaxEntriesCount = MAX_WIFI_ENTRY_COUNT;
+ final int maxCount = -1;
+
+ mInternetAdapter.setMaxEntriesCount(maxCount);
+
+ assertThat(mInternetAdapter.mMaxEntriesCount).isEqualTo(MAX_WIFI_ENTRY_COUNT);
+ }
+
+ @Test
+ public void setMaxEntriesCount_maxCountGreaterThenWifiCount_updateMaxCount() {
+ mInternetAdapter.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT - 2;
+ mInternetAdapter.mMaxEntriesCount = MAX_WIFI_ENTRY_COUNT;
+ final int maxCount = MAX_WIFI_ENTRY_COUNT - 1;
+
+ mInternetAdapter.setMaxEntriesCount(maxCount);
+
+ assertThat(mInternetAdapter.mWifiEntriesCount).isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
+ assertThat(mInternetAdapter.mMaxEntriesCount).isEqualTo(maxCount);
+ }
+
+ @Test
+ public void setMaxEntriesCount_maxCountLessThenWifiCount_updateBothCount() {
+ mInternetAdapter.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT;
+ mInternetAdapter.mMaxEntriesCount = MAX_WIFI_ENTRY_COUNT;
+ final int maxCount = MAX_WIFI_ENTRY_COUNT - 1;
+
+ mInternetAdapter.setMaxEntriesCount(maxCount);
+
+ assertThat(mInternetAdapter.mWifiEntriesCount).isEqualTo(maxCount);
+ assertThat(mInternetAdapter.mMaxEntriesCount).isEqualTo(maxCount);
+ }
+
+ @Test
public void viewHolderUpdateEndIcon_wifiConnected_updateGearIcon() {
mTestableResources.addOverride(GEAR_ICON_RES_ID, mGearIcon);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
index 47f6e5c..0d65541 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java
@@ -434,7 +434,6 @@
@Test
public void onAccessPointsChanged_oneConnectedEntry_callbackConnectedEntryOnly() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mConnectedEntry);
@@ -448,7 +447,6 @@
@Test
public void onAccessPointsChanged_noConnectedEntryAndOneOther_callbackWifiEntriesOnly() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mWifiEntry1);
@@ -463,7 +461,6 @@
@Test
public void onAccessPointsChanged_oneConnectedEntryAndOneOther_callbackCorrectly() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mConnectedEntry);
mAccessPoints.add(mWifiEntry1);
@@ -479,7 +476,6 @@
@Test
public void onAccessPointsChanged_oneConnectedEntryAndTwoOthers_callbackCorrectly() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mConnectedEntry);
mAccessPoints.add(mWifiEntry1);
@@ -497,7 +493,6 @@
@Test
public void onAccessPointsChanged_oneConnectedEntryAndThreeOthers_callbackCutMore() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mConnectedEntry);
mAccessPoints.add(mWifiEntry1);
@@ -509,86 +504,13 @@
mWifiEntries.clear();
mWifiEntries.add(mWifiEntry1);
mWifiEntries.add(mWifiEntry2);
- mWifiEntries.add(mWifiEntry3);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry,
- false /* hasMoreEntry */);
-
- // Turn off airplane mode to has carrier network, then Wi-Fi entries will cut last one.
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(false);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.remove(mWifiEntry3);
verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry,
true /* hasMoreEntry */);
}
@Test
- public void onAccessPointsChanged_oneConnectedEntryAndFourOthers_callbackCutMore() {
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
- mAccessPoints.clear();
- mAccessPoints.add(mConnectedEntry);
- mAccessPoints.add(mWifiEntry1);
- mAccessPoints.add(mWifiEntry2);
- mAccessPoints.add(mWifiEntry3);
- mAccessPoints.add(mWifiEntry4);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.clear();
- mWifiEntries.add(mWifiEntry1);
- mWifiEntries.add(mWifiEntry2);
- mWifiEntries.add(mWifiEntry3);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry,
- true /* hasMoreEntry */);
-
- // Turn off airplane mode to has carrier network, then Wi-Fi entries will cut last one.
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(false);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.remove(mWifiEntry3);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries, mConnectedEntry,
- true /* hasMoreEntry */);
- }
-
- @Test
- public void onAccessPointsChanged_oneCarrierWifiAndFourOthers_callbackCutMore() {
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
- when(mMergedCarrierEntry.isDefaultNetwork()).thenReturn(true);
- mAccessPoints.clear();
- mAccessPoints.add(mWifiEntry1);
- mAccessPoints.add(mWifiEntry2);
- mAccessPoints.add(mWifiEntry3);
- mAccessPoints.add(mWifiEntry4);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.clear();
- mWifiEntries.add(mWifiEntry1);
- mWifiEntries.add(mWifiEntry2);
- mWifiEntries.add(mWifiEntry3);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries,
- null /* connectedEntry */, true /* hasMoreEntry */);
-
- // Turn off airplane mode to has carrier WiFi, then Wi-Fi entries will keep the same.
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(false);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries,
- null /* connectedEntry */, true /* hasMoreEntry */);
- }
-
- @Test
public void onAccessPointsChanged_fourWifiEntries_callbackCutMore() {
reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(true);
mAccessPoints.clear();
mAccessPoints.add(mWifiEntry1);
mAccessPoints.add(mWifiEntry2);
@@ -601,27 +523,6 @@
mWifiEntries.add(mWifiEntry1);
mWifiEntries.add(mWifiEntry2);
mWifiEntries.add(mWifiEntry3);
- mWifiEntries.add(mWifiEntry4);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries,
- null /* connectedEntry */, false /* hasMoreEntry */);
-
- // If the Ethernet exists, then Wi-Fi entries will cut last one.
- reset(mInternetDialogCallback);
- mInternetDialogController.mHasEthernet = true;
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.remove(mWifiEntry4);
- verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries,
- null /* connectedEntry */, true /* hasMoreEntry */);
-
- // Turn off airplane mode to has carrier network, then Wi-Fi entries will cut last one.
- reset(mInternetDialogCallback);
- fakeAirplaneModeEnabled(false);
-
- mInternetDialogController.onAccessPointsChanged(mAccessPoints);
-
- mWifiEntries.remove(mWifiEntry3);
verify(mInternetDialogCallback).onAccessPointsChanged(mWifiEntries,
null /* connectedEntry */, true /* hasMoreEntry */);
}
@@ -644,6 +545,37 @@
}
@Test
+ public void onAccessPointsChanged_connectedWifiNoInternetAccess_shouldSetListener() {
+ reset(mWifiEntry1);
+ mAccessPoints.clear();
+ when(mWifiEntry1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
+ when(mWifiEntry1.isDefaultNetwork()).thenReturn(true);
+ when(mWifiEntry1.hasInternetAccess()).thenReturn(false);
+ mAccessPoints.add(mWifiEntry1);
+
+ mInternetDialogController.onAccessPointsChanged(mAccessPoints);
+
+ verify(mWifiEntry1).setListener(mInternetDialogController.mConnectedWifiInternetMonitor);
+ }
+
+ @Test
+ public void onUpdated_connectedWifiHasInternetAccess_shouldScanWifiAccessPoints() {
+ reset(mAccessPointController);
+ when(mWifiEntry1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
+ when(mWifiEntry1.isDefaultNetwork()).thenReturn(true);
+ when(mWifiEntry1.hasInternetAccess()).thenReturn(false);
+ InternetDialogController.ConnectedWifiInternetMonitor mConnectedWifiInternetMonitor =
+ mInternetDialogController.mConnectedWifiInternetMonitor;
+ mConnectedWifiInternetMonitor.registerCallbackIfNeed(mWifiEntry1);
+
+ // When the hasInternetAccess() changed to true, and call back the onUpdated() function.
+ when(mWifiEntry1.hasInternetAccess()).thenReturn(true);
+ mConnectedWifiInternetMonitor.onUpdated();
+
+ verify(mAccessPointController).scanForAccessPoints();
+ }
+
+ @Test
public void setMergedCarrierWifiEnabledIfNeed_carrierProvisionsEnabled_doNothing() {
when(mCarrierConfigTracker.getCarrierProvisionsWifiMergedNetworksBool(SUB_ID))
.thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
index 8953788..c20e887 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java
@@ -312,6 +312,7 @@
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
// Show a blank block to fix the dialog height even if there is no WiFi list
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+ verify(mInternetAdapter).setMaxEntriesCount(3);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
}
@@ -326,6 +327,7 @@
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
// Show a blank block to fix the dialog height even if there is no WiFi list
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+ verify(mInternetAdapter).setMaxEntriesCount(3);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
}
@@ -339,6 +341,7 @@
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
// Show a blank block to fix the dialog height even if there is no WiFi list
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+ verify(mInternetAdapter).setMaxEntriesCount(2);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.INVISIBLE);
}
@@ -347,12 +350,13 @@
// The preconditions WiFi ON and WiFi entries are already in setUp()
mInternetDialog.mConnectedWifiEntry = null;
mInternetDialog.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT;
- mInternetDialog.mHasMoreEntry = true;
+ mInternetDialog.mHasMoreWifiEntries = true;
mInternetDialog.updateDialog(false);
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.GONE);
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+ verify(mInternetAdapter).setMaxEntriesCount(3);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -360,12 +364,13 @@
public void updateDialog_wifiOnAndHasBothWifiEntry_showBothWifiEntryAndSeeAll() {
// The preconditions WiFi ON and WiFi entries are already in setUp()
mInternetDialog.mWifiEntriesCount = MAX_WIFI_ENTRY_COUNT - 1;
- mInternetDialog.mHasMoreEntry = true;
+ mInternetDialog.mHasMoreWifiEntries = true;
mInternetDialog.updateDialog(false);
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(mWifiList.getVisibility()).isEqualTo(View.VISIBLE);
+ verify(mInternetAdapter).setMaxEntriesCount(2);
assertThat(mSeeAll.getVisibility()).isEqualTo(View.VISIBLE);
}
@@ -518,45 +523,46 @@
@Test
public void getWifiListMaxCount_returnCountCorrectly() {
- // Ethernet, MobileData, ConnectedWiFi are all hidden.
+ // Both of the Ethernet, MobileData is hidden.
// Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
setNetworkVisible(false, false, false);
assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
- // Only one of Ethernet, MobileData, ConnectedWiFi is displayed.
- // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 1.
- setNetworkVisible(true, false, false);
-
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
- setNetworkVisible(false, true, false);
-
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
-
+ // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
setNetworkVisible(false, false, true);
assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
- // Only one of Ethernet, MobileData, ConnectedWiFi is hidden.
- // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 2.
- setNetworkVisible(true, true, false);
+ // Only one of Ethernet, MobileData is displayed.
+ // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT.
+ setNetworkVisible(true, false, false);
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
+ setNetworkVisible(false, true, false);
+
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT);
+
+ // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
setNetworkVisible(true, false, true);
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
setNetworkVisible(false, true, true);
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
- // Ethernet, MobileData, ConnectedWiFi are all displayed.
- // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 3.
+ // Both of Ethernet, MobileData, ConnectedWiFi is displayed.
+ // Then the maximum count is equal to MAX_WIFI_ENTRY_COUNT - 1.
+ setNetworkVisible(true, true, false);
+
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 1);
+
+ // If the Connected Wi-Fi is displayed then reduce one of the Wi-Fi list max count.
setNetworkVisible(true, true, true);
- assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 3);
+ assertThat(mInternetDialog.getWifiListMaxCount()).isEqualTo(MAX_WIFI_ENTRY_COUNT - 2);
}
private void setNetworkVisible(boolean ethernetVisible, boolean mobileDataVisible,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index c5bdfed..cc59b6c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -389,6 +389,39 @@
}
@Test
+ public void testShowAltAuth_unlockingWithBiometricNotAllowed() {
+ // GIVEN alt auth exists, unlocking with biometric isn't allowed
+ mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
+ when(mBouncer.isShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
+ .thenReturn(false);
+
+ // WHEN showGenericBouncer is called
+ final boolean scrimmed = true;
+ mStatusBarKeyguardViewManager.showGenericBouncer(scrimmed);
+
+ // THEN regular bouncer is shown
+ verify(mBouncer).show(anyBoolean(), eq(scrimmed));
+ verify(mAlternateAuthInterceptor, never()).showAlternateAuthBouncer();
+ }
+
+ @Test
+ public void testShowAltAuth_unlockingWithBiometricAllowed() {
+ // GIVEN alt auth exists, unlocking with biometric is allowed
+ mStatusBarKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
+ when(mBouncer.isShowing()).thenReturn(false);
+ when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean()))
+ .thenReturn(true);
+
+ // WHEN showGenericBouncer is called
+ mStatusBarKeyguardViewManager.showGenericBouncer(true);
+
+ // THEN alt auth bouncer is shown
+ verify(mAlternateAuthInterceptor).showAlternateAuthBouncer();
+ verify(mBouncer, never()).show(anyBoolean(), anyBoolean());
+ }
+
+ @Test
public void testUpdateResources_delegatesToBouncer() {
mStatusBarKeyguardViewManager.updateResources();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ec15af3..330d2dd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -92,6 +92,7 @@
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -300,6 +301,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
+import android.util.FeatureFlagUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.Pair;
@@ -14276,6 +14278,8 @@
private void checkExcessivePowerUsage() {
updateCpuStatsNow();
+ final boolean monitorPhantomProcs = mSystemReady && FeatureFlagUtils.isEnabled(mContext,
+ SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
synchronized (mProcLock) {
final boolean doCpuKills = mLastPowerCheckUptime != 0;
final long curUptime = SystemClock.uptimeMillis();
@@ -14301,9 +14305,11 @@
updateAppProcessCpuTimeLPr(uptimeSince, doCpuKills, checkDur, cpuLimit, app);
- // Also check the phantom processes if there is any
- updatePhantomProcessCpuTimeLPr(
- uptimeSince, doCpuKills, checkDur, cpuLimit, app);
+ if (monitorPhantomProcs) {
+ // Also check the phantom processes if there is any
+ updatePhantomProcessCpuTimeLPr(
+ uptimeSince, doCpuKills, checkDur, cpuLimit, app);
+ }
}
});
}
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index ad0485b..293b8a9 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.Process.FIRST_APPLICATION_UID;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
@@ -77,6 +78,7 @@
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.DebugUtils;
+import android.util.FeatureFlagUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -1783,6 +1785,8 @@
}
void updateCpuStatsNow() {
+ final boolean monitorPhantomProcs = mService.mSystemReady && FeatureFlagUtils.isEnabled(
+ mService.mContext, SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
synchronized (mProcessCpuTracker) {
mProcessCpuMutexFree.set(false);
final long now = SystemClock.uptimeMillis();
@@ -1821,7 +1825,7 @@
}
}
- if (haveNewCpuStats) {
+ if (monitorPhantomProcs && haveNewCpuStats) {
mService.mPhantomProcessList.updateProcessCpuStatesLocked(mProcessCpuTracker);
}
diff --git a/services/core/java/com/android/server/am/PhantomProcessList.java b/services/core/java/com/android/server/am/PhantomProcessList.java
index b07684c..2ec1aed 100644
--- a/services/core/java/com/android/server/am/PhantomProcessList.java
+++ b/services/core/java/com/android/server/am/PhantomProcessList.java
@@ -18,6 +18,7 @@
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
+import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -28,6 +29,7 @@
import android.os.Handler;
import android.os.Process;
import android.os.StrictMode;
+import android.util.FeatureFlagUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -419,6 +421,10 @@
* order of the oom adjs of their parent process.
*/
void trimPhantomProcessesIfNecessary() {
+ if (!mService.mSystemReady || !FeatureFlagUtils.isEnabled(mService.mContext,
+ SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS)) {
+ return;
+ }
synchronized (mService.mProcLock) {
synchronized (mLock) {
mTrimPhantomProcessScheduled = false;
diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
index 22a675a..5e38bca 100644
--- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java
@@ -23,6 +23,8 @@
import static com.android.server.location.LocationManagerService.TAG;
import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG;
+import static java.lang.Math.max;
+
import android.annotation.Nullable;
import android.location.Location;
import android.location.LocationResult;
@@ -53,6 +55,7 @@
implements DeviceIdleHelper.DeviceIdleListener, DeviceIdleInternal.StationaryListener {
private static final long MAX_STATIONARY_LOCATION_AGE_MS = 30000;
+ private static final long MIN_INTERVAL_MS = 1000;
final Object mLock = new Object();
@@ -179,7 +182,7 @@
&& mLastLocation != null
&& mLastLocation.getElapsedRealtimeAgeMillis(mDeviceStationaryRealtimeMs)
<= MAX_STATIONARY_LOCATION_AGE_MS) {
- throttlingIntervalMs = mIncomingRequest.getIntervalMillis();
+ throttlingIntervalMs = max(mIncomingRequest.getIntervalMillis(), MIN_INTERVAL_MS);
}
ProviderRequest newRequest;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 20687c6..cfefffc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -4899,6 +4899,8 @@
? ALLOWED_REASON_POWER_SAVE_ALLOWLIST : 0);
newAllowedReasons |= (isWhitelistedFromPowerSaveExceptIdleUL(uid)
? ALLOWED_REASON_POWER_SAVE_EXCEPT_IDLE_ALLOWLIST : 0);
+ newAllowedReasons |= (uidBlockedState.allowedReasons
+ & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
if (LOGV) {
Log.v(TAG, "updateRulesForPowerRestrictionsUL(" + uid + ")"
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 35e9c8f..d1e9d6b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2039,16 +2039,14 @@
final DisplayCutout displayCutout = wmDisplayCutout.getDisplayCutout();
final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation);
- final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
- displayCutout);
- final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
+ final Point appSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode,
displayCutout);
mDisplayInfo.rotation = rotation;
mDisplayInfo.logicalWidth = dw;
mDisplayInfo.logicalHeight = dh;
mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity;
- mDisplayInfo.appWidth = appWidth;
- mDisplayInfo.appHeight = appHeight;
+ mDisplayInfo.appWidth = appSize.x;
+ mDisplayInfo.appHeight = appSize.y;
if (isDefaultDisplay) {
mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
@@ -2177,24 +2175,22 @@
/** Compute configuration related to application without changing current display. */
private void computeScreenAppConfiguration(Configuration outConfig, int dw, int dh,
int rotation, int uiMode, DisplayCutout displayCutout) {
- final int appWidth = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
- displayCutout);
- final int appHeight = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
+ final Point appSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode,
displayCutout);
mDisplayPolicy.getNonDecorInsetsLw(rotation, dw, dh, displayCutout, mTmpRect);
final int leftInset = mTmpRect.left;
final int topInset = mTmpRect.top;
// AppBounds at the root level should mirror the app screen size.
outConfig.windowConfiguration.setAppBounds(leftInset /* left */, topInset /* top */,
- leftInset + appWidth /* right */, topInset + appHeight /* bottom */);
+ leftInset + appSize.x /* right */, topInset + appSize.y /* bottom */);
outConfig.windowConfiguration.setRotation(rotation);
outConfig.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
final float density = mDisplayMetrics.density;
- outConfig.screenWidthDp = (int) (mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation,
- uiMode, displayCutout) / density);
- outConfig.screenHeightDp = (int) (mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation,
- uiMode, displayCutout) / density);
+ final Point configSize = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, uiMode,
+ displayCutout);
+ outConfig.screenWidthDp = (int) (configSize.x / density);
+ outConfig.screenHeightDp = (int) (configSize.y / density);
outConfig.compatScreenWidthDp = (int) (outConfig.screenWidthDp / mCompatibleScreenScale);
outConfig.compatScreenHeightDp = (int) (outConfig.screenHeightDp / mCompatibleScreenScale);
@@ -2333,10 +2329,10 @@
DisplayMetrics dm, int dw, int dh) {
final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
rotation).getDisplayCutout();
- dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode,
+ final Point nonDecorSize = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode,
displayCutout);
- dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode,
- displayCutout);
+ dm.noncompatWidthPixels = nonDecorSize.x;
+ dm.noncompatHeightPixels = nonDecorSize.y;
float scale = CompatibilityInfo.computeCompatibleScaling(dm, null);
int size = (int)(((dm.noncompatWidthPixels / scale) / dm.density) + .5f);
if (curSize == 0 || size < curSize) {
@@ -2388,12 +2384,12 @@
rotation).getDisplayCutout();
// Get the app screen size at this rotation.
- int w = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, displayCutout);
- int h = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, displayCutout);
+ final Point size = mDisplayPolicy.getNonDecorDisplaySize(dw, dh, rotation, uiMode,
+ displayCutout);
// Compute the screen layout size class for this rotation.
- int longSize = w;
- int shortSize = h;
+ int longSize = size.x;
+ int shortSize = size.y;
if (longSize < shortSize) {
int tmp = longSize;
longSize = shortSize;
@@ -2408,21 +2404,19 @@
int uiMode, int dw, int dh) {
final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(
rotation).getDisplayCutout();
- final int width = mDisplayPolicy.getConfigDisplayWidth(dw, dh, rotation, uiMode,
+ final Point size = mDisplayPolicy.getConfigDisplaySize(dw, dh, rotation, uiMode,
displayCutout);
- if (width < displayInfo.smallestNominalAppWidth) {
- displayInfo.smallestNominalAppWidth = width;
+ if (size.x < displayInfo.smallestNominalAppWidth) {
+ displayInfo.smallestNominalAppWidth = size.x;
}
- if (width > displayInfo.largestNominalAppWidth) {
- displayInfo.largestNominalAppWidth = width;
+ if (size.x > displayInfo.largestNominalAppWidth) {
+ displayInfo.largestNominalAppWidth = size.x;
}
- final int height = mDisplayPolicy.getConfigDisplayHeight(dw, dh, rotation, uiMode,
- displayCutout);
- if (height < displayInfo.smallestNominalAppHeight) {
- displayInfo.smallestNominalAppHeight = height;
+ if (size.y < displayInfo.smallestNominalAppHeight) {
+ displayInfo.smallestNominalAppHeight = size.y;
}
- if (height > displayInfo.largestNominalAppHeight) {
- displayInfo.largestNominalAppHeight = height;
+ if (size.y > displayInfo.largestNominalAppHeight) {
+ displayInfo.largestNominalAppHeight = size.y;
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index b2657e8..1c027a8 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -121,6 +121,7 @@
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.PixelFormat;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
import android.gui.DropInputMode;
@@ -2325,6 +2326,24 @@
}
}
+ private int getAltBarWidth(@InternalInsetsType int insetsType) {
+ final InsetsSource source = mDisplayContent.getInsetsStateController().getRawInsetsState()
+ .peekSource(insetsType);
+ if (source == null) {
+ return 0;
+ }
+ return source.getFrame().width();
+ }
+
+ private int getAltBarHeight(@InternalInsetsType int insetsType) {
+ final InsetsSource source = mDisplayContent.getInsetsStateController().getRawInsetsState()
+ .peekSource(insetsType);
+ if (source == null) {
+ return 0;
+ }
+ return source.getFrame().height();
+ }
+
void notifyDisplayReady() {
mHandler.post(() -> {
final int displayId = getDisplayId();
@@ -2340,26 +2359,6 @@
});
}
- /**
- * Return the display width available after excluding any screen
- * decorations that could never be removed in Honeycomb. That is, system bar or
- * button bar.
- */
- public int getNonDecorDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
- DisplayCutout displayCutout) {
- int width = fullWidth;
- if (hasNavigationBar()) {
- final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation);
- if (navBarPosition == NAV_BAR_LEFT || navBarPosition == NAV_BAR_RIGHT) {
- width -= getNavigationBarWidth(rotation, uiMode, navBarPosition);
- }
- }
- if (displayCutout != null) {
- width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight();
- }
- return width;
- }
-
private int getNavigationBarHeight(int rotation, int uiMode) {
if (INSETS_LAYOUT_GENERALIZATION) {
if (mNavigationBar == null) {
@@ -2407,43 +2406,59 @@
}
/**
- * Return the display height available after excluding any screen
+ * Return the display size available after excluding any screen
* decorations that could never be removed in Honeycomb. That is, system bar or
* button bar.
*/
- public int getNonDecorDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+ Point getNonDecorDisplaySize(int fullWidth, int fullHeight, int rotation, int uiMode,
DisplayCutout displayCutout) {
+ int width = fullWidth;
int height = fullHeight;
+ int navBarReducedHeight = 0;
+ int navBarReducedWidth = 0;
+ final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation);
if (hasNavigationBar()) {
- final int navBarPosition = navigationBarPosition(fullWidth, fullHeight, rotation);
if (navBarPosition == NAV_BAR_BOTTOM) {
- height -= getNavigationBarHeight(rotation, uiMode);
+ navBarReducedHeight = getNavigationBarHeight(rotation, uiMode);
+ } else if (navBarPosition == NAV_BAR_LEFT || navBarPosition == NAV_BAR_RIGHT) {
+ navBarReducedWidth = getNavigationBarWidth(rotation, uiMode, navBarPosition);
}
}
+ if (mExtraNavBarAlt != null) {
+ final LayoutParams altBarParams = mExtraNavBarAlt.getLayoutingAttrs(rotation);
+ final int altBarPosition = getAltBarPosition(altBarParams);
+ if (altBarPosition == ALT_BAR_BOTTOM || altBarPosition == ALT_BAR_TOP) {
+ if (altBarPosition == navBarPosition) {
+ navBarReducedHeight = Math.max(navBarReducedHeight,
+ getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR));
+ } else {
+ navBarReducedHeight += getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR);
+ }
+ } else if (altBarPosition == ALT_BAR_LEFT || altBarPosition == ALT_BAR_RIGHT) {
+ if (altBarPosition == navBarPosition) {
+ navBarReducedWidth = Math.max(navBarReducedWidth,
+ getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR));
+ } else {
+ navBarReducedWidth += getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR);
+ }
+ }
+ }
+ height -= navBarReducedHeight;
+ width -= navBarReducedWidth;
if (displayCutout != null) {
height -= displayCutout.getSafeInsetTop() + displayCutout.getSafeInsetBottom();
+ width -= displayCutout.getSafeInsetLeft() + displayCutout.getSafeInsetRight();
}
- return height;
+ return new Point(width, height);
}
/**
- * Return the available screen width that we should report for the
+ * Return the available screen size that we should report for the
* configuration. This must be no larger than
- * {@link #getNonDecorDisplayWidth(int, int, int, int, DisplayCutout)}; it may be smaller
+ * {@link #getNonDecorDisplaySize(int, int, int, int, DisplayCutout)}; it may be smaller
* than that to account for more transient decoration like a status bar.
*/
- public int getConfigDisplayWidth(int fullWidth, int fullHeight, int rotation, int uiMode,
- DisplayCutout displayCutout) {
- return getNonDecorDisplayWidth(fullWidth, fullHeight, rotation, uiMode, displayCutout);
- }
-
- /**
- * Return the available screen height that we should report for the
- * configuration. This must be no larger than
- * {@link #getNonDecorDisplayHeight(int, int, int, int, DisplayCutout)}; it may be smaller
- * than that to account for more transient decoration like a status bar.
- */
- public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation, int uiMode,
+ Point getConfigDisplaySize(int fullWidth, int fullHeight, int rotation, int uiMode,
DisplayCutout displayCutout) {
// There is a separate status bar at the top of the display. We don't count that as part
// of the fixed decor, since it can hide; however, for purposes of configurations,
@@ -2455,8 +2470,9 @@
// bar height.
statusBarHeight = Math.max(0, statusBarHeight - displayCutout.getSafeInsetTop());
}
- return getNonDecorDisplayHeight(fullWidth, fullHeight, rotation, uiMode, displayCutout)
- - statusBarHeight;
+ final Point nonDecorSize = getNonDecorDisplaySize(fullWidth, fullHeight, rotation,
+ uiMode, displayCutout);
+ return new Point(nonDecorSize.x, nonDecorSize.y - statusBarHeight);
}
/**
@@ -2504,7 +2520,7 @@
/**
* Calculates the insets for the areas that could never be removed in Honeycomb, i.e. system
- * bar or button bar. See {@link #getNonDecorDisplayWidth}.
+ * bar or button bar. See {@link #getNonDecorDisplaySize}.
*
* @param displayRotation the current display rotation
* @param displayWidth the current display width
@@ -2516,7 +2532,7 @@
DisplayCutout displayCutout, Rect outInsets) {
outInsets.setEmpty();
- // Only navigation bar
+ // Only navigation bar and extra navigation bar
if (hasNavigationBar()) {
final int uiMode = mService.mPolicy.getUiMode();
int position = navigationBarPosition(displayWidth, displayHeight, displayRotation);
@@ -2528,6 +2544,24 @@
outInsets.left = getNavigationBarWidth(displayRotation, uiMode, position);
}
}
+ if (mExtraNavBarAlt != null) {
+ final LayoutParams extraNavLayoutParams =
+ mExtraNavBarAlt.getLayoutingAttrs(displayRotation);
+ final int position = getAltBarPosition(extraNavLayoutParams);
+ if (position == ALT_BAR_BOTTOM) {
+ outInsets.bottom = Math.max(outInsets.bottom,
+ getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR));
+ } else if (position == ALT_BAR_RIGHT) {
+ outInsets.right = Math.max(outInsets.right,
+ getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR));
+ } else if (position == ALT_BAR_LEFT) {
+ outInsets.left = Math.max(outInsets.left,
+ getAltBarWidth(ITYPE_EXTRA_NAVIGATION_BAR));
+ } else if (position == ALT_BAR_TOP) {
+ outInsets.top = Math.max(outInsets.top,
+ getAltBarHeight(ITYPE_EXTRA_NAVIGATION_BAR));
+ }
+ }
if (displayCutout != null) {
outInsets.left += displayCutout.getSafeInsetLeft();
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 9ad30da..1da0fe7 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -243,7 +243,8 @@
int oldRotation, int newRotation) {
final Rect bounds = mDestRotatedBounds;
final PictureInPictureSurfaceTransaction pipTx = mPipTransaction;
- if (bounds == null && pipTx == null) {
+ final boolean emptyPipPositionTx = pipTx == null || pipTx.mPosition == null;
+ if (bounds == null && emptyPipPositionTx) {
return;
}
final TaskDisplayArea taskArea = mDisplayContent.getDefaultTaskDisplayArea();
@@ -255,7 +256,7 @@
mDestRotatedBounds = null;
mPipTransaction = null;
final Rect areaBounds = taskArea.getBounds();
- if (pipTx != null && pipTx.mPosition != null) {
+ if (!emptyPipPositionTx) {
// The transaction from recents animation is in old rotation. So the position needs to
// be rotated.
float dx = pipTx.mPosition.x;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fa47700..696513c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6171,9 +6171,10 @@
+ " callers=" + Debug.getCallers(3));
return NAV_BAR_INVALID;
}
- displayContent.performLayout(false /* initial */,
- false /* updateInputWindows */);
- return displayContent.getDisplayPolicy().getNavBarPosition();
+ return displayContent.getDisplayPolicy().navigationBarPosition(
+ displayContent.mBaseDisplayWidth,
+ displayContent.mBaseDisplayHeight,
+ displayContent.getDisplayRotation().getRotation());
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
index 4d6f49e..4eba219 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java
@@ -90,6 +90,19 @@
}
@Test
+ public void testThrottle_lowInterval() {
+ ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(0).build();
+
+ mProvider.getController().setRequest(request);
+ mDelegateProvider.reportLocation(createLocationResult("test_provider", mRandom));
+ verify(mListener, times(1)).onReportLocation(any(LocationResult.class));
+
+ mInjector.getDeviceStationaryHelper().setStationary(true);
+ mInjector.getDeviceIdleHelper().setIdle(true);
+ verify(mListener, after(1500).times(2)).onReportLocation(any(LocationResult.class));
+ }
+
+ @Test
public void testThrottle_stationaryExit() {
ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(50).build();
@@ -104,17 +117,16 @@
mInjector.getDeviceIdleHelper().setIdle(true);
verify(mDelegate).onSetRequest(ProviderRequest.EMPTY_REQUEST);
- verify(mListener, timeout(75).times(2)).onReportLocation(any(LocationResult.class));
- verify(mListener, timeout(75).times(3)).onReportLocation(any(LocationResult.class));
+ verify(mListener, timeout(1100).times(2)).onReportLocation(any(LocationResult.class));
mInjector.getDeviceStationaryHelper().setStationary(false);
verify(mDelegate, times(2)).onSetRequest(request);
- verify(mListener, after(75).times(3)).onReportLocation(any(LocationResult.class));
+ verify(mListener, after(1000).times(2)).onReportLocation(any(LocationResult.class));
}
@Test
public void testThrottle_idleExit() {
- ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(50).build();
+ ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(1000).build();
mProvider.getController().setRequest(request);
verify(mDelegate).onSetRequest(request);
@@ -127,17 +139,16 @@
mInjector.getDeviceStationaryHelper().setStationary(true);
verify(mDelegate).onSetRequest(ProviderRequest.EMPTY_REQUEST);
- verify(mListener, timeout(75).times(2)).onReportLocation(any(LocationResult.class));
- verify(mListener, timeout(75).times(3)).onReportLocation(any(LocationResult.class));
+ verify(mListener, timeout(1100).times(2)).onReportLocation(any(LocationResult.class));
mInjector.getDeviceIdleHelper().setIdle(false);
verify(mDelegate, times(2)).onSetRequest(request);
- verify(mListener, after(75).times(3)).onReportLocation(any(LocationResult.class));
+ verify(mListener, after(1000).times(2)).onReportLocation(any(LocationResult.class));
}
@Test
public void testThrottle_NoInitialLocation() {
- ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(50).build();
+ ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis(1000).build();
mProvider.getController().setRequest(request);
verify(mDelegate).onSetRequest(request);
@@ -149,11 +160,11 @@
mDelegateProvider.reportLocation(createLocationResult("test_provider", mRandom));
verify(mListener, times(1)).onReportLocation(any(LocationResult.class));
verify(mDelegate, times(1)).onSetRequest(ProviderRequest.EMPTY_REQUEST);
- verify(mListener, timeout(75).times(2)).onReportLocation(any(LocationResult.class));
+ verify(mListener, timeout(1100).times(2)).onReportLocation(any(LocationResult.class));
mInjector.getDeviceStationaryHelper().setStationary(false);
verify(mDelegate, times(2)).onSetRequest(request);
- verify(mListener, after(75).times(2)).onReportLocation(any(LocationResult.class));
+ verify(mListener, after(1000).times(2)).onReportLocation(any(LocationResult.class));
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
index 004e45a..b2b844b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
@@ -180,23 +180,23 @@
}
private int getNonDecorDisplayWidth(DisplayInfo di) {
- return mDisplayPolicy.getNonDecorDisplayWidth(di.logicalWidth, di.logicalHeight,
- di.rotation, 0 /* ui */, di.displayCutout);
+ return mDisplayPolicy.getNonDecorDisplaySize(di.logicalWidth, di.logicalHeight,
+ di.rotation, 0 /* ui */, di.displayCutout).x;
}
private int getNonDecorDisplayHeight(DisplayInfo di) {
- return mDisplayPolicy.getNonDecorDisplayHeight(di.logicalWidth, di.logicalHeight,
- di.rotation, 0 /* ui */, di.displayCutout);
+ return mDisplayPolicy.getNonDecorDisplaySize(di.logicalWidth, di.logicalHeight,
+ di.rotation, 0 /* ui */, di.displayCutout).y;
}
private int getConfigDisplayWidth(DisplayInfo di) {
- return mDisplayPolicy.getConfigDisplayWidth(di.logicalWidth, di.logicalHeight,
- di.rotation, 0 /* ui */, di.displayCutout);
+ return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight,
+ di.rotation, 0 /* ui */, di.displayCutout).x;
}
private int getConfigDisplayHeight(DisplayInfo di) {
- return mDisplayPolicy.getConfigDisplayHeight(di.logicalWidth, di.logicalHeight,
- di.rotation, 0 /* ui */, di.displayCutout);
+ return mDisplayPolicy.getConfigDisplaySize(di.logicalWidth, di.logicalHeight,
+ di.rotation, 0 /* ui */, di.displayCutout).y;
}
private static DisplayInfo displayInfoForRotation(int rotation, boolean withDisplayCutout) {