diff options
55 files changed, 826 insertions, 751 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 76e392d6cead..46f6597bb042 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2685,6 +2685,16 @@ public final class ActivityThread extends ClientTransactionHandler } } + void onSystemUiContextCleanup(ContextImpl context) { + synchronized (this) { + if (mDisplaySystemUiContexts == null) return; + final int index = mDisplaySystemUiContexts.indexOfValue(context); + if (index >= 0) { + mDisplaySystemUiContexts.removeAt(index); + } + } + } + public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { synchronized (this) { getSystemContext().installSystemApplicationInfo(info, classLoader); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index db3c7d9bcb02..fc1884a41653 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -3191,6 +3191,10 @@ class ContextImpl extends Context { final void performFinalCleanup(String who, String what) { //Log.i(TAG, "Cleanup up context: " + this); mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); + if (mContextType == CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI + && mToken instanceof WindowTokenClient) { + mMainThread.onSystemUiContextCleanup(this); + } } @UnsupportedAppUsage diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 9605cbdb48c6..2c02be7dc6b9 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -5810,6 +5810,7 @@ public class Notification implements Parcelable p, result); buildCustomContentIntoTemplate(mContext, standard, customContent, p, result); + makeHeaderExpanded(standard); return standard; } diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java index 4edff27d0ced..0b50192bfa48 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -646,7 +646,7 @@ public final class ArrayMap<K, V> implements Map<K, V> { e.fillInStackTrace(); Log.w(TAG, "New hash " + hash + " is before end of array hash " + mHashes[index-1] - + " at index " + index + " key " + key, e); + + " at index " + index + (DEBUG ? " key " + key : ""), e); put(key, value); return; } diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 86cf28ffa0e0..e08b913fe248 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -54,6 +54,10 @@ public class FeatureFlagUtils { /** @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 @@ public class FeatureFlagUtils { 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 @@ public class FeatureFlagUtils { 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 721260e8cafe..1244d750e164 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3682,14 +3682,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } - invalidateTopGlow(); + invalidateEdgeEffects(); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPullDistance( (float) -overScrollDistance / getHeight(), @@ -3737,7 +3737,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } - invalidateBottomGlow(); + invalidateEdgeEffects(); } } } @@ -3783,17 +3783,21 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te // 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @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 void invalidateTopGlow() { - 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 boolean doesTouchStopStretch() { + return (mEdgeGlowBottom.getDistance() != 0 && !canScrollDown()) + || (mEdgeGlowTop.getDistance() != 0 && !canScrollUp()); } - private void invalidateBottomGlow() { + private void invalidateEdgeEffects() { 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te canvas.translate(edgeX, edgeY); canvas.rotate(180, width, 0); if (mEdgeGlowBottom.draw(canvas)) { - invalidateBottomGlow(); + invalidateEdgeEffects(); } canvas.restoreToCount(restoreCount); } @@ -4573,7 +4563,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te 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 abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void setBottomEdgeEffectColor(@ColorInt int color) { mEdgeGlowBottom.setColor(color); - invalidateBottomGlow(); + invalidateEdgeEffects(); } /** @@ -6593,7 +6583,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void setTopEdgeEffectColor(@ColorInt int color) { mEdgeGlowTop.setColor(color); - invalidateTopGlow(); + invalidateEdgeEffects(); } /** diff --git a/core/java/android/window/WindowTokenClient.java b/core/java/android/window/WindowTokenClient.java index b331a9e81e27..4ba7ef26e9cb 100644 --- a/core/java/android/window/WindowTokenClient.java +++ b/core/java/android/window/WindowTokenClient.java @@ -15,7 +15,6 @@ */ package android.window; -import static android.window.ConfigurationHelper.diffPublicWithSizeBuckets; import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded; import static android.window.ConfigurationHelper.isDifferentDisplay; import static android.window.ConfigurationHelper.shouldUpdateResources; @@ -222,14 +221,7 @@ public class WindowTokenClient extends IWindowToken.Stub { () -> windowContext.dispatchConfigurationChanged(newConfig)); } - // Dispatch onConfigurationChanged only if there's a significant public change to - // make it compatible with the original behavior. - final Configuration[] sizeConfigurations = context.getResources() - .getSizeConfigurations(); - final SizeConfigurationBuckets buckets = sizeConfigurations != null - ? new SizeConfigurationBuckets(sizeConfigurations) : null; - final int diff = diffPublicWithSizeBuckets(mConfiguration, newConfig, buckets); - + final int diff = mConfiguration.diffPublicOnly(newConfig); if (shouldReportConfigChange && diff != 0 && context instanceof WindowProviderService) { final WindowProviderService windowProviderService = (WindowProviderService) context; diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index af19bd0a79ac..b8e8b0114b47 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -295,11 +295,12 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen @NonNull TaskFragmentContainer primaryContainer, @NonNull Activity primaryActivity, @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { + SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, + secondaryContainer, splitRule); + // Remove container later to prevent pinning escaping toast showing in lock task mode. if (splitRule instanceof SplitPairRule && ((SplitPairRule) splitRule).shouldClearTop()) { removeExistingSecondaryContainers(wct, primaryContainer); } - SplitContainer splitContainer = new SplitContainer(primaryContainer, primaryActivity, - secondaryContainer, splitRule); mSplitContainers.add(splitContainer); } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index 81be21cbd7aa..ade573132eef 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -112,8 +112,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryContainer.setLastRequestedBounds(secondaryRectBounds); // Set adjacent to each other so that the containers below will be invisible. - setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), - secondaryContainer.getTaskFragmentToken(), rule); + setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); @@ -149,8 +148,7 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { secondaryActivity, secondaryRectBounds, primaryContainer); // Set adjacent to each other so that the containers below will be invisible. - setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), - secondaryContainer.getTaskFragmentToken(), rule); + setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); mController.registerSplit(wct, primaryContainer, primaryActivity, secondaryContainer, rule); @@ -269,8 +267,22 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); resizeTaskFragmentIfRegistered(wct, secondaryContainer, secondaryRectBounds); - setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), - secondaryContainer.getTaskFragmentToken(), rule); + setAdjacentTaskFragments(wct, primaryContainer, secondaryContainer, rule); + } + + private void setAdjacentTaskFragments(@NonNull WindowContainerTransaction wct, + @NonNull TaskFragmentContainer primaryContainer, + @NonNull TaskFragmentContainer secondaryContainer, @NonNull SplitRule splitRule) { + final Rect parentBounds = getParentContainerBounds(primaryContainer); + // Clear adjacent TaskFragments if the container is shown in fullscreen, or the + // secondaryContainer could not be finished. + if (!shouldShowSideBySide(parentBounds, splitRule)) { + setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), + null /* secondary */, null /* splitRule */); + } else { + setAdjacentTaskFragments(wct, primaryContainer.getTaskFragmentToken(), + secondaryContainer.getTaskFragmentToken(), splitRule); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java index 519a856538c7..cd635c10fd8e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java @@ -328,6 +328,7 @@ public class BubbleData { if (prevBubble == null) { // Create a new bubble bubble.setSuppressFlyout(suppressFlyout); + bubble.markUpdatedAt(mTimeSource.currentTimeMillis()); doAdd(bubble); trim(); } else { 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 b65a2e4ffca6..8e6c05d83906 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 @@ public class DragAndDropPolicy { 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 @@ public class DragAndDropPolicy { 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 67f9062b0a66..fd3be2b11c15 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.Context; 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 @@ public class DragLayout extends LinearLayout { private DropZoneView mDropZoneView2; private int mDisplayMargin; + private int mDividerSize; private Insets mInsets = Insets.NONE; private boolean mIsShowing; @@ -89,13 +92,15 @@ public class DragLayout extends LinearLayout { 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,42 +170,80 @@ public class DragLayout extends LinearLayout { 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() { 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 6d4773bdeb1f..c0734e95ecb7 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 @@ public interface Pip { 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 e3674dc920d5..b3558ad4b91e 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 com.android.wm.shell.common.DisplayLayout; 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 @@ public final class PipBoundsState { 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 @@ public final class PipBoundsState { /** 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 @@ public final class PipBoundsState { } /** - * 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 26fd962ea6c5..a41fd8429e35 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 @@ public class PipController implements PipTransitionController.PipTransitionCallb } @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 cf4e56e128bf..46c4a40191be 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 @@ public class SplitScreenController implements DragAndDropPolicy.Starter, 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 dd538dc4602c..da78d5e4d244 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 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, 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/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java index bc701d0c70bc..8bc1223cfd64 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java @@ -39,6 +39,7 @@ import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.util.Log; import android.util.Pair; import android.view.WindowManager; @@ -913,6 +914,31 @@ public class BubbleDataTest extends ShellTestCase { assertSelectionChangedTo(mBubbleA2); } + /** + * - have a maxed out bubble stack & all of the bubbles have been recently accessed + * - bubble a notification that was posted before any of those bubbles were accessed + * => that bubble should be added + * + */ + @Test + public void test_addOldNotifWithNewerBubbles() { + sendUpdatedEntryAtTime(mEntryA1, 2000); + sendUpdatedEntryAtTime(mEntryA2, 3000); + sendUpdatedEntryAtTime(mEntryA3, 4000); + sendUpdatedEntryAtTime(mEntryB1, 5000); + sendUpdatedEntryAtTime(mEntryB2, 6000); + + mBubbleData.setListener(mListener); + sendUpdatedEntryAtTime(mEntryB3, 1000 /* postTime */, 7000 /* currentTime */); + verifyUpdateReceived(); + + // B3 is in the stack + assertThat(mBubbleData.getBubbleInStackWithKey(mBubbleB3.getKey())).isNotNull(); + // A1 is the oldest so it's in the overflow + assertThat(mBubbleData.getOverflowBubbleWithKey(mEntryA1.getKey())).isNotNull(); + assertOrderChangedTo(mBubbleB3, mBubbleB2, mBubbleB1, mBubbleA3, mBubbleA2); + } + private void verifyUpdateReceived() { verify(mListener).applyUpdate(mUpdateCaptor.capture()); reset(mListener); @@ -1014,6 +1040,12 @@ public class BubbleDataTest extends ShellTestCase { } private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime) { + setCurrentTime(postTime); + sendUpdatedEntryAtTime(entry, postTime, true /* isTextChanged */); + } + + private void sendUpdatedEntryAtTime(BubbleEntry entry, long postTime, long currentTime) { + setCurrentTime(currentTime); sendUpdatedEntryAtTime(entry, postTime, true /* isTextChanged */); } 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 a6215d3347a8..8e30f65cee78 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 @@ public class PipBoundsStateTest extends ShellTestCase { 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/res-keyguard/drawable/super_lock_icon.xml b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml index 67a70bb39964..b3987f1aeeda 100644 --- a/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml +++ b/packages/SystemUI/res-keyguard/drawable/super_lock_icon.xml @@ -94,4 +94,9 @@ android:fromId="@id/unlocked" android:toId="@id/unlocked_aod" android:drawable="@drawable/unlocked_ls_to_aod" /> + + <transition + android:fromId="@id/unlocked" + android:toId="@id/locked_aod" + android:drawable="@drawable/unlocked_to_aod_lock" /> </animated-selector> diff --git a/packages/SystemUI/res-keyguard/drawable/unlocked_to_aod_lock.xml b/packages/SystemUI/res-keyguard/drawable/unlocked_to_aod_lock.xml new file mode 100644 index 000000000000..b6d76e01ad95 --- /dev/null +++ b/packages/SystemUI/res-keyguard/drawable/unlocked_to_aod_lock.xml @@ -0,0 +1,169 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Copyright (C) 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<animated-vector xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> + <aapt:attr name="android:drawable"> + <vector android:height="65dp" android:width="46dp" android:viewportHeight="65" android:viewportWidth="46"> + <group android:name="_R_G"> + <group android:name="_R_G_L_2_G_T_1" android:translateX="22.75" android:translateY="22.25" android:scaleX="1.02" android:scaleY="1.02"> + <group android:name="_R_G_L_2_G" android:translateX="-8.75" android:translateY="-8.75"> + <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#FF000000" + android:strokeLineJoin="round" + android:strokeWidth="2.5" + android:strokeAlpha="1" + android:pathData=" M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " /> + </group> + </group> + <group android:name="_R_G_L_1_G" android:translateX="23" android:translateY="32.125"> + <path android:name="_R_G_L_1_G_D_0_P_0" + android:strokeColor="#FF000000" + android:strokeLineJoin="round" + android:strokeWidth="2" + android:strokeAlpha="1" + android:pathData=" M11.25 -0.64 C11.25,-0.64 11.25,13.64 11.25,13.64 C11.25,15.22 9.97,16.5 8.39,16.5 C8.39,16.5 -8.39,16.5 -8.39,16.5 C-9.97,16.5 -11.25,15.22 -11.25,13.64 C-11.25,13.64 -11.25,-0.64 -11.25,-0.64 C-11.25,-2.22 -9.97,-3.5 -8.39,-3.5 C-8.39,-3.5 8.39,-3.5 8.39,-3.5 C9.97,-3.5 11.25,-2.22 11.25,-0.64c " /> + </group> + <group android:name="_R_G_L_0_G" android:translateX="23" android:translateY="32.125"> + <path android:name="_R_G_L_0_G_D_0_P_0" + android:fillColor="#FF000000" + android:fillAlpha="1" + android:fillType="nonZero" + android:pathData=" M-0.09 8.63 C1.2,8.63 2.25,7.57 2.25,6.28 C2.25,4.99 1.2,3.94 -0.09,3.94 C-1.39,3.94 -2.44,4.99 -2.44,6.28 C-2.44,7.57 -1.39,8.63 -0.09,8.63c " /> + </group> + </group> + <group android:name="time_group" /> + </vector> + </aapt:attr> + <target android:name="_R_G_L_2_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="strokeWidth" + android:duration="333" android:startOffset="0" android:valueFrom="2.5" android:valueTo="2" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0.833,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="pathData" + android:duration="83" android:startOffset="0" android:valueFrom="M27.19 14.81 C27.19,14.81 27.19,8.3 27.19,8.3 C27.19,4.92 24.44,2.88 21.19,2.75 C17.74,2.62 15,4.74 15,8.11 C15,8.11 15,15 15,15 " android:valueTo="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.456,0 0.464,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="pathData" + android:duration="133" android:startOffset="83" android:valueFrom="M27.13 10.19 C27.13,10.19 27.13,3.67 27.13,3.67 C27.13,0.3 24.38,-1.75 21.13,-1.87 C17.68,-2.01 14.94,0.11 14.94,3.49 C14.94,3.49 15,15 15,15 " android:valueTo="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.606,0 0.035,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="pathData" + android:duration="117" android:startOffset="217" android:valueFrom="M2.5 10.38 C2.5,10.38 2.5,3.99 2.5,3.99 C2.5,0.61 5.3,-2.12 8.75,-2.12 C12.2,-2.12 15,0.61 15,3.99 C15,3.99 15,15 15,15 " android:valueTo="M2.5 15 C2.5,15 2.5,8.61 2.5,8.61 C2.5,5.24 5.3,2.5 8.75,2.5 C12.2,2.5 15,5.24 15,8.61 C15,8.61 15,15 15,15 " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.511,0 0.409,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateX" + android:duration="333" android:startOffset="0" android:valueFrom="22.75" android:valueTo="23" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateY" android:duration="333" android:startOffset="0" android:valueFrom="22.25" android:valueTo="25.5" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_2_G_T_1"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="scaleX" + android:duration="333" android:startOffset="0" android:valueFrom="1.02" android:valueTo="0.72" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + <objectAnimator android:propertyName="scaleY" + android:duration="333" android:startOffset="0" android:valueFrom="1.02" android:valueTo="0.72" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.2,0 0,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_1_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="strokeWidth" + android:duration="333" android:startOffset="0" android:valueFrom="2" android:valueTo="1.5" android:valueType="floatType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.38,0 0.274,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_1_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="pathData" + android:duration="333" android:startOffset="0" android:valueFrom="M11.25 -0.64 C11.25,-0.64 11.25,13.64 11.25,13.64 C11.25,15.22 9.97,16.5 8.39,16.5 C8.39,16.5 -8.39,16.5 -8.39,16.5 C-9.97,16.5 -11.25,15.22 -11.25,13.64 C-11.25,13.64 -11.25,-0.64 -11.25,-0.64 C-11.25,-2.22 -9.97,-3.5 -8.39,-3.5 C-8.39,-3.5 8.39,-3.5 8.39,-3.5 C9.97,-3.5 11.25,-2.22 11.25,-0.64c " android:valueTo="M7.88 -0.62 C7.88,-0.62 7.88,9.38 7.88,9.38 C7.88,10.48 6.98,11.38 5.88,11.38 C5.88,11.38 -5.87,11.38 -5.87,11.38 C-6.98,11.38 -7.87,10.48 -7.87,9.38 C-7.87,9.38 -7.87,-0.62 -7.87,-0.62 C-7.87,-1.73 -6.98,-2.62 -5.87,-2.62 C-5.87,-2.62 5.88,-2.62 5.88,-2.62 C6.98,-2.62 7.88,-1.73 7.88,-0.62c " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.431,0 0.133,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="_R_G_L_0_G_D_0_P_0"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="pathData" + android:duration="333" android:startOffset="0" android:valueFrom="M-0.09 8.63 C1.2,8.63 2.25,7.57 2.25,6.28 C2.25,4.99 1.2,3.94 -0.09,3.94 C-1.39,3.94 -2.44,4.99 -2.44,6.28 C-2.44,7.57 -1.39,8.63 -0.09,8.63c " android:valueTo="M0 6.13 C0.97,6.13 1.75,5.34 1.75,4.38 C1.75,3.41 0.97,2.63 0,2.63 C-0.97,2.63 -1.75,3.41 -1.75,4.38 C-1.75,5.34 -0.97,6.13 0,6.13c " android:valueType="pathType"> + <aapt:attr name="android:interpolator"> + <pathInterpolator android:pathData="M 0.0,0.0 c0.431,0 0.133,1 1.0,1.0" /> + </aapt:attr> + </objectAnimator> + </set> + </aapt:attr> + </target> + <target android:name="time_group"> + <aapt:attr name="android:animation"> + <set android:ordering="together"> + <objectAnimator android:propertyName="translateX" + android:duration="850" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" /> + </set> + </aapt:attr> + </target> +</animated-vector>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-h800dp/dimens.xml b/packages/SystemUI/res/values-h800dp/dimens.xml index f057603e2cd0..1d6f279afc66 100644 --- a/packages/SystemUI/res/values-h800dp/dimens.xml +++ b/packages/SystemUI/res/values-h800dp/dimens.xml @@ -22,5 +22,5 @@ <dimen name="large_clock_text_size">200dp</dimen> <!-- With the large clock, move up slightly from the center --> - <dimen name="keyguard_large_clock_top_margin">-104dp</dimen> + <dimen name="keyguard_large_clock_top_margin">-112dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1938e48e859a..a67d5c254ebf 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -601,7 +601,7 @@ <!-- When large clock is showing, offset the smartspace by this amount --> <dimen name="keyguard_smartspace_top_offset">12dp</dimen> <!-- With the large clock, move up slightly from the center --> - <dimen name="keyguard_large_clock_top_margin">-52dp</dimen> + <dimen name="keyguard_large_clock_top_margin">-60dp</dimen> <!-- Default line spacing multiplier between hours and minutes of the keyguard clock --> <item name="keyguard_clock_line_spacing_scale" type="dimen" format="float">.7</item> 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 78867f7220af..605d37628ec7 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.Looper; 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 @@ public class RotationButtonController { 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/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index 032da789518c..324fae161afc 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -275,11 +275,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS } private void updateClockLayout() { - int largeClockTopMargin = 0; - if (mSmartspaceController.isEnabled()) { - largeClockTopMargin = getContext().getResources().getDimensionPixelSize( - R.dimen.keyguard_large_clock_top_margin); - } + int largeClockTopMargin = getContext().getResources().getDimensionPixelSize( + R.dimen.keyguard_large_clock_top_margin); + RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); lp.topMargin = largeClockTopMargin; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 237ca71027b5..2789e27178cc 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -830,7 +830,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab if (isUdfpsEnrolled()) { updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE); } + stopListeningForFace(); } for (int i = 0; i < mCallbacks.size(); i++) { @@ -1049,7 +1052,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) { lockedOutStateChanged = !mFaceLockedOutPermanent; mFaceLockedOutPermanent = true; - requireStrongAuthIfAllLockedOut(); } if (isHwUnavailable && cameraPrivacyEnabled) { @@ -1163,19 +1165,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab 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 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && !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/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 7ac3ca629e3f..cc452c6f3b79 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -281,10 +281,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mView.setContentDescription(mUnlockedLabel); mView.setVisibility(View.VISIBLE); } else if (mShowAodLockIcon) { - if (wasShowingUnlock) { - // transition to the unlock icon first - mView.updateIcon(ICON_LOCK, false); - } mView.updateIcon(ICON_LOCK, true); mView.setContentDescription(mLockedLabel); mView.setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java index 03bceacdfbdc..963576bc7dc2 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 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater); mSplitScreenOptional.ifPresent(mNavigationBarView::registerDockedListener); - mPipOptional.ifPresent(mNavigationBarView::registerPipExclusionBoundsChangeListener); + mPipOptional.ifPresent(mNavigationBarView::addPipExclusionBoundsChangeListener); prepareNavigationBarView(); checkNavBarModes(); @@ -699,6 +699,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, mHandler.removeCallbacks(mOnVariableDurationHomeLongClick); mHandler.removeCallbacks(mEnableLayoutTransitions); mNavBarHelper.removeNavTaskStateUpdater(mNavbarTaskbarStateUpdater); + mPipOptional.ifPresent(mNavigationBarView::removePipExclusionBoundsChangeListener); mFrame = null; mNavigationBarView = null; mOrientationHandle = null; @@ -1252,6 +1253,7 @@ public class NavigationBar implements View.OnAttachStateChangeListener, private void onImeSwitcherClick(View v) { mInputMethodManager.showInputMethodPickerFromSystem( true /* showAuxiliarySubtypes */, mDisplayId); + mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP); }; private boolean onLongPressBackHome(View v) { diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index bfabf716803b..a984974c6bba 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.AutoHideController; 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 @@ public class NavigationBarController implements NavigationBar.Factory navigationBarFactory, DumpManager dumpManager, AutoHideController autoHideController, - LightBarController lightBarController) { + LightBarController lightBarController, + Optional<Pip> pipOptional) { mContext = context; mHandler = mainHandler; mNavigationBarFactory = navigationBarFactory; @@ -118,7 +121,7 @@ public class NavigationBarController implements 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 7c8c3e0dce44..7adb7ac92dc1 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.KeyButtonDrawable; 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 @@ public class NavigationBarView extends FrameLayout implements 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 68f4aeaa7f17..feda99fd3471 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.app.StatusBarManager.WindowVisibleState; 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.AutoHideController; 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 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, 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 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, 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 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, .create(context); mContext = context; mDisplayManager = mContext.getSystemService(DisplayManager.class); + mPipListener = mEdgeBackGestureHandler::setPipStashExclusionBounds; } public void setDependencies(CommandQueue commandQueue, @@ -151,7 +158,8 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, 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 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, mAutoHideController = autoHideController; mLightBarController = lightBarController; mLightBarTransitionsController = createLightBarTransitionsController(); + mPipOptional = pipOptional; } // Separated into a method to keep setDependencies() clean/readable. @@ -207,6 +216,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, updateSysuiFlags(); mAutoHideController.setNavigationBar(mAutoHideUiElement); mLightBarController.setNavigationBar(mLightBarTransitionsController); + mPipOptional.ifPresent(this::addPipExclusionBoundsChangeListener); mInitialized = true; } @@ -228,9 +238,18 @@ public class TaskbarDelegate implements CommandQueue.Callbacks, 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/navigationbar/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java index debd2ebb51be..d27b71673ce5 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/buttons/KeyButtonView.java @@ -96,6 +96,9 @@ public class KeyButtonView extends ImageView implements ButtonInterface { @UiEvent(doc = "The overview button was pressed in the navigation bar.") NAVBAR_OVERVIEW_BUTTON_TAP(535), + @UiEvent(doc = "The ime switcher button was pressed in the navigation bar.") + NAVBAR_IME_SWITCHER_BUTTON_TAP(923), + @UiEvent(doc = "The home button was long-pressed in the navigation bar.") NAVBAR_HOME_BUTTON_LONGPRESS(536), diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 3ed7e84af020..e7cd1e2dab3c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -76,6 +76,7 @@ import androidx.annotation.NonNull; import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.UiEventLogger; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.util.ScreenshotHelper; import com.android.systemui.Dumpable; @@ -88,6 +89,7 @@ import com.android.systemui.navigationbar.NavigationBar; import com.android.systemui.navigationbar.NavigationBarController; import com.android.systemui.navigationbar.NavigationBarView; import com.android.systemui.navigationbar.NavigationModeController; +import com.android.systemui.navigationbar.buttons.KeyButtonView; import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener; import com.android.systemui.settings.CurrentUserTracker; import com.android.systemui.shared.recents.IOverviewProxy; @@ -161,6 +163,7 @@ public class OverviewProxyService extends CurrentUserTracker implements private final Optional<StartingSurface> mStartingSurface; private final SmartspaceTransitionController mSmartspaceTransitionController; private final Optional<RecentTasks> mRecentTasks; + private final UiEventLogger mUiEventLogger; private Region mActiveNavBarRegion; @@ -248,6 +251,7 @@ public class OverviewProxyService extends CurrentUserTracker implements mContext.getSystemService(InputMethodManager.class) .showInputMethodPickerFromSystem(true /* showAuxiliarySubtypes */, DEFAULT_DISPLAY); + mUiEventLogger.log(KeyButtonView.NavBarButtonEvent.NAVBAR_IME_SWITCHER_BUTTON_TAP); } @Override @@ -560,6 +564,7 @@ public class OverviewProxyService extends CurrentUserTracker implements ShellTransitions shellTransitions, ScreenLifecycle screenLifecycle, SmartspaceTransitionController smartspaceTransitionController, + UiEventLogger uiEventLogger, DumpManager dumpManager) { super(broadcastDispatcher); mContext = context; @@ -581,6 +586,7 @@ public class OverviewProxyService extends CurrentUserTracker implements mOneHandedOptional = oneHandedOptional; mShellTransitions = shellTransitions; mRecentTasks = recentTasks; + mUiEventLogger = uiEventLogger; // Assumes device always starts with back button until launcher tells it that it does not mNavBarButtonAlpha = 1.0f; 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 04c60fc197d8..8909e9d9e9f7 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 @@ class WiredChargingRippleController @Inject constructor( 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 @@ class WiredChargingRippleController @Inject constructor( } 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/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java index 16c9fa79f24c..79231796577b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java @@ -668,6 +668,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable public void setIsRemoteInputActive(boolean isActive) { mIsRemoteInputActive = isActive; + updateFooter(); } @VisibleForTesting diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt index bceffb3de208..401c1b477b3a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt @@ -46,10 +46,11 @@ class SplitShadeHeaderController @Inject constructor( private val SPLIT_HEADER_TRANSITION_ID = R.id.split_header_transition } + private val carrierIconSlots: List<String> private val combinedHeaders = featureFlags.useCombinedQSHeaders() - // TODO(b/194178072) Handle RSSI hiding when multi carrier private val iconManager: StatusBarIconController.IconManager private val qsCarrierGroupController: QSCarrierGroupController + private val iconContainer: StatusIconContainer private var visible = false set(value) { if (field == value) { @@ -115,7 +116,16 @@ class SplitShadeHeaderController @Inject constructor( batteryMeterViewController.ignoreTunerUpdates() batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) - val iconContainer: StatusIconContainer = statusBar.findViewById(R.id.statusIcons) + carrierIconSlots = if (featureFlags.isCombinedStatusBarSignalIconsEnabled) { + listOf( + statusBar.context.getString(com.android.internal.R.string.status_bar_no_calling), + statusBar.context.getString(com.android.internal.R.string.status_bar_call_strength) + ) + } else { + listOf(statusBar.context.getString(com.android.internal.R.string.status_bar_mobile)) + } + + iconContainer = statusBar.findViewById(R.id.statusIcons) iconManager = StatusBarIconController.IconManager(iconContainer, featureFlags) qsCarrierGroupController = qsCarrierGroupControllerBuilder .setQSCarrierGroup(statusBar.findViewById(R.id.carrier_group)) @@ -181,9 +191,20 @@ class SplitShadeHeaderController @Inject constructor( private fun updateListeners() { qsCarrierGroupController.setListening(visible) if (visible) { + updateSingleCarrier(qsCarrierGroupController.isSingleCarrier) + qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) } statusBarIconController.addIconGroup(iconManager) } else { + qsCarrierGroupController.setOnSingleCarrierChangedListener(null) statusBarIconController.removeIconGroup(iconManager) } } + + private fun updateSingleCarrier(singleCarrier: Boolean) { + if (singleCarrier) { + iconContainer.removeIgnoredSlots(carrierIconSlots) + } else { + iconContainer.addIgnoredSlots(carrierIconSlots) + } + } } 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 b84e6e6f37cc..e7889286d195 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 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb * 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 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb showBouncer(scrimmed); } + private boolean shouldShowAltAuth() { + return mAlternateAuthInterceptor != null + && mKeyguardUpdateManager.isUnlockingWithBiometricAllowed(true); + } + /** * Hides the input bouncer (pin/password/pattern). */ @@ -479,7 +484,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb // 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 ef9b850c99c2..70792cfee301 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 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { 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 9d2541c0150f..3e8e8748a679 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.CommandQueue; 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.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.Optional; + /** atest NavigationBarControllerTest */ @RunWith(AndroidTestingRunner.class) @RunWithLooper @@ -88,7 +91,8 @@ public class NavigationBarControllerTest extends SysuiTestCase { 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/statusbar/phone/SplitShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt index 2e7f8a2897f2..e45fa773ea85 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt @@ -1,8 +1,8 @@ package com.android.systemui.statusbar.phone -import android.test.suitebuilder.annotation.SmallTest import android.testing.AndroidTestingRunner import android.view.View +import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.animation.ShadeInterpolation @@ -41,6 +41,7 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { var viewVisibility = View.GONE private lateinit var splitShadeHeaderController: SplitShadeHeaderController + private lateinit var carrierIconSlots: List<String> @Before fun setup() { @@ -66,12 +67,13 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { featureFlags, batteryMeterViewController ) + carrierIconSlots = listOf( + context.getString(com.android.internal.R.string.status_bar_mobile)) } @Test fun setVisible_onlyInSplitShade() { - splitShadeHeaderController.splitShadeMode = true - splitShadeHeaderController.shadeExpanded = true + makeShadeVisible() assertThat(viewVisibility).isEqualTo(View.VISIBLE) splitShadeHeaderController.splitShadeMode = false @@ -80,17 +82,38 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() { @Test fun updateListeners_registersWhenVisible() { - splitShadeHeaderController.splitShadeMode = true - splitShadeHeaderController.shadeExpanded = true + makeShadeVisible() verify(qsCarrierGroupController).setListening(true) verify(statusBarIconController).addIconGroup(any()) } @Test fun shadeExpandedFraction_updatesAlpha() { - splitShadeHeaderController.splitShadeMode = true - splitShadeHeaderController.shadeExpanded = true + makeShadeVisible() splitShadeHeaderController.shadeExpandedFraction = 0.5f verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f)) } -}
\ No newline at end of file + + @Test + fun singleCarrier_enablesCarrierIconsInStatusIcons() { + whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true) + + makeShadeVisible() + + verify(statusIcons).removeIgnoredSlots(carrierIconSlots) + } + + @Test + fun dualCarrier_disablesCarrierIconsInStatusIcons() { + whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false) + + makeShadeVisible() + + verify(statusIcons).addIgnoredSlots(carrierIconSlots) + } + + private fun makeShadeVisible() { + splitShadeHeaderController.splitShadeMode = true + splitShadeHeaderController.shadeExpanded = true + } +} 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 c5bdfed6082b..cc59b6c96fbc 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 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { } @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 ec15af335c78..330d2ddc0a94 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.DEBUG_APP; 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.text.style.SuggestionSpan; 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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 @@ public class ActivityManagerService extends IActivityManager.Stub 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 ad0485b6df28..293b8a9e0b12 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 @@ package com.android.server.am; 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.provider.DeviceConfig.Properties; 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 @@ public class AppProfiler { } 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 @@ public class AppProfiler { } } - 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 b07684c9a004..2ec1aedd18f9 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 @@ package com.android.server.am; 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.app.ApplicationExitInfo.SubReason; 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 @@ public final class PhantomProcessList { * 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/LocationProviderManager.java b/services/core/java/com/android/server/location/provider/LocationProviderManager.java index 155b61891d12..737b653318d2 100644 --- a/services/core/java/com/android/server/location/provider/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/provider/LocationProviderManager.java @@ -177,7 +177,7 @@ public class LocationProviderManager extends protected interface LocationTransport { void deliverOnLocationChanged(LocationResult locationResult, - @Nullable Runnable onCompleteCallback) throws Exception; + @Nullable IRemoteCallback onCompleteCallback) throws Exception; void deliverOnFlushComplete(int requestCode) throws Exception; } @@ -197,9 +197,8 @@ public class LocationProviderManager extends @Override public void deliverOnLocationChanged(LocationResult locationResult, - @Nullable Runnable onCompleteCallback) throws RemoteException { - mListener.onLocationChanged(locationResult.asList(), - SingleUseCallback.wrap(onCompleteCallback)); + @Nullable IRemoteCallback onCompleteCallback) throws RemoteException { + mListener.onLocationChanged(locationResult.asList(), onCompleteCallback); } @Override @@ -227,7 +226,7 @@ public class LocationProviderManager extends @Override public void deliverOnLocationChanged(LocationResult locationResult, - @Nullable Runnable onCompleteCallback) + @Nullable IRemoteCallback onCompleteCallback) throws PendingIntent.CanceledException { BroadcastOptions options = BroadcastOptions.makeBasic(); options.setDontSendToRestrictedApps(true); @@ -243,20 +242,34 @@ public class LocationProviderManager extends intent.putExtra(KEY_LOCATIONS, locationResult.asList().toArray(new Location[0])); } + PendingIntent.OnFinished onFinished = null; + // send() SHOULD only run the completion callback if it completes successfully. however, - // b/199464864 (which could not be fixed in the S timeframe) means that it's possible + // b/201299281 (which could not be fixed in the S timeframe) means that it's possible // for send() to throw an exception AND run the completion callback. if this happens, we // would over-release the wakelock... we take matters into our own hands to ensure that // the completion callback can only be run if send() completes successfully. this means // the completion callback may be run inline - but as we've never specified what thread // the callback is run on, this is fine. - GatedCallback gatedCallback = new GatedCallback(onCompleteCallback); + GatedCallback gatedCallback; + if (onCompleteCallback != null) { + gatedCallback = new GatedCallback(() -> { + try { + onCompleteCallback.sendResult(null); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + }); + onFinished = (pI, i, rC, rD, rE) -> gatedCallback.run(); + } else { + gatedCallback = new GatedCallback(null); + } mPendingIntent.send( mContext, 0, intent, - (pI, i, rC, rD, rE) -> gatedCallback.run(), + onFinished, null, null, options.toBundle()); @@ -293,7 +306,7 @@ public class LocationProviderManager extends @Override public void deliverOnLocationChanged(@Nullable LocationResult locationResult, - @Nullable Runnable onCompleteCallback) + @Nullable IRemoteCallback onCompleteCallback) throws RemoteException { // ILocationCallback doesn't currently support completion callbacks Preconditions.checkState(onCompleteCallback == null); @@ -714,6 +727,13 @@ public class LocationProviderManager extends final PowerManager.WakeLock mWakeLock; + // b/206340085 - if we allocate a new wakelock releaser object for every delivery we + // increase the risk of resource starvation. if a client stops processing deliveries the + // system server binder allocation pool will be starved as we continue to queue up + // deliveries, each with a new allocation. in order to mitigate this, we use a single + // releaser object per registration rather than per delivery. + final ExternalWakeLockReleaser mWakeLockReleaser; + private volatile ProviderTransport mProviderTransport; private int mNumLocationsDelivered = 0; private long mExpirationRealtimeMs = Long.MAX_VALUE; @@ -727,6 +747,7 @@ public class LocationProviderManager extends .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); mWakeLock.setReferenceCounted(true); mWakeLock.setWorkSource(request.getWorkSource()); + mWakeLockReleaser = new ExternalWakeLockReleaser(identity, mWakeLock); } @Override @@ -943,7 +964,7 @@ public class LocationProviderManager extends } listener.deliverOnLocationChanged(deliverLocationResult, - mUseWakeLock ? mWakeLock::release : null); + mUseWakeLock ? mWakeLockReleaser : null); EVENT_LOG.logProviderDeliveredLocations(mName, locationResult.size(), getIdentity()); } @@ -2761,7 +2782,7 @@ public class LocationProviderManager extends @GuardedBy("this") private boolean mRun; - GatedCallback(Runnable callback) { + GatedCallback(@Nullable Runnable callback) { mCallback = callback; } @@ -2796,4 +2817,24 @@ public class LocationProviderManager extends } } } + + private static class ExternalWakeLockReleaser extends IRemoteCallback.Stub { + + private final CallerIdentity mIdentity; + private final PowerManager.WakeLock mWakeLock; + + ExternalWakeLockReleaser(CallerIdentity identity, PowerManager.WakeLock wakeLock) { + mIdentity = identity; + mWakeLock = Objects.requireNonNull(wakeLock); + } + + @Override + public void sendResult(Bundle data) { + try { + mWakeLock.release(); + } catch (RuntimeException e) { + Log.e(TAG, "wakelock over-released by " + mIdentity, e); + } + } + } } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 20687c6764db..cfefffcdd2e8 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { ? 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 35e9c8fc258c..d1e9d6b60038 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 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp /** 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 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp DisplayMetrics dm, int dw, int dh) { final DisplayCutout displayCutout = calculateDisplayCutoutForRotation( rotation).getDisplayCutout(); - dm.noncompatWidthPixels = mDisplayPolicy.getNonDecorDisplayWidth(dw, dh, rotation, uiMode, - displayCutout); - dm.noncompatHeightPixels = mDisplayPolicy.getNonDecorDisplayHeight(dw, dh, rotation, uiMode, + final Point nonDecorSize = mDisplayPolicy.getNonDecorDisplaySize(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 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp 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 b2657e82eb6c..1c027a87e414 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.pm.PackageManager; 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 @@ public class DisplayPolicy { } } + 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 @@ public class DisplayPolicy { }); } - /** - * 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 @@ public class DisplayPolicy { } /** - * 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 @@ public class DisplayPolicy { // 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 @@ public class DisplayPolicy { /** * 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 @@ public class DisplayPolicy { 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 @@ public class DisplayPolicy { 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/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index cbb473c10c6d..212a036f15c2 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -30,8 +30,7 @@ import java.lang.annotation.RetentionPolicy; final class LetterboxConfiguration { /** - * Override of aspect ratio for fixed orientation letterboxing that is set via ADB with - * set-fixed-orientation-letterbox-aspect-ratio or via {@link + * Override of aspect ratio for fixed orientation letterboxing that is set via {@link * com.android.internal.R.dimen.config_fixedOrientationLetterboxAspectRatio} will be ignored * if it is <= this value. */ @@ -251,7 +250,7 @@ final class LetterboxConfiguration { /** * Gets {@link LetterboxBackgroundType} specified in {@link - * com.android.internal.R.integer.config_letterboxBackgroundType} or over via ADB command. + * com.android.internal.R.integer.config_letterboxBackgroundType}. */ @LetterboxBackgroundType int getLetterboxBackgroundType() { @@ -359,9 +358,8 @@ final class LetterboxConfiguration { /* * Gets horizontal position of a center of the letterboxed app window specified - * in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier} - * or via an ADB command. 0 corresponds to the left side of the screen and 1 to the - * right side. + * in {@link com.android.internal.R.dimen.config_letterboxHorizontalPositionMultiplier}. + * 0 corresponds to the left side of the screen and 1 to the right side. */ float getLetterboxHorizontalPositionMultiplier() { return (mLetterboxHorizontalPositionMultiplier < 0.0f @@ -416,8 +414,7 @@ final class LetterboxConfiguration { /* * Gets default horizontal position of the letterboxed app window when reachability is enabled. - * Specified in {@link R.integer.config_letterboxDefaultPositionForReachability} or via an ADB - * command. + * Specified in {@link R.integer.config_letterboxDefaultPositionForReachability}. */ @LetterboxReachabilityPosition int getDefaultPositionForReachability() { diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java index 94a175caba22..8a2d11636fe3 100644 --- a/services/core/java/com/android/server/wm/LockTaskController.java +++ b/services/core/java/com/android/server/wm/LockTaskController.java @@ -251,15 +251,47 @@ public class LockTaskController { */ boolean activityBlockedFromFinish(ActivityRecord activity) { final Task task = activity.getTask(); - if (activity == task.getRootActivity() - && activity == task.getTopNonFinishingActivity() - && task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV - && isRootTask(task)) { - Slog.i(TAG, "Not finishing task in lock task mode"); - showLockTaskToast(); - return true; + if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV || !isRootTask(task)) { + return false; } - return false; + + final ActivityRecord taskTop = task.getTopNonFinishingActivity(); + final ActivityRecord taskRoot = task.getRootActivity(); + // If task has more than one Activity, verify if there's only adjacent TaskFragments that + // should be finish together in the Task. + if (activity != taskRoot || activity != taskTop) { + final TaskFragment taskFragment = activity.getTaskFragment(); + final TaskFragment adjacentTaskFragment = taskFragment.getAdjacentTaskFragment(); + if (taskFragment.asTask() != null + || !taskFragment.isDelayLastActivityRemoval() + || adjacentTaskFragment == null) { + // Don't block activity from finishing if the TaskFragment don't have any adjacent + // TaskFragment, or it won't finish together with its adjacent TaskFragment. + return false; + } + + final boolean hasOtherActivityInTaskFragment = + taskFragment.getActivity(a -> !a.finishing && a != activity) != null; + if (hasOtherActivityInTaskFragment) { + // Don't block activity from finishing if there's other Activity in the same + // TaskFragment. + return false; + } + + final boolean hasOtherActivityInTask = task.getActivity(a -> !a.finishing + && a != activity && a.getTaskFragment() != adjacentTaskFragment) != null; + if (hasOtherActivityInTask) { + // Do not block activity from finishing if there are another running activities + // after the current and adjacent TaskFragments are removed. Note that we don't + // check activities in adjacent TaskFragment because it will be finished together + // with TaskFragment regardless of numbers of activities. + return false; + } + } + + Slog.i(TAG, "Not finishing task in lock task mode"); + showLockTaskToast(); + return true; } /** diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index ef143c21ff95..916fa5be12d8 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -241,7 +241,7 @@ class TaskFragment extends WindowContainer<WindowContainer> { /** * Whether to delay the last activity of TaskFragment being immediately removed while finishing. * This should only be set on a embedded TaskFragment, where the organizer can have the - * opportunity to perform other actions or animations. + * opportunity to perform animations and finishing the adjacent TaskFragment. */ private boolean mDelayLastActivityRemoval; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index fa47700b7fe7..696513cff9d5 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 @@ public class WindowManagerService extends IWindowManager.Stub + " 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/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index 0f8587c99958..a94fd074ff2e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -19,16 +19,6 @@ package com.android.server.wm; import static android.os.Build.IS_USER; import static android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_SOLID_COLOR; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_BACKGROUND_WALLPAPER; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_CENTER; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_LEFT; -import static com.android.server.wm.LetterboxConfiguration.LETTERBOX_REACHABILITY_POSITION_RIGHT; - -import android.content.res.Resources.NotFoundException; -import android.graphics.Color; import android.graphics.Point; import android.graphics.Rect; import android.os.ParcelFileDescriptor; @@ -46,8 +36,6 @@ import com.android.internal.os.ByteTransferPipe; import com.android.internal.protolog.ProtoLogImpl; import com.android.server.LocalServices; import com.android.server.statusbar.StatusBarManagerInternal; -import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType; -import com.android.server.wm.LetterboxConfiguration.LetterboxReachabilityPosition; import java.io.IOException; import java.io.PrintWriter; @@ -70,12 +58,10 @@ public class WindowManagerShellCommand extends ShellCommand { // Internal service impl -- must perform security checks before touching. private final WindowManagerService mInternal; - private final LetterboxConfiguration mLetterboxConfiguration; public WindowManagerShellCommand(WindowManagerService service) { mInterface = service; mInternal = service; - mLetterboxConfiguration = service.mLetterboxConfiguration; } @Override @@ -127,14 +113,6 @@ public class WindowManagerShellCommand extends ShellCommand { return runGetIgnoreOrientationRequest(pw); case "dump-visible-window-views": return runDumpVisibleWindowViews(pw); - case "set-letterbox-style": - return runSetLetterboxStyle(pw); - case "get-letterbox-style": - return runGetLetterboxStyle(pw); - case "reset-letterbox-style": - return runResetLetterboxStyle(pw); - case "set-sandbox-display-apis": - return runSandboxDisplayApis(pw); case "set-multi-window-config": return runSetMultiWindowConfig(); case "get-multi-window-config": @@ -353,37 +331,6 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } - /** - * Override display size and metrics to reflect the DisplayArea of the calling activity. - */ - private int runSandboxDisplayApis(PrintWriter pw) throws RemoteException { - int displayId = Display.DEFAULT_DISPLAY; - String arg = getNextArgRequired(); - if ("-d".equals(arg)) { - displayId = Integer.parseInt(getNextArgRequired()); - arg = getNextArgRequired(); - } - - final boolean sandboxDisplayApis; - switch (arg) { - case "true": - case "1": - sandboxDisplayApis = true; - break; - case "false": - case "0": - sandboxDisplayApis = false; - break; - default: - getErrPrintWriter().println("Error: expecting true, 1, false, 0, but we " - + "get " + arg); - return -1; - } - - mInternal.setSandboxDisplayApis(displayId, sandboxDisplayApis); - return 0; - } - private int runDismissKeyguard(PrintWriter pw) throws RemoteException { mInterface.dismissKeyguard(null /* callback */, null /* message */); return 0; @@ -601,318 +548,6 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } - private int runSetFixedOrientationLetterboxAspectRatio(PrintWriter pw) throws RemoteException { - final float aspectRatio; - try { - String arg = getNextArgRequired(); - aspectRatio = Float.parseFloat(arg); - } catch (NumberFormatException e) { - getErrPrintWriter().println("Error: bad aspect ratio format " + e); - return -1; - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: aspect ratio should be provided as an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setFixedOrientationLetterboxAspectRatio(aspectRatio); - } - return 0; - } - - private int runSetLetterboxActivityCornersRadius(PrintWriter pw) throws RemoteException { - final int cornersRadius; - try { - String arg = getNextArgRequired(); - cornersRadius = Integer.parseInt(arg); - } catch (NumberFormatException e) { - getErrPrintWriter().println("Error: bad corners radius format " + e); - return -1; - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: corners radius should be provided as an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxActivityCornersRadius(cornersRadius); - } - return 0; - } - - private int runSetLetterboxBackgroundType(PrintWriter pw) throws RemoteException { - @LetterboxBackgroundType final int backgroundType; - try { - String arg = getNextArgRequired(); - switch (arg) { - case "solid_color": - backgroundType = LETTERBOX_BACKGROUND_SOLID_COLOR; - break; - case "app_color_background": - backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND; - break; - case "app_color_background_floating": - backgroundType = LETTERBOX_BACKGROUND_APP_COLOR_BACKGROUND_FLOATING; - break; - case "wallpaper": - backgroundType = LETTERBOX_BACKGROUND_WALLPAPER; - break; - default: - getErrPrintWriter().println( - "Error: 'solid_color', 'app_color_background' or " - + "'wallpaper' should be provided as an argument"); - return -1; - } - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: 'solid_color', 'app_color_background' or " - + "'wallpaper' should be provided as an argument" + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxBackgroundType(backgroundType); - } - return 0; - } - - private int runSetLetterboxBackgroundColorResource(PrintWriter pw) throws RemoteException { - final int colorId; - try { - String arg = getNextArgRequired(); - colorId = mInternal.mContext.getResources() - .getIdentifier(arg, "color", "com.android.internal"); - } catch (NotFoundException e) { - getErrPrintWriter().println( - "Error: color in '@android:color/resource_name' format should be provided as " - + "an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxBackgroundColorResourceId(colorId); - } - return 0; - } - - private int runSetLetterboxBackgroundColor(PrintWriter pw) throws RemoteException { - final Color color; - try { - String arg = getNextArgRequired(); - color = Color.valueOf(Color.parseColor(arg)); - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: color in #RRGGBB format should be provided as " - + "an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxBackgroundColor(color); - } - return 0; - } - - private int runSetLetterboxBackgroundWallpaperBlurRadius(PrintWriter pw) - throws RemoteException { - final int radius; - try { - String arg = getNextArgRequired(); - radius = Integer.parseInt(arg); - } catch (NumberFormatException e) { - getErrPrintWriter().println("Error: blur radius format " + e); - return -1; - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: blur radius should be provided as an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxBackgroundWallpaperBlurRadius(radius); - } - return 0; - } - - private int runSetLetterboxBackgroundWallpaperDarkScrimAlpha(PrintWriter pw) - throws RemoteException { - final float alpha; - try { - String arg = getNextArgRequired(); - alpha = Float.parseFloat(arg); - } catch (NumberFormatException e) { - getErrPrintWriter().println("Error: bad alpha format " + e); - return -1; - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: alpha should be provided as an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxBackgroundWallpaperDarkScrimAlpha(alpha); - } - return 0; - } - - private int runSetLetterboxHorizontalPositionMultiplier(PrintWriter pw) throws RemoteException { - final float multiplier; - try { - String arg = getNextArgRequired(); - multiplier = Float.parseFloat(arg); - } catch (NumberFormatException e) { - getErrPrintWriter().println("Error: bad multiplier format " + e); - return -1; - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: multiplier should be provided as an argument " + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setLetterboxHorizontalPositionMultiplier(multiplier); - } - return 0; - } - - private int runSetLetterboxIsReachabilityEnabled(PrintWriter pw) throws RemoteException { - String arg = getNextArg(); - final boolean enabled; - switch (arg) { - case "true": - case "1": - enabled = true; - break; - case "false": - case "0": - enabled = false; - break; - default: - getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg); - return -1; - } - - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setIsReachabilityEnabled(enabled); - } - return 0; - } - - private int runSetLetterboxDefaultPositionForReachability(PrintWriter pw) - throws RemoteException { - @LetterboxReachabilityPosition final int position; - try { - String arg = getNextArgRequired(); - switch (arg) { - case "left": - position = LETTERBOX_REACHABILITY_POSITION_LEFT; - break; - case "center": - position = LETTERBOX_REACHABILITY_POSITION_CENTER; - break; - case "right": - position = LETTERBOX_REACHABILITY_POSITION_RIGHT; - break; - default: - getErrPrintWriter().println( - "Error: 'left', 'center' or 'right' are expected as an argument"); - return -1; - } - } catch (IllegalArgumentException e) { - getErrPrintWriter().println( - "Error: 'left', 'center' or 'right' are expected as an argument" + e); - return -1; - } - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.setDefaultPositionForReachability(position); - } - return 0; - } - - private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException { - if (peekNextArg() == null) { - getErrPrintWriter().println("Error: No arguments provided."); - } - while (peekNextArg() != null) { - String arg = getNextArg(); - switch (arg) { - case "--aspectRatio": - runSetFixedOrientationLetterboxAspectRatio(pw); - break; - case "--cornerRadius": - runSetLetterboxActivityCornersRadius(pw); - break; - case "--backgroundType": - runSetLetterboxBackgroundType(pw); - break; - case "--backgroundColor": - runSetLetterboxBackgroundColor(pw); - break; - case "--backgroundColorResource": - runSetLetterboxBackgroundColorResource(pw); - break; - case "--wallpaperBlurRadius": - runSetLetterboxBackgroundWallpaperBlurRadius(pw); - break; - case "--wallpaperDarkScrimAlpha": - runSetLetterboxBackgroundWallpaperDarkScrimAlpha(pw); - break; - case "--horizontalPositionMultiplier": - runSetLetterboxHorizontalPositionMultiplier(pw); - break; - case "--isReachabilityEnabled": - runSetLetterboxIsReachabilityEnabled(pw); - break; - case "--defaultPositionForReachability": - runSetLetterboxDefaultPositionForReachability(pw); - break; - default: - getErrPrintWriter().println( - "Error: Unrecognized letterbox style option: " + arg); - return -1; - } - } - return 0; - } - - private int runResetLetterboxStyle(PrintWriter pw) throws RemoteException { - if (peekNextArg() == null) { - resetLetterboxStyle(); - } - synchronized (mInternal.mGlobalLock) { - while (peekNextArg() != null) { - String arg = getNextArg(); - switch (arg) { - case "aspectRatio": - mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio(); - break; - case "cornerRadius": - mLetterboxConfiguration.resetLetterboxActivityCornersRadius(); - break; - case "backgroundType": - mLetterboxConfiguration.resetLetterboxBackgroundType(); - break; - case "backgroundColor": - mLetterboxConfiguration.resetLetterboxBackgroundColor(); - break; - case "wallpaperBlurRadius": - mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius(); - break; - case "wallpaperDarkScrimAlpha": - mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); - break; - case "horizontalPositionMultiplier": - mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); - break; - case "isReachabilityEnabled": - mLetterboxConfiguration.getIsReachabilityEnabled(); - break; - case "defaultPositionForReachability": - mLetterboxConfiguration.getDefaultPositionForReachability(); - break; - default: - getErrPrintWriter().println( - "Error: Unrecognized letterbox style option: " + arg); - return -1; - } - } - } - return 0; - } - private int runSetMultiWindowConfig() { if (peekNextArg() == null) { getErrPrintWriter().println("Error: No arguments provided."); @@ -987,47 +622,6 @@ public class WindowManagerShellCommand extends ShellCommand { return 0; } - private void resetLetterboxStyle() { - synchronized (mInternal.mGlobalLock) { - mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio(); - mLetterboxConfiguration.resetLetterboxActivityCornersRadius(); - mLetterboxConfiguration.resetLetterboxBackgroundType(); - mLetterboxConfiguration.resetLetterboxBackgroundColor(); - mLetterboxConfiguration.resetLetterboxBackgroundWallpaperBlurRadius(); - mLetterboxConfiguration.resetLetterboxBackgroundWallpaperDarkScrimAlpha(); - mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier(); - mLetterboxConfiguration.resetIsReachabilityEnabled(); - mLetterboxConfiguration.resetDefaultPositionForReachability(); - } - } - - private int runGetLetterboxStyle(PrintWriter pw) throws RemoteException { - synchronized (mInternal.mGlobalLock) { - pw.println("Corner radius: " - + mLetterboxConfiguration.getLetterboxActivityCornersRadius()); - pw.println("Horizontal position multiplier: " - + mLetterboxConfiguration.getLetterboxHorizontalPositionMultiplier()); - pw.println("Aspect ratio: " - + mLetterboxConfiguration.getFixedOrientationLetterboxAspectRatio()); - pw.println("Is reachability enabled: " - + mLetterboxConfiguration.getIsReachabilityEnabled()); - pw.println("Default position for reachability: " - + LetterboxConfiguration.letterboxReachabilityPositionToString( - mLetterboxConfiguration.getDefaultPositionForReachability())); - - pw.println("Background type: " - + LetterboxConfiguration.letterboxBackgroundTypeToString( - mLetterboxConfiguration.getLetterboxBackgroundType())); - pw.println(" Background color: " + Integer.toHexString( - mLetterboxConfiguration.getLetterboxBackgroundColor().toArgb())); - pw.println(" Wallpaper blur radius: " - + mLetterboxConfiguration.getLetterboxBackgroundWallpaperBlurRadius()); - pw.println(" Wallpaper dark scrim alpha: " - + mLetterboxConfiguration.getLetterboxBackgroundWallpaperDarkScrimAlpha()); - } - return 0; - } - private int runReset(PrintWriter pw) throws RemoteException { int displayId = getDisplayId(getNextArg()); @@ -1052,12 +646,6 @@ public class WindowManagerShellCommand extends ShellCommand { // set-ignore-orientation-request mInterface.setIgnoreOrientationRequest(displayId, false /* ignoreOrientationRequest */); - // set-letterbox-style - resetLetterboxStyle(); - - // set-sandbox-display-apis - mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true); - // set-multi-window-config runResetMultiWindowConfig(); @@ -1092,12 +680,7 @@ public class WindowManagerShellCommand extends ShellCommand { pw.println(" set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]"); pw.println(" get-ignore-orientation-request [-d DISPLAY_ID] "); pw.println(" If app requested orientation should be ignored."); - pw.println(" set-sandbox-display-apis [true|1|false|0]"); - pw.println(" Sets override of Display APIs getRealSize / getRealMetrics to reflect "); - pw.println(" DisplayArea of the activity, or the window bounds if in letterbox or"); - pw.println(" Size Compat Mode."); - printLetterboxHelp(pw); printMultiWindowConfigHelp(pw); pw.println(" reset [-d DISPLAY_ID]"); @@ -1110,61 +693,6 @@ public class WindowManagerShellCommand extends ShellCommand { } } - private void printLetterboxHelp(PrintWriter pw) { - pw.println(" set-letterbox-style"); - pw.println(" Sets letterbox style using the following options:"); - pw.println(" --aspectRatio aspectRatio"); - pw.println(" Aspect ratio of letterbox for fixed orientation. If aspectRatio <= " - + LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO); - pw.println(" both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will"); - pw.println(" be ignored and framework implementation will determine aspect ratio."); - pw.println(" --cornerRadius radius"); - pw.println(" Corners radius for activities in the letterbox mode. If radius < 0,"); - pw.println(" both it and R.integer.config_letterboxActivityCornersRadius will be"); - pw.println(" ignored and corners of the activity won't be rounded."); - pw.println(" --backgroundType [reset|solid_color|app_color_background"); - pw.println(" |app_color_background_floating|wallpaper]"); - pw.println(" Type of background used in the letterbox mode."); - pw.println(" --backgroundColor color"); - pw.println(" Color of letterbox which is be used when letterbox background type"); - pw.println(" is 'solid-color'. Use (set)get-letterbox-style to check and control"); - pw.println(" letterbox background type. See Color#parseColor for allowed color"); - pw.println(" formats (#RRGGBB and some colors by name, e.g. magenta or olive)."); - pw.println(" --backgroundColorResource resource_name"); - pw.println(" Color resource name of letterbox background which is used when"); - pw.println(" background type is 'solid-color'. Use (set)get-letterbox-style to"); - pw.println(" check and control background type. Parameter is a color resource"); - pw.println(" name, for example, @android:color/system_accent2_50."); - pw.println(" --wallpaperBlurRadius radius"); - pw.println(" Blur radius for 'wallpaper' letterbox background. If radius <= 0"); - pw.println(" both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius"); - pw.println(" are ignored and 0 is used."); - pw.println(" --wallpaperDarkScrimAlpha alpha"); - pw.println(" Alpha of a black translucent scrim shown over 'wallpaper'"); - pw.println(" letterbox background. If alpha < 0 or >= 1 both it and"); - pw.println(" R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored"); - pw.println(" and 0.0 (transparent) is used instead."); - pw.println(" --horizontalPositionMultiplier multiplier"); - pw.println(" Horizontal position of app window center. If multiplier < 0 or > 1,"); - pw.println(" both it and R.dimen.config_letterboxHorizontalPositionMultiplier"); - pw.println(" are ignored and central position (0.5) is used."); - pw.println(" --isReachabilityEnabled [true|1|false|0]"); - pw.println(" Whether reachability repositioning is allowed for letterboxed"); - pw.println(" fullscreen apps in landscape device orientation."); - pw.println(" --defaultPositionForReachability [left|center|right]"); - pw.println(" Default horizontal position of app window when reachability is."); - pw.println(" enabled."); - pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType"); - pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha"); - pw.println(" |horizontalPositionMultiplier|isReachabilityEnabled"); - pw.println(" |defaultPositionMultiplierForReachability]"); - pw.println(" Resets overrides to default values for specified properties separated"); - pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'."); - pw.println(" If no arguments provided, all values will be reset."); - pw.println(" get-letterbox-style"); - pw.println(" Prints letterbox style configuration."); - } - private void printMultiWindowConfigHelp(PrintWriter pw) { pw.println(" set-multi-window-config"); pw.println(" Sets options to determine if activity should be shown in multi window:"); 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 004e45a8be4b..b2b844b94d43 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 @@ public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase { } 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) { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 9c9e41b64892..b8a14b8ea72e 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -5794,6 +5794,7 @@ public class CarrierConfigManager { sDefaults.putInt( KEY_OPPORTUNISTIC_TIME_TO_SCAN_AFTER_CAPABILITY_SWITCH_TO_PRIMARY_LONG, 120000); + sDefaults.putAll(ImsServiceEntitlement.getDefaults()); sDefaults.putAll(Gps.getDefaults()); sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY, new int[] { |