summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java6
-rw-r--r--core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java2
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java4
-rw-r--r--core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java2
-rw-r--r--data/etc/services.core.protolog.json12
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java6
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java4
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java70
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java2
-rw-r--r--libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java130
-rw-r--r--packages/SystemUI/OWNERS6
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt50
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManager.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt97
-rw-r--r--services/core/java/com/android/server/audio/SoundDoseHelper.java5
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java6
-rw-r--r--services/core/java/com/android/server/inputmethod/HandwritingModeController.java1
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java10
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java27
-rw-r--r--services/core/java/com/android/server/wm/ContentRecorder.java28
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java75
25 files changed, 370 insertions, 211 deletions
diff --git a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
index 5e2eceb23789..dee49350d93e 100644
--- a/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/AbstractMultiProfilePagerAdapter.java
@@ -177,7 +177,7 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
* <code>1</code> would return the work profile {@link ProfileDescriptor}.</li>
* </ul>
*/
- abstract ProfileDescriptor getItem(int pageIndex);
+ public abstract ProfileDescriptor getItem(int pageIndex);
/**
* Returns the number of {@link ProfileDescriptor} objects.
@@ -438,8 +438,8 @@ public abstract class AbstractMultiProfilePagerAdapter extends PagerAdapter {
&& isQuietModeEnabled(mWorkProfileUserHandle));
}
- protected class ProfileDescriptor {
- final ViewGroup rootView;
+ public static class ProfileDescriptor {
+ public final ViewGroup rootView;
private final ViewGroup mEmptyStateView;
ProfileDescriptor(ViewGroup rootView) {
this.rootView = rootView;
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index 7beb059fb648..8197e265ca29 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -94,7 +94,7 @@ public class ChooserMultiProfilePagerAdapter extends AbstractMultiProfilePagerAd
}
@Override
- ChooserProfileDescriptor getItem(int pageIndex) {
+ public ChooserProfileDescriptor getItem(int pageIndex) {
return mItems[pageIndex];
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index ac15f11ee989..7534d2960b7c 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -2623,13 +2623,13 @@ public class ResolverActivity extends Activity implements
* An a11y delegate that expands resolver drawer when gesture navigation reaches a partially
* invisible target in the list.
*/
- private static class AppListAccessibilityDelegate extends View.AccessibilityDelegate {
+ public static class AppListAccessibilityDelegate extends View.AccessibilityDelegate {
private final ResolverDrawerLayout mDrawer;
@Nullable
private final View mBottomBar;
private final Rect mRect = new Rect();
- private AppListAccessibilityDelegate(ResolverDrawerLayout drawer) {
+ public AppListAccessibilityDelegate(ResolverDrawerLayout drawer) {
mDrawer = drawer;
mBottomBar = mDrawer.findViewById(R.id.button_bar_container);
}
diff --git a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
index 767791263673..031f9d3168bf 100644
--- a/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ResolverMultiProfilePagerAdapter.java
@@ -79,7 +79,7 @@ public class ResolverMultiProfilePagerAdapter extends AbstractMultiProfilePagerA
}
@Override
- ResolverProfileDescriptor getItem(int pageIndex) {
+ public ResolverProfileDescriptor getItem(int pageIndex) {
return mItems[pageIndex];
}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index b6c39c67954d..16e94f8737d7 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -1015,6 +1015,12 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/NonAppWindowAnimationAdapter.java"
},
+ "-1152771606": {
+ "message": "Content Recording: Display %d was already recording, but pause capture since the task is in PIP",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"-1145384901": {
"message": "shouldWaitAnimatingExit: isTransition: %s",
"level": "DEBUG",
@@ -2323,6 +2329,12 @@
"group": "WM_DEBUG_SYNC_ENGINE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "1877956": {
+ "message": "Content Recording: Display %d should start recording, but don't yet since the task is in PIP",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_CONTENT_RECORDING",
+ "at": "com\/android\/server\/wm\/ContentRecorder.java"
+ },
"3593205": {
"message": "commitVisibility: %s: visible=%b mVisibleRequested=%b",
"level": "VERBOSE",
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
index 0000aa4cdfd8..2eacaaf28bba 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -327,17 +327,13 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
return features;
}
- // We will transform the feature bounds to the Activity window, so using the rotation
- // from the same source (WindowConfiguration) to make sure they are synchronized.
- final int rotation = windowConfiguration.getDisplayRotation();
-
for (CommonFoldingFeature baseFeature : storedFeatures) {
Integer state = convertToExtensionState(baseFeature.getState());
if (state == null) {
continue;
}
Rect featureRect = baseFeature.getRect();
- rotateRectToDisplayRotation(displayId, rotation, featureRect);
+ rotateRectToDisplayRotation(displayId, featureRect);
transformToWindowSpaceRect(windowConfiguration, featureRect);
if (isZero(featureRect)) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index 15a329bd9509..5bfb0ebdcaa8 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -120,12 +120,10 @@ class SampleSidecarImpl extends StubSidecar {
}
List<SidecarDisplayFeature> features = new ArrayList<>();
- final int rotation = activity.getResources().getConfiguration().windowConfiguration
- .getDisplayRotation();
for (CommonFoldingFeature baseFeature : mStoredFeatures) {
SidecarDisplayFeature feature = new SidecarDisplayFeature();
Rect featureRect = baseFeature.getRect();
- rotateRectToDisplayRotation(displayId, rotation, featureRect);
+ rotateRectToDisplayRotation(displayId, featureRect);
transformToWindowSpaceRect(activity, featureRect);
feature.setRect(featureRect);
feature.setType(baseFeature.getType());
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java
index 6b193fc53935..9e2611f392a3 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/util/ExtensionHelper.java
@@ -16,6 +16,8 @@
package androidx.window.util;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -23,14 +25,12 @@ import android.app.WindowConfiguration;
import android.content.Context;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
-import android.util.RotationUtils;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.annotation.UiContext;
-import androidx.annotation.VisibleForTesting;
/**
* Util class for both Sidecar and Extensions.
@@ -44,41 +44,47 @@ public final class ExtensionHelper {
/**
* Rotates the input rectangle specified in default display orientation to the current display
* rotation.
- *
- * @param displayId the display id.
- * @param rotation the target rotation relative to the default display orientation.
- * @param inOutRect the input/output Rect as specified in the default display orientation.
*/
- public static void rotateRectToDisplayRotation(
- int displayId, @Surface.Rotation int rotation, @NonNull Rect inOutRect) {
- final DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance();
- final DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId);
+ public static void rotateRectToDisplayRotation(int displayId, Rect inOutRect) {
+ DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance();
+ DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId);
+ int rotation = displayInfo.rotation;
- rotateRectToDisplayRotation(displayInfo, rotation, inOutRect);
+ boolean isSideRotation = rotation == ROTATION_90 || rotation == ROTATION_270;
+ int displayWidth = isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth;
+ int displayHeight = isSideRotation ? displayInfo.logicalWidth : displayInfo.logicalHeight;
+
+ inOutRect.intersect(0, 0, displayWidth, displayHeight);
+
+ rotateBounds(inOutRect, displayWidth, displayHeight, rotation);
}
- @VisibleForTesting
- static void rotateRectToDisplayRotation(@NonNull DisplayInfo displayInfo,
- @Surface.Rotation int rotation, @NonNull Rect inOutRect) {
- // The inOutRect is specified in the default display orientation, so here we need to get
- // the display width and height in the default orientation to perform the intersection and
- // rotation.
- final boolean isSideRotation =
- displayInfo.rotation == ROTATION_90 || displayInfo.rotation == ROTATION_270;
- final int baseDisplayWidth =
- isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth;
- final int baseDisplayHeight =
- isSideRotation ? displayInfo.logicalWidth : displayInfo.logicalHeight;
-
- final boolean success = inOutRect.intersect(0, 0, baseDisplayWidth, baseDisplayHeight);
- if (!success) {
- throw new IllegalArgumentException("inOutRect must intersect with the display."
- + " inOutRect: " + inOutRect
- + ", baseDisplayWidth: " + baseDisplayWidth
- + ", baseDisplayHeight: " + baseDisplayHeight);
+ /**
+ * Rotates the input rectangle within parent bounds for a given delta.
+ */
+ private static void rotateBounds(Rect inOutRect, int parentWidth, int parentHeight,
+ @Surface.Rotation int delta) {
+ int origLeft = inOutRect.left;
+ switch (delta) {
+ case ROTATION_0:
+ return;
+ case ROTATION_90:
+ inOutRect.left = inOutRect.top;
+ inOutRect.top = parentWidth - inOutRect.right;
+ inOutRect.right = inOutRect.bottom;
+ inOutRect.bottom = parentWidth - origLeft;
+ return;
+ case ROTATION_180:
+ inOutRect.left = parentWidth - inOutRect.right;
+ inOutRect.right = parentWidth - origLeft;
+ return;
+ case ROTATION_270:
+ inOutRect.left = parentHeight - inOutRect.bottom;
+ inOutRect.bottom = inOutRect.right;
+ inOutRect.right = parentHeight - inOutRect.top;
+ inOutRect.top = origLeft;
+ return;
}
-
- RotationUtils.rotateBounds(inOutRect, baseDisplayWidth, baseDisplayHeight, rotation);
}
/** Transforms rectangle from absolute coordinate space to the window coordinate space. */
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
index a0590dc2c832..d189ae2cf72e 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/WindowExtensionsTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
/**
- * Test class for {@link WindowExtensions}.
+ * Test class for {@link WindowExtensionsTest}.
*
* Build/Install/Run:
* atest WMJetpackUnitTests:WindowExtensionsTest
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java
deleted file mode 100644
index ae783de228fb..000000000000
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/util/ExtensionHelperTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package androidx.window.util;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThrows;
-
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-import android.view.DisplayInfo;
-import android.view.Surface;
-
-import androidx.annotation.NonNull;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test class for {@link ExtensionHelper}.
- *
- * Build/Install/Run:
- * atest WMJetpackUnitTests:ExtensionHelperTest
- */
-@Presubmit
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ExtensionHelperTest {
-
- private static final int MOCK_DISPLAY_HEIGHT = 1000;
- private static final int MOCK_DISPLAY_WIDTH = 2000;
- private static final int MOCK_FEATURE_LEFT = 100;
- private static final int MOCK_FEATURE_RIGHT = 200;
-
- private static final int[] ROTATIONS = {
- Surface.ROTATION_0,
- Surface.ROTATION_90,
- Surface.ROTATION_180,
- Surface.ROTATION_270
- };
-
- private static final DisplayInfo[] MOCK_DISPLAY_INFOS = {
- getMockDisplayInfo(Surface.ROTATION_0),
- getMockDisplayInfo(Surface.ROTATION_90),
- getMockDisplayInfo(Surface.ROTATION_180),
- getMockDisplayInfo(Surface.ROTATION_270),
- };
-
- @Test
- public void testRotateRectToDisplayRotation() {
- for (int rotation : ROTATIONS) {
- final Rect expectedResult = getExpectedFeatureRectAfterRotation(rotation);
- // The method should return correctly rotated Rect even if the requested rotation value
- // differs from the rotation in DisplayInfo. This is because the WindowConfiguration is
- // not always synced with DisplayInfo.
- for (DisplayInfo displayInfo : MOCK_DISPLAY_INFOS) {
- final Rect rect = getMockFeatureRect();
- ExtensionHelper.rotateRectToDisplayRotation(displayInfo, rotation, rect);
- assertEquals(
- "Result Rect should equal to expected for rotation: " + rotation
- + "; displayInfo: " + displayInfo,
- expectedResult, rect);
- }
- }
- }
-
- @Test
- public void testRotateRectToDisplayRotation_invalidInputRect() {
- final Rect invalidRect = new Rect(
- MOCK_DISPLAY_WIDTH + 10, 0, MOCK_DISPLAY_WIDTH + 10, MOCK_DISPLAY_HEIGHT);
- assertThrows(IllegalArgumentException.class,
- () -> ExtensionHelper.rotateRectToDisplayRotation(
- MOCK_DISPLAY_INFOS[0], ROTATIONS[0], invalidRect));
- }
-
-
- @NonNull
- private static DisplayInfo getMockDisplayInfo(@Surface.Rotation int rotation) {
- final DisplayInfo displayInfo = new DisplayInfo();
- displayInfo.rotation = rotation;
- if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
- displayInfo.logicalWidth = MOCK_DISPLAY_WIDTH;
- displayInfo.logicalHeight = MOCK_DISPLAY_HEIGHT;
- } else {
- displayInfo.logicalWidth = MOCK_DISPLAY_HEIGHT;
- displayInfo.logicalHeight = MOCK_DISPLAY_WIDTH;
- }
- return displayInfo;
- }
-
- @NonNull
- private static Rect getMockFeatureRect() {
- return new Rect(MOCK_FEATURE_LEFT, 0, MOCK_FEATURE_RIGHT, MOCK_DISPLAY_HEIGHT);
- }
-
- @NonNull
- private static Rect getExpectedFeatureRectAfterRotation(@Surface.Rotation int rotation) {
- switch (rotation) {
- case Surface.ROTATION_0:
- return new Rect(
- MOCK_FEATURE_LEFT, 0, MOCK_FEATURE_RIGHT, MOCK_DISPLAY_HEIGHT);
- case Surface.ROTATION_90:
- return new Rect(0, MOCK_DISPLAY_WIDTH - MOCK_FEATURE_RIGHT,
- MOCK_DISPLAY_HEIGHT, MOCK_DISPLAY_WIDTH - MOCK_FEATURE_LEFT);
- case Surface.ROTATION_180:
- return new Rect(MOCK_DISPLAY_WIDTH - MOCK_FEATURE_RIGHT, 0,
- MOCK_DISPLAY_WIDTH - MOCK_FEATURE_LEFT, MOCK_DISPLAY_HEIGHT);
- case Surface.ROTATION_270:
- return new Rect(0, MOCK_FEATURE_LEFT, MOCK_DISPLAY_HEIGHT,
- MOCK_FEATURE_RIGHT);
- default:
- throw new IllegalArgumentException("Unknown rotation value: " + rotation);
- }
- }
-}
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index b708fc27448d..285fc5f1f332 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -6,6 +6,7 @@ dsandler@android.com
aaliomer@google.com
aaronjli@google.com
+achalke@google.com
acul@google.com
adamcohen@google.com
aioana@google.com
@@ -70,6 +71,7 @@ omarmt@google.com
patmanning@google.com
peanutbutter@google.com
peskal@google.com
+petrcermak@google.com
pinyaoting@google.com
pixel@google.com
pomini@google.com
@@ -81,13 +83,17 @@ santie@google.com
shanh@google.com
snoeberger@google.com
steell@google.com
+stevenckng@google.com
stwu@google.com
syeonlee@google.com
sunnygoyal@google.com
thiruram@google.com
+tkachenkoi@google.com
tracyzhou@google.com
tsuji@google.com
twickham@google.com
+vadimt@google.com
+vanjan@google.com
victortulias@google.com
winsonc@google.com
wleshner@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 42cb739dba6a..b6c50f7603c7 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -119,7 +119,7 @@ object Flags {
// TODO(b/292213543): Tracking Bug
@JvmField
val NOTIFICATION_GROUP_EXPANSION_CHANGE =
- unreleasedFlag("notification_group_expansion_change", teamfood = true)
+ unreleasedFlag("notification_group_expansion_change")
// 200 - keyguard/lockscreen
// ** Flag retired **
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
index 053c9b56ef96..60fd10492628 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
@@ -29,7 +29,10 @@ import android.os.Bundle
import android.os.IBinder
import android.os.ResultReceiver
import android.os.UserHandle
+import android.util.Log
+import android.view.View
import android.view.ViewGroup
+import android.view.accessibility.AccessibilityEvent
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
@@ -40,6 +43,9 @@ import com.android.internal.app.ChooserActivity
import com.android.internal.app.ResolverListController
import com.android.internal.app.chooser.NotSelectableTargetInfo
import com.android.internal.app.chooser.TargetInfo
+import com.android.internal.widget.RecyclerView
+import com.android.internal.widget.RecyclerViewAccessibilityDelegate
+import com.android.internal.widget.ResolverDrawerLayout
import com.android.systemui.R
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorComponent
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorController
@@ -105,6 +111,10 @@ class MediaProjectionAppSelectorActivity(
super.onCreate(bundle)
controller.init()
+ // we override AppList's AccessibilityDelegate set in ResolverActivity.onCreate because in
+ // our case this delegate must extend RecyclerViewAccessibilityDelegate, otherwise
+ // RecyclerView scrolling is broken
+ setAppListAccessibilityDelegate()
}
override fun onStart() {
@@ -277,6 +287,8 @@ class MediaProjectionAppSelectorActivity(
recentsViewController.createView(parent)
companion object {
+ const val TAG = "MediaProjectionAppSelectorActivity"
+
/**
* When EXTRA_CAPTURE_REGION_RESULT_RECEIVER is passed as intent extra the activity will
* send the [CaptureRegion] to the result receiver instead of returning media projection
@@ -313,4 +325,42 @@ class MediaProjectionAppSelectorActivity(
putExtra(EXTRA_SELECTED_PROFILE, selectedProfile)
}
}
+
+ private fun setAppListAccessibilityDelegate() {
+ val rdl = requireViewById<ResolverDrawerLayout>(com.android.internal.R.id.contentPanel)
+ for (i in 0 until mMultiProfilePagerAdapter.count) {
+ val list =
+ mMultiProfilePagerAdapter
+ .getItem(i)
+ .rootView
+ .findViewById<View>(com.android.internal.R.id.resolver_list)
+ if (list == null || list !is RecyclerView) {
+ Log.wtf(TAG, "MediaProjection only supports RecyclerView")
+ } else {
+ list.accessibilityDelegate = RecyclerViewExpandingAccessibilityDelegate(rdl, list)
+ }
+ }
+ }
+
+ /**
+ * An a11y delegate propagating all a11y events to [AppListAccessibilityDelegate] so that it can
+ * expand drawer when needed. It needs to extend [RecyclerViewAccessibilityDelegate] because
+ * that superclass handles RecyclerView scrolling while using a11y services.
+ */
+ private class RecyclerViewExpandingAccessibilityDelegate(
+ rdl: ResolverDrawerLayout,
+ view: RecyclerView
+ ) : RecyclerViewAccessibilityDelegate(view) {
+
+ private val delegate = AppListAccessibilityDelegate(rdl)
+
+ override fun onRequestSendAccessibilityEvent(
+ host: ViewGroup,
+ child: View,
+ event: AccessibilityEvent
+ ): Boolean {
+ super.onRequestSendAccessibilityEvent(host, child, event)
+ return delegate.onRequestSendAccessibilityEvent(host, child, event)
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManager.java
index 51eb9f7220fc..c24e9dcea29d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManager.java
@@ -36,7 +36,7 @@ import javax.inject.Inject;
@SysUISingleton
public class NotifInflationErrorManager {
- Set<NotificationEntry> mErroredNotifs = new ArraySet<>();
+ Set<String> mErroredNotifs = new ArraySet<>();
List<NotifInflationErrorListener> mListeners = new ArrayList<>();
@Inject
@@ -48,7 +48,7 @@ public class NotifInflationErrorManager {
* @param e the exception encountered while inflating
*/
public void setInflationError(NotificationEntry entry, Exception e) {
- mErroredNotifs.add(entry);
+ mErroredNotifs.add(entry.getKey());
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onNotifInflationError(entry, e);
}
@@ -58,8 +58,8 @@ public class NotifInflationErrorManager {
* Notification inflated successfully and is no longer errored out.
*/
public void clearInflationError(NotificationEntry entry) {
- if (mErroredNotifs.contains(entry)) {
- mErroredNotifs.remove(entry);
+ if (mErroredNotifs.contains(entry.getKey())) {
+ mErroredNotifs.remove(entry.getKey());
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onNotifInflationErrorCleared(entry);
}
@@ -70,7 +70,7 @@ public class NotifInflationErrorManager {
* Whether or not the notification encountered an exception while inflating.
*/
public boolean hasInflationError(@NonNull NotificationEntry entry) {
- return mErroredNotifs.contains(entry);
+ return mErroredNotifs.contains(entry.getKey());
}
/**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
new file mode 100644
index 000000000000..e38adeb0fcd9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotifInflationErrorManagerTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.row
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager.NotifInflationErrorListener
+import com.android.systemui.util.mockito.any
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class NotifInflationErrorManagerTest : SysuiTestCase() {
+ private lateinit var manager: NotifInflationErrorManager
+
+ private val listener1 = mock(NotifInflationErrorListener::class.java)
+ private val listener2 = mock(NotifInflationErrorListener::class.java)
+
+ private val foo: NotificationEntry = NotificationEntryBuilder().setPkg("foo").build()
+ private val bar: NotificationEntry = NotificationEntryBuilder().setPkg("bar").build()
+ private val baz: NotificationEntry = NotificationEntryBuilder().setPkg("baz").build()
+
+ private val fooException = Exception("foo")
+ private val barException = Exception("bar")
+
+ @Before
+ fun setUp() {
+ // Reset manager instance before each test.
+ manager = NotifInflationErrorManager()
+ }
+
+ @Test
+ fun testTracksInflationErrors() {
+ manager.setInflationError(foo, fooException)
+ manager.setInflationError(bar, barException)
+
+ assertThat(manager.hasInflationError(foo)).isTrue()
+ assertThat(manager.hasInflationError(bar)).isTrue()
+ assertThat(manager.hasInflationError(baz)).isFalse()
+
+ manager.clearInflationError(bar)
+
+ assertThat(manager.hasInflationError(bar)).isFalse()
+ }
+
+ @Test
+ fun testNotifiesListeners() {
+ manager.addInflationErrorListener(listener1)
+ manager.setInflationError(foo, fooException)
+
+ verify(listener1).onNotifInflationError(foo, fooException)
+
+ manager.addInflationErrorListener(listener2)
+ manager.setInflationError(bar, barException)
+
+ verify(listener1).onNotifInflationError(bar, barException)
+ verify(listener2).onNotifInflationError(bar, barException)
+
+ manager.clearInflationError(foo)
+
+ verify(listener1).onNotifInflationErrorCleared(foo)
+ verify(listener2).onNotifInflationErrorCleared(foo)
+ }
+
+ @Test
+ fun testClearUnknownEntry() {
+ manager.addInflationErrorListener(listener1)
+ manager.clearInflationError(foo)
+
+ verify(listener1, never()).onNotifInflationErrorCleared(any())
+ }
+}
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 5ebc1c055b50..95b6c2cef963 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -334,9 +334,8 @@ public class SoundDoseHelper {
SAFE_MEDIA_VOLUME_UNINITIALIZED);
mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
SAFE_MEDIA_VOLUME_UNINITIALIZED);
- // TODO(b/278265907): enable A2DP when we can distinguish A2DP headsets
- // mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- // SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
}
float getOutputRs2UpperBound() {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 51a938558e57..4502e5d0c4b6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -128,7 +128,11 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements
vibrateSuccess();
try {
- getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
+ if (getListener() != null) {
+ getListener().onDetected(getSensorId(), getTargetUserId(), mIsStrongBiometric);
+ } else {
+ Slog.e(TAG, "Listener is null!");
+ }
mCallback.onClientFinished(this, true /* success */);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when sending onDetected", e);
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
index aa99dab8f007..7b613874e25e 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingModeController.java
@@ -235,6 +235,7 @@ final class HandwritingModeController {
@Nullable
HandwritingSession startHandwritingSession(
int requestId, int imePid, int imeUid, IBinder focusedWindowToken) {
+ clearPendingHandwritingDelegation();
if (mHandwritingSurface == null) {
Slog.e(TAG, "Cannot start handwriting session: Handwriting was not initialized.");
return null;
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index aff20eea9aa3..7aea63255dc8 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -3453,13 +3453,19 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
@BinderThread
@Override
public void startStylusHandwriting(IInputMethodClient client) {
+ startStylusHandwriting(client, false /* usesDelegation */);
+ }
+
+ private void startStylusHandwriting(IInputMethodClient client, boolean usesDelegation) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.startStylusHandwriting");
try {
ImeTracing.getInstance().triggerManagerServiceDump(
"InputMethodManagerService#startStylusHandwriting");
int uid = Binder.getCallingUid();
synchronized (ImfLock.class) {
- mHwController.clearPendingHandwritingDelegation();
+ if (!usesDelegation) {
+ mHwController.clearPendingHandwritingDelegation();
+ }
if (!canInteractWithImeLocked(uid, client, "startStylusHandwriting",
null /* statsToken */)) {
return;
@@ -3541,7 +3547,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub
return false;
}
- startStylusHandwriting(client);
+ startStylusHandwriting(client, true /* usesDelegation */);
return true;
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 309a9c0e0372..5b25e890aaa2 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -321,9 +321,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.d(TAG, "publish system wallpaper changed!");
}
- if (localSync != null) {
- localSync.complete();
- }
notifyWallpaperChanged(wallpaper);
}
};
@@ -331,7 +328,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
// If this was the system wallpaper, rebind...
bindWallpaperComponentLocked(mImageWallpaper, true, false, wallpaper,
callback);
- notifyColorsWhich |= FLAG_SYSTEM;
+ notifyColorsWhich |= wallpaper.mWhich;
}
if (lockWallpaperChanged) {
@@ -345,9 +342,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.d(TAG, "publish lock wallpaper changed!");
}
- if (localSync != null) {
- localSync.complete();
- }
notifyWallpaperChanged(wallpaper);
}
};
@@ -372,9 +366,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
saveSettingsLocked(wallpaper.userId);
- // Notify the client immediately if only lockscreen wallpaper changed.
- if (lockWallpaperChanged && !sysWallpaperChanged) {
- notifyWallpaperChanged(wallpaper);
+ if ((sysWallpaperChanged || lockWallpaperChanged) && localSync != null) {
+ localSync.complete();
}
}
@@ -1383,7 +1376,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
lockWp.connection.mWallpaper = lockWp;
mOriginalSystem.mWhich = FLAG_LOCK;
updateEngineFlags(mOriginalSystem);
- notifyWallpaperColorsChanged(lockWp, FLAG_LOCK);
} else {
// Failed rename, use current system wp for both
if (DEBUG) {
@@ -1403,7 +1395,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
updateEngineFlags(mOriginalSystem);
mLockWallpaperMap.put(mNewWallpaper.userId, mOriginalSystem);
mLastLockWallpaper = mOriginalSystem;
- notifyWallpaperColorsChanged(mOriginalSystem, FLAG_LOCK);
}
} else if (mNewWallpaper.mWhich == FLAG_LOCK) {
// New wp is lock only, so old system+lock is now system only
@@ -1417,10 +1408,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
}
-
- synchronized (mLock) {
- saveSettingsLocked(mNewWallpaper.userId);
- }
+ saveSettingsLocked(mNewWallpaper.userId);
if (DEBUG) {
Slog.v(TAG, "--- wallpaper changed --");
@@ -3300,7 +3288,6 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
if (DEBUG) {
Slog.d(TAG, "publish system wallpaper changed!");
}
- liveSync.complete();
}
};
@@ -3356,6 +3343,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
mLockWallpaperMap.remove(newWallpaper.userId);
}
+ if (liveSync != null) liveSync.complete();
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -3474,6 +3462,11 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
// Has the component changed?
if (!force && changingToSame(componentName, wallpaper)) {
+ try {
+ if (reply != null) reply.sendResult(null);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to send callback", e);
+ }
return true;
}
diff --git a/services/core/java/com/android/server/wm/ContentRecorder.java b/services/core/java/com/android/server/wm/ContentRecorder.java
index f0e4149a9159..7cd07d6f3a5f 100644
--- a/services/core/java/com/android/server/wm/ContentRecorder.java
+++ b/services/core/java/com/android/server/wm/ContentRecorder.java
@@ -151,6 +151,20 @@ final class ContentRecorder implements WindowContainerListener {
return;
}
+ // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are
+ // inaccurate.
+ if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
+ final Task capturedTask = mRecordedWindowContainer.asTask();
+ if (capturedTask.inPinnedWindowingMode()) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Display %d was already recording, but "
+ + "pause capture since the task is in PIP",
+ mDisplayContent.getDisplayId());
+ pauseRecording();
+ return;
+ }
+ }
+
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Display %d was already recording, so apply "
+ "transformations if necessary",
@@ -292,6 +306,17 @@ final class ContentRecorder implements WindowContainerListener {
return;
}
+ // TODO(b/297514518) Do not start capture if the app is in PIP, the bounds are inaccurate.
+ if (mContentRecordingSession.getContentToRecord() == RECORD_CONTENT_TASK) {
+ if (mRecordedWindowContainer.asTask().inPinnedWindowingMode()) {
+ ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
+ "Content Recording: Display %d should start recording, but "
+ + "don't yet since the task is in PIP",
+ mDisplayContent.getDisplayId());
+ return;
+ }
+ }
+
final Point surfaceSize = fetchSurfaceSizeIfPresent();
if (surfaceSize == null) {
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
@@ -305,9 +330,6 @@ final class ContentRecorder implements WindowContainerListener {
+ "state %d",
mDisplayContent.getDisplayId(), mDisplayContent.getDisplayInfo().state);
- // TODO(b/274790702): Do not start recording if waiting for consent - for now,
- // go ahead.
-
// Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture.
mRecordedSurface = SurfaceControl.mirrorSurface(
mRecordedWindowContainer.getSurfaceControl());
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 75458302586d..034299659dd5 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -1147,7 +1147,7 @@ class TransitionController {
Transition.asyncTraceBegin("animating", 0x41bfaf1 /* hashcode of TAG */);
} else if (!animatingState && mAnimatingState) {
t.setEarlyWakeupEnd();
- mAtm.mWindowManager.requestTraversal();
+ mAtm.mWindowManager.scheduleAnimationLocked();
mSnapshotController.setPause(false);
mAnimatingState = false;
Transition.asyncTraceEnd(0x41bfaf1 /* hashcode of TAG */);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
index 20d5f93a2c07..78d3a9dd9f9e 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
@@ -19,6 +19,7 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
@@ -147,6 +148,24 @@ public class FingerprintDetectClientTest {
verify(mBiometricContext).unsubscribe(same(mOperationContextCaptor.getValue()));
}
+ @Test
+ public void testWhenListenerIsNull() {
+ final AidlSession aidl = new AidlSession(0, mHal, USER_ID, mHalSessionCallback);
+ final FingerprintDetectClient client = new FingerprintDetectClient(mContext, () -> aidl,
+ mToken, 6 /* requestId */, null /* listener */,
+ new FingerprintAuthenticateOptions.Builder()
+ .setUserId(2)
+ .setSensorId(1)
+ .setOpPackageName("a-test")
+ .build(),
+ mBiometricLogger, mBiometricContext,
+ mUdfpsOverlayController, true /* isStrongBiometric */);
+ client.start(mCallback);
+ client.onInteractionDetected();
+
+ verify(mCallback).onClientFinished(eq(client), anyBoolean());
+ }
+
private FingerprintDetectClient createClient() throws RemoteException {
return createClient(200 /* version */);
}
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index f158ce14549f..9d2b34cc6ba5 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -84,6 +84,7 @@ import android.view.Display;
import android.view.InputDevice;
import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.FrameworkStatsLog;
@@ -813,6 +814,7 @@ public class VibratorManagerServiceTest {
eq(AudioAttributes.USAGE_UNKNOWN), anyInt(), anyString());
}
+ @FlakyTest
@Test
public void vibrate_withOngoingRepeatingVibration_ignoresEffect() throws Exception {
mockVibrators(1);
@@ -899,6 +901,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up repeating effect.
}
+ @FlakyTest
@Test
public void vibrate_withNewSameImportanceVibrationButOngoingIsRepeating_ignoreNewVibration()
throws Exception {
@@ -952,6 +955,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up repeating effect.
}
+ @FlakyTest
@Test
public void vibrate_withNewUnknownUsageVibrationAndNotRepeating_ignoreNewVibration()
throws Exception {
@@ -1687,6 +1691,7 @@ public class VibratorManagerServiceTest {
cancelVibrate(service); // Clean up long effect.
}
+ @FlakyTest
@Test
public void onExternalVibration_withNewSameImportanceButRepeating_cancelsOngoingVibration()
throws Exception {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
index aa2b93506f8e..b8f6cb8b5eba 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ContentRecorderTests.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -360,6 +363,39 @@ public class ContentRecorderTests extends WindowTestsBase {
}
@Test
+ public void testTaskWindowingModeChanged_pip_stopsRecording() {
+ // WHEN a recording is ongoing.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+
+ // WHEN a configuration change arrives, and the task is now pinned.
+ mTask.setWindowingMode(WINDOWING_MODE_PINNED);
+ Configuration configuration = mTask.getConfiguration();
+ mTask.onConfigurationChanged(configuration);
+
+ // THEN recording is paused.
+ assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+ }
+
+ @Test
+ public void testTaskWindowingModeChanged_fullscreen_startsRecording() {
+ // WHEN a recording is ongoing.
+ mTask.setWindowingMode(WINDOWING_MODE_PINNED);
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mContentRecorder.updateRecording();
+ assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+
+ // WHEN the task is now fullscreen.
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ mContentRecorder.updateRecording();
+
+ // THEN recording is started.
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+ }
+
+ @Test
public void testStartRecording_notifiesCallback_taskSession() {
// WHEN a recording is ongoing.
mContentRecorder.setContentRecordingSession(mTaskSession);
@@ -384,6 +420,45 @@ public class ContentRecorderTests extends WindowTestsBase {
}
@Test
+ public void testStartRecording_taskInPIP_recordingNotStarted() {
+ // GIVEN a task is in PIP.
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mTask.setWindowingMode(WINDOWING_MODE_PINNED);
+
+ // WHEN a recording tries to start.
+ mContentRecorder.updateRecording();
+
+ // THEN recording does not start.
+ assertThat(mContentRecorder.isCurrentlyRecording()).isFalse();
+ }
+
+ @Test
+ public void testStartRecording_taskInSplit_recordingStarted() {
+ // GIVEN a task is in PIP.
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mTask.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+
+ // WHEN a recording tries to start.
+ mContentRecorder.updateRecording();
+
+ // THEN recording does not start.
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+ }
+
+ @Test
+ public void testStartRecording_taskInFullscreen_recordingStarted() {
+ // GIVEN a task is in PIP.
+ mContentRecorder.setContentRecordingSession(mTaskSession);
+ mTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+ // WHEN a recording tries to start.
+ mContentRecorder.updateRecording();
+
+ // THEN recording does not start.
+ assertThat(mContentRecorder.isCurrentlyRecording()).isTrue();
+ }
+
+ @Test
public void testOnVisibleRequestedChanged_notifiesCallback() {
// WHEN a recording is ongoing.
mContentRecorder.setContentRecordingSession(mTaskSession);