summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/accessibility/IMagnificationConnection.aidl5
-rw-r--r--core/java/android/window/flags/accessibility.aconfig7
-rw-r--r--core/res/res/values/config_telephony.xml5
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java2
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java41
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java8
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java63
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java21
-rw-r--r--libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java7
-rw-r--r--media/java/android/media/tv/ITvInputSessionWrapper.java2
-rw-r--r--packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.pngbin57340 -> 58496 bytes
-rw-r--r--packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.pngbin48422 -> 49467 bytes
-rw-r--r--packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.pngbin28871 -> 29537 bytes
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt24
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt12
-rw-r--r--packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt29
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt42
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt8
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java15
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java39
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java16
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java6
-rw-r--r--services/core/java/com/android/server/display/AutomaticBrightnessController.java53
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java26
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessEvent.java36
-rw-r--r--services/core/java/com/android/server/display/brightness/BrightnessReason.java5
-rw-r--r--services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java17
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java23
-rw-r--r--services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java13
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java68
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java15
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java31
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java29
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java23
-rw-r--r--services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java29
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java41
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java8
48 files changed, 741 insertions, 106 deletions
diff --git a/core/java/android/view/accessibility/IMagnificationConnection.aidl b/core/java/android/view/accessibility/IMagnificationConnection.aidl
index aae51abd3c78..450cf7558c6f 100644
--- a/core/java/android/view/accessibility/IMagnificationConnection.aidl
+++ b/core/java/android/view/accessibility/IMagnificationConnection.aidl
@@ -124,4 +124,9 @@ oneway interface IMagnificationConnection {
* @param scale magnification scale.
*/
void onUserMagnificationScaleChanged(int userId, int displayId, float scale);
+
+ /**
+ * Notify the changes of fullscreen magnification activation on the specified display
+ */
+ void onFullscreenMagnificationActivationChanged(int displayId, boolean activated);
}
diff --git a/core/java/android/window/flags/accessibility.aconfig b/core/java/android/window/flags/accessibility.aconfig
index d467be6e5311..814c62017391 100644
--- a/core/java/android/window/flags/accessibility.aconfig
+++ b/core/java/android/window/flags/accessibility.aconfig
@@ -5,4 +5,11 @@ flag {
namespace: "accessibility"
description: "The flag controls whether the intersection check for non-magnifiable windows is needed when onWindowTransition,"
bug: "312624253"
+}
+
+flag {
+ name: "magnification_always_draw_fullscreen_border"
+ namespace: "accessibility"
+ description: "Always draw fullscreen orange border in fullscreen magnification"
+ bug: "291891390"
} \ No newline at end of file
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 104b7cd5450b..c87b7cdb1e8e 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -73,6 +73,11 @@
<bool name="auto_data_switch_ping_test_before_switch">true</bool>
<java-symbol type="bool" name="auto_data_switch_ping_test_before_switch" />
+ <!-- TODO: remove after V -->
+ <!-- Boolean indicating whether allow to use a roaming nonDDS if user enabled its roaming. -->
+ <bool name="auto_data_switch_allow_roaming">true</bool>
+ <java-symbol type="bool" name="auto_data_switch_allow_roaming" />
+
<!-- Define the tolerated gap of score for auto data switch decision, larger than which the
device will switch to the SIM with higher score. The score is used in conjunction with the
score table defined in
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
index 65955b1d9bcc..e37dea4dfd69 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/CommonFoldingFeature.java
@@ -126,7 +126,7 @@ public final class CommonFoldingFeature {
* @see #FEATURE_PATTERN
* @return {@link List} of {@link CommonFoldingFeature}.
*/
- static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
+ public static List<CommonFoldingFeature> parseListFromString(@NonNull String value,
@State int hingeState) {
List<CommonFoldingFeature> features = new ArrayList<>();
String[] featureStrings = value.split(";");
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
index a184dff5005b..88fd461debbe 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/common/DeviceStateManagerFoldingFeatureProducer.java
@@ -36,6 +36,7 @@ import androidx.window.util.BaseDataProducer;
import com.android.internal.R;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -78,7 +79,9 @@ public final class DeviceStateManagerFoldingFeatureProducer
private int mCurrentBaseDeviceState = INVALID_DEVICE_STATE;
@NonNull
- private final BaseDataProducer<String> mRawFoldSupplier;
+ private final RawFoldingFeatureProducer mRawFoldSupplier;
+
+ private final boolean mIsHalfOpenedSupported;
private final DeviceStateCallback mDeviceStateCallback = new DeviceStateCallback() {
@Override
@@ -101,10 +104,12 @@ public final class DeviceStateManagerFoldingFeatureProducer
};
public DeviceStateManagerFoldingFeatureProducer(@NonNull Context context,
- @NonNull BaseDataProducer<String> rawFoldSupplier) {
+ @NonNull RawFoldingFeatureProducer rawFoldSupplier,
+ @NonNull DeviceStateManager deviceStateManager) {
mRawFoldSupplier = rawFoldSupplier;
String[] deviceStatePosturePairs = context.getResources()
.getStringArray(R.array.config_device_state_postures);
+ boolean isHalfOpenedSupported = false;
for (String deviceStatePosturePair : deviceStatePosturePairs) {
String[] deviceStatePostureMapping = deviceStatePosturePair.split(":");
if (deviceStatePostureMapping.length != 2) {
@@ -128,12 +133,13 @@ public final class DeviceStateManagerFoldingFeatureProducer
}
continue;
}
-
+ isHalfOpenedSupported = isHalfOpenedSupported
+ || posture == CommonFoldingFeature.COMMON_STATE_HALF_OPENED;
mDeviceStateToPostureMap.put(deviceState, posture);
}
-
+ mIsHalfOpenedSupported = isHalfOpenedSupported;
if (mDeviceStateToPostureMap.size() > 0) {
- Objects.requireNonNull(context.getSystemService(DeviceStateManager.class))
+ Objects.requireNonNull(deviceStateManager)
.registerCallback(context.getMainExecutor(), mDeviceStateCallback);
}
}
@@ -188,6 +194,31 @@ public final class DeviceStateManagerFoldingFeatureProducer
}
/**
+ * Returns a {@link List} of all the {@link CommonFoldingFeature} with the state set to
+ * {@link CommonFoldingFeature#COMMON_STATE_UNKNOWN}. This method parses a {@link String} so a
+ * caller should consider caching the value or the derived value.
+ */
+ @NonNull
+ public List<CommonFoldingFeature> getFoldsWithUnknownState() {
+ Optional<String> optionalFoldingFeatureString = mRawFoldSupplier.getCurrentData();
+
+ if (optionalFoldingFeatureString.isPresent()) {
+ return CommonFoldingFeature.parseListFromString(
+ optionalFoldingFeatureString.get(), CommonFoldingFeature.COMMON_STATE_UNKNOWN
+ );
+ }
+ return Collections.emptyList();
+ }
+
+
+ /**
+ * Returns {@code true} if the device supports half-opened mode, {@code false} otherwise.
+ */
+ public boolean isHalfOpenedSupported() {
+ return mIsHalfOpenedSupported;
+ }
+
+ /**
* Adds the data to the storeFeaturesConsumer when the data is ready.
* @param storeFeaturesConsumer a consumer to collect the data when it is first available.
*/
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
index 29cf05407a61..6714263ad952 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/WindowExtensionsImpl.java
@@ -20,6 +20,7 @@ import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
+import android.hardware.devicestate.DeviceStateManager;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -64,6 +65,11 @@ public class WindowExtensionsImpl implements WindowExtensions {
}
@NonNull
+ private DeviceStateManager getDeviceStateManager() {
+ return Objects.requireNonNull(getApplication().getSystemService(DeviceStateManager.class));
+ }
+
+ @NonNull
private DeviceStateManagerFoldingFeatureProducer getFoldingFeatureProducer() {
if (mFoldingFeatureProducer == null) {
synchronized (mLock) {
@@ -73,7 +79,7 @@ public class WindowExtensionsImpl implements WindowExtensions {
new RawFoldingFeatureProducer(context);
mFoldingFeatureProducer =
new DeviceStateManagerFoldingFeatureProducer(context,
- foldingFeatureProducer);
+ foldingFeatureProducer, getDeviceStateManager());
}
}
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
new file mode 100644
index 000000000000..a0f481a911ad
--- /dev/null
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/DisplayFoldFeatureUtil.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 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.extensions.layout;
+
+import androidx.window.common.CommonFoldingFeature;
+import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Util functions for working with {@link androidx.window.extensions.layout.DisplayFoldFeature}.
+ */
+public class DisplayFoldFeatureUtil {
+
+ private DisplayFoldFeatureUtil() {}
+
+ private static DisplayFoldFeature create(CommonFoldingFeature foldingFeature,
+ boolean isHalfOpenedSupported) {
+ final int foldType;
+ if (foldingFeature.getType() == CommonFoldingFeature.COMMON_TYPE_HINGE) {
+ foldType = DisplayFoldFeature.TYPE_HINGE;
+ } else {
+ foldType = DisplayFoldFeature.TYPE_SCREEN_FOLD_IN;
+ }
+ DisplayFoldFeature.Builder featureBuilder = new DisplayFoldFeature.Builder(foldType);
+
+ if (isHalfOpenedSupported) {
+ featureBuilder.addProperty(DisplayFoldFeature.FOLD_PROPERTY_SUPPORTS_HALF_OPENED);
+ }
+ return featureBuilder.build();
+ }
+
+ /**
+ * Returns the list of supported {@link DisplayFeature} calculated from the
+ * {@link DeviceStateManagerFoldingFeatureProducer}.
+ */
+ public static List<DisplayFoldFeature> extractDisplayFoldFeatures(
+ DeviceStateManagerFoldingFeatureProducer producer) {
+ List<DisplayFoldFeature> foldFeatures = new ArrayList<>();
+ List<CommonFoldingFeature> folds = producer.getFoldsWithUnknownState();
+
+ final boolean isHalfOpenedSupported = producer.isHalfOpenedSupported();
+ for (CommonFoldingFeature fold : folds) {
+ foldFeatures.add(DisplayFoldFeatureUtil.create(fold, isHalfOpenedSupported));
+ }
+ return foldFeatures;
+ }
+}
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 6e704f35fb22..4fd11c495529 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/layout/WindowLayoutComponentImpl.java
@@ -45,7 +45,6 @@ import androidx.window.common.CommonFoldingFeature;
import androidx.window.common.DeviceStateManagerFoldingFeatureProducer;
import androidx.window.common.EmptyLifecycleCallbacksAdapter;
import androidx.window.extensions.core.util.function.Consumer;
-import androidx.window.util.DataProducer;
import java.util.ArrayList;
import java.util.Collections;
@@ -56,10 +55,6 @@ import java.util.Set;
/**
* Reference implementation of androidx.window.extensions.layout OEM interface for use with
* WindowManager Jetpack.
- *
- * NOTE: This version is a work in progress and under active development. It MUST NOT be used in
- * production builds since the interface can still change before reaching stable version.
- * Please refer to {@link androidx.window.sidecar.SampleSidecarImpl} instead.
*/
public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private static final String TAG = WindowLayoutComponentImpl.class.getSimpleName();
@@ -71,7 +66,7 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
new ArrayMap<>();
@GuardedBy("mLock")
- private final DataProducer<List<CommonFoldingFeature>> mFoldingFeatureProducer;
+ private final DeviceStateManagerFoldingFeatureProducer mFoldingFeatureProducer;
@GuardedBy("mLock")
private final List<CommonFoldingFeature> mLastReportedFoldingFeatures = new ArrayList<>();
@@ -87,12 +82,17 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
private final RawConfigurationChangedListener mRawConfigurationChangedListener =
new RawConfigurationChangedListener();
+ private final SupportedWindowFeatures mSupportedWindowFeatures;
+
public WindowLayoutComponentImpl(@NonNull Context context,
@NonNull DeviceStateManagerFoldingFeatureProducer foldingFeatureProducer) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
mFoldingFeatureProducer = foldingFeatureProducer;
mFoldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
+ final List<DisplayFoldFeature> displayFoldFeatures =
+ DisplayFoldFeatureUtil.extractDisplayFoldFeatures(mFoldingFeatureProducer);
+ mSupportedWindowFeatures = new SupportedWindowFeatures.Builder(displayFoldFeatures).build();
}
/**
@@ -283,6 +283,15 @@ public class WindowLayoutComponentImpl implements WindowLayoutComponent {
}
}
+ /**
+ * Returns the {@link SupportedWindowFeatures} for the device. This list does not change over
+ * time.
+ */
+ @NonNull
+ public SupportedWindowFeatures getSupportedWindowFeatures() {
+ return mSupportedWindowFeatures;
+ }
+
/** @see #getWindowLayoutInfo(Context, List) */
private WindowLayoutInfo getWindowLayoutInfo(int displayId,
@NonNull WindowConfiguration windowConfiguration,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
index a836e05b2d66..56c3bce87d6e 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/sidecar/SampleSidecarImpl.java
@@ -17,6 +17,7 @@
package androidx.window.sidecar;
import static android.view.Display.DEFAULT_DISPLAY;
+
import static androidx.window.util.ExtensionHelper.rotateRectToDisplayRotation;
import static androidx.window.util.ExtensionHelper.transformToWindowSpaceRect;
@@ -25,6 +26,7 @@ import android.app.ActivityThread;
import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
+import android.hardware.devicestate.DeviceStateManager;
import android.os.Bundle;
import android.os.IBinder;
@@ -49,10 +51,11 @@ class SampleSidecarImpl extends StubSidecar {
SampleSidecarImpl(Context context) {
((Application) context.getApplicationContext())
.registerActivityLifecycleCallbacks(new NotifyOnConfigurationChanged());
- BaseDataProducer<String> settingsFeatureProducer = new RawFoldingFeatureProducer(context);
+ RawFoldingFeatureProducer settingsFeatureProducer = new RawFoldingFeatureProducer(context);
BaseDataProducer<List<CommonFoldingFeature>> foldingFeatureProducer =
new DeviceStateManagerFoldingFeatureProducer(context,
- settingsFeatureProducer);
+ settingsFeatureProducer,
+ context.getSystemService(DeviceStateManager.class));
foldingFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged);
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index d1453975f801..ed543e67fdf1 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -519,7 +519,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand
@Override
public void stopPlayback(int mode) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_STOP_PLAYBACK, mode));
+ mCaller.executeOrSendMessage(mCaller.obtainMessageI(DO_STOP_PLAYBACK, mode));
}
@Override
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png
index a038779b0e79..e1f5c742dab7 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_slider.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png
index 03db688f6799..928e9268292b 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_slider.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png
index 1345c379cfb0..05213688b0a8 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_slider.png
Binary files differ
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index a69a2a64dccb..f5c4843e1324 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -546,3 +546,13 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "notify_power_manager_user_activity_background"
+ namespace: "systemui"
+ description: "Decide whether to notify the user activity to power manager in the background thread."
+ bug: "325203885"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
index d2fda4cfd186..88fa2de186d0 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/Magnification.java
@@ -273,6 +273,10 @@ public class Magnification implements CoreStartable, CommandQueue.Callbacks {
}
}
+ void onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
+ // Do nothing
+ }
+
@MainThread
void toggleSettingsPanelVisibility(int displayId) {
final MagnificationSettingsController magnificationSettingsController =
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
index ba943b07b704..b5f3aef88dc4 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationConnectionImpl.java
@@ -47,6 +47,12 @@ class MagnificationConnectionImpl extends IMagnificationConnection.Stub {
}
@Override
+ public void onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
+ mHandler.post(() -> mMagnification
+ .onFullscreenMagnificationActivationChanged(displayId, activated));
+ }
+
+ @Override
public void enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY,
IRemoteMagnificationAnimationCallback callback) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
index ae1539ebaf89..59b59bf1e437 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/data/repository/FacePropertyRepository.kt
@@ -50,6 +50,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
@@ -64,13 +65,16 @@ interface FacePropertyRepository {
/** The current face sensor location in current device rotation */
val sensorLocation: StateFlow<Point?>
+
+ /** The info of current available camera. */
+ val cameraInfo: StateFlow<CameraInfo?>
}
/** Describes a biometric sensor */
data class FaceSensorInfo(val id: Int, val strength: SensorStrength)
/** Data class for camera info */
-private data class CameraInfo(
+data class CameraInfo(
/** The logical id of the camera */
val cameraId: String,
/** The physical id of the camera */
@@ -124,7 +128,7 @@ constructor(
private val cameraInfoList: List<CameraInfo> = loadCameraInfoList()
private var currentPhysicalCameraId: String? = null
- private val defaultSensorLocation: StateFlow<Point?> =
+ override val cameraInfo: StateFlow<CameraInfo?> =
ConflatedCallbackFlow.conflatedCallbackFlow {
val callback =
object : CameraManager.AvailabilityCallback() {
@@ -142,7 +146,7 @@ constructor(
physicalCameraId == it.cameraPhysicalId
}
trySendWithFailureLogging(
- cameraInfo?.cameraLocation,
+ cameraInfo,
TAG,
"Update face sensor location to $cameraInfo."
)
@@ -168,7 +172,7 @@ constructor(
}
currentPhysicalCameraId = cameraInfo?.cameraPhysicalId
trySendWithFailureLogging(
- cameraInfo?.cameraLocation,
+ cameraInfo,
TAG,
"Update face sensor location to $cameraInfo."
)
@@ -181,8 +185,16 @@ constructor(
.stateIn(
applicationScope,
started = SharingStarted.WhileSubscribed(),
- initialValue =
- if (cameraInfoList.isNotEmpty()) cameraInfoList[0].cameraLocation else null
+ initialValue = if (cameraInfoList.isNotEmpty()) cameraInfoList[0] else null
+ )
+
+ private val defaultSensorLocation: StateFlow<Point?> =
+ cameraInfo
+ .map { it?.cameraLocation }
+ .stateIn(
+ applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = null
)
override val sensorLocation: StateFlow<Point?> =
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
index cf91e147d1b3..0c9fbc27cc5d 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/SystemUIDeviceEntryFaceAuthInteractor.kt
@@ -189,6 +189,18 @@ constructor(
}
}
.launchIn(applicationScope)
+
+ facePropertyRepository.cameraInfo
+ .onEach {
+ if (it != null && isRunning()) {
+ repository.cancel()
+ runFaceAuth(
+ FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED,
+ fallbackToDetect = true
+ )
+ }
+ }
+ .launchIn(applicationScope)
}
private suspend fun resetLockedOutState(currentUserId: Int) {
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
index ee220d5fb713..08a6166fe557 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/FaceAuthReason.kt
@@ -31,6 +31,7 @@ import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ALTERNATE
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.ASSISTANT_VISIBILITY_CHANGED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.AUTH_REQUEST_DURING_CANCELLATION
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.BIOMETRIC_ENABLED
+import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_AVAILABLE_CHANGED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.CAMERA_LAUNCHED
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DEVICE_WOKEN_UP_ON_REACH_GESTURE
import com.android.systemui.deviceentry.shared.InternalFaceAuthReasons.DISPLAY_OFF
@@ -130,6 +131,7 @@ private object InternalFaceAuthReasons {
"Face auth stopped because non strong biometric allowed changed"
const val POSTURE_CHANGED = "Face auth started/stopped due to device posture changed."
const val DISPLAY_OFF = "Face auth stopped due to display state OFF."
+ const val CAMERA_AVAILABLE_CHANGED = "Face auth started due to the available camera changed"
}
/**
@@ -221,7 +223,9 @@ constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
@UiEvent(doc = NON_STRONG_BIOMETRIC_ALLOWED_CHANGED)
FACE_AUTH_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED(1256, NON_STRONG_BIOMETRIC_ALLOWED_CHANGED),
@UiEvent(doc = ACCESSIBILITY_ACTION) FACE_AUTH_ACCESSIBILITY_ACTION(1454, ACCESSIBILITY_ACTION),
- @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF);
+ @UiEvent(doc = DISPLAY_OFF) FACE_AUTH_DISPLAY_OFF(1461, DISPLAY_OFF),
+ @UiEvent(doc = CAMERA_AVAILABLE_CHANGED)
+ FACE_AUTH_CAMERA_AVAILABLE_CHANGED(1623, CAMERA_AVAILABLE_CHANGED);
override fun getId(): Int = this.id
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c6b99528b2ba..6d917bbde82b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -40,6 +40,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.Flags.notifyPowerManagerUserActivityBackground;
import static com.android.systemui.Flags.refactorGetCurrentUser;
import static com.android.systemui.keyguard.ui.viewmodel.LockscreenToDreamingTransitionViewModel.DREAMING_ANIMATION_DURATION_MS;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
@@ -1488,7 +1489,11 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
}
public void userActivity() {
- mPM.userActivity(mSystemClock.uptimeMillis(), false);
+ if (notifyPowerManagerUserActivityBackground()) {
+ mUiBgExecutor.execute(() -> mPM.userActivity(mSystemClock.uptimeMillis(), false));
+ } else {
+ mPM.userActivity(mSystemClock.uptimeMillis(), false);
+ }
}
private void setupLocked() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
index 9f24d5dfea79..f5e96c93271a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/data/repository/FacePropertyRepositoryImplTest.kt
@@ -237,6 +237,35 @@ class FacePropertyRepositoryImplTest : SysuiTestCase() {
}
}
+ @Test
+ fun providesTheCameraInfoOnCameraAvailableChange() {
+ testScope.runTest {
+ runCurrent()
+ collectLastValue(underTest.cameraInfo)
+
+ verify(faceManager).addAuthenticatorsRegisteredCallback(callback.capture())
+ callback.value.onAllAuthenticatorsRegistered(
+ listOf(createSensorProperties(1, SensorProperties.STRENGTH_STRONG))
+ )
+ runCurrent()
+ verify(cameraManager)
+ .registerAvailabilityCallback(any(Executor::class.java), cameraCallback.capture())
+
+ cameraCallback.value.onPhysicalCameraAvailable("0", PHYSICAL_CAMERA_ID_OUTER_FRONT)
+ runCurrent()
+
+ val cameraInfo by collectLastValue(underTest.cameraInfo)
+ assertThat(cameraInfo)
+ .isEqualTo(
+ CameraInfo(
+ "0",
+ PHYSICAL_CAMERA_ID_OUTER_FRONT,
+ Point(OUTER_FRONT_SENSOR_LOCATION[0], OUTER_FRONT_SENSOR_LOCATION[1])
+ )
+ )
+ }
+ }
+
private fun createSensorProperties(id: Int, strength: Int) =
FaceSensorPropertiesInternal(id, strength, 0, emptyList(), 1, false, false, false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
index e30dd35d74c1..e1e9fcb2d059 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFaceAuthInteractorTest.kt
@@ -25,6 +25,7 @@ import androidx.test.filters.SmallTest
import com.android.keyguard.keyguardUpdateMonitor
import com.android.keyguard.trustManager
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.CameraInfo
import com.android.systemui.biometrics.data.repository.FaceSensorInfo
import com.android.systemui.biometrics.data.repository.facePropertyRepository
import com.android.systemui.biometrics.shared.model.LockoutMode
@@ -490,6 +491,47 @@ class DeviceEntryFaceAuthInteractorTest : SysuiTestCase() {
verify(trustManager).clearAllBiometricRecognized(eq(BiometricSourceType.FACE), anyInt())
}
+ @Test
+ fun faceAuthIsRequestedWhenAuthIsRunningWhileCameraInfoChanged() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ faceAuthRepository.requestAuthenticate(
+ FaceAuthUiEvent.FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED,
+ true
+ )
+ facePropertyRepository.setCameraIno(CameraInfo("0", "1", null))
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value)
+ .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_CAMERA_AVAILABLE_CHANGED, true))
+ }
+
+ @Test
+ fun faceAuthIsNotRequestedWhenNoAuthRunningWhileCameraInfoChanged() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ facePropertyRepository.setCameraIno(CameraInfo("0", "1", null))
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
+ @Test
+ fun faceAuthIsNotRequestedWhenAuthIsRunningWhileCameraInfoIsNull() =
+ testScope.runTest {
+ facePropertyRepository.setCameraIno(null)
+ underTest.start()
+
+ facePropertyRepository.setCameraIno(null)
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
companion object {
private const val primaryUserId = 1
private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
index 77f501f550d7..68ef55573dc8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/data/repository/FakeFacePropertyRepository.kt
@@ -33,6 +33,10 @@ class FakeFacePropertyRepository : FacePropertyRepository {
override val sensorLocation: StateFlow<Point?>
get() = faceSensorLocation
+ private val currentCameraInfo = MutableStateFlow<CameraInfo?>(null)
+ override val cameraInfo: StateFlow<CameraInfo?>
+ get() = currentCameraInfo
+
fun setLockoutMode(userId: Int, mode: LockoutMode) {
lockoutModesForUser[userId] = mode
}
@@ -47,4 +51,8 @@ class FakeFacePropertyRepository : FacePropertyRepository {
fun setSensorLocation(value: Point?) {
faceSensorLocation.value = value
}
+
+ fun setCameraIno(value: CameraInfo?) {
+ currentCameraInfo.value = value
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 46db624cf3c1..43c018cfeea3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -3460,13 +3460,20 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (!mMagnificationController.supportWindowMagnification()) {
return;
}
- final boolean connect = (userState.isShortcutMagnificationEnabledLocked()
+
+ final boolean shortcutEnabled = (userState.isShortcutMagnificationEnabledLocked()
|| userState.isMagnificationSingleFingerTripleTapEnabledLocked()
|| (Flags.enableMagnificationMultipleFingerMultipleTapGesture()
- && userState.isMagnificationTwoFingerTripleTapEnabledLocked()))
- && (userState.getMagnificationCapabilitiesLocked()
- != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)
+ && userState.isMagnificationTwoFingerTripleTapEnabledLocked()));
+
+ final boolean createConnectionForCurrentCapability =
+ com.android.window.flags.Flags.magnificationAlwaysDrawFullscreenBorder()
+ || (userState.getMagnificationCapabilitiesLocked()
+ != Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+
+ final boolean connect = (shortcutEnabled && createConnectionForCurrentCapability)
|| userHasMagnificationServicesLocked(userState);
+
getMagnificationConnectionManager().requestConnection(connect);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
index e11c36a91830..bc143428e1ae 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionManager.java
@@ -674,6 +674,23 @@ public class MagnificationConnectionManager implements
}
/**
+ * Notify Fullscreen magnification activation changes.
+ */
+ public boolean onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
+ synchronized (mLock) {
+ waitForConnectionIfNeeded();
+ if (mConnectionWrapper == null) {
+ Slog.w(TAG,
+ "onFullscreenMagnificationActivationChanged mConnectionWrapper is null. "
+ + "mConnectionState=" + connectionStateToString(mConnectionState));
+ return false;
+ }
+ return mConnectionWrapper
+ .onFullscreenMagnificationActivationChanged(displayId, activated);
+ }
+ }
+
+ /**
* Calculates the number of fingers in the window.
*
* @param displayId The logical display id.
@@ -1267,15 +1284,7 @@ public class MagnificationConnectionManager implements
float centerY, float magnificationFrameOffsetRatioX,
float magnificationFrameOffsetRatioY,
MagnificationAnimationCallback animationCallback) {
- // Wait for the connection with a timeout.
- final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS;
- while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) {
- try {
- mLock.wait(endMillis - SystemClock.uptimeMillis());
- } catch (InterruptedException ie) {
- /* ignore */
- }
- }
+ waitForConnectionIfNeeded();
if (mConnectionWrapper == null) {
Slog.w(TAG,
"enableWindowMagnificationInternal mConnectionWrapper is null. "
@@ -1317,4 +1326,16 @@ public class MagnificationConnectionManager implements
return mConnectionWrapper != null && mConnectionWrapper.moveWindowMagnifierToPosition(
displayId, positionX, positionY, animationCallback);
}
+
+ private void waitForConnectionIfNeeded() {
+ // Wait for the connection with a timeout.
+ final long endMillis = SystemClock.uptimeMillis() + WAIT_CONNECTION_TIMEOUT_MILLIS;
+ while (mConnectionState == CONNECTING && (SystemClock.uptimeMillis() < endMillis)) {
+ try {
+ mLock.wait(endMillis - SystemClock.uptimeMillis());
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
index db5b3133169a..f6fb24f38a7a 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationConnectionWrapper.java
@@ -58,6 +58,22 @@ class MagnificationConnectionWrapper {
mConnection.asBinder().linkToDeath(deathRecipient, 0);
}
+ boolean onFullscreenMagnificationActivationChanged(int displayId, boolean activated) {
+ if (mTrace.isA11yTracingEnabledForTypes(FLAGS_MAGNIFICATION_CONNECTION)) {
+ mTrace.logTrace(TAG + ".onFullscreenMagnificationActivationChanged",
+ FLAGS_MAGNIFICATION_CONNECTION);
+ }
+ try {
+ mConnection.onFullscreenMagnificationActivationChanged(displayId, activated);
+ } catch (RemoteException e) {
+ if (DBG) {
+ Slog.e(TAG, "Error calling onFullscreenMagnificationActivationChanged");
+ }
+ return false;
+ }
+ return true;
+ }
+
boolean enableWindowMagnification(int displayId, float scale, float centerX, float centerY,
float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY,
@Nullable MagnificationAnimationCallback callback) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
index 52e123a5e70c..0d5fd1435ca0 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationController.java
@@ -50,6 +50,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.wm.WindowManagerInternal;
+import com.android.window.flags.Flags;
import java.util.concurrent.Executor;
@@ -586,6 +587,11 @@ public class MagnificationController implements MagnificationConnectionManager.C
@Override
public void onFullScreenMagnificationActivationState(int displayId, boolean activated) {
+ if (Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ getMagnificationConnectionManager()
+ .onFullscreenMagnificationActivationChanged(displayId, activated);
+ }
+
if (activated) {
synchronized (mLock) {
mFullScreenModeEnabledTimeArray.put(displayId, SystemClock.uptimeMillis());
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 082776ad6085..fb4976d3cef2 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import static com.android.server.display.BrightnessMappingStrategy.INVALID_LUX;
import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessModeToString;
import android.annotation.IntDef;
@@ -202,7 +203,7 @@ public class AutomaticBrightnessController {
private float mScreenBrighteningThreshold;
private float mScreenDarkeningThreshold;
// The most recent light sample.
- private float mLastObservedLux;
+ private float mLastObservedLux = INVALID_LUX;
// The time of the most light recent sample.
private long mLastObservedLuxTime;
@@ -403,8 +404,8 @@ public class AutomaticBrightnessController {
brightnessEvent.setFlags(brightnessEvent.getFlags()
| (!mAmbientLuxValid ? BrightnessEvent.FLAG_INVALID_LUX : 0)
| (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE
- ? BrightnessEvent.FLAG_DOZE_SCALE : 0)
- | (isInIdleMode() ? BrightnessEvent.FLAG_IDLE_CURVE : 0));
+ ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
+ brightnessEvent.setAutoBrightnessMode(getMode());
}
if (!mAmbientLuxValid) {
@@ -420,6 +421,35 @@ public class AutomaticBrightnessController {
return mRawScreenAutoBrightness;
}
+ /**
+ * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
+ * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
+ * the initial brightness in doze mode.
+ */
+ public float getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ BrightnessEvent brightnessEvent) {
+ if (mLastObservedLux == INVALID_LUX) {
+ return PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+
+ float brightness = mCurrentBrightnessMapper.getBrightness(mLastObservedLux,
+ mForegroundAppPackageName, mForegroundAppCategory);
+ if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
+ brightness *= mDozeScaleFactor;
+ }
+
+ if (brightnessEvent != null) {
+ brightnessEvent.setLux(mLastObservedLux);
+ brightnessEvent.setRecommendedBrightness(brightness);
+ brightnessEvent.setFlags(brightnessEvent.getFlags()
+ | (mLastObservedLux == INVALID_LUX ? BrightnessEvent.FLAG_INVALID_LUX : 0)
+ | (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE
+ ? BrightnessEvent.FLAG_DOZE_SCALE : 0));
+ brightnessEvent.setAutoBrightnessMode(getMode());
+ }
+ return brightness;
+ }
+
public boolean hasValidAmbientLux() {
return mAmbientLuxValid;
}
@@ -539,7 +569,7 @@ public class AutomaticBrightnessController {
}
private boolean setScreenBrightnessByUser(float lux, float brightness) {
- if (lux == BrightnessMappingStrategy.INVALID_LUX || Float.isNaN(brightness)) {
+ if (lux == INVALID_LUX || Float.isNaN(brightness)) {
return false;
}
mCurrentBrightnessMapper.addUserDataPoint(lux, brightness);
@@ -564,6 +594,15 @@ public class AutomaticBrightnessController {
return false;
}
+ /**
+ * @return The auto-brightness mode of the current mapping strategy. Different modes use
+ * different brightness curves.
+ */
+ @AutomaticBrightnessController.AutomaticBrightnessMode
+ public int getMode() {
+ return mCurrentBrightnessMapper.getMode();
+ }
+
public boolean isInIdleMode() {
return mCurrentBrightnessMapper.getMode() == AUTO_BRIGHTNESS_MODE_IDLE;
}
@@ -1236,12 +1275,12 @@ public class AutomaticBrightnessController {
// light.
// The anchor determines what were the light levels when the user has set their preference,
// and we use a relative threshold to determine when to revert to the OEM curve.
- private float mAnchor = BrightnessMappingStrategy.INVALID_LUX;
+ private float mAnchor = INVALID_LUX;
private float mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
private boolean mIsValid = false;
private void reset() {
- mAnchor = BrightnessMappingStrategy.INVALID_LUX;
+ mAnchor = INVALID_LUX;
mBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
mIsValid = false;
}
@@ -1265,7 +1304,7 @@ public class AutomaticBrightnessController {
private boolean maybeReset(float currentLux) {
// If the short term model was invalidated and the change is drastic enough, reset it.
// Otherwise, we revalidate it.
- if (!mIsValid && mAnchor != BrightnessMappingStrategy.INVALID_LUX) {
+ if (!mIsValid && mAnchor != INVALID_LUX) {
if (mCurrentBrightnessMapper.shouldResetShortTermModel(currentLux, mAnchor)) {
resetShortTermModel();
} else {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 3965d55b0c28..dbe85ea0fa04 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -16,6 +16,8 @@
package com.android.server.display;
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DOZE;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
@@ -37,7 +39,6 @@ import android.hardware.display.AmbientBrightnessDayStats;
import android.hardware.display.BrightnessChangeEvent;
import android.hardware.display.BrightnessConfiguration;
import android.hardware.display.BrightnessInfo;
-import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayOffloadSession;
import android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
@@ -1378,7 +1379,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// Switch to doze auto-brightness mode if needed
if (mFlags.areAutoBrightnessModesEnabled() && mAutomaticBrightnessController != null
&& !mAutomaticBrightnessController.isInIdleMode()) {
- setAutomaticScreenBrightnessMode(Display.isDozeState(state)
+ mAutomaticBrightnessController.switchMode(mPowerRequest.policy == POLICY_DOZE
? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT);
}
@@ -1466,6 +1467,22 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false);
}
+ // If there's an offload session and auto-brightness is on, we need to set the initial doze
+ // brightness using the doze auto-brightness curve before the offload session starts
+ // controlling the brightness.
+ if (Float.isNaN(brightnessState) && mFlags.areAutoBrightnessModesEnabled()
+ && mFlags.isDisplayOffloadEnabled()
+ && mPowerRequest.policy == POLICY_DOZE
+ && mDisplayOffloadSession != null
+ && mAutomaticBrightnessStrategy.shouldUseAutoBrightness()) {
+ rawBrightnessState = mAutomaticBrightnessController
+ .getAutomaticScreenBrightnessBasedOnLastObservedLux(mTempBrightnessEvent);
+ if (BrightnessUtils.isValidBrightnessValue(rawBrightnessState)) {
+ brightnessState = clampScreenBrightness(rawBrightnessState);
+ mBrightnessReasonTemp.setReason(BrightnessReason.REASON_DOZE_INITIAL);
+ }
+ }
+
// Use default brightness when dozing unless overridden.
if ((Float.isNaN(brightnessState))
&& Display.isDozeState(state)) {
@@ -1618,7 +1635,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
// if doze or suspend state is requested, we want to finish brightnes animation fast
// to allow state animation to start
- if (mPowerRequest.policy == DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE
+ if (mPowerRequest.policy == POLICY_DOZE
&& (mPowerRequest.dozeScreenState == Display.STATE_UNKNOWN // dozing
|| mPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND
|| mPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND)) {
@@ -1706,6 +1723,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mTempBrightnessEvent.setTime(System.currentTimeMillis());
mTempBrightnessEvent.setBrightness(brightnessState);
mTempBrightnessEvent.setPhysicalDisplayId(mUniqueDisplayId);
+ mTempBrightnessEvent.setDisplayState(state);
mTempBrightnessEvent.setReason(mBrightnessReason);
mTempBrightnessEvent.setHbmMax(mBrightnessRangeController.getCurrentBrightnessMax());
mTempBrightnessEvent.setHbmMode(mBrightnessRangeController.getHighBrightnessMode());
@@ -2879,7 +2897,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
(flags & BrightnessEvent.FLAG_INVALID_LUX) > 0,
(flags & BrightnessEvent.FLAG_DOZE_SCALE) > 0,
(flags & BrightnessEvent.FLAG_USER_SET) > 0,
- (flags & BrightnessEvent.FLAG_IDLE_CURVE) > 0,
+ event.getAutoBrightnessMode() == AUTO_BRIGHTNESS_MODE_IDLE,
(flags & BrightnessEvent.FLAG_LOW_POWER_MODE) > 0);
}
}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
index d4d1bae78a33..5423b74711a2 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessEvent.java
@@ -16,11 +16,16 @@
package com.android.server.display.brightness;
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
+import static com.android.server.display.config.DisplayBrightnessMappingConfig.autoBrightnessModeToString;
+
import android.hardware.display.BrightnessInfo;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.AutomaticBrightnessController;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -33,7 +38,6 @@ public final class BrightnessEvent {
public static final int FLAG_INVALID_LUX = 0x2;
public static final int FLAG_DOZE_SCALE = 0x4;
public static final int FLAG_USER_SET = 0x8;
- public static final int FLAG_IDLE_CURVE = 0x10;
public static final int FLAG_LOW_POWER_MODE = 0x20;
private static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
@@ -41,6 +45,7 @@ public final class BrightnessEvent {
private BrightnessReason mReason = new BrightnessReason();
private int mDisplayId;
private String mPhysicalDisplayId;
+ private int mDisplayState;
private long mTime;
private float mLux;
private float mPreThresholdLux;
@@ -58,6 +63,8 @@ public final class BrightnessEvent {
private int mAdjustmentFlags;
private boolean mAutomaticBrightnessEnabled;
private String mDisplayBrightnessStrategyName;
+ @AutomaticBrightnessController.AutomaticBrightnessMode
+ private int mAutoBrightnessMode;
public BrightnessEvent(BrightnessEvent that) {
copyFrom(that);
@@ -77,6 +84,7 @@ public final class BrightnessEvent {
mReason.set(that.getReason());
mDisplayId = that.getDisplayId();
mPhysicalDisplayId = that.getPhysicalDisplayId();
+ mDisplayState = that.mDisplayState;
mTime = that.getTime();
// Lux values
mLux = that.getLux();
@@ -98,6 +106,7 @@ public final class BrightnessEvent {
// Auto-brightness setting
mAutomaticBrightnessEnabled = that.isAutomaticBrightnessEnabled();
mDisplayBrightnessStrategyName = that.getDisplayBrightnessStrategyName();
+ mAutoBrightnessMode = that.mAutoBrightnessMode;
}
/**
@@ -107,6 +116,7 @@ public final class BrightnessEvent {
mReason = new BrightnessReason();
mTime = SystemClock.uptimeMillis();
mPhysicalDisplayId = "";
+ mDisplayState = Display.STATE_UNKNOWN;
// Lux values
mLux = 0;
mPreThresholdLux = 0;
@@ -127,6 +137,7 @@ public final class BrightnessEvent {
// Auto-brightness setting
mAutomaticBrightnessEnabled = true;
mDisplayBrightnessStrategyName = "";
+ mAutoBrightnessMode = AUTO_BRIGHTNESS_MODE_DEFAULT;
}
/**
@@ -143,6 +154,7 @@ public final class BrightnessEvent {
return mReason.equals(that.mReason)
&& mDisplayId == that.mDisplayId
&& mPhysicalDisplayId.equals(that.mPhysicalDisplayId)
+ && mDisplayState == that.mDisplayState
&& Float.floatToRawIntBits(mLux) == Float.floatToRawIntBits(that.mLux)
&& Float.floatToRawIntBits(mPreThresholdLux)
== Float.floatToRawIntBits(that.mPreThresholdLux)
@@ -163,7 +175,8 @@ public final class BrightnessEvent {
&& mFlags == that.mFlags
&& mAdjustmentFlags == that.mAdjustmentFlags
&& mAutomaticBrightnessEnabled == that.mAutomaticBrightnessEnabled
- && mDisplayBrightnessStrategyName.equals(that.mDisplayBrightnessStrategyName);
+ && mDisplayBrightnessStrategyName.equals(that.mDisplayBrightnessStrategyName)
+ && mAutoBrightnessMode == that.mAutoBrightnessMode;
}
/**
@@ -177,6 +190,7 @@ public final class BrightnessEvent {
+ "BrightnessEvent: "
+ "disp=" + mDisplayId
+ ", physDisp=" + mPhysicalDisplayId
+ + ", displayState=" + Display.stateToString(mDisplayState)
+ ", brt=" + mBrightness + ((mFlags & FLAG_USER_SET) != 0 ? "(user_set)" : "")
+ ", initBrt=" + mInitialBrightness
+ ", rcmdBrt=" + mRecommendedBrightness
@@ -192,7 +206,8 @@ public final class BrightnessEvent {
+ ", flags=" + flagsToString()
+ ", reason=" + mReason.toString(mAdjustmentFlags)
+ ", autoBrightness=" + mAutomaticBrightnessEnabled
- + ", strategy=" + mDisplayBrightnessStrategyName;
+ + ", strategy=" + mDisplayBrightnessStrategyName
+ + ", autoBrightnessMode=" + autoBrightnessModeToString(mAutoBrightnessMode);
}
@Override
@@ -232,6 +247,10 @@ public final class BrightnessEvent {
this.mPhysicalDisplayId = mPhysicalDisplayId;
}
+ public void setDisplayState(int state) {
+ mDisplayState = state;
+ }
+
public float getLux() {
return mLux;
}
@@ -374,6 +393,16 @@ public final class BrightnessEvent {
this.mAutomaticBrightnessEnabled = mAutomaticBrightnessEnabled;
}
+ @AutomaticBrightnessController.AutomaticBrightnessMode
+ public int getAutoBrightnessMode() {
+ return mAutoBrightnessMode;
+ }
+
+ public void setAutoBrightnessMode(
+ @AutomaticBrightnessController.AutomaticBrightnessMode int mode) {
+ mAutoBrightnessMode = mode;
+ }
+
/**
* A utility to stringify flags from a BrightnessEvent
* @return Stringified flags from BrightnessEvent
@@ -384,7 +413,6 @@ public final class BrightnessEvent {
+ ((mFlags & FLAG_RBC) != 0 ? "rbc " : "")
+ ((mFlags & FLAG_INVALID_LUX) != 0 ? "invalid_lux " : "")
+ ((mFlags & FLAG_DOZE_SCALE) != 0 ? "doze_scale " : "")
- + ((mFlags & FLAG_IDLE_CURVE) != 0 ? "idle_curve " : "")
+ ((mFlags & FLAG_LOW_POWER_MODE) != 0 ? "low_power_mode " : "");
}
}
diff --git a/services/core/java/com/android/server/display/brightness/BrightnessReason.java b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
index bc443a8167ab..fc95d15ae6f4 100644
--- a/services/core/java/com/android/server/display/brightness/BrightnessReason.java
+++ b/services/core/java/com/android/server/display/brightness/BrightnessReason.java
@@ -40,7 +40,8 @@ public final class BrightnessReason {
public static final int REASON_SCREEN_OFF_BRIGHTNESS_SENSOR = 9;
public static final int REASON_FOLLOWER = 10;
public static final int REASON_OFFLOAD = 11;
- public static final int REASON_MAX = REASON_OFFLOAD;
+ public static final int REASON_DOZE_INITIAL = 12;
+ public static final int REASON_MAX = REASON_DOZE_INITIAL;
public static final int MODIFIER_DIMMED = 0x1;
public static final int MODIFIER_LOW_POWER = 0x2;
@@ -207,6 +208,8 @@ public final class BrightnessReason {
return "follower";
case REASON_OFFLOAD:
return "offload";
+ case REASON_DOZE_INITIAL:
+ return "doze_initial";
default:
return Integer.toString(reason);
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index 3e6e09da9753..8eaecef6e562 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -267,6 +267,23 @@ public class AutomaticBrightnessStrategy {
}
/**
+ * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
+ * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
+ * the initial brightness in doze mode.
+ * @param brightnessEvent Event object to populate with details about why the specific
+ * brightness was chosen.
+ */
+ public float getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ BrightnessEvent brightnessEvent) {
+ float brightness = (mAutomaticBrightnessController != null)
+ ? mAutomaticBrightnessController
+ .getAutomaticScreenBrightnessBasedOnLastObservedLux(brightnessEvent)
+ : PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ adjustAutomaticBrightnessStateIfValid(brightness);
+ return brightness;
+ }
+
+ /**
* Gets the auto-brightness adjustment flag change reason
*/
public int getAutoBrightnessAdjustmentReasonsFlags() {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 796d8d73fc51..582058d21256 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -729,7 +729,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Map of uid -> UidStateCallbackInfo objects holding the data received from
* {@link IUidObserver#onUidStateChanged(int, int, long, int)} callbacks. In order to avoid
* creating a new object for every callback received, we hold onto the object created for each
- * uid and reuse it.
+ * uid and reuse it until the uid stays alive.
*
* Note that the lock used for accessing this object should not be used for anything else and we
* should not be acquiring new locks or doing any heavy work while this lock is held since this
@@ -802,6 +802,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
Clock.systemUTC());
}
+ @VisibleForTesting
+ UidState getUidStateForTest(int uid) {
+ synchronized (mUidRulesFirstLock) {
+ return mUidState.get(uid);
+ }
+ }
+
static class Dependencies {
final Context mContext;
final NetworkStatsManager mNetworkStatsManager;
@@ -1257,6 +1264,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
@Override public void onUidGone(int uid, boolean disabled) {
+ synchronized (mUidStateCallbackInfos) {
+ mUidStateCallbackInfos.remove(uid);
+ }
+ // TODO: b/327058756 - Remove any pending UID_MSG_STATE_CHANGED on the handler.
mUidEventHandler.obtainMessage(UID_MSG_GONE, uid, 0).sendToTarget();
}
};
@@ -5918,7 +5929,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
void handleUidGone(int uid) {
Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "onUidGone");
try {
- boolean updated;
+ final boolean updated;
synchronized (mUidRulesFirstLock) {
updated = removeUidStateUL(uid);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index dadafd7f9438..3c256b1caa7d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -721,7 +721,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
- @GuardedBy("mAvailableFeatures")
private final ArrayMap<String, FeatureInfo> mAvailableFeatures;
@Watched
@@ -2983,13 +2982,11 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public boolean hasSystemFeature(String name, int version) {
// allow instant applications
- synchronized (mAvailableFeatures) {
- final FeatureInfo feat = mAvailableFeatures.get(name);
- if (feat == null) {
- return false;
- } else {
- return feat.version >= version;
- }
+ final FeatureInfo feat = mAvailableFeatures.get(name);
+ if (feat == null) {
+ return false;
+ } else {
+ return feat.version >= version;
}
}
@@ -5335,10 +5332,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
// allow instant applications
ArrayList<FeatureInfo> res;
- synchronized (mAvailableFeatures) {
- res = new ArrayList<>(mAvailableFeatures.size() + 1);
- res.addAll(mAvailableFeatures.values());
- }
+ res = new ArrayList<>(mAvailableFeatures.size() + 1);
+ res.addAll(mAvailableFeatures.values());
final FeatureInfo fi = new FeatureInfo();
fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
FeatureInfo.GL_ES_VERSION_UNDEFINED);
@@ -6542,9 +6537,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
mOverlayConfigSignaturePackage,
mRecentsPackage);
final ArrayMap<String, FeatureInfo> availableFeatures;
- synchronized (mAvailableFeatures) {
- availableFeatures = new ArrayMap<>(mAvailableFeatures);
- }
+ availableFeatures = new ArrayMap<>(mAvailableFeatures);
final ArraySet<String> protectedBroadcasts;
synchronized (mProtectedBroadcasts) {
protectedBroadcasts = new ArraySet<>(mProtectedBroadcasts);
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 1c70af0a56ea..b18503d7d5cb 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -596,7 +596,7 @@ public class PackageInfoUtils {
ai.requiredDisplayCategory = a.getRequiredDisplayCategory();
ai.requireContentUriPermissionFromCaller = a.getRequireContentUriPermissionFromCaller();
ai.setKnownActivityEmbeddingCerts(a.getKnownActivityEmbeddingCerts());
- assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, userId);
+ assignFieldsComponentInfoParsedMainComponent(ai, a, pkgSetting, state, userId);
return ai;
}
@@ -659,7 +659,7 @@ public class PackageInfoUtils {
// Backwards compatibility, coerce to null if empty
si.metaData = metaData.isEmpty() ? null : metaData;
}
- assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, userId);
+ assignFieldsComponentInfoParsedMainComponent(si, s, pkgSetting, state, userId);
return si;
}
@@ -710,7 +710,7 @@ public class PackageInfoUtils {
pi.metaData = metaData.isEmpty() ? null : metaData;
}
pi.applicationInfo = applicationInfo;
- assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, userId);
+ assignFieldsComponentInfoParsedMainComponent(pi, p, pkgSetting, state, userId);
return pi;
}
@@ -903,8 +903,13 @@ public class PackageInfoUtils {
private static void assignFieldsComponentInfoParsedMainComponent(
@NonNull ComponentInfo info, @NonNull ParsedMainComponent component,
- @NonNull PackageStateInternal pkgSetting, @UserIdInt int userId) {
+ @NonNull PackageStateInternal pkgSetting, @NonNull PackageUserStateInternal state,
+ @UserIdInt int userId) {
assignFieldsComponentInfoParsedMainComponent(info, component);
+ // overwrite the enabled state with the current user state
+ info.enabled = PackageUserStateUtils.isEnabled(state, info.applicationInfo.enabled,
+ info.enabled, info.name, /* flags */ 0);
+
Pair<CharSequence, Integer> labelAndIcon =
ParsedComponentStateUtils.getNonLocalizedLabelAndIcon(component, pkgSetting,
userId);
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 44a0547a6828..d08e272d76dd 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -304,9 +304,9 @@ final class AccessibilityController {
Surface forceShowMagnifierSurface(int displayId) {
final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
if (displayMagnifier != null) {
- displayMagnifier.mMagnifedViewport.mWindow.setAlpha(DisplayMagnifier.MagnifiedViewport
+ displayMagnifier.mMagnifiedViewport.mWindow.setAlpha(DisplayMagnifier.MagnifiedViewport
.ViewportWindow.AnimationController.MAX_ALPHA);
- return displayMagnifier.mMagnifedViewport.mWindow.mSurface;
+ return displayMagnifier.mMagnifiedViewport.mWindow.mSurface;
}
return null;
}
@@ -463,6 +463,10 @@ final class AccessibilityController {
}
void drawMagnifiedRegionBorderIfNeeded(int displayId) {
+ if (Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ return;
+ }
+
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(
TAG + ".drawMagnifiedRegionBorderIfNeeded",
@@ -614,7 +618,7 @@ final class AccessibilityController {
private final Context mDisplayContext;
private final WindowManagerService mService;
- private final MagnifiedViewport mMagnifedViewport;
+ private final MagnifiedViewport mMagnifiedViewport;
private final Handler mHandler;
private final DisplayContent mDisplayContent;
private final Display mDisplay;
@@ -649,7 +653,8 @@ final class AccessibilityController {
mDisplayContent = displayContent;
mDisplay = display;
mHandler = new MyHandler(mService.mH.getLooper());
- mMagnifedViewport = new MagnifiedViewport();
+ mMagnifiedViewport = Flags.magnificationAlwaysDrawFullscreenBorder()
+ ? null : new MagnifiedViewport();
mAccessibilityTracing =
AccessibilityController.getAccessibilityControllerInternal(mService);
mLongAnimationDuration = mDisplayContext.getResources().getInteger(
@@ -692,7 +697,9 @@ final class AccessibilityController {
mMagnificationSpec.clear();
}
- mMagnifedViewport.setShowMagnifiedBorderIfNeeded();
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.setShowMagnifiedBorderIfNeeded();
+ }
}
void setFullscreenMagnificationActivated(boolean activated) {
@@ -701,8 +708,10 @@ final class AccessibilityController {
FLAGS_MAGNIFICATION_CALLBACK, "activated=" + activated);
}
mIsFullscreenMagnificationActivated = activated;
- mMagnifedViewport.setMagnifiedRegionBorderShown(activated, true);
- mMagnifedViewport.showMagnificationBoundsIfNeeded();
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.setMagnifiedRegionBorderShown(activated, true);
+ mMagnifiedViewport.showMagnificationBoundsIfNeeded();
+ }
}
boolean isFullscreenMagnificationActivated() {
@@ -737,7 +746,9 @@ final class AccessibilityController {
}
recomputeBounds();
- mMagnifedViewport.onDisplaySizeChanged();
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.onDisplaySizeChanged();
+ }
mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED);
}
@@ -901,7 +912,10 @@ final class AccessibilityController {
if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
mAccessibilityTracing.logTrace(LOG_TAG + ".destroy", FLAGS_MAGNIFICATION_CALLBACK);
}
- mMagnifedViewport.destroyWindow();
+
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.destroyWindow();
+ }
}
void drawMagnifiedRegionBorderIfNeeded() {
@@ -909,7 +923,10 @@ final class AccessibilityController {
mAccessibilityTracing.logTrace(LOG_TAG + ".drawMagnifiedRegionBorderIfNeeded",
FLAGS_MAGNIFICATION_CALLBACK);
}
- mMagnifedViewport.drawWindowIfNeeded();
+
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.drawWindowIfNeeded();
+ }
}
void recomputeBounds() {
@@ -1006,14 +1023,16 @@ final class AccessibilityController {
}
visibleWindows.clear();
- mMagnifedViewport.intersectWithDrawBorderInset(screenWidth, screenHeight);
-
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.intersectWithDrawBorderInset(screenWidth, screenHeight);
+ }
final boolean magnifiedChanged =
!mOldMagnificationRegion.equals(mMagnificationRegion);
if (magnifiedChanged) {
- mMagnifedViewport.updateBorderDrawingStatus(screenWidth, screenHeight);
-
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.updateBorderDrawingStatus(screenWidth, screenHeight);
+ }
mOldMagnificationRegion.set(mMagnificationRegion);
final SomeArgs args = SomeArgs.obtain();
args.arg1 = Region.obtain(mMagnificationRegion);
@@ -1070,7 +1089,9 @@ final class AccessibilityController {
}
void dump(PrintWriter pw, String prefix) {
- mMagnifedViewport.dump(pw, prefix);
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.dump(pw, prefix);
+ }
}
private final class MagnifiedViewport {
@@ -1079,7 +1100,7 @@ final class AccessibilityController {
private final int mHalfBorderWidth;
private final int mDrawBorderInset;
- private final ViewportWindow mWindow;
+ @Nullable private final ViewportWindow mWindow;
private boolean mFullRedrawNeeded;
@@ -1138,9 +1159,9 @@ final class AccessibilityController {
void onDisplaySizeChanged() {
// If fullscreen magnification is activated, hide the border immediately so
// the user does not see strange artifacts during display size changed caused by
- // rotation or folding/unfolding the device. In the rotation case, the screenshot
- // used for rotation already has the border. After the rotation is complete
- // we will show the border.
+ // rotation or folding/unfolding the device. In the rotation case, the
+ // screenshot used for rotation already has the border. After the rotation is
+ // completed we will show the border.
if (isFullscreenMagnificationActivated()) {
setMagnifiedRegionBorderShown(false, false);
final long delay = (long) (mLongAnimationDuration
@@ -1173,6 +1194,8 @@ final class AccessibilityController {
mWindow.dump(pw, prefix);
}
+ // TODO(291891390): Remove this class when we clean up the flag
+ // magnificationAlwaysDrawFullscreenBorder
private final class ViewportWindow implements Runnable {
private static final String SURFACE_TITLE = "Magnification Overlay";
@@ -1467,6 +1490,9 @@ final class AccessibilityController {
public static final int MESSAGE_NOTIFY_MAGNIFICATION_REGION_CHANGED = 1;
public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
public static final int MESSAGE_NOTIFY_DISPLAY_SIZE_CHANGED = 4;
+
+ // TODO(291891390): Remove this field when we clean up the flag
+ // magnificationAlwaysDrawFullscreenBorder
public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
public static final int MESSAGE_NOTIFY_IME_WINDOW_VISIBILITY_CHANGED = 6;
@@ -1495,7 +1521,9 @@ final class AccessibilityController {
case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : {
synchronized (mService.mGlobalLock) {
if (isFullscreenMagnificationActivated()) {
- mMagnifedViewport.setMagnifiedRegionBorderShown(true, true);
+ if (!Flags.magnificationAlwaysDrawFullscreenBorder()) {
+ mMagnifiedViewport.setMagnifiedRegionBorderShown(true, true);
+ }
mService.scheduleAnimationLocked();
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 066d26222fbd..c137c54949e9 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1548,6 +1548,8 @@ class ActivityStarter {
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, options, inTask, inTaskFragment, balVerdict,
intentGrants, realCallingUid);
+ } catch (Exception ex) {
+ Slog.e(TAG, "Exception on startActivityInner", ex);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index e0faddf171ca..aefa777a1db7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1893,7 +1893,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Check that we aren't reparenting to the same root task that the task is already in
if (prevRootTask != null && prevRootTask.mTaskId == rootTaskId) {
Slog.w(TAG, "Can not reparent to same root task, task=" + task
- + " already in rootTaskId=" + rootTaskId);
+ + " already in rootTaskId=" + rootTaskId + " by " + Debug.getCallers(8));
return prevRootTask;
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 5cf9acdbc0d6..7f3df958664c 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -47,6 +47,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLO
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
@@ -1533,9 +1534,19 @@ public class DisplayPolicy {
// Check the windows that overlap with system bars to determine system bars' appearance.
if ((appWindow && attached == null && attrs.isFullscreen())
|| attrs.type == TYPE_VOICE_INTERACTION) {
- // Record the top-fullscreen-app-window which will be used to determine system UI
+
+ // If this is the exiting starting window, don't let it control the system bars.
+ // The app window behind it should be the controlling window instead. Reason: when an
+ // activity starts another activity behind a starting window, the app window of the
+ // first activity will lose the window focus. And then mTopFullscreenOpaqueWindowState
+ // will control the system bars. The logic here is to let first app window keep
+ // controlling system bars until the second app window is ready.
+ final boolean exitingStartingWindow =
+ attrs.type == TYPE_APPLICATION_STARTING && win.mAnimatingExit;
+
+ // Record the top-fullscreen-app-window which will be used to determine the system UI
// controlling window.
- if (mTopFullscreenOpaqueWindowState == null) {
+ if (mTopFullscreenOpaqueWindowState == null && !exitingStartingWindow) {
mTopFullscreenOpaqueWindowState = win;
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 418b78cd696b..9c9aeeaadb71 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -16,6 +16,7 @@
package com.android.server.display;
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_DEFAULT;
import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
@@ -1016,4 +1017,34 @@ public class AutomaticBrightnessControllerTest {
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 500));
assertEquals(500, mController.getAmbientLux(), EPSILON);
}
+
+ @Test
+ public void testBrightnessBasedOnLastObservedLux() throws Exception {
+ ArgumentCaptor<SensorEventListener> listenerCaptor =
+ ArgumentCaptor.forClass(SensorEventListener.class);
+ verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor),
+ eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
+ SensorEventListener listener = listenerCaptor.getValue();
+
+ // Set up system to return 0.3f as a brightness value
+ float lux = 100.0f;
+ // Brightness as float (from 0.0f to 1.0f)
+ float normalizedBrightness = 0.3f;
+ when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux)).thenReturn(lux);
+ when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux)).thenReturn(lux);
+ when(mBrightnessMappingStrategy.getBrightness(eq(lux), eq(null), anyInt()))
+ .thenReturn(normalizedBrightness);
+ when(mBrightnessThrottler.getBrightnessCap()).thenReturn(BRIGHTNESS_MAX_FLOAT);
+ when(mBrightnessThrottler.isThrottled()).thenReturn(true);
+
+ // Send a new sensor value, disable the sensor and verify
+ listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, (int) lux));
+ mController.configure(AUTO_BRIGHTNESS_DISABLED, /* configuration= */ null,
+ /* brightness= */ 0, /* userChangedBrightness= */ false, /* adjustment= */ 0,
+ /* userChanged= */ false, DisplayPowerRequest.POLICY_BRIGHT,
+ /* shouldResetShortTermModel= */ true);
+ assertEquals(normalizedBrightness,
+ mController.getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ /* brightnessEvent= */ null), EPSILON);
+ }
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index 807774f90655..acddc9d22953 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -1665,6 +1665,35 @@ public final class DisplayPowerControllerTest {
/* luxTimestamps= */ any());
}
+ @Test
+ public void testInitialDozeBrightness() {
+ when(mDisplayManagerFlagsMock.areAutoBrightnessModesEnabled()).thenReturn(true);
+ when(mDisplayManagerFlagsMock.isDisplayOffloadEnabled()).thenReturn(true);
+ mHolder.dpc.setDisplayOffloadSession(mDisplayOffloadSession);
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ mContext.getOrCreateTestableResources().addOverride(
+ com.android.internal.R.bool.config_allowAutoBrightnessWhileDozing, false);
+ float brightness = 0.277f;
+ when(mHolder.displayPowerState.getColorFadeLevel()).thenReturn(1.0f);
+ when(mHolder.automaticBrightnessController
+ .getAutomaticScreenBrightnessBasedOnLastObservedLux(any(BrightnessEvent.class)))
+ .thenReturn(brightness);
+ when(mHolder.hbmController.getCurrentBrightnessMax())
+ .thenReturn(PowerManager.BRIGHTNESS_MAX);
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_DOZE);
+
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ dpr.policy = DisplayPowerRequest.POLICY_DOZE;
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(mHolder.animator).animateTo(eq(brightness),
+ /* linearSecondTarget= */ anyFloat(), /* rate= */ anyFloat(),
+ /* ignoreAnimationLimits= */ anyBoolean());
+ }
+
/**
* Creates a mock and registers it to {@link LocalServices}.
*/
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
index c0c63c69add8..060f99b4317a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/BrightnessEventTest.java
@@ -16,9 +16,12 @@
package com.android.server.display.brightness;
+import static com.android.server.display.AutomaticBrightnessController.AUTO_BRIGHTNESS_MODE_IDLE;
+
import static org.junit.Assert.assertEquals;
import android.hardware.display.BrightnessInfo;
+import android.view.Display;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -39,6 +42,7 @@ public final class BrightnessEventTest {
mBrightnessEvent.setReason(
getReason(BrightnessReason.REASON_DOZE, BrightnessReason.MODIFIER_LOW_POWER));
mBrightnessEvent.setPhysicalDisplayId("test");
+ mBrightnessEvent.setDisplayState(Display.STATE_ON);
mBrightnessEvent.setLux(100.0f);
mBrightnessEvent.setPreThresholdLux(150.0f);
mBrightnessEvent.setTime(System.currentTimeMillis());
@@ -55,6 +59,7 @@ public final class BrightnessEventTest {
mBrightnessEvent.setAdjustmentFlags(0);
mBrightnessEvent.setAutomaticBrightnessEnabled(true);
mBrightnessEvent.setDisplayBrightnessStrategyName(DISPLAY_BRIGHTNESS_STRATEGY_NAME);
+ mBrightnessEvent.setAutoBrightnessMode(AUTO_BRIGHTNESS_MODE_IDLE);
}
@Test
@@ -69,20 +74,20 @@ public final class BrightnessEventTest {
public void testToStringWorksAsExpected() {
String actualString = mBrightnessEvent.toString(false);
String expectedString =
- "BrightnessEvent: disp=1, physDisp=test, brt=0.6, initBrt=25.0, rcmdBrt=0.6,"
- + " preBrt=NaN, lux=100.0, preLux=150.0, hbmMax=0.62, hbmMode=off, rbcStrength=-1,"
- + " thrmMax=0.65, powerFactor=0.2, wasShortTermModelActive=true, flags=,"
- + " reason=doze [ low_pwr ], autoBrightness=true, strategy="
- + DISPLAY_BRIGHTNESS_STRATEGY_NAME;
+ "BrightnessEvent: disp=1, physDisp=test, displayState=ON, brt=0.6, initBrt=25.0,"
+ + " rcmdBrt=0.6, preBrt=NaN, lux=100.0, preLux=150.0, hbmMax=0.62, hbmMode=off,"
+ + " rbcStrength=-1, thrmMax=0.65, powerFactor=0.2, wasShortTermModelActive=true,"
+ + " flags=, reason=doze [ low_pwr ], autoBrightness=true, strategy="
+ + DISPLAY_BRIGHTNESS_STRATEGY_NAME + ", autoBrightnessMode=idle";
assertEquals(expectedString, actualString);
}
@Test
public void testFlagsToString() {
mBrightnessEvent.reset();
- mBrightnessEvent.setFlags(mBrightnessEvent.getFlags() | BrightnessEvent.FLAG_IDLE_CURVE);
+ mBrightnessEvent.setFlags(mBrightnessEvent.getFlags() | BrightnessEvent.FLAG_RBC);
String actualString = mBrightnessEvent.flagsToString();
- String expectedString = "idle_curve ";
+ String expectedString = "rbc ";
assertEquals(expectedString, actualString);
}
@@ -90,10 +95,10 @@ public final class BrightnessEventTest {
public void testFlagsToString_multipleFlags() {
mBrightnessEvent.reset();
mBrightnessEvent.setFlags(mBrightnessEvent.getFlags()
- | BrightnessEvent.FLAG_IDLE_CURVE
+ | BrightnessEvent.FLAG_RBC
| BrightnessEvent.FLAG_LOW_POWER_MODE);
String actualString = mBrightnessEvent.flagsToString();
- String expectedString = "idle_curve low_power_mode ";
+ String expectedString = "rbc low_power_mode ";
assertEquals(expectedString, actualString);
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index 5408e1143330..886780655de2 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -359,11 +359,17 @@ public class AutomaticBrightnessStrategyTest {
AutomaticBrightnessController.class);
when(automaticBrightnessController.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
.thenReturn(automaticScreenBrightness);
+ when(automaticBrightnessController.getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ any(BrightnessEvent.class)))
+ .thenReturn(automaticScreenBrightness);
mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
automaticBrightnessController);
assertEquals(automaticScreenBrightness,
mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
new BrightnessEvent(DISPLAY_ID)), 0.0f);
+ assertEquals(automaticScreenBrightness,
+ mAutomaticBrightnessStrategy.getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ new BrightnessEvent(DISPLAY_ID)), 0.0f);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
index 009bfb7efca6..87fe6cf8f283 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionManagerTest.java
@@ -813,6 +813,18 @@ public class MagnificationConnectionManagerTest {
anyBoolean());
}
+ @Test
+ public void onFullscreenMagnificationActivationChanged_hasConnection_notifyActivatedState()
+ throws RemoteException {
+ mMagnificationConnectionManager.setConnection(mMockConnection.getConnection());
+
+ mMagnificationConnectionManager
+ .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
+
+ verify(mMockConnection.getConnection())
+ .onFullscreenMagnificationActivationChanged(eq(TEST_DISPLAY), eq(true));
+ }
+
private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
final int len = pointersLocation.length;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
index 07f3036410a0..2120b2e8e1f3 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationConnectionWrapperTest.java
@@ -131,6 +131,14 @@ public class MagnificationConnectionWrapperTest {
}
@Test
+ public void onFullscreenMagnificationActivationChanged() throws RemoteException {
+ mConnectionWrapper
+ .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
+ verify(mConnection)
+ .onFullscreenMagnificationActivationChanged(eq(TEST_DISPLAY), eq(true));
+ }
+
+ @Test
public void setMirrorWindowCallback() throws RemoteException {
mConnectionWrapper.setConnectionCallback(mCallback);
verify(mConnection).setConnectionCallback(mCallback);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
index a0c4b5e26c3f..1a51c45e2ef6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MagnificationControllerTest.java
@@ -53,6 +53,10 @@ import android.hardware.display.DisplayManagerInternal;
import android.os.Looper;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.test.mock.MockContentResolver;
import android.testing.DexmakerShareClassLoaderRule;
@@ -73,6 +77,7 @@ import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.accessibility.test.MessageCapturingHandler;
import com.android.server.wm.WindowManagerInternal;
+import com.android.window.flags.Flags;
import org.junit.After;
import org.junit.Before;
@@ -91,6 +96,9 @@ import org.mockito.stubbing.Answer;
@RunWith(AndroidJUnit4.class)
public class MagnificationControllerTest {
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
private static final int TEST_SERVICE_ID = 1;
private static final Region INITIAL_SCREEN_MAGNIFICATION_REGION =
@@ -1263,6 +1271,27 @@ public class MagnificationControllerTest {
verify(mService).changeMagnificationMode(TEST_DISPLAY, MODE_WINDOW);
}
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_MAGNIFICATION_ALWAYS_DRAW_FULLSCREEN_BORDER)
+ public void onFullscreenMagnificationActivationState_systemUiBorderFlagOn_notifyConnection() {
+ mMagnificationController.onFullScreenMagnificationActivationState(
+ TEST_DISPLAY, /* activated= */ true);
+
+ verify(mMagnificationConnectionManager)
+ .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
+ }
+
+ @Test
+ @RequiresFlagsDisabled(Flags.FLAG_MAGNIFICATION_ALWAYS_DRAW_FULLSCREEN_BORDER)
+ public void
+ onFullscreenMagnificationActivationState_systemUiBorderFlagOff_neverNotifyConnection() {
+ mMagnificationController.onFullScreenMagnificationActivationState(
+ TEST_DISPLAY, /* activated= */ true);
+
+ verify(mMagnificationConnectionManager, never())
+ .onFullscreenMagnificationActivationChanged(TEST_DISPLAY, /* activated= */ true);
+ }
+
private void setMagnificationEnabled(int mode) throws RemoteException {
setMagnificationEnabled(mode, MAGNIFIED_CENTER_X, MAGNIFIED_CENTER_Y);
}
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index a529382bfb26..b1e62f9c9a82 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -149,6 +149,7 @@ import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkStateSnapshot;
import android.net.NetworkTemplate;
import android.net.TelephonyNetworkSpecifier;
@@ -1620,6 +1621,12 @@ public class NetworkPolicyManagerServiceTest {
verify(mActivityManagerInternal).notifyNetworkPolicyRulesUpdated(UID_A, procStateSeq);
}
+ private void callAndWaitOnUidGone(int uid) throws Exception {
+ // The disabled argument is used only for ephemeral apps and does not matter here.
+ mUidObserver.onUidGone(uid, false /* disabled */);
+ waitForUidEventHandlerIdle();
+ }
+
private void callAndWaitOnUidStateChanged(int uid, int procState, long procStateSeq)
throws Exception {
callAndWaitOnUidStateChanged(uid, procState, procStateSeq,
@@ -2250,6 +2257,15 @@ public class NetworkPolicyManagerServiceTest {
assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
}
+ private boolean isUidState(int uid, int procState, int procStateSeq, int capability) {
+ final NetworkPolicyManager.UidState uidState = mService.getUidStateForTest(uid);
+ if (uidState == null) {
+ return false;
+ }
+ return uidState.uid == uid && uidState.procStateSeq == procStateSeq
+ && uidState.procState == procState && uidState.capability == capability;
+ }
+
@Ignore("Temporarily disabled until the feature is enabled")
@Test
@RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
@@ -2371,6 +2387,31 @@ public class NetworkPolicyManagerServiceTest {
}
@Test
+ public void testUidStateChangeAfterUidGone() throws Exception {
+ final int testProcStateSeq = 51;
+ final int testProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+
+ try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
+ // First callback for uid.
+ callOnUidStatechanged(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE);
+ assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
+ }
+ waitForUidEventHandlerIdle();
+ assertTrue(isUidState(UID_B, testProcState, testProcStateSeq, PROCESS_CAPABILITY_NONE));
+
+ callAndWaitOnUidGone(UID_B);
+ try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
+ // Even though the procState is the same, the uid had exited - so this should be
+ // processed as a fresh callback.
+ callOnUidStatechanged(UID_B, testProcState, testProcStateSeq + 1,
+ PROCESS_CAPABILITY_NONE);
+ assertTrue(mService.mUidEventHandler.hasMessages(UID_MSG_STATE_CHANGED));
+ }
+ waitForUidEventHandlerIdle();
+ assertTrue(isUidState(UID_B, testProcState, testProcStateSeq + 1, PROCESS_CAPABILITY_NONE));
+ }
+
+ @Test
public void testLowPowerStandbyAllowlist() throws Exception {
// Chain background is also enabled but these procstates are important enough to be exempt.
callAndWaitOnUidStateChanged(UID_A, PROCESS_STATE_TOP, 0);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index a0e64bf94393..12f46df451fe 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -82,7 +82,10 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.ArraySet;
import android.util.MergedConfiguration;
import android.view.ContentRecordingSession;
@@ -109,6 +112,7 @@ import com.android.internal.os.IResultReceiver;
import com.android.server.LocalServices;
import com.android.server.wm.SensitiveContentPackages.PackageInfo;
import com.android.server.wm.WindowManagerService.WindowContainerInfo;
+import com.android.window.flags.Flags;
import com.google.common.truth.Expect;
@@ -140,6 +144,9 @@ public class WindowManagerServiceTests extends WindowTestsBase {
@Rule
public Expect mExpect = Expect.create();
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@After
public void tearDown() {
mWm.mSensitiveContentPackages.clearBlockedApps();
@@ -1106,6 +1113,7 @@ public class WindowManagerServiceTests extends WindowTestsBase {
argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
}
+ @RequiresFlagsDisabled(Flags.FLAG_MAGNIFICATION_ALWAYS_DRAW_FULLSCREEN_BORDER)
@Test
public void testDrawMagnifiedViewport() {
final int displayId = mDisplayContent.mDisplayId;