Merge "Fix test failures when NICRefactor flag is enabled" into main
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 8ce3a8d..63b1429 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3350,7 +3350,7 @@
}
@FlaggedApi("android.companion.virtual.flags.virtual_camera") public interface VirtualCameraCallback {
- method public void onProcessCaptureRequest(int, long, @Nullable android.companion.virtual.camera.VirtualCameraMetadata);
+ method public default void onProcessCaptureRequest(int, long);
method public void onStreamClosed(int);
method public void onStreamConfigured(int, @NonNull android.view.Surface, @NonNull android.companion.virtual.camera.VirtualCameraStreamConfig);
}
@@ -3371,12 +3371,6 @@
method @NonNull public android.companion.virtual.camera.VirtualCameraConfig.Builder setVirtualCameraCallback(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.camera.VirtualCameraCallback);
}
- @FlaggedApi("android.companion.virtual.flags.virtual_camera") public final class VirtualCameraMetadata implements android.os.Parcelable {
- method public int describeContents();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.camera.VirtualCameraMetadata> CREATOR;
- }
-
@FlaggedApi("android.companion.virtual.flags.virtual_camera") public final class VirtualCameraStreamConfig implements android.os.Parcelable {
ctor public VirtualCameraStreamConfig(@IntRange(from=1) int, @IntRange(from=1) int, int);
method public int describeContents();
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index ea9bb39..37692d3 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -537,8 +537,8 @@
/**
* Returns whether the given user requires credential entry at this time. This is used to
- * intercept activity launches for locked work apps due to work challenge being triggered or
- * when the profile user is yet to be unlocked.
+ * intercept activity launches for apps corresponding to locked profiles due to separate
+ * challenge being triggered or when the profile user is yet to be unlocked.
*/
public abstract boolean shouldConfirmCredentials(@UserIdInt int userId);
diff --git a/core/java/android/companion/virtual/camera/IVirtualCameraCallback.aidl b/core/java/android/companion/virtual/camera/IVirtualCameraCallback.aidl
index fac44b5..44942d6 100644
--- a/core/java/android/companion/virtual/camera/IVirtualCameraCallback.aidl
+++ b/core/java/android/companion/virtual/camera/IVirtualCameraCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,11 @@
package android.companion.virtual.camera;
import android.companion.virtual.camera.VirtualCameraStreamConfig;
-import android.companion.virtual.camera.VirtualCameraMetadata;
import android.view.Surface;
/**
- * Interface for the virtual camera service and system server to talk back to the virtual camera owner.
+ * Interface for the virtual camera service and system server to talk back to the virtual camera
+ * owner.
*
* @hide
*/
@@ -40,8 +40,7 @@
in VirtualCameraStreamConfig streamConfig);
/**
- * The client application is requesting a camera frame for the given streamId with the provided
- * metadata.
+ * The client application is requesting a camera frame for the given streamId and frameId.
*
* <p>The virtual camera needs to write the frame data in the {@link Surface} corresponding to
* this stream that was provided during the {@link #onStreamConfigured(int, Surface,
@@ -52,16 +51,14 @@
* VirtualCameraStreamConfig)}
* @param frameId The frameId that is being requested. Each request will have a different
* frameId, that will be increasing for each call with a particular streamId.
- * @param metadata The metadata requested for the frame. The virtual camera should do its best
- * to honor the requested metadata.
*/
- oneway void onProcessCaptureRequest(
- int streamId, long frameId, in VirtualCameraMetadata metadata);
+ oneway void onProcessCaptureRequest(int streamId, long frameId);
/**
* The stream previously configured when {@link #onStreamConfigured(int, Surface,
* VirtualCameraStreamConfig)} was called is now being closed and associated resources can be
- * freed. The Surface was disposed on the client side and should not be used anymore by the virtual camera owner
+ * freed. The Surface was disposed on the client side and should not be used anymore by the
+ * virtual camera owner.
*
* @param streamId The id of the stream that was closed.
*/
diff --git a/core/java/android/companion/virtual/camera/VirtualCameraCallback.java b/core/java/android/companion/virtual/camera/VirtualCameraCallback.java
index a18ae03..5b658b8 100644
--- a/core/java/android/companion/virtual/camera/VirtualCameraCallback.java
+++ b/core/java/android/companion/virtual/camera/VirtualCameraCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.companion.virtual.flags.Flags;
import android.view.Surface;
@@ -50,8 +49,7 @@
@NonNull VirtualCameraStreamConfig streamConfig);
/**
- * The client application is requesting a camera frame for the given streamId with the provided
- * metadata.
+ * The client application is requesting a camera frame for the given streamId and frameId.
*
* <p>The virtual camera needs to write the frame data in the {@link Surface} corresponding to
* this stream that was provided during the {@link #onStreamConfigured(int, Surface,
@@ -62,12 +60,8 @@
* VirtualCameraStreamConfig)}
* @param frameId The frameId that is being requested. Each request will have a different
* frameId, that will be increasing for each call with a particular streamId.
- * @param metadata The metadata requested for the frame. The virtual camera should do its best
- * to honor the requested metadata but the consumer won't be informed about the metadata set
- * for a particular frame. If null, the requested frame can be anything the producer sends.
*/
- void onProcessCaptureRequest(
- int streamId, long frameId, @Nullable VirtualCameraMetadata metadata);
+ default void onProcessCaptureRequest(int streamId, long frameId) {}
/**
* The stream previously configured when {@link #onStreamConfigured(int, Surface,
diff --git a/core/java/android/companion/virtual/camera/VirtualCameraConfig.java b/core/java/android/companion/virtual/camera/VirtualCameraConfig.java
index f1eb240..a939251 100644
--- a/core/java/android/companion/virtual/camera/VirtualCameraConfig.java
+++ b/core/java/android/companion/virtual/camera/VirtualCameraConfig.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -224,9 +224,8 @@
}
@Override
- public void onProcessCaptureRequest(
- int streamId, long frameId, VirtualCameraMetadata metadata) {
- mExecutor.execute(() -> mCallback.onProcessCaptureRequest(streamId, frameId, metadata));
+ public void onProcessCaptureRequest(int streamId, long frameId) {
+ mExecutor.execute(() -> mCallback.onProcessCaptureRequest(streamId, frameId));
}
@Override
diff --git a/core/java/android/companion/virtual/camera/VirtualCameraMetadata.aidl b/core/java/android/companion/virtual/camera/VirtualCameraMetadata.aidl
deleted file mode 100644
index 6c1f0fc..0000000
--- a/core/java/android/companion/virtual/camera/VirtualCameraMetadata.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.companion.virtual.camera;
-
-/**
- * Data structure used to store {@link android.hardware.camera2.CameraMetadata} compatible with
- * VirtualCamera.
- * @hide
- */
-parcelable VirtualCameraMetadata;
diff --git a/core/java/android/companion/virtual/camera/VirtualCameraMetadata.java b/core/java/android/companion/virtual/camera/VirtualCameraMetadata.java
deleted file mode 100644
index 1ba36d0..0000000
--- a/core/java/android/companion/virtual/camera/VirtualCameraMetadata.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.companion.virtual.camera;
-
-import android.annotation.FlaggedApi;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.companion.virtual.flags.Flags;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Data structure used to store camera metadata compatible with VirtualCamera.
- *
- * @hide
- */
-@SystemApi
-@FlaggedApi(Flags.FLAG_VIRTUAL_CAMERA)
-public final class VirtualCameraMetadata implements Parcelable {
-
- /** @hide */
- public VirtualCameraMetadata(@NonNull Parcel in) {}
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {}
-
- @NonNull
- public static final Creator<VirtualCameraMetadata> CREATOR =
- new Creator<>() {
- @Override
- @NonNull
- public VirtualCameraMetadata createFromParcel(Parcel in) {
- return new VirtualCameraMetadata(in);
- }
-
- @Override
- @NonNull
- public VirtualCameraMetadata[] newArray(int size) {
- return new VirtualCameraMetadata[size];
- }
- };
-}
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index b04b7ba..60d5c14 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -115,3 +115,11 @@
description: "Feature flag to fix duplicated PackageManager flag values"
bug: "314815969"
}
+
+flag {
+ name: "provide_info_of_apk_in_apex"
+ namespace: "package_manager_service"
+ description: "Feature flag to provide the information of APK-in-APEX"
+ bug: "306329516"
+ is_fixed_read_only: true
+}
diff --git a/core/java/android/service/voice/VisualQueryDetector.java b/core/java/android/service/voice/VisualQueryDetector.java
index b7d9705..adc54f5 100644
--- a/core/java/android/service/voice/VisualQueryDetector.java
+++ b/core/java/android/service/voice/VisualQueryDetector.java
@@ -94,7 +94,9 @@
*/
public void updateState(@Nullable PersistableBundle options,
@Nullable SharedMemory sharedMemory) {
- mInitializationDelegate.updateState(options, sharedMemory);
+ synchronized (mInitializationDelegate.getLock()) {
+ mInitializationDelegate.updateState(options, sharedMemory);
+ }
}
@@ -116,18 +118,21 @@
if (DEBUG) {
Slog.i(TAG, "#startRecognition");
}
- // check if the detector is active with the initialization delegate
- mInitializationDelegate.startRecognition();
+ synchronized (mInitializationDelegate.getLock()) {
+ // check if the detector is active with the initialization delegate
+ mInitializationDelegate.startRecognition();
- try {
- mManagerService.startPerceiving(new BinderCallback(mExecutor, mCallback));
- } catch (SecurityException e) {
- Slog.e(TAG, "startRecognition failed: " + e);
- return false;
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ try {
+ mManagerService.startPerceiving(new BinderCallback(
+ mExecutor, mCallback, mInitializationDelegate.getLock()));
+ } catch (SecurityException e) {
+ Slog.e(TAG, "startRecognition failed: " + e);
+ return false;
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return true;
}
- return true;
}
/**
@@ -140,15 +145,17 @@
if (DEBUG) {
Slog.i(TAG, "#stopRecognition");
}
- // check if the detector is active with the initialization delegate
- mInitializationDelegate.startRecognition();
+ synchronized (mInitializationDelegate.getLock()) {
+ // check if the detector is active with the initialization delegate
+ mInitializationDelegate.stopRecognition();
- try {
- mManagerService.stopPerceiving();
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ try {
+ mManagerService.stopPerceiving();
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ return true;
}
- return true;
}
/**
@@ -160,12 +167,16 @@
if (DEBUG) {
Slog.i(TAG, "#destroy");
}
- mInitializationDelegate.destroy();
+ synchronized (mInitializationDelegate.getLock()) {
+ mInitializationDelegate.destroy();
+ }
}
/** @hide */
public void dump(String prefix, PrintWriter pw) {
- // TODO: implement this
+ synchronized (mInitializationDelegate.getLock()) {
+ mInitializationDelegate.dump(prefix, pw);
+ }
}
/** @hide */
@@ -175,7 +186,9 @@
/** @hide */
void registerOnDestroyListener(Consumer<AbstractDetector> onDestroyListener) {
- mInitializationDelegate.registerOnDestroyListener(onDestroyListener);
+ synchronized (mInitializationDelegate.getLock()) {
+ mInitializationDelegate.registerOnDestroyListener(onDestroyListener);
+ }
}
/**
@@ -282,6 +295,15 @@
public boolean isUsingSandboxedDetectionService() {
return true;
}
+
+ @Override
+ public void dump(String prefix, PrintWriter pw) {
+ // No-op
+ }
+
+ private Object getLock() {
+ return mLock;
+ }
}
private static class BinderCallback
@@ -289,31 +311,43 @@
private final Executor mExecutor;
private final VisualQueryDetector.Callback mCallback;
- BinderCallback(Executor executor, VisualQueryDetector.Callback callback) {
+ private final Object mLock;
+
+ BinderCallback(Executor executor, VisualQueryDetector.Callback callback, Object lock) {
this.mExecutor = executor;
this.mCallback = callback;
+ this.mLock = lock;
}
/** Called when the detected result is valid. */
@Override
public void onQueryDetected(@NonNull String partialQuery) {
Slog.v(TAG, "BinderCallback#onQueryDetected");
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(
- () -> mCallback.onQueryDetected(partialQuery)));
+ Binder.withCleanCallingIdentity(() -> {
+ synchronized (mLock) {
+ mCallback.onQueryDetected(partialQuery);
+ }
+ });
}
@Override
public void onQueryFinished() {
Slog.v(TAG, "BinderCallback#onQueryFinished");
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(
- () -> mCallback.onQueryFinished()));
+ Binder.withCleanCallingIdentity(() -> {
+ synchronized (mLock) {
+ mCallback.onQueryFinished();
+ }
+ });
}
@Override
public void onQueryRejected() {
Slog.v(TAG, "BinderCallback#onQueryRejected");
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(
- () -> mCallback.onQueryRejected()));
+ Binder.withCleanCallingIdentity(() -> {
+ synchronized (mLock) {
+ mCallback.onQueryRejected();
+ }
+ });
}
/** Called when the detection fails due to an error. */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e83488e..9f6395e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -528,8 +528,6 @@
// Set to true to stop input during an Activity Transition.
boolean mPausedForTransition = false;
- boolean mLastInCompatMode = false;
-
SurfaceHolder.Callback2 mSurfaceHolderCallback;
BaseSurfaceHolder mSurfaceHolder;
boolean mIsCreating;
@@ -1375,11 +1373,6 @@
}
if (DEBUG_LAYOUT) Log.d(mTag, "WindowLayout in setView:" + attrs);
- if (!compatibilityInfo.supportsScreen()) {
- attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- mLastInCompatMode = true;
- }
-
mSoftInputMode = attrs.softInputMode;
mWindowAttributesChanged = true;
mAttachInfo.mRootView = view;
@@ -1913,10 +1906,6 @@
// Keep track of the actual window flags supplied by the client.
mClientWindowLayoutFlags = attrs.flags;
- // Preserve compatible window flag if exists.
- final int compatibleWindowFlag = mWindowAttributes.privateFlags
- & WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-
// Preserve system UI visibility.
final int systemUiVisibility = mWindowAttributes.systemUiVisibility;
final int subtreeSystemUiVisibility = mWindowAttributes.subtreeSystemUiVisibility;
@@ -1948,8 +1937,7 @@
mWindowAttributes.subtreeSystemUiVisibility = subtreeSystemUiVisibility;
mWindowAttributes.insetsFlags.appearance = appearance;
mWindowAttributes.insetsFlags.behavior = behavior;
- mWindowAttributes.privateFlags |= compatibleWindowFlag
- | appearanceAndBehaviorPrivateFlags;
+ mWindowAttributes.privateFlags |= appearanceAndBehaviorPrivateFlags;
if (mWindowAttributes.preservePreviousSurfaceInsets) {
// Restore old surface insets.
@@ -3150,21 +3138,6 @@
final boolean shouldOptimizeMeasure = shouldOptimizeMeasure(lp);
WindowManager.LayoutParams params = null;
- CompatibilityInfo compatibilityInfo =
- mDisplay.getDisplayAdjustments().getCompatibilityInfo();
- if (compatibilityInfo.supportsScreen() == mLastInCompatMode) {
- params = lp;
- mFullRedrawNeeded = true;
- mLayoutRequested = true;
- if (mLastInCompatMode) {
- params.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- mLastInCompatMode = false;
- } else {
- params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- mLastInCompatMode = true;
- }
- }
-
Rect frame = mWinFrame;
if (mFirst) {
mFullRedrawNeeded = true;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 1712fd3..07a347a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -3143,13 +3143,6 @@
@UnsupportedAppUsage
public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 1 << 6;
- /** Window flag: special flag to limit the size of the window to be
- * original size ([320x480] x density). Used to create window for applications
- * running under compatibility mode.
- *
- * {@hide} */
- public static final int PRIVATE_FLAG_COMPATIBLE_WINDOW = 1 << 7;
-
/** Window flag: a special option intended for system dialogs. When
* this flag is set, the window will demand focus unconditionally when
* it is created.
@@ -3345,7 +3338,6 @@
SYSTEM_FLAG_SHOW_FOR_ALL_USERS,
PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION,
PRIVATE_FLAG_NO_MOVE_ANIMATION,
- PRIVATE_FLAG_COMPATIBLE_WINDOW,
PRIVATE_FLAG_SYSTEM_ERROR,
PRIVATE_FLAG_OPTIMIZE_MEASURE,
PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS,
@@ -3399,10 +3391,6 @@
equals = PRIVATE_FLAG_NO_MOVE_ANIMATION,
name = "NO_MOVE_ANIMATION"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_COMPATIBLE_WINDOW,
- equals = PRIVATE_FLAG_COMPATIBLE_WINDOW,
- name = "COMPATIBLE_WINDOW"),
- @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_SYSTEM_ERROR,
equals = PRIVATE_FLAG_SYSTEM_ERROR,
name = "SYSTEM_ERROR"),
diff --git a/core/java/android/window/BackMotionEvent.java b/core/java/android/window/BackMotionEvent.java
index c475723..7cda3a3 100644
--- a/core/java/android/window/BackMotionEvent.java
+++ b/core/java/android/window/BackMotionEvent.java
@@ -36,6 +36,7 @@
private final float mProgress;
private final float mVelocityX;
private final float mVelocityY;
+ private final boolean mTriggerBack;
@BackEvent.SwipeEdge
private final int mSwipeEdge;
@@ -54,6 +55,7 @@
* Value in pixels/second. {@link Float#NaN} if was not computed.
* @param velocityY Y velocity computed from the touch point of this event.
* Value in pixels/second. {@link Float#NaN} if was not computed.
+ * @param triggerBack Indicates whether the back arrow is in the triggered state or not
* @param swipeEdge Indicates which edge the swipe starts from.
* @param departingAnimationTarget The remote animation target of the departing
* application window.
@@ -64,6 +66,7 @@
float progress,
float velocityX,
float velocityY,
+ boolean triggerBack,
@BackEvent.SwipeEdge int swipeEdge,
@Nullable RemoteAnimationTarget departingAnimationTarget) {
mTouchX = touchX;
@@ -71,6 +74,7 @@
mProgress = progress;
mVelocityX = velocityX;
mVelocityY = velocityY;
+ mTriggerBack = triggerBack;
mSwipeEdge = swipeEdge;
mDepartingAnimationTarget = departingAnimationTarget;
}
@@ -81,6 +85,7 @@
mProgress = in.readFloat();
mVelocityX = in.readFloat();
mVelocityY = in.readFloat();
+ mTriggerBack = in.readBoolean();
mSwipeEdge = in.readInt();
mDepartingAnimationTarget = in.readTypedObject(RemoteAnimationTarget.CREATOR);
}
@@ -110,6 +115,7 @@
dest.writeFloat(mProgress);
dest.writeFloat(mVelocityX);
dest.writeFloat(mVelocityY);
+ dest.writeBoolean(mTriggerBack);
dest.writeInt(mSwipeEdge);
dest.writeTypedObject(mDepartingAnimationTarget, flags);
}
@@ -157,6 +163,15 @@
}
/**
+ * Returns whether the back arrow is in the triggered state or not
+ *
+ * @return boolean indicating whether the back arrow is in the triggered state or not
+ */
+ public boolean getTriggerBack() {
+ return mTriggerBack;
+ }
+
+ /**
* Returns the screen edge that the swipe starts from.
*/
@BackEvent.SwipeEdge
@@ -182,6 +197,7 @@
+ ", mProgress=" + mProgress
+ ", mVelocityX=" + mVelocityX
+ ", mVelocityY=" + mVelocityY
+ + ", mTriggerBack=" + mTriggerBack
+ ", mSwipeEdge" + mSwipeEdge
+ ", mDepartingAnimationTarget" + mDepartingAnimationTarget
+ "}";
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 52ad49a..216acdc 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -66,4 +66,12 @@
description: "Predictive back for system animations"
bug: "309545085"
is_fixed_read_only: true
+}
+
+flag {
+ name: "activity_snapshot_by_default"
+ namespace: "systemui"
+ description: "Enable record activity snapshot by default"
+ bug: "259497289"
+ is_fixed_read_only: true
}
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
index 68c0693..a709d7b 100644
--- a/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
+++ b/core/tests/coretests/src/android/window/WindowOnBackInvokedDispatcherTest.java
@@ -84,6 +84,7 @@
/* progress = */ 0,
/* velocityX = */ 0,
/* velocityY = */ 0,
+ /* triggerBack = */ false,
/* swipeEdge = */ BackEvent.EDGE_LEFT,
/* departingAnimationTarget = */ null);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java
index e06d3ef..5b0de50 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationConstants.java
@@ -21,5 +21,4 @@
*/
class BackAnimationConstants {
static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.20f;
- static final float PROGRESS_COMMIT_THRESHOLD = 0.1f;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index d8c691b..a498236 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -70,9 +70,11 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.annotations.ShellBackgroundThread;
import com.android.wm.shell.common.annotations.ShellMainThread;
+import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
+import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;
/**
@@ -124,6 +126,7 @@
private final Context mContext;
private final ContentResolver mContentResolver;
private final ShellController mShellController;
+ private final ShellCommandHandler mShellCommandHandler;
private final ShellExecutor mShellExecutor;
private final Handler mBgHandler;
@@ -180,7 +183,8 @@
@NonNull @ShellBackgroundThread Handler backgroundHandler,
Context context,
@NonNull BackAnimationBackground backAnimationBackground,
- ShellBackAnimationRegistry shellBackAnimationRegistry) {
+ ShellBackAnimationRegistry shellBackAnimationRegistry,
+ ShellCommandHandler shellCommandHandler) {
this(
shellInit,
shellController,
@@ -190,7 +194,8 @@
context,
context.getContentResolver(),
backAnimationBackground,
- shellBackAnimationRegistry);
+ shellBackAnimationRegistry,
+ shellCommandHandler);
}
@VisibleForTesting
@@ -203,7 +208,8 @@
Context context,
ContentResolver contentResolver,
@NonNull BackAnimationBackground backAnimationBackground,
- ShellBackAnimationRegistry shellBackAnimationRegistry) {
+ ShellBackAnimationRegistry shellBackAnimationRegistry,
+ ShellCommandHandler shellCommandHandler) {
mShellController = shellController;
mShellExecutor = shellExecutor;
mActivityTaskManager = activityTaskManager;
@@ -219,6 +225,7 @@
.build();
mShellBackAnimationRegistry = shellBackAnimationRegistry;
mLatencyTracker = LatencyTracker.getInstance(mContext);
+ mShellCommandHandler = shellCommandHandler;
}
private void onInit() {
@@ -227,6 +234,7 @@
createAdapter();
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION,
this::createExternalInterface, this);
+ mShellCommandHandler.addDumpCallback(this::dump, this);
}
private void setupAnimationDeveloperSettingsObserver(
@@ -968,4 +976,20 @@
};
mBackAnimationAdapter = new BackAnimationAdapter(runner);
}
+
+ /**
+ * Description of current BackAnimationController state.
+ */
+ private void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "BackAnimationController state:");
+ pw.println(prefix + " mEnableAnimations=" + mEnableAnimations.get());
+ pw.println(prefix + " mBackGestureStarted=" + mBackGestureStarted);
+ pw.println(prefix + " mPostCommitAnimationInProgress=" + mPostCommitAnimationInProgress);
+ pw.println(prefix + " mShouldStartOnNextMoveEvent=" + mShouldStartOnNextMoveEvent);
+ pw.println(prefix + " mCurrentTracker state:");
+ mCurrentTracker.dump(pw, prefix + " ");
+ pw.println(prefix + " mQueuedTracker state:");
+ mQueuedTracker.dump(pw, prefix + " ");
+ }
+
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
index 215a6cc..30d5edb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.java
@@ -18,9 +18,9 @@
import static android.view.RemoteAnimationTarget.MODE_CLOSING;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
+import static android.window.BackEvent.EDGE_RIGHT;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY;
-import static com.android.wm.shell.back.BackAnimationConstants.PROGRESS_COMMIT_THRESHOLD;
import static com.android.wm.shell.back.BackAnimationConstants.UPDATE_SYSUI_FLAGS_THRESHOLD;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BACK_PREVIEW;
@@ -91,7 +91,7 @@
}
};
private static final float MIN_WINDOW_ALPHA = 0.01f;
- private static final float WINDOW_X_SHIFT_DP = 96;
+ private static final float WINDOW_X_SHIFT_DP = 48;
private static final int SCALE_FACTOR = 100;
// TODO(b/264710590): Use the progress commit threshold from ViewConfiguration once it exists.
private static final float TARGET_COMMIT_PROGRESS = 0.5f;
@@ -126,6 +126,8 @@
private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();
private boolean mBackInProgress = false;
+ private boolean mIsRightEdge;
+ private boolean mTriggerBack = false;
private PointF mTouchPos = new PointF();
private IRemoteAnimationFinishedCallback mFinishCallback;
@@ -209,6 +211,7 @@
private void finishAnimation() {
if (mEnteringTarget != null) {
+ mTransaction.setCornerRadius(mEnteringTarget.leash, 0);
mEnteringTarget.leash.release();
mEnteringTarget = null;
}
@@ -241,14 +244,15 @@
private void onGestureProgress(@NonNull BackEvent backEvent) {
if (!mBackInProgress) {
+ mIsRightEdge = backEvent.getSwipeEdge() == EDGE_RIGHT;
mInitialTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
mBackInProgress = true;
}
mTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY());
float progress = backEvent.getProgress();
- float springProgress = (progress > PROGRESS_COMMIT_THRESHOLD
- ? mapLinear(progress, 0.1f, 1, TARGET_COMMIT_PROGRESS, 1)
+ float springProgress = (mTriggerBack
+ ? mapLinear(progress, 0f, 1, TARGET_COMMIT_PROGRESS, 1)
: mapLinear(progress, 0, 1f, 0, TARGET_COMMIT_PROGRESS)) * SCALE_FACTOR;
mLeavingProgressSpring.animateToFinalPosition(springProgress);
mEnteringProgressSpring.animateToFinalPosition(springProgress);
@@ -312,7 +316,7 @@
transformWithProgress(
mEnteringProgress,
Math.max(
- smoothstep(ENTER_ALPHA_THRESHOLD, 1, mEnteringProgress),
+ smoothstep(ENTER_ALPHA_THRESHOLD, 0.7f, mEnteringProgress),
MIN_WINDOW_ALPHA), /* alpha */
mEnteringTarget.leash,
mEnteringRect,
@@ -337,14 +341,13 @@
mClosingTarget.leash,
mClosingRect,
0,
- mWindowXShift
+ mIsRightEdge ? 0 : mWindowXShift
);
}
}
private void transformWithProgress(float progress, float alpha, SurfaceControl surface,
RectF targetRect, float deltaXMin, float deltaXMax) {
- final float touchY = mTouchPos.y;
final int width = mStartTaskRect.width();
final int height = mStartTaskRect.height();
@@ -376,12 +379,14 @@
private final class Callback extends IOnBackInvokedCallback.Default {
@Override
public void onBackStarted(BackMotionEvent backEvent) {
+ mTriggerBack = backEvent.getTriggerBack();
mProgressAnimator.onBackStarted(backEvent,
CrossActivityBackAnimation.this::onGestureProgress);
}
@Override
public void onBackProgressed(@NonNull BackMotionEvent backEvent) {
+ mTriggerBack = backEvent.getTriggerBack();
mProgressAnimator.onBackProgressed(backEvent);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
index 4bd56d4..6213f62 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TouchTracker.java
@@ -24,6 +24,8 @@
import android.window.BackEvent;
import android.window.BackMotionEvent;
+import java.io.PrintWriter;
+
/**
* Helper class to record the touch location for gesture and generate back events.
*/
@@ -129,6 +131,7 @@
/* progress = */ 0,
/* velocityX = */ 0,
/* velocityY = */ 0,
+ /* triggerBack = */ mTriggerBack,
/* swipeEdge = */ mSwipeEdge,
/* departingAnimationTarget = */ target);
}
@@ -204,6 +207,7 @@
/* progress = */ progress,
/* velocityX = */ mLatestVelocityX,
/* velocityY = */ mLatestVelocityY,
+ /* triggerBack = */ mTriggerBack,
/* swipeEdge = */ mSwipeEdge,
/* departingAnimationTarget = */ null);
}
@@ -219,6 +223,12 @@
mNonLinearFactor = nonLinearFactor;
}
+ void dump(PrintWriter pw, String prefix) {
+ pw.println(prefix + "TouchTracker state:");
+ pw.println(prefix + " mState=" + mState);
+ pw.println(prefix + " mTriggerBack=" + mTriggerBack);
+ }
+
enum TouchTrackerState {
INITIAL, ACTIVE, FINISHED
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 3c6bc17..fc97c798 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -363,7 +363,8 @@
@ShellMainThread ShellExecutor shellExecutor,
@ShellBackgroundThread Handler backgroundHandler,
BackAnimationBackground backAnimationBackground,
- Optional<ShellBackAnimationRegistry> shellBackAnimationRegistry) {
+ Optional<ShellBackAnimationRegistry> shellBackAnimationRegistry,
+ ShellCommandHandler shellCommandHandler) {
if (BackAnimationController.IS_ENABLED) {
return shellBackAnimationRegistry.map(
(animations) ->
@@ -374,7 +375,8 @@
backgroundHandler,
context,
backAnimationBackground,
- animations));
+ animations,
+ shellCommandHandler));
}
return Optional.empty();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index ae21c4b..f58aeac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -277,11 +277,6 @@
params.token = appToken;
params.packageName = activityInfo.packageName;
params.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
-
- if (!context.getResources().getCompatibilityInfo().supportsScreen()) {
- params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
- }
-
params.setTitle("Splash Screen " + title);
return params;
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 771876f..9ded6ea 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -63,6 +63,7 @@
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.wm.shell.ShellTestCase;
import com.android.wm.shell.TestShellExecutor;
+import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.sysui.ShellSharedConstants;
@@ -110,6 +111,8 @@
@Mock
private InputManager mInputManager;
+ @Mock
+ private ShellCommandHandler mShellCommandHandler;
private BackAnimationController mController;
private TestableContentResolver mContentResolver;
@@ -145,7 +148,8 @@
mContext,
mContentResolver,
mAnimationBackground,
- mShellBackAnimationRegistry);
+ mShellBackAnimationRegistry,
+ mShellCommandHandler);
mShellInit.init();
mShellExecutor.flushAll();
}
@@ -298,7 +302,8 @@
mContext,
mContentResolver,
mAnimationBackground,
- mShellBackAnimationRegistry);
+ mShellBackAnimationRegistry,
+ mShellCommandHandler);
shellInit.init();
registerAnimation(BackNavigationInfo.TYPE_RETURN_TO_HOME);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
index 874ef80..91503b1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackProgressAnimatorTest.java
@@ -53,6 +53,7 @@
/* progress = */ progress,
/* velocityX = */ 0,
/* velocityY = */ 0,
+ /* triggerBack = */ false,
/* swipeEdge = */ BackEvent.EDGE_LEFT,
/* departingAnimationTarget = */ null);
}
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/core/Android.bp
similarity index 100%
rename from packages/SystemUI/animation/Android.bp
rename to packages/SystemUI/animation/core/Android.bp
diff --git a/packages/SystemUI/animation/AndroidManifest.xml b/packages/SystemUI/animation/core/AndroidManifest.xml
similarity index 100%
rename from packages/SystemUI/animation/AndroidManifest.xml
rename to packages/SystemUI/animation/core/AndroidManifest.xml
diff --git a/packages/SystemUI/animation/build.gradle b/packages/SystemUI/animation/core/build.gradle
similarity index 81%
rename from packages/SystemUI/animation/build.gradle
rename to packages/SystemUI/animation/core/build.gradle
index 939455f..12637f4 100644
--- a/packages/SystemUI/animation/build.gradle
+++ b/packages/SystemUI/animation/core/build.gradle
@@ -5,8 +5,8 @@
android {
sourceSets {
main {
- java.srcDirs = ["${SYS_UI_DIR}/animation/src/com/android/systemui/surfaceeffects/"]
- manifest.srcFile "${SYS_UI_DIR}/animation/AndroidManifest.xml"
+ java.srcDirs = ["${SYS_UI_DIR}/animation/core/src/com/android/systemui/surfaceeffects/"]
+ manifest.srcFile "${SYS_UI_DIR}/animation/core/AndroidManifest.xml"
}
}
diff --git a/packages/SystemUI/animation/res/anim/launch_dialog_enter.xml b/packages/SystemUI/animation/core/res/anim/launch_dialog_enter.xml
similarity index 100%
rename from packages/SystemUI/animation/res/anim/launch_dialog_enter.xml
rename to packages/SystemUI/animation/core/res/anim/launch_dialog_enter.xml
diff --git a/packages/SystemUI/animation/res/anim/launch_dialog_exit.xml b/packages/SystemUI/animation/core/res/anim/launch_dialog_exit.xml
similarity index 100%
rename from packages/SystemUI/animation/res/anim/launch_dialog_exit.xml
rename to packages/SystemUI/animation/core/res/anim/launch_dialog_exit.xml
diff --git a/packages/SystemUI/animation/res/values/ids.xml b/packages/SystemUI/animation/core/res/values/ids.xml
similarity index 100%
rename from packages/SystemUI/animation/res/values/ids.xml
rename to packages/SystemUI/animation/core/res/values/ids.xml
diff --git a/packages/SystemUI/animation/res/values/styles.xml b/packages/SystemUI/animation/core/res/values/styles.xml
similarity index 100%
rename from packages/SystemUI/animation/res/values/styles.xml
rename to packages/SystemUI/animation/core/res/values/styles.xml
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/AnimationFeatureFlags.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/AnimationFeatureFlags.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/AnimationFeatureFlags.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/AnimationFeatureFlags.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/DelegateLaunchAnimatorController.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/DialogLaunchAnimator.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/DialogLaunchAnimator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/DialogLaunchAnimator.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/Expandable.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/Expandable.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/Expandable.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/FontInterpolator.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/FontInterpolator.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/FontVariationUtils.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/FontVariationUtils.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/FontVariationUtils.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/LaunchAnimator.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/LaunchAnimator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/LaunchAnimator.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/LaunchableView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/LaunchableView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/LaunchableView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/RemoteAnimationDelegate.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ShadeInterpolation.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/ShadeInterpolation.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/ShadeInterpolation.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/TextAnimator.kt
similarity index 93%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/TextAnimator.kt
index 8dc7495..dc54240 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+++ b/packages/SystemUI/animation/core/src/com/android/systemui/animation/TextAnimator.kt
@@ -42,9 +42,9 @@
return baseTypeface
}
- val axes = FontVariationAxis.fromFontVariationSettings(fVar)
- ?.toMutableList()
- ?: mutableListOf()
+ val axes =
+ FontVariationAxis.fromFontVariationSettings(fVar)?.toMutableList()
+ ?: mutableListOf()
axes.removeIf { !baseTypeface.isSupportedAxes(it.getOpenTypeTagValue()) }
if (axes.isEmpty()) {
return baseTypeface
@@ -206,12 +206,14 @@
*
* Here is an example of font runs: "fin. 終わり"
*
+ * ```
* Characters : f i n . _ 終 わ り
* Code Points: \u0066 \u0069 \u006E \u002E \u0020 \u7D42 \u308F \u308A
* Font Runs : <-- Roboto-Regular.ttf --><-- NotoSans-CJK.otf -->
* runStart = 0, runLength = 5 runStart = 5, runLength = 3
* Glyph IDs : 194 48 7 8 4367 1039 1002
* Glyph Index: 0 1 2 3 0 1 2
+ * ```
*
* In this example, the "fi" is converted into ligature form, thus the single glyph ID is
* assigned for two characters, f and i.
@@ -243,22 +245,21 @@
/**
* Set text style with animation.
*
- * By passing -1 to weight, the view preserve the current weight.
- * By passing -1 to textSize, the view preserve the current text size.
- * Bu passing -1 to duration, the default text animation, 1000ms, is used.
- * By passing false to animate, the text will be updated without animation.
+ * By passing -1 to weight, the view preserve the current weight. By passing -1 to textSize, the
+ * view preserve the current text size. Bu passing -1 to duration, the default text animation,
+ * 1000ms, is used. By passing false to animate, the text will be updated without animation.
*
* @param fvar an optional text fontVariationSettings.
* @param textSize an optional font size.
- * @param colors an optional colors array that must be the same size as numLines passed to
- * the TextInterpolator
+ * @param colors an optional colors array that must be the same size as numLines passed to the
+ * TextInterpolator
* @param strokeWidth an optional paint stroke width
* @param animate an optional boolean indicating true for showing style transition as animation,
- * false for immediate style transition. True by default.
+ * false for immediate style transition. True by default.
* @param duration an optional animation duration in milliseconds. This is ignored if animate is
- * false.
+ * false.
* @param interpolator an optional time interpolator. If null is passed, last set interpolator
- * will be used. This is ignored if animate is false.
+ * will be used. This is ignored if animate is false.
*/
fun setTextStyle(
fvar: String? = "",
@@ -324,7 +325,8 @@
}
/**
- * Set text style with animation. Similar as
+ * Set text style with animation. Similar as fun setTextStyle( fvar: String? = "", textSize:
+ * ```
* fun setTextStyle(
* fvar: String? = "",
* textSize: Float = -1f,
@@ -336,6 +338,7 @@
* delay: Long = 0,
* onAnimationEnd: Runnable? = null
* )
+ * ```
*
* @param weight an optional style value for `wght` in fontVariationSettings.
* @param width an optional style value for `wdth` in fontVariationSettings.
@@ -356,12 +359,13 @@
delay: Long = 0,
onAnimationEnd: Runnable? = null
) {
- val fvar = fontVariationUtils.updateFontVariation(
- weight = weight,
- width = width,
- opticalSize = opticalSize,
- roundness = roundness,
- )
+ val fvar =
+ fontVariationUtils.updateFontVariation(
+ weight = weight,
+ width = width,
+ opticalSize = opticalSize,
+ roundness = roundness,
+ )
setTextStyle(
fvar = fvar,
textSize = textSize,
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/TextInterpolator.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/TextInterpolator.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewDialogLaunchAnimatorController.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
similarity index 92%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
index 00d9056..a9c53d1 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+++ b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
@@ -196,9 +196,9 @@
*
* @param includeFadeIn true if the animator should also fade in the view and child views.
* @param fadeInInterpolator the interpolator to use when fading in the view. Unused if
- * [includeFadeIn] is false.
- * @param onAnimationEnd an optional runnable that will be run once the animation
- * finishes successfully. Will not be run if the animation is cancelled.
+ * [includeFadeIn] is false.
+ * @param onAnimationEnd an optional runnable that will be run once the animation finishes
+ * successfully. Will not be run if the animation is cancelled.
*/
@JvmOverloads
fun animateAddition(
@@ -241,7 +241,10 @@
// First, fade in the container view
val containerDuration = duration / 6
createAndStartFadeInAnimator(
- rootView, containerDuration, startDelay = 0, interpolator = fadeInInterpolator
+ rootView,
+ containerDuration,
+ startDelay = 0,
+ interpolator = fadeInInterpolator
)
// Then, fade in the child views
@@ -397,7 +400,7 @@
* included by specifying [includeMargins].
*
* @param onAnimationEnd an optional runnable that will be run once the animation finishes
- * successfully. Will not be run if the animation is cancelled.
+ * successfully. Will not be run if the animation is cancelled.
*/
@JvmOverloads
fun animateRemoval(
@@ -616,6 +619,7 @@
* not newly introduced margins are included.
*
* Base case
+ *
* ```
* 1) origin=TOP
* x---------x x---------x x---------x x---------x x---------x
@@ -636,9 +640,11 @@
* x-----x x-------x | |
* x---------x
* ```
+ *
* In case the start and end values differ in the direction of the origin, and
* [ignorePreviousValues] is false, the previous values are used and a translation is
* included in addition to the view expansion.
+ *
* ```
* origin=TOP_LEFT - (0,0,0,0) -> (30,30,70,70)
* x
@@ -777,8 +783,7 @@
includeMargins: Boolean = false,
): Map<Bound, Int> {
val marginAdjustment =
- if (includeMargins &&
- (rootView.layoutParams is ViewGroup.MarginLayoutParams)) {
+ if (includeMargins && (rootView.layoutParams is ViewGroup.MarginLayoutParams)) {
val marginLp = rootView.layoutParams as ViewGroup.MarginLayoutParams
DimenHolder(
left = marginLp.leftMargin,
@@ -786,9 +791,9 @@
right = marginLp.rightMargin,
bottom = marginLp.bottomMargin
)
- } else {
- DimenHolder(0, 0, 0, 0)
- }
+ } else {
+ DimenHolder(0, 0, 0, 0)
+ }
// These are the end values to use *if* this bound is part of the destination.
val endLeft = left - marginAdjustment.left
@@ -805,60 +810,69 @@
// - If destination=BOTTOM_LEFT, then endBottom == endTop AND endLeft == endRight.
return when (destination) {
- Hotspot.TOP -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.LEFT to left,
- Bound.RIGHT to right,
- )
- Hotspot.TOP_RIGHT -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- )
- Hotspot.RIGHT -> mapOf(
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- Bound.TOP to top,
- Bound.BOTTOM to bottom,
- )
- Hotspot.BOTTOM_RIGHT -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.RIGHT to endRight,
- Bound.LEFT to endRight,
- )
- Hotspot.BOTTOM -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.LEFT to left,
- Bound.RIGHT to right,
- )
- Hotspot.BOTTOM_LEFT -> mapOf(
- Bound.BOTTOM to endBottom,
- Bound.TOP to endBottom,
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- )
- Hotspot.LEFT -> mapOf(
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- Bound.TOP to top,
- Bound.BOTTOM to bottom,
- )
- Hotspot.TOP_LEFT -> mapOf(
- Bound.TOP to endTop,
- Bound.BOTTOM to endTop,
- Bound.LEFT to endLeft,
- Bound.RIGHT to endLeft,
- )
- Hotspot.CENTER -> mapOf(
- Bound.LEFT to (endLeft + endRight) / 2,
- Bound.RIGHT to (endLeft + endRight) / 2,
- Bound.TOP to (endTop + endBottom) / 2,
- Bound.BOTTOM to (endTop + endBottom) / 2,
- )
+ Hotspot.TOP ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.LEFT to left,
+ Bound.RIGHT to right,
+ )
+ Hotspot.TOP_RIGHT ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ )
+ Hotspot.RIGHT ->
+ mapOf(
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ Bound.TOP to top,
+ Bound.BOTTOM to bottom,
+ )
+ Hotspot.BOTTOM_RIGHT ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.RIGHT to endRight,
+ Bound.LEFT to endRight,
+ )
+ Hotspot.BOTTOM ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.LEFT to left,
+ Bound.RIGHT to right,
+ )
+ Hotspot.BOTTOM_LEFT ->
+ mapOf(
+ Bound.BOTTOM to endBottom,
+ Bound.TOP to endBottom,
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ )
+ Hotspot.LEFT ->
+ mapOf(
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ Bound.TOP to top,
+ Bound.BOTTOM to bottom,
+ )
+ Hotspot.TOP_LEFT ->
+ mapOf(
+ Bound.TOP to endTop,
+ Bound.BOTTOM to endTop,
+ Bound.LEFT to endLeft,
+ Bound.RIGHT to endLeft,
+ )
+ Hotspot.CENTER ->
+ mapOf(
+ Bound.LEFT to (endLeft + endRight) / 2,
+ Bound.RIGHT to (endLeft + endRight) / 2,
+ Bound.TOP to (endTop + endBottom) / 2,
+ Bound.BOTTOM to (endTop + endBottom) / 2,
+ )
}
}
@@ -1083,11 +1097,13 @@
animator.startDelay = startDelay
animator.duration = duration
animator.interpolator = interpolator
- animator.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- view.setTag(R.id.tag_alpha_animator, null /* tag */)
+ animator.addListener(
+ object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator) {
+ view.setTag(R.id.tag_alpha_animator, null /* tag */)
+ }
}
- })
+ )
(view.getTag(R.id.tag_alpha_animator) as? ObjectAnimator)?.cancel()
view.setTag(R.id.tag_alpha_animator, animator)
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewRootSync.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/ViewRootSync.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/ViewRootSync.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackAnimationSpec.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpec.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackAnimationSpec.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpecForSysUi.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackAnimationSpecForSysUi.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/back/BackAnimationSpecForSysUi.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackAnimationSpecForSysUi.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/BackTransformation.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackTransformation.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/back/BackTransformation.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/back/BackTransformation.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/back/OnBackAnimationCallbackExtension.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableFrameLayout.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableFrameLayout.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableFrameLayout.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableFrameLayout.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableImageView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableImageView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableImageView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableLinearLayout.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableTextView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/animation/view/LaunchableTextView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/animation/view/LaunchableTextView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/MultiRippleController.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/MultiRippleView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleAnimation.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleAnimationConfig.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleShader.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/ripple/RippleView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaders/SolidColorShader.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaders/SparkleShader.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaderutil/SdfShaderLibrary.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseAnimationConfig.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseController.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt b/packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseView.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/util/AnimatorExtensions.kt b/packages/SystemUI/animation/core/src/com/android/systemui/util/AnimatorExtensions.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/util/AnimatorExtensions.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/util/AnimatorExtensions.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/util/Dialog.kt b/packages/SystemUI/animation/core/src/com/android/systemui/util/Dialog.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/util/Dialog.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/util/Dialog.kt
diff --git a/packages/SystemUI/animation/src/com/android/systemui/util/Dimension.kt b/packages/SystemUI/animation/core/src/com/android/systemui/util/Dimension.kt
similarity index 100%
rename from packages/SystemUI/animation/src/com/android/systemui/util/Dimension.kt
rename to packages/SystemUI/animation/core/src/com/android/systemui/util/Dimension.kt
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index 9d9b0a9..a85d9bf 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -16,6 +16,7 @@
package com.android.compose.animation.scene
+import android.graphics.Picture
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
@@ -66,12 +67,21 @@
* The movable content of this element, if this element is composed using
* [SceneScope.MovableElement].
*/
- val movableContent by
- // This is only accessed from the composition (main) thread, so no need to use the default
- // lock of lazy {} to synchronize.
- lazy(mode = LazyThreadSafetyMode.NONE) {
- movableContentOf { content: @Composable () -> Unit -> content() }
- }
+ private var _movableContent: (@Composable (@Composable () -> Unit) -> Unit)? = null
+ val movableContent: @Composable (@Composable () -> Unit) -> Unit
+ get() =
+ _movableContent
+ ?: movableContentOf { content: @Composable () -> Unit -> content() }
+ .also { _movableContent = it }
+
+ /**
+ * The [Picture] to which we save the last drawing commands of this element, if it is movable.
+ * This is necessary because the content of this element might not be composed in the scene it
+ * should currently be drawn.
+ */
+ private var _picture: Picture? = null
+ val picture: Picture
+ get() = _picture ?: Picture().also { _picture = it }
override fun toString(): String {
return "Element(key=$key)"
@@ -521,11 +531,6 @@
sceneValues.targetOffset = targetOffsetInScene
}
- // No need to place the element in this scene if we don't want to draw it anyways.
- if (!shouldDrawElement(layoutImpl, scene, element)) {
- return
- }
-
val currentOffset = lookaheadScopeCoordinates.localPositionOf(coords, Offset.Zero)
val lastSharedValues = element.lastSharedValues
val lastValues = sceneValues.lastValues
@@ -548,6 +553,13 @@
lastSharedValues.offset = targetOffset
lastValues.offset = targetOffset
+ // No need to place the element in this scene if we don't want to draw it anyways. Note that
+ // it's still important to compute the target offset and update lastValues, otherwise it
+ // will be out of date.
+ if (!shouldDrawElement(layoutImpl, scene, element)) {
+ return
+ }
+
val offset = (targetOffset - currentOffset).round()
if (isElementOpaque(layoutImpl, element, scene, sceneValues)) {
// TODO(b/291071158): Call placeWithLayer() if offset != IntOffset.Zero and size is not
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
index 306f276..49df2f6 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/MovableElement.kt
@@ -16,7 +16,6 @@
package com.android.compose.animation.scene
-import android.graphics.Picture
import android.util.Log
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
@@ -60,7 +59,7 @@
// The [Picture] to which we save the last drawing commands of this element. This is
// necessary because the content of this element might not be composed in this scene, in
// which case we still need to draw it.
- val picture = remember { Picture() }
+ val picture = element.picture
// Whether we should compose the movable element here. The scene picker logic to know in
// which scene we should compose/draw a movable element might depend on the current
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
index 6a7a3a0..30e50a9 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Scene.kt
@@ -34,6 +34,7 @@
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.zIndex
+import com.android.compose.animation.scene.modifiers.noResizeDuringTransitions
/** A scene in a [SceneTransitionLayout]. */
@Stable
@@ -152,4 +153,8 @@
bounds: ElementKey,
shape: Shape
): Modifier = punchHole(layoutImpl, element, bounds, shape)
+
+ override fun Modifier.noResizeDuringTransitions(): Modifier {
+ return noResizeDuringTransitions(layoutState = layoutImpl.state)
+ }
}
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 3608e37..5eb339e 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -65,11 +65,11 @@
SceneTransitionLayoutForTesting(
currentScene,
onChangeScene,
+ modifier,
transitions,
state,
edgeDetector,
transitionInterceptionThreshold,
- modifier,
onLayoutImpl = null,
scenes,
)
@@ -205,6 +205,12 @@
* the result.
*/
fun Modifier.punchHole(element: ElementKey, bounds: ElementKey, shape: Shape): Modifier
+
+ /**
+ * Don't resize during transitions. This can for instance be used to make sure that scrollable
+ * lists keep a constant size during transitions even if its elements are growing/shrinking.
+ */
+ fun Modifier.noResizeDuringTransitions(): Modifier
}
// TODO(b/291053742): Add animateSharedValueAsState(targetValue) without any ValueKey and ElementKey
@@ -257,12 +263,12 @@
internal fun SceneTransitionLayoutForTesting(
currentScene: SceneKey,
onChangeScene: (SceneKey) -> Unit,
- transitions: SceneTransitions,
- state: SceneTransitionLayoutState,
- edgeDetector: EdgeDetector,
- transitionInterceptionThreshold: Float,
- modifier: Modifier,
- onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)?,
+ modifier: Modifier = Modifier,
+ transitions: SceneTransitions = transitions {},
+ state: SceneTransitionLayoutState = remember { SceneTransitionLayoutState(currentScene) },
+ edgeDetector: EdgeDetector = DefaultEdgeDetector,
+ transitionInterceptionThreshold: Float = 0f,
+ onLayoutImpl: ((SceneTransitionLayoutImpl) -> Unit)? = null,
scenes: SceneTransitionLayoutScope.() -> Unit,
) {
val density = LocalDensity.current
@@ -280,6 +286,10 @@
.also { onLayoutImpl?.invoke(it) }
}
+ // TODO(b/317014852): Move this into the SideEffect {} again once STLImpl.scenes is not a
+ // SnapshotStateMap anymore.
+ layoutImpl.updateScenes(scenes)
+
val targetSceneChannel = remember { Channel<SceneKey>(Channel.CONFLATED) }
SideEffect {
if (state != layoutImpl.state) {
@@ -293,7 +303,6 @@
(state as SceneTransitionLayoutStateImpl).transitions = transitions
layoutImpl.density = density
layoutImpl.edgeDetector = edgeDetector
- layoutImpl.updateScenes(scenes)
state.transitions = transitions
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index c99c325..45e1a0f 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -46,7 +46,12 @@
builder: SceneTransitionLayoutScope.() -> Unit,
coroutineScope: CoroutineScope,
) {
- internal val scenes = mutableMapOf<SceneKey, Scene>()
+ /**
+ * The map of [Scene]s.
+ *
+ * TODO(b/317014852): Make this a normal MutableMap instead.
+ */
+ internal val scenes = SnapshotStateMap<SceneKey, Scene>()
/**
* The map of [Element]s.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/Size.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/Size.kt
new file mode 100644
index 0000000..bd36cb8
--- /dev/null
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/modifiers/Size.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.modifiers
+
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.intermediateLayout
+import androidx.compose.ui.unit.Constraints
+import com.android.compose.animation.scene.SceneTransitionLayoutState
+
+@OptIn(ExperimentalComposeUiApi::class)
+internal fun Modifier.noResizeDuringTransitions(layoutState: SceneTransitionLayoutState): Modifier {
+ return intermediateLayout { measurable, constraints ->
+ if (layoutState.currentTransition == null) {
+ return@intermediateLayout measurable.measure(constraints).run {
+ layout(width, height) { place(0, 0) }
+ }
+ }
+
+ // Make sure that this layout node has the same size than when we are at rest.
+ val sizeAtRest = lookaheadSize
+ measurable.measure(Constraints.fixed(sizeAtRest.width, sizeAtRest.height)).run {
+ layout(width, height) { place(0, 0) }
+ }
+ }
+}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index d332910..da5a0a0 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -16,6 +16,7 @@
package com.android.compose.animation.scene
+import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
@@ -30,16 +31,21 @@
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.layout.intermediateLayout
+import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.test.subjects.DpOffsetSubject
+import com.android.compose.test.subjects.assertThat
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -259,11 +265,6 @@
SceneTransitionLayoutForTesting(
currentScene = currentScene,
onChangeScene = { currentScene = it },
- transitions = remember { transitions {} },
- state = remember { SceneTransitionLayoutState(currentScene) },
- edgeDetector = DefaultEdgeDetector,
- modifier = Modifier,
- transitionInterceptionThreshold = 0f,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(TestScenes.SceneA) { /* Nothing */}
@@ -429,11 +430,6 @@
SceneTransitionLayoutForTesting(
currentScene = TestScenes.SceneA,
onChangeScene = {},
- transitions = remember { transitions {} },
- state = remember { SceneTransitionLayoutState(TestScenes.SceneA) },
- edgeDetector = DefaultEdgeDetector,
- modifier = Modifier,
- transitionInterceptionThreshold = 0f,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(TestScenes.SceneA) { Box(Modifier.element(key)) }
@@ -484,11 +480,6 @@
SceneTransitionLayoutForTesting(
currentScene = TestScenes.SceneA,
onChangeScene = {},
- transitions = remember { transitions {} },
- state = remember { SceneTransitionLayoutState(TestScenes.SceneA) },
- edgeDetector = DefaultEdgeDetector,
- modifier = Modifier,
- transitionInterceptionThreshold = 0f,
onLayoutImpl = { nullableLayoutImpl = it },
) {
scene(TestScenes.SceneA) {
@@ -574,4 +565,86 @@
after { assertThat(fooCompositions).isEqualTo(1) }
}
}
+
+ @Test
+ fun sharedElementOffsetIsUpdatedEvenWhenNotPlaced() {
+ var nullableLayoutImpl: SceneTransitionLayoutImpl? = null
+ var density: Density? = null
+
+ fun layoutImpl() = nullableLayoutImpl ?: error("nullableLayoutImpl was not set")
+
+ fun density() = density ?: error("density was not set")
+
+ fun Offset.toDpOffset() = with(density()) { DpOffset(x.toDp(), y.toDp()) }
+
+ fun foo() = layoutImpl().elements[TestElements.Foo] ?: error("Foo not in elements map")
+
+ fun Element.lastSharedOffset() = lastSharedValues.offset.toDpOffset()
+
+ fun Element.lastOffsetIn(scene: SceneKey) =
+ (sceneValues[scene] ?: error("$scene not in sceneValues map"))
+ .lastValues
+ .offset
+ .toDpOffset()
+
+ rule.testTransition(
+ from = TestScenes.SceneA,
+ to = TestScenes.SceneB,
+ transitionLayout = { currentScene, onChangeScene ->
+ density = LocalDensity.current
+
+ SceneTransitionLayoutForTesting(
+ currentScene = currentScene,
+ onChangeScene = onChangeScene,
+ onLayoutImpl = { nullableLayoutImpl = it },
+ transitions =
+ transitions {
+ from(TestScenes.SceneA, to = TestScenes.SceneB) {
+ spec = tween(durationMillis = 4 * 16, easing = LinearEasing)
+ }
+ }
+ ) {
+ scene(TestScenes.SceneA) { Box(Modifier.element(TestElements.Foo)) }
+ scene(TestScenes.SceneB) {
+ Box(Modifier.offset(x = 40.dp, y = 80.dp).element(TestElements.Foo))
+ }
+ }
+ }
+ ) {
+ val tolerance = DpOffsetSubject.DefaultTolerance
+
+ before {
+ val expected = DpOffset(0.dp, 0.dp)
+ assertThat(foo().lastSharedOffset()).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneA)).isWithin(tolerance).of(expected)
+ }
+
+ at(16) {
+ val expected = DpOffset(10.dp, 20.dp)
+ assertThat(foo().lastSharedOffset()).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneA)).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneB)).isWithin(tolerance).of(expected)
+ }
+
+ at(32) {
+ val expected = DpOffset(20.dp, 40.dp)
+ assertThat(foo().lastSharedOffset()).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneA)).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneB)).isWithin(tolerance).of(expected)
+ }
+
+ at(48) {
+ val expected = DpOffset(30.dp, 60.dp)
+ assertThat(foo().lastSharedOffset()).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneA)).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneB)).isWithin(tolerance).of(expected)
+ }
+
+ after {
+ val expected = DpOffset(40.dp, 80.dp)
+ assertThat(foo().lastSharedOffset()).isWithin(tolerance).of(expected)
+ assertThat(foo().lastOffsetIn(TestScenes.SceneB)).isWithin(tolerance).of(expected)
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeTest.kt
new file mode 100644
index 0000000..2c159d1
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/modifiers/SizeTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.compose.animation.scene.modifiers
+
+import androidx.compose.animation.core.LinearEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.size
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.unit.dp
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compose.animation.scene.TestElements
+import com.android.compose.animation.scene.element
+import com.android.compose.animation.scene.testTransition
+import com.android.compose.test.assertSizeIsEqualTo
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SizeTest {
+ @get:Rule val rule = createComposeRule()
+
+ @Test
+ fun noResizeDuringTransitions() {
+ // The tag for the parent of the shared Foo element.
+ val parentTag = "parent"
+
+ rule.testTransition(
+ fromSceneContent = { Box(Modifier.element(TestElements.Foo).size(100.dp)) },
+ toSceneContent = {
+ // Don't resize the parent of Foo during transitions so that it's always the same
+ // size as when there is no transition (200dp).
+ Box(Modifier.noResizeDuringTransitions().testTag(parentTag)) {
+ Box(Modifier.element(TestElements.Foo).size(200.dp))
+ }
+ },
+ transition = { spec = tween(durationMillis = 4 * 16, easing = LinearEasing) },
+ ) {
+ at(16) { rule.onNodeWithTag(parentTag).assertSizeIsEqualTo(200.dp, 200.dp) }
+ at(32) { rule.onNodeWithTag(parentTag).assertSizeIsEqualTo(200.dp, 200.dp) }
+ at(48) { rule.onNodeWithTag(parentTag).assertSizeIsEqualTo(200.dp, 200.dp) }
+ after { rule.onNodeWithTag(parentTag).assertSizeIsEqualTo(200.dp, 200.dp) }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 0e7e69b..270bfbe 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -263,11 +263,7 @@
* If the shortcut entry `android:enabled` is set to `true`, the shortcut will be visible in the
* Widget Picker to all users.
*/
- // TODO(b/316332684)
- @Suppress("UNREACHABLE_CODE")
fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) {
- return // shortcut should not be enabled until additional features are implemented.
-
if (!userManager.isUserUnlocked(user)) {
debugLog { "setNoteTaskShortcutEnabled call but user locked: user=$user" }
return
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 4d42324..b7618d2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -75,7 +75,6 @@
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import org.junit.Before
-import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
@@ -463,7 +462,6 @@
// region setNoteTaskShortcutEnabled
@Test
- @Ignore("b/316332684")
fun setNoteTaskShortcutEnabled_setTrue() {
createNoteTaskController().setNoteTaskShortcutEnabled(value = true, userTracker.userHandle)
@@ -480,7 +478,6 @@
}
@Test
- @Ignore("b/316332684")
fun setNoteTaskShortcutEnabled_setFalse() {
createNoteTaskController().setNoteTaskShortcutEnabled(value = false, userTracker.userHandle)
@@ -497,7 +494,6 @@
}
@Test
- @Ignore("b/316332684")
fun setNoteTaskShortcutEnabled_workProfileUser_setTrue() {
whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any()))
.thenReturn(workProfileContext)
@@ -519,7 +515,6 @@
}
@Test
- @Ignore("b/316332684")
fun setNoteTaskShortcutEnabled_workProfileUser_setFalse() {
whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any()))
.thenReturn(workProfileContext)
@@ -738,7 +733,6 @@
// region internalUpdateNoteTaskAsUser
@Test
- @Ignore("b/316332684")
fun updateNoteTaskAsUserInternal_withNotesRole_withShortcuts_shouldUpdateShortcuts() {
createNoteTaskController(isEnabled = true)
.launchUpdateNoteTaskAsUser(userTracker.userHandle)
@@ -772,7 +766,6 @@
}
@Test
- @Ignore("b/316332684")
fun updateNoteTaskAsUserInternal_noNotesRole_shouldDisableShortcuts() {
whenever(roleManager.getRoleHoldersAsUser(ROLE_NOTES, userTracker.userHandle))
.thenReturn(emptyList())
@@ -796,7 +789,6 @@
}
@Test
- @Ignore("b/316332684")
fun updateNoteTaskAsUserInternal_flagDisabled_shouldDisableShortcuts() {
createNoteTaskController(isEnabled = false)
.launchUpdateNoteTaskAsUser(userTracker.userHandle)
diff --git a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
index a159a5e..5a548fd 100644
--- a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
+++ b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING
@@ -54,9 +54,7 @@
"exclude-annotation": "android.support.test.filters.FlakyTest"
}
]
- }
- ],
- "postsubmit": [
+ },
{
"name": "CtsVirtualDevicesCameraTestCases",
"options": [
diff --git a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
index 6940ffe..f24c4cc 100644
--- a/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
+++ b/services/companion/java/com/android/server/companion/virtual/camera/VirtualCameraConversionUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,7 +70,7 @@
@Override
public void onProcessCaptureRequest(int streamId, int frameId) throws RemoteException {
- camera.onProcessCaptureRequest(streamId, frameId, /*metadata=*/ null);
+ camera.onProcessCaptureRequest(streamId, frameId);
}
@Override
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index a6b532c..badd7f0 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -3050,8 +3050,8 @@
/**
* Returns whether the given user requires credential entry at this time. This is used to
- * intercept activity launches for locked work apps due to work challenge being triggered
- * or when the profile user is yet to be unlocked.
+ * intercept activity launches for apps corresponding to locked profiles due to separate
+ * challenge being triggered or when the profile user is yet to be unlocked.
*/
protected boolean shouldConfirmCredentials(@UserIdInt int userId) {
if (getStartedUserState(userId) == null) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 8091753..dada72e 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -56,6 +56,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.PrintWriterPrinter;
import com.android.internal.annotations.GuardedBy;
@@ -1640,7 +1641,7 @@
return mBtHelper.getLeAudioDeviceGroupId(device);
}
- /*package*/ List<String> getLeAudioGroupAddresses(int groupId) {
+ /*package*/ List<Pair<String, String>> getLeAudioGroupAddresses(int groupId) {
return mBtHelper.getLeAudioGroupAddresses(groupId);
}
@@ -2651,9 +2652,9 @@
}
}
- List<String> getDeviceAddresses(AudioDeviceAttributes device) {
+ List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) {
synchronized (mDeviceStateLock) {
- return mDeviceInventory.getDeviceAddresses(device);
+ return mDeviceInventory.getDeviceIdentityAddresses(device);
}
}
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index d138f24..e05824a 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -566,23 +566,40 @@
final int mDeviceType;
final @NonNull String mDeviceName;
final @NonNull String mDeviceAddress;
+ @NonNull String mDeviceIdentityAddress;
int mDeviceCodecFormat;
- @NonNull String mPeerDeviceAddress;
final int mGroupId;
+ @NonNull String mPeerDeviceAddress;
+ @NonNull String mPeerIdentityDeviceAddress;
/** Disabled operating modes for this device. Use a negative logic so that by default
* an empty list means all modes are allowed.
* See BluetoothAdapter.AUDIO_MODE_DUPLEX and BluetoothAdapter.AUDIO_MODE_OUTPUT_ONLY */
@NonNull ArraySet<String> mDisabledModes = new ArraySet(0);
- DeviceInfo(int deviceType, String deviceName, String deviceAddress,
- int deviceCodecFormat, String peerDeviceAddress, int groupId) {
+ DeviceInfo(int deviceType, String deviceName, String address,
+ String identityAddress, int codecFormat,
+ int groupId, String peerAddress, String peerIdentityAddress) {
mDeviceType = deviceType;
- mDeviceName = deviceName == null ? "" : deviceName;
- mDeviceAddress = deviceAddress == null ? "" : deviceAddress;
- mDeviceCodecFormat = deviceCodecFormat;
- mPeerDeviceAddress = peerDeviceAddress == null ? "" : peerDeviceAddress;
+ mDeviceName = TextUtils.emptyIfNull(deviceName);
+ mDeviceAddress = TextUtils.emptyIfNull(address);
+ mDeviceIdentityAddress = TextUtils.emptyIfNull(identityAddress);
+ mDeviceCodecFormat = codecFormat;
mGroupId = groupId;
+ mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
+ mPeerIdentityDeviceAddress = TextUtils.emptyIfNull(peerIdentityAddress);
+ }
+
+ /** Constructor for all devices except A2DP sink and LE Audio */
+ DeviceInfo(int deviceType, String deviceName, String address) {
+ this(deviceType, deviceName, address, null, AudioSystem.AUDIO_FORMAT_DEFAULT);
+ }
+
+ /** Constructor for A2DP sink devices */
+ DeviceInfo(int deviceType, String deviceName, String address,
+ String identityAddress, int codecFormat) {
+ this(deviceType, deviceName, address, identityAddress, codecFormat,
+ BluetoothLeAudio.GROUP_ID_INVALID, null, null);
}
void setModeDisabled(String mode) {
@@ -601,25 +618,20 @@
return isModeEnabled(BluetoothAdapter.AUDIO_MODE_DUPLEX);
}
- DeviceInfo(int deviceType, String deviceName, String deviceAddress,
- int deviceCodecFormat) {
- this(deviceType, deviceName, deviceAddress, deviceCodecFormat,
- null, BluetoothLeAudio.GROUP_ID_INVALID);
- }
-
- DeviceInfo(int deviceType, String deviceName, String deviceAddress) {
- this(deviceType, deviceName, deviceAddress, AudioSystem.AUDIO_FORMAT_DEFAULT);
- }
-
@Override
public String toString() {
return "[DeviceInfo: type:0x" + Integer.toHexString(mDeviceType)
+ " (" + AudioSystem.getDeviceName(mDeviceType)
+ ") name:" + mDeviceName
+ " addr:" + Utils.anonymizeBluetoothAddress(mDeviceType, mDeviceAddress)
+ + " identity addr:"
+ + Utils.anonymizeBluetoothAddress(mDeviceType, mDeviceIdentityAddress)
+ " codec: " + Integer.toHexString(mDeviceCodecFormat)
- + " peer addr:" + mPeerDeviceAddress
+ " group:" + mGroupId
+ + " peer addr:"
+ + Utils.anonymizeBluetoothAddress(mDeviceType, mPeerDeviceAddress)
+ + " peer identity addr:"
+ + Utils.anonymizeBluetoothAddress(mDeviceType, mPeerIdentityDeviceAddress)
+ " disabled modes: " + mDisabledModes + "]";
}
@@ -947,20 +959,44 @@
}
+ /**
+ * Goes over all connected LE Audio devices in the provided group ID and
+ * update:
+ * - the peer address according to the addres of other device in the same
+ * group (can also clear the peer address is not anymore in the group)
+ * - The dentity address if not yet set.
+ * LE Audio buds in a pair are in the same group.
+ * @param groupId the LE Audio group to update
+ */
/*package*/ void onUpdateLeAudioGroupAddresses(int groupId) {
synchronized (mDevicesLock) {
+ // <address, identy address>
+ List<Pair<String, String>> addresses = new ArrayList<>();
for (DeviceInfo di : mConnectedDevices.values()) {
if (di.mGroupId == groupId) {
- List<String> addresses = mDeviceBroker.getLeAudioGroupAddresses(groupId);
+ if (addresses.isEmpty()) {
+ addresses = mDeviceBroker.getLeAudioGroupAddresses(groupId);
+ }
if (di.mPeerDeviceAddress.equals("")) {
- for (String addr : addresses) {
- if (!addr.equals(di.mDeviceAddress)) {
- di.mPeerDeviceAddress = addr;
+ for (Pair<String, String> addr : addresses) {
+ if (!addr.first.equals(di.mDeviceAddress)) {
+ di.mPeerDeviceAddress = addr.first;
+ di.mPeerIdentityDeviceAddress = addr.second;
break;
}
}
- } else if (!addresses.contains(di.mPeerDeviceAddress)) {
+ } else if (!addresses.contains(
+ new Pair(di.mPeerDeviceAddress, di.mPeerIdentityDeviceAddress))) {
di.mPeerDeviceAddress = "";
+ di.mPeerIdentityDeviceAddress = "";
+ }
+ if (di.mDeviceIdentityAddress.equals("")) {
+ for (Pair<String, String> addr : addresses) {
+ if (addr.first.equals(di.mDeviceAddress)) {
+ di.mDeviceIdentityAddress = addr.second;
+ break;
+ }
+ }
}
}
}
@@ -1964,7 +2000,7 @@
mDeviceBroker.clearA2dpSuspended(true /* internalOnly */);
final DeviceInfo di = new DeviceInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name,
- address, codec);
+ address, btInfo.mDevice.getIdentityAddress(), codec);
final String diKey = di.getKey();
mConnectedDevices.put(diKey, di);
// on a connection always overwrite the device seen by AudioPolicy, see comment above when
@@ -2381,12 +2417,15 @@
// Find LE Group ID and peer headset address if available
final int groupId = mDeviceBroker.getLeAudioDeviceGroupId(btInfo.mDevice);
String peerAddress = "";
+ String peerIdentityAddress = "";
if (groupId != BluetoothLeAudio.GROUP_ID_INVALID) {
- List<String> addresses = mDeviceBroker.getLeAudioGroupAddresses(groupId);
+ List<Pair<String, String>> addresses =
+ mDeviceBroker.getLeAudioGroupAddresses(groupId);
if (addresses.size() > 1) {
- for (String addr : addresses) {
- if (!addr.equals(address)) {
- peerAddress = addr;
+ for (Pair<String, String> addr : addresses) {
+ if (!addr.first.equals(address)) {
+ peerAddress = addr.first;
+ peerIdentityAddress = addr.second;
break;
}
}
@@ -2420,8 +2459,9 @@
// Reset LEA suspend state each time a new sink is connected
mDeviceBroker.clearLeAudioSuspended(true /* internalOnly */);
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
- new DeviceInfo(device, name, address, codec,
- peerAddress, groupId));
+ new DeviceInfo(device, name, address,
+ btInfo.mDevice.getIdentityAddress(), codec,
+ groupId, peerAddress, peerIdentityAddress));
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
setCurrentAudioRouteNameIfPossible(name, /*fromA2dp=*/false);
addAudioDeviceInInventoryIfNeeded(device, address, peerAddress,
@@ -2806,18 +2846,19 @@
mDevRoleCapturePresetDispatchers.finishBroadcast();
}
- List<String> getDeviceAddresses(AudioDeviceAttributes device) {
+ List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) {
List<String> addresses = new ArrayList<String>();
final String key = DeviceInfo.makeDeviceListKey(device.getInternalType(),
device.getAddress());
synchronized (mDevicesLock) {
DeviceInfo di = mConnectedDevices.get(key);
if (di != null) {
- if (!di.mDeviceAddress.isEmpty()) {
- addresses.add(di.mDeviceAddress);
+ if (!di.mDeviceIdentityAddress.isEmpty()) {
+ addresses.add(di.mDeviceIdentityAddress);
}
- if (!di.mPeerDeviceAddress.isEmpty()) {
- addresses.add(di.mPeerDeviceAddress);
+ if (!di.mPeerIdentityDeviceAddress.isEmpty()
+ && !di.mPeerIdentityDeviceAddress.equals(di.mDeviceIdentityAddress)) {
+ addresses.add(di.mPeerIdentityDeviceAddress);
}
}
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0c78231..56ae2bf 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -13775,8 +13775,8 @@
return activeAssistantUids;
}
- List<String> getDeviceAddresses(AudioDeviceAttributes device) {
- return mDeviceBroker.getDeviceAddresses(device);
+ List<String> getDeviceIdentityAddresses(AudioDeviceAttributes device) {
+ return mDeviceBroker.getDeviceIdentityAddresses(device);
}
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 8075618..a818c30 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -58,6 +58,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
import com.android.server.utils.EventLogger;
@@ -1077,8 +1078,8 @@
return mLeAudio.getGroupId(device);
}
- /*package*/ List<String> getLeAudioGroupAddresses(int groupId) {
- List<String> addresses = new ArrayList<String>();
+ /*package*/ List<Pair<String, String>> getLeAudioGroupAddresses(int groupId) {
+ List<Pair<String, String>> addresses = new ArrayList<>();
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null || mLeAudio == null) {
return addresses;
@@ -1086,7 +1087,7 @@
List<BluetoothDevice> activeDevices = adapter.getActiveDevices(BluetoothProfile.LE_AUDIO);
for (BluetoothDevice device : activeDevices) {
if (device != null && mLeAudio.getGroupId(device) == groupId) {
- addresses.add(device.getAddress());
+ addresses.add(new Pair(device.getAddress(), device.getIdentityAddress()));
}
}
return addresses;
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 4f7f31d..8428f12 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -1639,8 +1639,7 @@
return -1;
}
final AudioDeviceAttributes currentDevice = sRoutingDevices.get(0);
- List<String> deviceAddresses = mAudioService.getDeviceAddresses(currentDevice);
-
+ List<String> deviceAddresses = mAudioService.getDeviceIdentityAddresses(currentDevice);
// We limit only to Sensor.TYPE_HEAD_TRACKER here to avoid confusion
// with gaming sensors. (Note that Sensor.TYPE_ROTATION_VECTOR
// and Sensor.TYPE_GAME_ROTATION_VECTOR are supported internally by
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index acd253b..f2ffd4d 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -35,7 +35,6 @@
import android.util.Spline;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.display.BrightnessUtils;
import com.android.internal.util.Preconditions;
import com.android.server.display.utils.Plog;
@@ -97,28 +96,17 @@
float[] brightnessLevels = null;
float[] luxLevels = null;
switch (mode) {
- case AUTO_BRIGHTNESS_MODE_DEFAULT:
+ case AUTO_BRIGHTNESS_MODE_DEFAULT -> {
brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits();
luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux();
-
brightnessLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevels();
- if (brightnessLevels == null || brightnessLevels.length == 0) {
- // Load the old configuration in the range [0, 255]. The values need to be
- // normalized to the range [0, 1].
- int[] brightnessLevelsInt = resources.getIntArray(
- com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
- brightnessLevels = new float[brightnessLevelsInt.length];
- for (int i = 0; i < brightnessLevels.length; i++) {
- brightnessLevels[i] = normalizeAbsoluteBrightness(brightnessLevelsInt[i]);
- }
- }
- break;
- case AUTO_BRIGHTNESS_MODE_IDLE:
+ }
+ case AUTO_BRIGHTNESS_MODE_IDLE -> {
brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle));
luxLevels = getLuxLevels(resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevelsIdle));
- break;
+ }
}
// Display independent, mode independent values
@@ -426,11 +414,6 @@
}
}
- // Normalize entire brightness range to 0 - 1.
- protected static float normalizeAbsoluteBrightness(int brightness) {
- return BrightnessSynchronizer.brightnessIntToFloat(brightness);
- }
-
private Pair<float[], float[]> insertControlPoint(
float[] luxLevels, float[] brightnessLevels, float lux, float brightness) {
final int idx = findInsertionPoint(luxLevels, lux);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index d97127c..7d22a87 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -49,6 +49,7 @@
import com.android.server.display.config.BrightnessThrottlingMap;
import com.android.server.display.config.BrightnessThrottlingPoint;
import com.android.server.display.config.Density;
+import com.android.server.display.config.DisplayBrightnessMappingConfig;
import com.android.server.display.config.DisplayBrightnessPoint;
import com.android.server.display.config.DisplayConfiguration;
import com.android.server.display.config.DisplayQuirks;
@@ -57,7 +58,6 @@
import com.android.server.display.config.HighBrightnessMode;
import com.android.server.display.config.IntegerArray;
import com.android.server.display.config.LuxThrottling;
-import com.android.server.display.config.LuxToBrightnessMapping;
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.NonNegativeFloatToFloatPoint;
import com.android.server.display.config.Point;
@@ -313,6 +313,21 @@
* 1000
* </darkeningLightDebounceIdleMillis>
* <luxToBrightnessMapping>
+ * <mode>default</mode>
+ * <map>
+ * <point>
+ * <first>0</first>
+ * <second>0.2</second>
+ * </point>
+ * <point>
+ * <first>80</first>
+ * <second>0.3</second>
+ * </point>
+ * </map>
+ * </luxToBrightnessMapping>
+ * <luxToBrightnessMapping>
+ * <mode>doze</mode>
+ * <setting>dim</setting>
* <map>
* <point>
* <first>0</first>
@@ -634,36 +649,8 @@
// for the corresponding values above
private float[] mBrightness;
- /**
- * Array of desired screen brightness in nits corresponding to the lux values
- * in the mBrightnessLevelsLux array. The display brightness is defined as the
- * measured brightness of an all-white image. The brightness values must be non-negative and
- * non-decreasing. This must be overridden in platform specific overlays
- */
- private float[] mBrightnessLevelsNits;
-
- /**
- * Array of desired screen brightness corresponding to the lux values
- * in the mBrightnessLevelsLux array. The brightness values must be non-negative and
- * non-decreasing. They must be between {@link PowerManager.BRIGHTNESS_MIN} and
- * {@link PowerManager.BRIGHTNESS_MAX}. This must be overridden in platform specific overlays
- */
- private float[] mBrightnessLevels;
-
- /**
- * Array of light sensor lux values to define our levels for auto-brightness support.
- *
- * The first lux value is always 0.
- *
- * The control points must be strictly increasing. Each control point corresponds to an entry
- * in the brightness values arrays. For example, if lux == luxLevels[1] (second element
- * of the levels array) then the brightness will be determined by brightnessLevels[1] (second
- * element of the brightness values array).
- *
- * Spline interpolation is used to determine the auto-brightness values for lux levels between
- * these control points.
- */
- private float[] mBrightnessLevelsLux;
+ @Nullable
+ private DisplayBrightnessMappingConfig mDisplayBrightnessMapping;
private float mBacklightMinimum = Float.NaN;
private float mBacklightMaximum = Float.NaN;
@@ -1604,24 +1591,57 @@
}
/**
- * @return Auto brightness brightening ambient lux levels
+ * @return The default auto-brightness brightening ambient lux levels
*/
public float[] getAutoBrightnessBrighteningLevelsLux() {
- return mBrightnessLevelsLux;
+ if (mDisplayBrightnessMapping == null) {
+ return null;
+ }
+ return mDisplayBrightnessMapping.getLuxArray();
+ }
+
+ /**
+ * @param mode The auto-brightness mode
+ * @param setting The brightness setting
+ * @return Auto brightness brightening ambient lux levels for the specified mode and setting
+ */
+ public float[] getAutoBrightnessBrighteningLevelsLux(String mode, String setting) {
+ if (mDisplayBrightnessMapping == null) {
+ return null;
+ }
+ return mDisplayBrightnessMapping.getLuxArray(mode, setting);
}
/**
* @return Auto brightness brightening nits levels
*/
public float[] getAutoBrightnessBrighteningLevelsNits() {
- return mBrightnessLevelsNits;
+ if (mDisplayBrightnessMapping == null) {
+ return null;
+ }
+ return mDisplayBrightnessMapping.getNitsArray();
}
/**
- * @return Auto brightness brightening levels
+ * @return The default auto-brightness brightening levels
*/
public float[] getAutoBrightnessBrighteningLevels() {
- return mBrightnessLevels;
+ if (mDisplayBrightnessMapping == null) {
+ return null;
+ }
+ return mDisplayBrightnessMapping.getBrightnessArray();
+ }
+
+ /**
+ * @param mode The auto-brightness mode
+ * @param setting The brightness setting
+ * @return Auto brightness brightening backlight levels for the specified mode and setting
+ */
+ public float[] getAutoBrightnessBrighteningLevels(String mode, String setting) {
+ if (mDisplayBrightnessMapping == null) {
+ return null;
+ }
+ return mDisplayBrightnessMapping.getBrightnessArray(mode, setting);
}
/**
@@ -1875,9 +1895,7 @@
+ mAutoBrightnessBrighteningLightDebounceIdle
+ ", mAutoBrightnessDarkeningLightDebounceIdle= "
+ mAutoBrightnessDarkeningLightDebounceIdle
- + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux)
- + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
- + ", mBrightnessLevels= " + Arrays.toString(mBrightnessLevels)
+ + ", mDisplayBrightnessMapping= " + mDisplayBrightnessMapping
+ ", mDdcAutoBrightnessAvailable= " + mDdcAutoBrightnessAvailable
+ ", mAutoBrightnessAvailable= " + mAutoBrightnessAvailable
+ "\n"
@@ -2568,7 +2586,8 @@
// Idle must be called after interactive, since we fall back to it if needed.
loadAutoBrightnessBrighteningLightDebounceIdle(autoBrightness);
loadAutoBrightnessDarkeningLightDebounceIdle(autoBrightness);
- loadAutoBrightnessDisplayBrightnessMapping(autoBrightness);
+ mDisplayBrightnessMapping = new DisplayBrightnessMappingConfig(mContext, mFlags,
+ autoBrightness, mBacklightToBrightnessSpline);
loadEnableAutoBrightness(autoBrightness);
}
@@ -2633,38 +2652,6 @@
}
}
- /**
- * Loads the auto-brightness display brightness mappings. Internally, this takes care of
- * loading the value from the display config, and if not present, falls back to config.xml.
- */
- private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) {
- if (mFlags.areAutoBrightnessModesEnabled() && autoBrightnessConfig != null
- && autoBrightnessConfig.getLuxToBrightnessMapping() != null) {
- LuxToBrightnessMapping mapping = autoBrightnessConfig.getLuxToBrightnessMapping();
- final int size = mapping.getMap().getPoint().size();
- mBrightnessLevels = new float[size];
- mBrightnessLevelsLux = new float[size];
- for (int i = 0; i < size; i++) {
- float backlight = mapping.getMap().getPoint().get(i).getSecond().floatValue();
- mBrightnessLevels[i] = mBacklightToBrightnessSpline.interpolate(backlight);
- mBrightnessLevelsLux[i] = mapping.getMap().getPoint().get(i).getFirst()
- .floatValue();
- }
- if (size > 0 && mBrightnessLevelsLux[0] != 0) {
- throw new IllegalArgumentException(
- "The first lux value in the display brightness mapping must be 0");
- }
- } else {
- mBrightnessLevelsNits = getFloatArray(mContext.getResources()
- .obtainTypedArray(com.android.internal.R.array
- .config_autoBrightnessDisplayValuesNits), PowerManager
- .BRIGHTNESS_OFF_FLOAT);
- mBrightnessLevelsLux = getLuxLevels(mContext.getResources()
- .getIntArray(com.android.internal.R.array
- .config_autoBrightnessLevels));
- }
- }
-
private void loadAutoBrightnessAvailableFromConfigXml() {
mAutoBrightnessAvailable = mContext.getResources().getBoolean(
R.bool.config_automatic_brightness_available);
@@ -2977,7 +2964,8 @@
}
private void loadAutoBrightnessConfigsFromConfigXml() {
- loadAutoBrightnessDisplayBrightnessMapping(null /*AutoBrightnessConfig*/);
+ mDisplayBrightnessMapping = new DisplayBrightnessMappingConfig(mContext, mFlags,
+ /* autoBrightnessConfig= */ null, mBacklightToBrightnessSpline);
}
private void loadBrightnessChangeThresholdsFromXml() {
@@ -3347,7 +3335,12 @@
return vals;
}
- private static float[] getLuxLevels(int[] lux) {
+ /**
+ * @param lux The lux array
+ * @return The lux array with 0 appended at the beginning - the first lux value should always
+ * be 0
+ */
+ public static float[] getLuxLevels(int[] lux) {
// The first control point is implicit and always at 0 lux.
float[] levels = new float[lux.length + 1];
for (int i = 0; i < lux.length; i++) {
diff --git a/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java b/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java
new file mode 100644
index 0000000..2162850
--- /dev/null
+++ b/services/core/java/com/android/server/display/config/DisplayBrightnessMappingConfig.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.config;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.Spline;
+
+import com.android.internal.display.BrightnessSynchronizer;
+import com.android.server.display.DisplayDeviceConfig;
+import com.android.server.display.feature.DisplayManagerFlags;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides a mapping between lux and brightness values in order to support auto-brightness.
+ */
+public class DisplayBrightnessMappingConfig {
+
+ private static final String DEFAULT_BRIGHTNESS_MAPPING_KEY = "default_normal";
+
+ /**
+ * Array of desired screen brightness in nits corresponding to the lux values
+ * in the mBrightnessLevelsLuxMap.get(DEFAULT_ID) array. The display brightness is defined as
+ * the measured brightness of an all-white image. The brightness values must be non-negative and
+ * non-decreasing. This must be overridden in platform specific overlays
+ */
+ private float[] mBrightnessLevelsNits;
+
+ /**
+ * Map of arrays of desired screen brightness corresponding to the lux values
+ * in mBrightnessLevelsLuxMap, indexed by the auto-brightness mode and the brightness setting.
+ * The brightness values must be non-negative and non-decreasing. They must be between
+ * {@link PowerManager.BRIGHTNESS_MIN} and {@link PowerManager.BRIGHTNESS_MAX}.
+ *
+ * The keys are a concatenation of the auto-brightness mode and the brightness setting
+ * separated by an underscore, e.g. default_normal, default_dim, default_bright, doze_normal,
+ * doze_dim, doze_bright.
+ */
+ private final Map<String, float[]> mBrightnessLevelsMap = new HashMap<>();
+
+ /**
+ * Map of arrays of light sensor lux values to define our levels for auto-brightness support,
+ * indexed by the auto-brightness mode and the brightness setting.
+ *
+ * The first lux value in every array is always 0.
+ *
+ * The control points must be strictly increasing. Each control point corresponds to an entry
+ * in the brightness values arrays. For example, if lux == luxLevels[1] (second element
+ * of the levels array) then the brightness will be determined by brightnessLevels[1] (second
+ * element of the brightness values array).
+ *
+ * Spline interpolation is used to determine the auto-brightness values for lux levels between
+ * these control points.
+ *
+ * The keys are a concatenation of the auto-brightness mode and the brightness setting
+ * separated by an underscore, e.g. default_normal, default_dim, default_bright, doze_normal,
+ * doze_dim, doze_bright.
+ */
+ private final Map<String, float[]> mBrightnessLevelsLuxMap = new HashMap<>();
+
+ /**
+ * Loads the auto-brightness display brightness mappings. Internally, this takes care of
+ * loading the value from the display config, and if not present, falls back to config.xml.
+ */
+ public DisplayBrightnessMappingConfig(Context context, DisplayManagerFlags flags,
+ AutoBrightness autoBrightnessConfig, Spline backlightToBrightnessSpline) {
+ if (flags.areAutoBrightnessModesEnabled() && autoBrightnessConfig != null
+ && autoBrightnessConfig.getLuxToBrightnessMapping() != null
+ && autoBrightnessConfig.getLuxToBrightnessMapping().size() > 0) {
+ for (LuxToBrightnessMapping mapping
+ : autoBrightnessConfig.getLuxToBrightnessMapping()) {
+ final int size = mapping.getMap().getPoint().size();
+ float[] brightnessLevels = new float[size];
+ float[] brightnessLevelsLux = new float[size];
+ for (int i = 0; i < size; i++) {
+ float backlight = mapping.getMap().getPoint().get(i).getSecond().floatValue();
+ brightnessLevels[i] = backlightToBrightnessSpline.interpolate(backlight);
+ brightnessLevelsLux[i] = mapping.getMap().getPoint().get(i).getFirst()
+ .floatValue();
+ }
+ if (size == 0) {
+ throw new IllegalArgumentException(
+ "A display brightness mapping should not be empty");
+ }
+ if (brightnessLevelsLux[0] != 0) {
+ throw new IllegalArgumentException(
+ "The first lux value in the display brightness mapping must be 0");
+ }
+
+ String key = (mapping.getMode() == null ? "default" : mapping.getMode()) + "_"
+ + (mapping.getSetting() == null ? "normal" : mapping.getSetting());
+ if (mBrightnessLevelsMap.containsKey(key)
+ || mBrightnessLevelsLuxMap.containsKey(key)) {
+ throw new IllegalArgumentException(
+ "A display brightness mapping with key " + key + " already exists");
+ }
+ mBrightnessLevelsMap.put(key, brightnessLevels);
+ mBrightnessLevelsLuxMap.put(key, brightnessLevelsLux);
+ }
+ }
+
+ if (!mBrightnessLevelsMap.containsKey(DEFAULT_BRIGHTNESS_MAPPING_KEY)
+ || !mBrightnessLevelsLuxMap.containsKey(DEFAULT_BRIGHTNESS_MAPPING_KEY)) {
+ mBrightnessLevelsNits = DisplayDeviceConfig.getFloatArray(context.getResources()
+ .obtainTypedArray(com.android.internal.R.array
+ .config_autoBrightnessDisplayValuesNits), PowerManager
+ .BRIGHTNESS_OFF_FLOAT);
+
+ float[] brightnessLevelsLux = DisplayDeviceConfig.getLuxLevels(context.getResources()
+ .getIntArray(com.android.internal.R.array
+ .config_autoBrightnessLevels));
+ mBrightnessLevelsLuxMap.put(DEFAULT_BRIGHTNESS_MAPPING_KEY, brightnessLevelsLux);
+
+ // Load the old configuration in the range [0, 255]. The values need to be normalized
+ // to the range [0, 1].
+ int[] brightnessLevels = context.getResources().getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+ mBrightnessLevelsMap.put(DEFAULT_BRIGHTNESS_MAPPING_KEY,
+ brightnessArrayIntToFloat(brightnessLevels, backlightToBrightnessSpline));
+ }
+ }
+
+ /**
+ * @return The default auto-brightness brightening ambient lux levels
+ */
+ public float[] getLuxArray() {
+ return mBrightnessLevelsLuxMap.get(DEFAULT_BRIGHTNESS_MAPPING_KEY);
+ }
+
+ /**
+ * @param mode The auto-brightness mode
+ * @param setting The brightness setting
+ * @return Auto brightness brightening ambient lux levels for the specified mode and setting
+ */
+ public float[] getLuxArray(String mode, String setting) {
+ return mBrightnessLevelsLuxMap.get(mode + "_" + setting);
+ }
+
+ /**
+ * @return Auto brightness brightening nits levels
+ */
+ public float[] getNitsArray() {
+ return mBrightnessLevelsNits;
+ }
+
+ /**
+ * @return The default auto-brightness brightening levels
+ */
+ public float[] getBrightnessArray() {
+ return mBrightnessLevelsMap.get(DEFAULT_BRIGHTNESS_MAPPING_KEY);
+ }
+
+ /**
+ * @param mode The auto-brightness mode
+ * @param setting The brightness setting
+ * @return Auto brightness brightening ambient lux levels for the specified mode and setting
+ */
+ public float[] getBrightnessArray(String mode, String setting) {
+ return mBrightnessLevelsMap.get(mode + "_" + setting);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder brightnessLevelsLuxMapString = new StringBuilder("{");
+ for (Map.Entry<String, float[]> entry : mBrightnessLevelsLuxMap.entrySet()) {
+ brightnessLevelsLuxMapString.append(entry.getKey()).append("=").append(
+ Arrays.toString(entry.getValue())).append(", ");
+ }
+ if (brightnessLevelsLuxMapString.length() > 2) {
+ brightnessLevelsLuxMapString.delete(brightnessLevelsLuxMapString.length() - 2,
+ brightnessLevelsLuxMapString.length());
+ }
+ brightnessLevelsLuxMapString.append("}");
+
+ StringBuilder brightnessLevelsMapString = new StringBuilder("{");
+ for (Map.Entry<String, float[]> entry : mBrightnessLevelsMap.entrySet()) {
+ brightnessLevelsMapString.append(entry.getKey()).append("=").append(
+ Arrays.toString(entry.getValue())).append(", ");
+ }
+ if (brightnessLevelsMapString.length() > 2) {
+ brightnessLevelsMapString.delete(brightnessLevelsMapString.length() - 2,
+ brightnessLevelsMapString.length());
+ }
+ brightnessLevelsMapString.append("}");
+
+ return "mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
+ + ", mBrightnessLevelsLuxMap= " + brightnessLevelsLuxMapString
+ + ", mBrightnessLevelsMap= " + brightnessLevelsMapString;
+ }
+
+ private float[] brightnessArrayIntToFloat(int[] brightnessInt,
+ Spline backlightToBrightnessSpline) {
+ float[] brightnessFloat = new float[brightnessInt.length];
+ for (int i = 0; i < brightnessInt.length; i++) {
+ brightnessFloat[i] = backlightToBrightnessSpline.interpolate(
+ BrightnessSynchronizer.brightnessIntToFloat(brightnessInt[i]));
+ }
+ return brightnessFloat;
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
index 87158cd..df570a0 100644
--- a/services/core/java/com/android/server/notification/ZenModeEventLogger.java
+++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java
@@ -29,6 +29,7 @@
import android.os.Process;
import android.service.notification.DNDPolicyProto;
import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
import android.service.notification.ZenModeDiff;
import android.service.notification.ZenPolicy;
import android.util.ArrayMap;
@@ -58,7 +59,7 @@
// mode change.
ZenModeEventLogger.ZenStateChanges mChangeState = new ZenModeEventLogger.ZenStateChanges();
- private PackageManager mPm;
+ private final PackageManager mPm;
ZenModeEventLogger(PackageManager pm) {
mPm = pm;
@@ -97,11 +98,11 @@
* @param newInfo ZenModeInfo after this change takes effect
* @param callingUid the calling UID associated with the change; may be used to attribute the
* change to a particular package or determine if this is a user action
- * @param fromSystemOrSystemUi whether the calling UID is either system UID or system UI
+ * @param origin The origin of the Zen change.
*/
public final void maybeLogZenChange(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
- boolean fromSystemOrSystemUi) {
- mChangeState.init(prevInfo, newInfo, callingUid, fromSystemOrSystemUi);
+ @ConfigChangeOrigin int origin) {
+ mChangeState.init(prevInfo, newInfo, callingUid, origin);
if (mChangeState.shouldLogChanges()) {
maybeReassignCallingUid();
logChanges();
@@ -124,7 +125,7 @@
// We don't consider the manual rule in the old config because if a manual rule is turning
// off with a call from system, that could easily be a user action to explicitly turn it off
if (mChangeState.getChangedRuleType() == RULE_TYPE_MANUAL) {
- if (!mChangeState.mFromSystemOrSystemUi
+ if (!mChangeState.isFromSystemOrSystemUi()
|| mChangeState.getNewManualRuleEnabler() == null) {
return;
}
@@ -136,7 +137,7 @@
// - we've determined it's not a user action
// - our current best guess is that the calling uid is system/sysui
if (mChangeState.getChangedRuleType() == RULE_TYPE_AUTOMATIC) {
- if (mChangeState.getIsUserAction() || !mChangeState.mFromSystemOrSystemUi) {
+ if (mChangeState.getIsUserAction() || !mChangeState.isFromSystemOrSystemUi()) {
return;
}
@@ -221,10 +222,10 @@
ZenModeConfig mPrevConfig, mNewConfig;
NotificationManager.Policy mPrevPolicy, mNewPolicy;
int mCallingUid = Process.INVALID_UID;
- boolean mFromSystemOrSystemUi = false;
+ @ConfigChangeOrigin int mOrigin = ZenModeConfig.UPDATE_ORIGIN_UNKNOWN;
private void init(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid,
- boolean fromSystemOrSystemUi) {
+ @ConfigChangeOrigin int origin) {
// previous & new may be the same -- that would indicate that zen mode hasn't changed.
mPrevZenMode = prevInfo.mZenMode;
mNewZenMode = newInfo.mZenMode;
@@ -233,7 +234,7 @@
mPrevPolicy = prevInfo.mPolicy;
mNewPolicy = newInfo.mPolicy;
mCallingUid = callingUid;
- mFromSystemOrSystemUi = fromSystemOrSystemUi;
+ mOrigin = origin;
}
/**
@@ -389,12 +390,16 @@
/**
* Return our best guess as to whether the changes observed are due to a user action.
- * Note that this won't be 100% accurate as we can't necessarily distinguish between a
- * system uid call indicating "user interacted with Settings" vs "a system app changed
- * something automatically".
+ * Note that this (before {@code MODES_API}) won't be 100% accurate as we can't necessarily
+ * distinguish between a system uid call indicating "user interacted with Settings" vs "a
+ * system app changed something automatically".
*/
boolean getIsUserAction() {
- // Approach:
+ if (Flags.modesApi()) {
+ return mOrigin == ZenModeConfig.UPDATE_ORIGIN_USER;
+ }
+
+ // Approach for pre-MODES_API:
// - if manual rule turned on or off, the calling UID is system, and the new manual
// rule does not have an enabler set, guess that this is likely to be a user action.
// This may represent a system app turning on DND automatically, but we guess "user"
@@ -419,13 +424,13 @@
switch (getChangedRuleType()) {
case RULE_TYPE_MANUAL:
// TODO(b/278888961): Distinguish the automatically-turned-off state
- return mFromSystemOrSystemUi && (getNewManualRuleEnabler() == null);
+ return isFromSystemOrSystemUi() && (getNewManualRuleEnabler() == null);
case RULE_TYPE_AUTOMATIC:
for (ZenModeDiff.RuleDiff d : getChangedAutomaticRules().values()) {
if (d.wasAdded() || d.wasRemoved()) {
// If the change comes from system, a rule being added/removed indicates
// a likely user action. From an app, it's harder to know for sure.
- return mFromSystemOrSystemUi;
+ return isFromSystemOrSystemUi();
}
ZenModeDiff.FieldDiff enabled = d.getDiffForField(
ZenModeDiff.RuleDiff.FIELD_ENABLED);
@@ -455,6 +460,13 @@
return false;
}
+ boolean isFromSystemOrSystemUi() {
+ return mOrigin == ZenModeConfig.UPDATE_ORIGIN_INIT
+ || mOrigin == ZenModeConfig.UPDATE_ORIGIN_INIT_USER
+ || mOrigin == ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+ || mOrigin == ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP;
+ }
+
/**
* Get the package UID associated with this change, which is just the calling UID for the
* relevant method changes. This may get reset by ZenModeEventLogger, which has access to
@@ -612,7 +624,7 @@
copy.mPrevPolicy = mPrevPolicy.copy();
copy.mNewPolicy = mNewPolicy.copy();
copy.mCallingUid = mCallingUid;
- copy.mFromSystemOrSystemUi = mFromSystemOrSystemUi;
+ copy.mOrigin = mOrigin;
return copy;
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index d1de9b0..0a46901 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1371,12 +1371,8 @@
if (logZenModeEvents) {
ZenModeEventLogger.ZenModeInfo newInfo = new ZenModeEventLogger.ZenModeInfo(
mZenMode, mConfig, mConsolidatedPolicy);
- boolean fromSystemOrSystemUi = origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
- || origin == UPDATE_ORIGIN_INIT
- || origin == UPDATE_ORIGIN_INIT_USER
- || origin == UPDATE_ORIGIN_RESTORE_BACKUP;
mZenModeEventLogger.maybeLogZenChange(prevInfo, newInfo, callingUid,
- fromSystemOrSystemUi);
+ origin);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index 2864a8b..dcfc855d 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -132,6 +132,11 @@
private static final String EXTRA_INSTALLER_TITLE =
"com.android.content.pm.extra.UNARCHIVE_INSTALLER_TITLE";
+ private static final PorterDuffColorFilter OPACITY_LAYER_FILTER =
+ new PorterDuffColorFilter(
+ Color.argb(0.5f /* alpha */, 0f /* red */, 0f /* green */, 0f /* blue */),
+ PorterDuff.Mode.SRC_ATOP);
+
private final Context mContext;
private final PackageManagerService mPm;
@@ -746,11 +751,7 @@
return bitmap;
}
BitmapDrawable appIconDrawable = new BitmapDrawable(mContext.getResources(), bitmap);
- PorterDuffColorFilter colorFilter =
- new PorterDuffColorFilter(
- Color.argb(0.32f /* alpha */, 0f /* red */, 0f /* green */, 0f /* blue */),
- PorterDuff.Mode.SRC_ATOP);
- appIconDrawable.setColorFilter(colorFilter);
+ appIconDrawable.setColorFilter(OPACITY_LAYER_FILTER);
appIconDrawable.setBounds(
0 /* left */,
0 /* top */,
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 671e031..3afba39 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -3291,7 +3291,7 @@
final PermissionAllowlist permissionAllowlist =
SystemConfig.getInstance().getPermissionAllowlist();
final String packageName = packageState.getPackageName();
- if (packageState.isVendor()) {
+ if (packageState.isVendor() || packageState.isOdm()) {
return permissionAllowlist.getVendorPrivilegedAppAllowlistState(packageName,
permissionName);
} else if (packageState.isProduct()) {
@@ -3386,7 +3386,7 @@
// the permission's protectionLevel does not have the extra 'vendorPrivileged'
// flag.
if (allowed && isPrivilegedPermission && !bp.isVendorPrivileged()
- && pkgSetting.isVendor()) {
+ && (pkgSetting.isVendor() || pkgSetting.isOdm())) {
Slog.w(TAG, "Permission " + permissionName
+ " cannot be granted to privileged vendor apk " + pkg.getPackageName()
+ " because it isn't a 'vendorPrivileged' permission.");
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f3922f9..1ce87a7 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -565,7 +565,6 @@
boolean idle; // has the activity gone idle?
boolean hasBeenLaunched;// has this activity ever been launched?
boolean immersive; // immersive mode (don't interrupt if possible)
- boolean forceNewConfig; // force re-create with new config next time
boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
// activity can enter picture in picture while pausing (only when switching to another task)
// The PiP params used when deferring the entering of picture-in-picture.
@@ -9600,7 +9599,7 @@
// configurations because there are cases (like moving a task to the root pinned task) where
// the combine configurations are equal, but would otherwise differ in the override config
mTmpConfig.setTo(mLastReportedConfiguration.getMergedConfiguration());
- if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
+ if (getConfiguration().equals(mTmpConfig) && !displayChanged) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
+ "unchanged in %s", this);
return true;
@@ -9627,7 +9626,7 @@
return true;
}
- if (changes == 0 && !forceNewConfig) {
+ if (changes == 0) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration no differences in %s",
this);
// There are no significant differences, so we won't relaunch but should still deliver
@@ -9649,7 +9648,6 @@
// pick that up next time it starts.
if (!attachedToProcess()) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration doesn't matter not running %s", this);
- forceNewConfig = false;
return true;
}
@@ -9659,11 +9657,10 @@
Integer.toHexString(changes), Integer.toHexString(info.getRealConfigChanged()),
mLastReportedConfiguration);
- if (shouldRelaunchLocked(changes, mTmpConfig) || forceNewConfig) {
+ if (shouldRelaunchLocked(changes, mTmpConfig)) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
configChangeFlags |= changes;
startFreezingScreenLocked(globalChanges);
- forceNewConfig = false;
// Do not preserve window if it is freezing screen because the original window won't be
// able to update drawn state that causes freeze timeout.
preserveWindow &= isResizeOnlyChange(changes) && !mFreezingScreen;
@@ -9883,7 +9880,6 @@
try {
ProtoLog.i(WM_DEBUG_STATES, "Moving to %s Relaunching %s callers=%s" ,
(andResume ? "RESUMED" : "PAUSED"), this, Debug.getCallers(6));
- forceNewConfig = false;
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(token,
pendingResults, pendingNewIntents, configChangeFlags,
new MergedConfiguration(getProcessGlobalConfiguration(),
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
index 86be6ba..7af494c 100644
--- a/services/core/java/com/android/server/wm/ActivitySnapshotController.java
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -33,6 +33,7 @@
import com.android.server.LocalServices;
import com.android.server.pm.UserManagerInternal;
import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
+import com.android.window.flags.Flags;
import java.io.File;
import java.util.ArrayList;
@@ -121,7 +122,8 @@
// TODO remove when enabled
static boolean isSnapshotEnabled() {
- return SystemProperties.getInt("persist.wm.debug.activity_screenshot", 0) != 0;
+ return SystemProperties.getInt("persist.wm.debug.activity_screenshot", 0) != 0
+ || Flags.activitySnapshotByDefault();
}
static PersistInfoProvider createPersistInfoProvider(
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 1b45c1b..e7621ff 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -224,7 +224,7 @@
// before issuing the work challenge.
return true;
}
- if (interceptLockedManagedProfileIfNeeded()) {
+ if (interceptLockedProfileIfNeeded()) {
return true;
}
if (interceptHomeIfNeeded()) {
@@ -378,7 +378,7 @@
return true;
}
- private boolean interceptLockedManagedProfileIfNeeded() {
+ private boolean interceptLockedProfileIfNeeded() {
final Intent interceptingIntent = interceptWithConfirmCredentialsIfNeeded(mAInfo, mUserId);
if (interceptingIntent == null) {
return false;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index b5e5d84..cb2adbc 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -579,30 +579,11 @@
computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid),
realCallingPid);
if (resolveInfo == null) {
- final UserInfo userInfo = supervisor.getUserInfo(userId);
- if (userInfo != null && userInfo.isManagedProfile()) {
- // Special case for managed profiles, if attempting to launch non-cryto aware
- // app in a locked managed profile from an unlocked parent allow it to resolve
- // as user will be sent via confirm credentials to unlock the profile.
- final UserManager userManager = UserManager.get(supervisor.mService.mContext);
- boolean profileLockedAndParentUnlockingOrUnlocked = false;
- final long token = Binder.clearCallingIdentity();
- try {
- final UserInfo parent = userManager.getProfileParent(userId);
- profileLockedAndParentUnlockingOrUnlocked = (parent != null)
- && userManager.isUserUnlockingOrUnlocked(parent.id)
- && !userManager.isUserUnlockingOrUnlocked(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (profileLockedAndParentUnlockingOrUnlocked) {
- resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- computeResolveFilterUid(callingUid, realCallingUid,
- filterCallingUid), realCallingPid);
- }
- }
+ // Special case for profiles: If attempting to launch non-crypto aware app in a
+ // locked profile or launch an app in a profile that is stopped by quiet mode from
+ // an unlocked parent, allow it to resolve as user will be sent via confirm
+ // credentials to unlock the profile.
+ resolveInfo = resolveIntentForLockedOrStoppedProfiles(supervisor);
}
// Collect information about the target of the Intent.
@@ -616,6 +597,36 @@
UserHandle.getUserId(activityInfo.applicationInfo.uid));
}
}
+
+ /**
+ * Resolve intent for locked or stopped profiles if the parent profile is unlocking or
+ * unlocked.
+ */
+ ResolveInfo resolveIntentForLockedOrStoppedProfiles(
+ ActivityTaskSupervisor supervisor) {
+ final UserInfo userInfo = supervisor.getUserInfo(userId);
+ if (userInfo != null && userInfo.isProfile()) {
+ final UserManager userManager = UserManager.get(supervisor.mService.mContext);
+ boolean profileLockedAndParentUnlockingOrUnlocked = false;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final UserInfo parent = userManager.getProfileParent(userId);
+ profileLockedAndParentUnlockingOrUnlocked = (parent != null)
+ && userManager.isUserUnlockingOrUnlocked(parent.id)
+ && !userManager.isUserUnlockingOrUnlocked(userId);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ if (profileLockedAndParentUnlockingOrUnlocked) {
+ return supervisor.resolveIntent(intent, resolvedType, userId,
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+ computeResolveFilterUid(callingUid, realCallingUid,
+ filterCallingUid), realCallingPid);
+ }
+ }
+ return null;
+ }
}
ActivityStarter(ActivityStartController controller, ActivityTaskManagerService service,
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index e59601c..10efb94 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -906,7 +906,6 @@
}
mService.getPackageManagerInternalLocked().notifyPackageUse(
r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
- r.forceNewConfig = false;
mService.getAppWarningsLocked().onStartActivity(r);
// Because we could be starting an Activity in the system process this may not go
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 73bcc8d..1a8927e 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -19,7 +19,6 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.CompatScaleProvider.COMPAT_SCALE_MODE_SYSTEM_FIRST;
import static com.android.server.wm.CompatScaleProvider.COMPAT_SCALE_MODE_SYSTEM_LAST;
@@ -47,6 +46,7 @@
import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.Xml;
import com.android.internal.protolog.common.ProtoLog;
@@ -60,6 +60,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -347,6 +348,7 @@
private GameManagerInternal mGameManager;
private final AtomicFile mFile;
private final HashMap<String, Integer> mPackages = new HashMap<>();
+ private final SparseBooleanArray mLegacyScreenCompatPackages = new SparseBooleanArray();
private final CompatHandler mHandler;
private final SparseArray<CompatScaleProvider> mProviders = new SparseArray<>();
@@ -427,6 +429,7 @@
mPackages.remove(packageName);
scheduleWrite();
}
+ mLegacyScreenCompatPackages.delete(packageName.hashCode());
}
public void handlePackageAddedLocked(String packageName, boolean updated) {
@@ -458,6 +461,17 @@
mHandler.sendMessageDelayed(msg, 10000);
}
+ /**
+ * Returns {@code true} if the windows belonging to the package should be scaled with
+ * {@link DisplayContent#mCompatibleScreenScale}.
+ */
+ boolean useLegacyScreenCompatMode(String packageName) {
+ if (mLegacyScreenCompatPackages.size() == 0) {
+ return false;
+ }
+ return mLegacyScreenCompatPackages.get(packageName.hashCode());
+ }
+
public CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
final boolean forceCompat = getPackageCompatModeEnabledLocked(ai);
final CompatScale compatScale = getCompatScaleFromProvider(ai.packageName, ai.uid);
@@ -466,8 +480,18 @@
: getCompatScale(ai.packageName, ai.uid, /* checkProvider= */ false);
final float densityScale = compatScale != null ? compatScale.mDensityScaleFactor : appScale;
final Configuration config = mService.getGlobalConfiguration();
- return new CompatibilityInfo(ai, config.screenLayout, config.smallestScreenWidthDp,
- forceCompat, appScale, densityScale);
+ final CompatibilityInfo info = new CompatibilityInfo(ai, config.screenLayout,
+ config.smallestScreenWidthDp, forceCompat, appScale, densityScale);
+ // Ignore invalid info which may be a placeholder of isolated process.
+ if (ai.flags != 0 && ai.sourceDir != null) {
+ if (!info.supportsScreen() && !"android".equals(ai.packageName)) {
+ Slog.i(TAG, "Use legacy screen compat mode: " + ai.packageName);
+ mLegacyScreenCompatPackages.put(ai.packageName.hashCode(), true);
+ } else if (mLegacyScreenCompatPackages.size() > 0) {
+ mLegacyScreenCompatPackages.delete(ai.packageName.hashCode());
+ }
+ }
+ return info;
}
float getCompatScale(String packageName, int uid) {
@@ -718,14 +742,23 @@
scheduleWrite();
- final Task rootTask = mService.getTopDisplayFocusedRootTask();
- ActivityRecord starting = rootTask.restartPackage(packageName);
-
+ final ArrayList<WindowProcessController> restartedApps = new ArrayList<>();
+ mService.mRootWindowContainer.forAllWindows(w -> {
+ final ActivityRecord ar = w.mActivityRecord;
+ if (ar != null) {
+ if (ar.packageName.equals(packageName) && !restartedApps.contains(ar.app)) {
+ ar.restartProcessIfVisible();
+ restartedApps.add(ar.app);
+ }
+ } else if (w.getProcess().mInfo.packageName.equals(packageName)) {
+ w.updateGlobalScale();
+ }
+ }, true /* traverseTopToBottom */);
// Tell all processes that loaded this package about the change.
SparseArray<WindowProcessController> pidMap = mService.mProcessMap.getPidMap();
for (int i = pidMap.size() - 1; i >= 0; i--) {
final WindowProcessController app = pidMap.valueAt(i);
- if (!app.containsPackage(packageName)) {
+ if (!app.containsPackage(packageName) || restartedApps.contains(app)) {
continue;
}
try {
@@ -737,14 +770,6 @@
} catch (Exception e) {
}
}
-
- if (starting != null) {
- starting.ensureActivityConfiguration(0 /* globalChanges */,
- false /* preserveWindow */);
- // And we need to make sure at this point that all other activities
- // are made visible with the correct configuration.
- rootTask.ensureActivitiesVisible(starting, 0, !PRESERVE_WINDOWS);
- }
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index c98280e..f8dc9c7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -512,7 +512,11 @@
*/
private final DisplayMetrics mCompatDisplayMetrics = new DisplayMetrics();
- /** The desired scaling factor for compatible apps. */
+ /**
+ * The desired scaling factor for compatible apps. It limits the size of the window to be
+ * original size ([320x480] x density). Used to scale window for applications running under
+ * legacy compatibility mode.
+ */
float mCompatibleScreenScale;
/** @see #getCurrentOverrideConfigurationChanges */
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 671acfc..dbfcc22 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -34,7 +34,6 @@
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
@@ -5917,22 +5916,6 @@
return activities;
}
- ActivityRecord restartPackage(String packageName) {
- ActivityRecord starting = topRunningActivity();
-
- // All activities that came from the package must be
- // restarted as if there was a config change.
- forAllActivities(r -> {
- if (!r.info.packageName.equals(packageName)) return;
- r.forceNewConfig = true;
- if (starting != null && r == starting && r.isVisibleRequested()) {
- r.startFreezingScreenLocked(CONFIG_SCREEN_LAYOUT);
- }
- });
-
- return starting;
- }
-
Task reuseOrCreateTask(ActivityInfo info, Intent intent, boolean toTop) {
return reuseOrCreateTask(info, intent, null /*voiceSession*/, null /*voiceInteractor*/,
toTop, null /*activity*/, null /*source*/, null /*options*/);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 56e7c69..9c21e4c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -52,7 +52,6 @@
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NOT_MAGNIFIABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY;
@@ -1247,13 +1246,14 @@
* @see ActivityRecord#hasSizeCompatBounds()
*/
boolean hasCompatScale() {
- if ((mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0) {
- return true;
- }
if (mAttrs.type == TYPE_APPLICATION_STARTING) {
// Exclude starting window because it is not displayed by the application.
return false;
}
+ if (mWmService.mAtmService.mCompatModePackages.useLegacyScreenCompatMode(
+ mSession.mProcess.mInfo.packageName)) {
+ return true;
+ }
return mActivityRecord != null && mActivityRecord.hasSizeCompatBounds()
|| mOverrideScale != 1f;
}
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index c625b1e..adbd3c9 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -595,7 +595,7 @@
<!-- Sets the brightness mapping of the desired screen brightness to the corresponding
lux for the current display -->
<xs:element name="luxToBrightnessMapping" type="luxToBrightnessMapping"
- minOccurs="0" maxOccurs="1">
+ minOccurs="0" maxOccurs="unbounded">
<xs:annotation name="final"/>
</xs:element>
</xs:sequence>
@@ -619,12 +619,20 @@
This is used in place of config_autoBrightnessLevels and config_autoBrightnessLcdBacklightValues
defined in the config XML resource.
+
+ On devices that allow users to choose from a set of predefined options in display
+ auto-brightness settings, multiple mappings for different modes and settings can be defined.
+
+ If no mode is specified, the mapping will be used for the default mode.
+ If no setting is specified, the mapping will be used for the normal brightness setting.
-->
<xs:complexType name="luxToBrightnessMapping">
<xs:element name="map" type="nonNegativeFloatToFloatMap">
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
+ <xs:element name="mode" type="xs:string" minOccurs="0"/>
+ <xs:element name="setting" type="xs:string" minOccurs="0"/>
</xs:complexType>
<!-- Represents a point in the display brightness mapping, representing the lux level from the
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 8c8c123..98c95ed 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -8,13 +8,12 @@
method public final java.math.BigInteger getDarkeningLightDebounceIdleMillis();
method public final java.math.BigInteger getDarkeningLightDebounceMillis();
method public boolean getEnabled();
- method public final com.android.server.display.config.LuxToBrightnessMapping getLuxToBrightnessMapping();
+ method public final java.util.List<com.android.server.display.config.LuxToBrightnessMapping> getLuxToBrightnessMapping();
method public final void setBrighteningLightDebounceIdleMillis(java.math.BigInteger);
method public final void setBrighteningLightDebounceMillis(java.math.BigInteger);
method public final void setDarkeningLightDebounceIdleMillis(java.math.BigInteger);
method public final void setDarkeningLightDebounceMillis(java.math.BigInteger);
method public void setEnabled(boolean);
- method public final void setLuxToBrightnessMapping(com.android.server.display.config.LuxToBrightnessMapping);
}
public class BlockingZoneConfig {
@@ -220,7 +219,11 @@
public class LuxToBrightnessMapping {
ctor public LuxToBrightnessMapping();
method @NonNull public final com.android.server.display.config.NonNegativeFloatToFloatMap getMap();
+ method public String getMode();
+ method public String getSetting();
method public final void setMap(@NonNull com.android.server.display.config.NonNegativeFloatToFloatMap);
+ method public void setMode(String);
+ method public void setSetting(String);
}
public class NitsMap {
diff --git a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index 189d9bb..c5a1ba1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -107,20 +107,6 @@
468.5f,
};
- private static final int[] DISPLAY_LEVELS_INT = {
- 9,
- 30,
- 45,
- 62,
- 78,
- 96,
- 119,
- 146,
- 178,
- 221,
- 255
- };
-
private static final float[] DISPLAY_LEVELS = {
0.03f,
0.11f,
@@ -172,62 +158,23 @@
DisplayWhiteBalanceController mMockDwbc;
@Test
- public void testSimpleStrategyMappingAtControlPoints_IntConfig() {
- Resources res = createResources(DISPLAY_LEVELS_INT);
- DisplayDeviceConfig ddc = createDdc();
+ public void testSimpleStrategyMappingAtControlPoints() {
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevels(DISPLAY_LEVELS).build();
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc,
- AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
+ AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 0; i < LUX_LEVELS.length; i++) {
- final float expectedLevel = MathUtils.map(PowerManager.BRIGHTNESS_OFF + 1,
- PowerManager.BRIGHTNESS_ON, PowerManager.BRIGHTNESS_MIN,
- PowerManager.BRIGHTNESS_MAX, DISPLAY_LEVELS_INT[i]);
- assertEquals(expectedLevel,
- simple.getBrightness(LUX_LEVELS[i]), 0.0001f /*tolerance*/);
+ assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]), TOLERANCE);
}
}
@Test
- public void testSimpleStrategyMappingBetweenControlPoints_IntConfig() {
- Resources res = createResources(DISPLAY_LEVELS_INT);
- DisplayDeviceConfig ddc = createDdc();
+ public void testSimpleStrategyMappingBetweenControlPoints() {
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevels(DISPLAY_LEVELS).build();
BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc,
- AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
- assertNotNull("BrightnessMappingStrategy should not be null", simple);
- for (int i = 1; i < LUX_LEVELS.length; i++) {
- final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
- final float backlight = simple.getBrightness(lux) * PowerManager.BRIGHTNESS_ON;
- assertTrue("Desired brightness should be between adjacent control points.",
- backlight > DISPLAY_LEVELS_INT[i - 1]
- && backlight < DISPLAY_LEVELS_INT[i]);
- }
- }
-
- @Test
- public void testSimpleStrategyMappingAtControlPoints_FloatConfig() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
- EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
- BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc,
- AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
- assertNotNull("BrightnessMappingStrategy should not be null", simple);
- for (int i = 0; i < LUX_LEVELS.length; i++) {
- assertEquals(DISPLAY_LEVELS[i], simple.getBrightness(LUX_LEVELS[i]),
- /* tolerance= */ 0.0001f);
- }
- }
-
- @Test
- public void testSimpleStrategyMappingBetweenControlPoints_FloatConfig() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY, EMPTY_FLOAT_ARRAY, LUX_LEVELS,
- EMPTY_FLOAT_ARRAY, DISPLAY_LEVELS);
- BrightnessMappingStrategy simple = BrightnessMappingStrategy.create(res, ddc,
- AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
+ AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", simple);
for (int i = 1; i < LUX_LEVELS.length; i++) {
final float lux = (LUX_LEVELS[i - 1] + LUX_LEVELS[i]) / 2;
@@ -239,8 +186,8 @@
@Test
public void testSimpleStrategyIgnoresNewConfiguration() {
- Resources res = createResources(DISPLAY_LEVELS_INT);
- DisplayDeviceConfig ddc = createDdc();
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevels(DISPLAY_LEVELS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
@@ -255,25 +202,23 @@
@Test
public void testSimpleStrategyIgnoresNullConfiguration() {
- Resources res = createResources(DISPLAY_LEVELS_INT);
- DisplayDeviceConfig ddc = createDdc();
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevels(DISPLAY_LEVELS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
strategy.setBrightnessConfiguration(null);
- final int n = DISPLAY_LEVELS_INT.length;
- final float expectedBrightness =
- (float) DISPLAY_LEVELS_INT[n - 1] / PowerManager.BRIGHTNESS_ON;
+ final int n = DISPLAY_LEVELS.length;
+ final float expectedBrightness = DISPLAY_LEVELS[n - 1];
assertEquals(expectedBrightness,
strategy.getBrightness(LUX_LEVELS[n - 1]), 0.0001f /*tolerance*/);
}
@Test
public void testPhysicalStrategyMappingAtControlPoints() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT,
- LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS)
+ .build();
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
@@ -290,9 +235,9 @@
@Test
public void testPhysicalStrategyMappingBetweenControlPoints() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE,
- LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setBrightnessRange(BACKLIGHT_RANGE_ZERO_TO_ONE)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS).build();
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNotNull("BrightnessMappingStrategy should not be null", physical);
@@ -309,9 +254,9 @@
@Test
public void testPhysicalStrategyUsesNewConfigurations() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS)
+ .build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
@@ -336,9 +281,9 @@
@Test
public void testPhysicalStrategyRecalculateSplines() {
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS)
+ .build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
float[] adjustedNits50p = new float[DISPLAY_RANGE_NITS.length];
@@ -381,9 +326,10 @@
@Test
public void testDefaultStrategyIsPhysical() {
- Resources res = createResources(DISPLAY_LEVELS_INT);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevels(DISPLAY_LEVELS)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS)
+ .build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertTrue(strategy instanceof BrightnessMappingStrategy.PhysicalMappingStrategy);
@@ -396,17 +342,17 @@
float tmp = lux[idx];
lux[idx] = lux[idx + 1];
lux[idx + 1] = tmp;
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(lux)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNull(strategy);
// And make sure we get the same result even if it's monotone but not increasing.
lux[idx] = lux[idx + 1];
- ddc = createDdc(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux,
- DISPLAY_LEVELS_NITS);
+ ddc = new DdcBuilder().setAutoBrightnessLevelsLux(lux)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS).build();
strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
mMockDwbc);
assertNull(strategy);
@@ -419,25 +365,25 @@
// Make sure it's strictly increasing so that the only failure is the differing array
// lengths
lux[lux.length - 1] = lux[lux.length - 2] + 1;
- Resources res = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, lux, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(lux)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNull(strategy);
- res = createResources(DISPLAY_LEVELS_INT);
+ ddc = new DdcBuilder().setAutoBrightnessLevelsLux(lux)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS)
+ .setAutoBrightnessLevels(DISPLAY_LEVELS).build();
strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
mMockDwbc);
assertNull(strategy);
// Extra backlight level
- final int[] backlight = Arrays.copyOf(
- DISPLAY_LEVELS_INT, DISPLAY_LEVELS_INT.length + 1);
+ final float[] backlight = Arrays.copyOf(DISPLAY_LEVELS, DISPLAY_LEVELS.length + 1);
backlight[backlight.length - 1] = backlight[backlight.length - 2] + 1;
- res = createResources(backlight);
- ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, EMPTY_FLOAT_ARRAY);
+ res = createResources();
+ ddc = new DdcBuilder().setAutoBrightnessLevels(backlight).build();
strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
mMockDwbc);
assertNull(strategy);
@@ -445,9 +391,9 @@
// Extra nits level
final float[] nits = Arrays.copyOf(DISPLAY_RANGE_NITS, DISPLAY_LEVELS_NITS.length + 1);
nits[nits.length - 1] = nits[nits.length - 2] + 1;
- res = createResources(EMPTY_INT_ARRAY);
- ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, LUX_LEVELS, nits);
+ res = createResources();
+ ddc = new DdcBuilder().setAutoBrightnessLevelsNits(nits)
+ .setAutoBrightnessLevels(EMPTY_FLOAT_ARRAY).build();
strategy = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
mMockDwbc);
assertNull(strategy);
@@ -455,40 +401,32 @@
@Test
public void testPhysicalStrategyRequiresNitsMapping() {
- Resources res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/);
- DisplayDeviceConfig ddc = createDdc(EMPTY_FLOAT_ARRAY /*nitsRange*/);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setNitsRange(EMPTY_FLOAT_ARRAY).build();
BrightnessMappingStrategy physical = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertNull(physical);
-
- res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/);
- physical = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
- assertNull(physical);
-
- res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/);
- physical = BrightnessMappingStrategy.create(res, ddc, AUTO_BRIGHTNESS_MODE_DEFAULT,
- mMockDwbc);
- assertNull(physical);
}
@Test
public void testStrategiesAdaptToUserDataPoint() {
- Resources res = createResources(EMPTY_INT_ARRAY /*brightnessLevelsBacklight*/);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE,
- LUX_LEVELS, DISPLAY_LEVELS_NITS);
+ Resources res = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setBrightnessRange(BACKLIGHT_RANGE_ZERO_TO_ONE)
+ .setAutoBrightnessLevelsNits(DISPLAY_LEVELS_NITS).build();
assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc));
- ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
- res = createResources(DISPLAY_LEVELS_INT);
+ ddc = new DdcBuilder().setBrightnessRange(BACKLIGHT_RANGE_ZERO_TO_ONE)
+ .setAutoBrightnessLevels(DISPLAY_LEVELS).build();
+ res = createResources();
assertStrategyAdaptsToUserDataPoints(BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc));
}
@Test
public void testIdleModeConfigLoadsCorrectly() {
- Resources res = createResourcesIdle(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
+ Resources res = createResources(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
+ DisplayDeviceConfig ddc = new DdcBuilder().setBrightnessRange(BACKLIGHT_RANGE_ZERO_TO_ONE)
+ .build();
// Create an idle mode bms
// This will fail if it tries to fetch the wrong configuration.
@@ -562,17 +500,11 @@
assertEquals(minBrightness, strategy.getBrightness(LUX_LEVELS[0]), 0.0001f /*tolerance*/);
}
- private Resources createResources(int[] brightnessLevelsBacklight) {
- return createResources(brightnessLevelsBacklight, EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY);
+ private Resources createResources() {
+ return createResources(EMPTY_INT_ARRAY, EMPTY_FLOAT_ARRAY);
}
- private Resources createResourcesIdle(int[] luxLevelsIdle, float[] brightnessLevelsNitsIdle) {
- return createResources(EMPTY_INT_ARRAY,
- luxLevelsIdle, brightnessLevelsNitsIdle);
- }
-
- private Resources createResources(int[] brightnessLevelsBacklight, int[] luxLevelsIdle,
- float[] brightnessLevelsNitsIdle) {
+ private Resources createResources(int[] luxLevelsIdle, float[] brightnessLevelsNitsIdle) {
Resources mockResources = mock(Resources.class);
if (luxLevelsIdle.length > 0) {
@@ -583,10 +515,6 @@
.thenReturn(luxLevelsIdleResource);
}
- when(mockResources.getIntArray(
- com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
- .thenReturn(brightnessLevelsBacklight);
-
TypedArray mockBrightnessLevelNitsIdle = createFloatTypedArray(brightnessLevelsNitsIdle);
when(mockResources.obtainTypedArray(
com.android.internal.R.array.config_autoBrightnessDisplayValuesNitsIdle))
@@ -604,41 +532,6 @@
return mockResources;
}
- private DisplayDeviceConfig createDdc() {
- return createDdc(DISPLAY_RANGE_NITS);
- }
-
- private DisplayDeviceConfig createDdc(float[] nitsArray) {
- return createDdc(nitsArray, DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT);
- }
-
- private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray) {
- DisplayDeviceConfig mockDdc = mock(DisplayDeviceConfig.class);
- when(mockDdc.getNits()).thenReturn(nitsArray);
- when(mockDdc.getBrightness()).thenReturn(backlightArray);
- when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(LUX_LEVELS);
- when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(EMPTY_FLOAT_ARRAY);
- when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(EMPTY_FLOAT_ARRAY);
- return mockDdc;
- }
-
- private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
- float[] luxLevelsFloat, float[] brightnessLevelsNits) {
- return createDdc(nitsArray, backlightArray, luxLevelsFloat, brightnessLevelsNits,
- EMPTY_FLOAT_ARRAY);
- }
-
- private DisplayDeviceConfig createDdc(float[] nitsArray, float[] backlightArray,
- float[] luxLevelsFloat, float[] brightnessLevelsNits, float[] brightnessLevels) {
- DisplayDeviceConfig mockDdc = mock(DisplayDeviceConfig.class);
- when(mockDdc.getNits()).thenReturn(nitsArray);
- when(mockDdc.getBrightness()).thenReturn(backlightArray);
- when(mockDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(luxLevelsFloat);
- when(mockDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(brightnessLevelsNits);
- when(mockDdc.getAutoBrightnessBrighteningLevels()).thenReturn(brightnessLevels);
- return mockDdc;
- }
-
private TypedArray createFloatTypedArray(float[] vals) {
TypedArray mockArray = mock(TypedArray.class);
when(mockArray.length()).thenAnswer(invocation -> {
@@ -677,10 +570,9 @@
final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2);
final float y3 = GAMMA_CORRECTION_SPLINE.interpolate(x3);
- Resources resources = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX,
- GAMMA_CORRECTION_NITS);
+ Resources resources = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(GAMMA_CORRECTION_LUX)
+ .setAutoBrightnessLevelsNits(GAMMA_CORRECTION_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
// Let's start with a validity check:
@@ -708,10 +600,9 @@
final float y1 = GAMMA_CORRECTION_SPLINE.interpolate(x1);
final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2);
final float y3 = GAMMA_CORRECTION_SPLINE.interpolate(x3);
- Resources resources = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX,
- GAMMA_CORRECTION_NITS);
+ Resources resources = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(GAMMA_CORRECTION_LUX)
+ .setAutoBrightnessLevelsNits(GAMMA_CORRECTION_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
// Validity check:
@@ -736,10 +627,9 @@
public void testGammaCorrectionExtremeChangeAtCenter() {
// Extreme changes (e.g. setting brightness to 0.0 or 1.0) can't be gamma corrected, so we
// just make sure the adjustment reflects the change.
- Resources resources = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX,
- GAMMA_CORRECTION_NITS);
+ Resources resources = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(GAMMA_CORRECTION_LUX)
+ .setAutoBrightnessLevelsNits(GAMMA_CORRECTION_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
assertEquals(0.0f, strategy.getAutoBrightnessAdjustment(), /* delta= */ 0.0001f);
@@ -760,10 +650,9 @@
final float y0 = GAMMA_CORRECTION_SPLINE.interpolate(x0);
final float y2 = GAMMA_CORRECTION_SPLINE.interpolate(x2);
final float y4 = GAMMA_CORRECTION_SPLINE.interpolate(x4);
- Resources resources = createResources(EMPTY_INT_ARRAY);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS,
- DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT, GAMMA_CORRECTION_LUX,
- GAMMA_CORRECTION_NITS);
+ Resources resources = createResources();
+ DisplayDeviceConfig ddc = new DdcBuilder().setAutoBrightnessLevelsLux(GAMMA_CORRECTION_LUX)
+ .setAutoBrightnessLevelsNits(GAMMA_CORRECTION_NITS).build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(resources, ddc,
AUTO_BRIGHTNESS_MODE_DEFAULT, mMockDwbc);
// Validity, as per tradition:
@@ -790,11 +679,54 @@
@Test
public void testGetMode() {
- Resources res = createResourcesIdle(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
- DisplayDeviceConfig ddc = createDdc(DISPLAY_RANGE_NITS, BACKLIGHT_RANGE_ZERO_TO_ONE);
+ Resources res = createResources(LUX_LEVELS_IDLE, DISPLAY_LEVELS_NITS_IDLE);
+ DisplayDeviceConfig ddc = new DdcBuilder().setBrightnessRange(BACKLIGHT_RANGE_ZERO_TO_ONE)
+ .build();
BrightnessMappingStrategy strategy = BrightnessMappingStrategy.create(res, ddc,
AUTO_BRIGHTNESS_MODE_IDLE,
mMockDwbc);
assertEquals(AUTO_BRIGHTNESS_MODE_IDLE, strategy.getMode());
}
+
+ private static class DdcBuilder {
+ private DisplayDeviceConfig mDdc;
+
+ DdcBuilder() {
+ mDdc = mock(DisplayDeviceConfig.class);
+ when(mDdc.getNits()).thenReturn(DISPLAY_RANGE_NITS);
+ when(mDdc.getBrightness()).thenReturn(DISPLAY_LEVELS_RANGE_BACKLIGHT_FLOAT);
+ when(mDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(LUX_LEVELS);
+ when(mDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(EMPTY_FLOAT_ARRAY);
+ when(mDdc.getAutoBrightnessBrighteningLevels()).thenReturn(EMPTY_FLOAT_ARRAY);
+ }
+
+ DdcBuilder setNitsRange(float[] nitsArray) {
+ when(mDdc.getNits()).thenReturn(nitsArray);
+ return this;
+ }
+
+ DdcBuilder setBrightnessRange(float[] brightnessArray) {
+ when(mDdc.getBrightness()).thenReturn(brightnessArray);
+ return this;
+ }
+
+ DdcBuilder setAutoBrightnessLevelsLux(float[] luxLevels) {
+ when(mDdc.getAutoBrightnessBrighteningLevelsLux()).thenReturn(luxLevels);
+ return this;
+ }
+
+ DdcBuilder setAutoBrightnessLevelsNits(float[] brightnessLevelsNits) {
+ when(mDdc.getAutoBrightnessBrighteningLevelsNits()).thenReturn(brightnessLevelsNits);
+ return this;
+ }
+
+ DdcBuilder setAutoBrightnessLevels(float[] brightnessLevels) {
+ when(mDdc.getAutoBrightnessBrighteningLevels()).thenReturn(brightnessLevels);
+ return this;
+ }
+
+ DisplayDeviceConfig build() {
+ return mDdc;
+ }
+ }
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 31d7e88..a4c15b5 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -17,6 +17,7 @@
package com.android.server.display;
+import static com.android.internal.display.BrightnessSynchronizer.brightnessIntToFloat;
import static com.android.server.display.config.SensorData.SupportedMode;
import static com.android.server.display.utils.DeviceConfigParsingUtils.ambientBrightnessThresholdsIntToFloat;
import static com.android.server.display.utils.DeviceConfigParsingUtils.displayBrightnessThresholdsIntToFloat;
@@ -47,7 +48,6 @@
import androidx.test.filters.SmallTest;
import com.android.internal.R;
-import com.android.internal.display.BrightnessSynchronizer;
import com.android.server.display.config.HdrBrightnessData;
import com.android.server.display.config.ThermalStatus;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -609,6 +609,9 @@
float[]{2.0f, 200.0f, 600.0f}, ZERO_DELTA);
assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
float[]{0.0f, 110.0f, 500.0f}, ZERO_DELTA);
+ assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), new
+ float[]{brightnessIntToFloat(50), brightnessIntToFloat(100),
+ brightnessIntToFloat(150)}, SMALL_DELTA);
// Test thresholds
assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA);
@@ -674,7 +677,7 @@
assertEquals("test_light_sensor", mDisplayDeviceConfig.getAmbientLightSensor().type);
assertEquals("", mDisplayDeviceConfig.getAmbientLightSensor().name);
- assertEquals(BrightnessSynchronizer.brightnessIntToFloat(35),
+ assertEquals(brightnessIntToFloat(35),
mDisplayDeviceConfig.getBrightnessCapForWearBedtimeMode(), ZERO_DELTA);
}
@@ -737,6 +740,27 @@
mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
assertArrayEquals(new float[]{0.2f, 0.3f},
mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), SMALL_DELTA);
+
+ assertArrayEquals(new float[]{0.0f, 90},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux("default", "dim"),
+ ZERO_DELTA);
+ assertArrayEquals(new float[]{0.3f, 0.4f},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels("default", "dim"),
+ SMALL_DELTA);
+
+ assertArrayEquals(new float[]{0.0f, 95},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux("doze", "normal"),
+ ZERO_DELTA);
+ assertArrayEquals(new float[]{0.35f, 0.45f},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels("doze", "normal"),
+ SMALL_DELTA);
+
+ assertArrayEquals(new float[]{0.0f, 100},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux("doze", "bright"),
+ ZERO_DELTA);
+ assertArrayEquals(new float[]{0.4f, 0.5f},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels("doze", "bright"),
+ SMALL_DELTA);
}
@Test
@@ -746,7 +770,9 @@
setupDisplayDeviceConfigFromDisplayConfigFile(getContent(getValidLuxThrottling(),
getValidProxSensor(), /* includeIdleMode= */ false));
- assertNull(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels());
+ assertArrayEquals(new float[]{brightnessIntToFloat(50), brightnessIntToFloat(100),
+ brightnessIntToFloat(150)},
+ mDisplayDeviceConfig.getAutoBrightnessBrighteningLevels(), SMALL_DELTA);
assertArrayEquals(new float[]{0, 110, 500},
mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), ZERO_DELTA);
assertArrayEquals(new float[]{2, 200, 600},
@@ -1138,6 +1164,46 @@
+ "</point>\n"
+ "</map>\n"
+ "</luxToBrightnessMapping>\n"
+ + "<luxToBrightnessMapping>\n"
+ + "<setting>dim</setting>\n"
+ + "<map>\n"
+ + "<point>\n"
+ + "<first>0</first>\n"
+ + "<second>0.3</second>\n"
+ + "</point>\n"
+ + "<point>\n"
+ + "<first>90</first>\n"
+ + "<second>0.4</second>\n"
+ + "</point>\n"
+ + "</map>\n"
+ + "</luxToBrightnessMapping>\n"
+ + "<luxToBrightnessMapping>\n"
+ + "<mode>doze</mode>\n"
+ + "<map>\n"
+ + "<point>\n"
+ + "<first>0</first>\n"
+ + "<second>0.35</second>\n"
+ + "</point>\n"
+ + "<point>\n"
+ + "<first>95</first>\n"
+ + "<second>0.45</second>\n"
+ + "</point>\n"
+ + "</map>\n"
+ + "</luxToBrightnessMapping>\n"
+ + "<luxToBrightnessMapping>\n"
+ + "<mode>doze</mode>\n"
+ + "<setting>bright</setting>\n"
+ + "<map>\n"
+ + "<point>\n"
+ + "<first>0</first>\n"
+ + "<second>0.4</second>\n"
+ + "</point>\n"
+ + "<point>\n"
+ + "<first>100</first>\n"
+ + "<second>0.5</second>\n"
+ + "</point>\n"
+ + "</map>\n"
+ + "</luxToBrightnessMapping>\n"
+ "</autoBrightness>\n"
+ getPowerThrottlingConfig()
+ "<highBrightnessMode enabled=\"true\">\n"
@@ -1435,6 +1501,10 @@
when(mResources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevels))
.thenReturn(screenBrightnessLevelLux);
+ int[] screenBrightnessLevels = new int[]{50, 100, 150};
+ when(mResources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
+ .thenReturn(screenBrightnessLevels);
// Thresholds
// Config.xml requires the levels arrays to be of length N and the thresholds arrays to be
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 0c845de..00f9892 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -206,6 +206,9 @@
when(mMockedResources.getIntArray(
com.android.internal.R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate))
.thenReturn(new int[]{});
+ when(mMockedResources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLcdBacklightValues))
+ .thenReturn(new int[]{});
doReturn(true).when(mFlags).isDisplayOffloadEnabled();
initDisplayOffloadSession();
}
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
index edfe1b4..071d571 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/camera/VirtualCameraControllerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,10 +24,8 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.companion.virtual.camera.VirtualCameraCallback;
import android.companion.virtual.camera.VirtualCameraConfig;
-import android.companion.virtual.camera.VirtualCameraMetadata;
import android.companion.virtual.camera.VirtualCameraStreamConfig;
import android.companion.virtualcamera.IVirtualCameraService;
import android.companion.virtualcamera.VirtualCameraConfiguration;
@@ -156,10 +154,6 @@
@NonNull VirtualCameraStreamConfig streamConfig) {}
@Override
- public void onProcessCaptureRequest(
- int streamId, long frameId, @Nullable VirtualCameraMetadata metadata) {}
-
- @Override
public void onStreamClosed(int streamId) {}
};
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
index 4a1435f..1fcee06 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeEventLoggerFake.java
@@ -99,7 +99,7 @@
public boolean getFromSystemOrSystemUi(int i) throws IllegalArgumentException {
// While this isn't a logged output value, it's still helpful to check in tests.
checkInRange(i);
- return mChanges.get(i).mFromSystemOrSystemUi;
+ return mChanges.get(i).isFromSystemOrSystemUi();
}
public boolean getIsUserAction(int i) throws IllegalArgumentException {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index bc63c29e..44f0894 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -43,6 +43,8 @@
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;
+import static android.service.notification.Condition.SOURCE_SCHEDULE;
+import static android.service.notification.Condition.SOURCE_USER_ACTION;
import static android.service.notification.Condition.STATE_FALSE;
import static android.service.notification.Condition.STATE_TRUE;
import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP;
@@ -120,12 +122,13 @@
import android.service.notification.DeviceEffectsApplier;
import android.service.notification.ZenDeviceEffects;
import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
import android.service.notification.ZenModeConfig.ScheduleInfo;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.notification.ZenModeDiff;
import android.service.notification.ZenPolicy;
import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
+import android.testing.TestWithLooperRule;
import android.testing.TestableLooper;
import android.util.ArrayMap;
import android.util.Log;
@@ -148,6 +151,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.truth.Correspondence;
import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.testing.junit.testparameterinjector.TestParameter;
+import com.google.testing.junit.testparameterinjector.TestParameterInjector;
import org.junit.Before;
import org.junit.Rule;
@@ -173,7 +178,7 @@
@SmallTest
@SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service.
-@RunWith(AndroidTestingRunner.class)
+@RunWith(TestParameterInjector.class)
@TestableLooper.RunWithLooper
public class ZenModeHelperTest extends UiServiceTestCase {
@@ -215,6 +220,9 @@
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(
SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+ @Rule(order = Integer.MAX_VALUE) // set the highest order so it's the innermost rule
+ public TestWithLooperRule mLooperRule = new TestWithLooperRule();
+
ConditionProviders mConditionProviders;
@Mock NotificationManager mNotificationManager;
@Mock PackageManager mPackageManager;
@@ -2341,15 +2349,38 @@
assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
}
+ private enum ModesApiFlag {
+ ENABLED(true, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_USER),
+ DISABLED(false, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI);
+
+ private final boolean mEnabled;
+ @ConfigChangeOrigin private final int mOriginForUserActionInSystemUi;
+
+ ModesApiFlag(boolean enabled, @ConfigChangeOrigin int originForUserActionInSystemUi) {
+ this.mEnabled = enabled;
+ this.mOriginForUserActionInSystemUi = originForUserActionInSystemUi;
+ }
+
+ void applyFlag(SetFlagsRule setFlagsRule) {
+ if (mEnabled) {
+ setFlagsRule.enableFlags(Flags.FLAG_MODES_API);
+ } else {
+ setFlagsRule.disableFlags(Flags.FLAG_MODES_API);
+ }
+ }
+ }
+
@Test
- public void testZenModeEventLog_setManualZenMode() throws IllegalArgumentException {
+ public void testZenModeEventLog_setManualZenMode(@TestParameter ModesApiFlag modesApiFlag)
+ throws IllegalArgumentException {
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
// Turn zen mode on (to important_interruptions)
// Need to additionally call the looper in order to finish the post-apply-config process
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
+ modesApiFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
// Now turn zen mode off, but via a different package UID -- this should get registered as
// "not an action by the user" because some other app is changing zen mode
@@ -2376,7 +2407,8 @@
assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0));
assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
- assertTrue(mZenModeEventLogger.getFromSystemOrSystemUi(0));
+ assertThat(mZenModeEventLogger.getFromSystemOrSystemUi(0)).isEqualTo(
+ modesApiFlag == ModesApiFlag.DISABLED);
assertTrue(mZenModeEventLogger.getIsUserAction(0));
assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
@@ -2401,7 +2433,9 @@
}
@Test
- public void testZenModeEventLog_automaticRules() throws IllegalArgumentException {
+ public void testZenModeEventLog_automaticRules(@TestParameter ModesApiFlag modesApiFlag)
+ throws IllegalArgumentException {
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
@@ -2423,8 +2457,8 @@
// Event 2: "User" turns off the automatic rule (sets it to not enabled)
zenRule.setEnabled(false);
- mZenModeHelper.updateAutomaticZenRule(id, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
- Process.SYSTEM_UID);
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule,
+ modesApiFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
// Add a new system rule
AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
@@ -2442,8 +2476,8 @@
UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
// Event 4: "User" deletes the rule
- mZenModeHelper.removeAutomaticZenRule(systemId, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
- Process.SYSTEM_UID);
+ mZenModeHelper.removeAutomaticZenRule(systemId, modesApiFlag.mOriginForUserActionInSystemUi,
+ "", Process.SYSTEM_UID);
// In total, this represents 4 events
assertEquals(4, mZenModeEventLogger.numLoggedChanges());
@@ -2499,20 +2533,109 @@
}
@Test
- public void testZenModeEventLog_policyChanges() throws IllegalArgumentException {
+ @EnableFlags(Flags.FLAG_MODES_API)
+ public void testZenModeEventLog_automaticRuleActivatedFromAppByAppAndUser()
+ throws IllegalArgumentException {
+ mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
+ setupZenConfig();
+
+ // Ann app adds an automatic zen rule
+ AutomaticZenRule zenRule = new AutomaticZenRule("name",
+ null,
+ new ComponentName(CUSTOM_PKG_NAME, "ScheduleConditionProvider"),
+ ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
+ null,
+ NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
+ String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+ UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID);
+
+ // Event 1: Mimic the rule coming on manually when the user turns it on in the app
+ // ("Turn on bedtime now" because user goes to bed earlier).
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_USER_ACTION),
+ UPDATE_ORIGIN_USER, CUSTOM_PKG_UID);
+
+ // Event 2: App deactivates the rule automatically (it's 8 AM, bedtime schedule ends)
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE),
+ UPDATE_ORIGIN_APP, CUSTOM_PKG_UID);
+
+ // Event 3: App activates the rule automatically (it's now 11 PM, bedtime schedule starts)
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE),
+ UPDATE_ORIGIN_APP, CUSTOM_PKG_UID);
+
+ // Event 4: User deactivates the rule manually (they get up before 8 AM on the next day)
+ mZenModeHelper.setAutomaticZenRuleState(id,
+ new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_USER_ACTION),
+ UPDATE_ORIGIN_USER, CUSTOM_PKG_UID);
+
+ // In total, this represents 4 events
+ assertEquals(4, mZenModeEventLogger.numLoggedChanges());
+
+ // Automatic rule turning on manually:
+ // - event ID: DND_TURNED_ON
+ // - 1 rule (newly) active
+ // - is a user action
+ // - package UID is the calling package
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(0));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
+ assertTrue(mZenModeEventLogger.getIsUserAction(0));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0));
+
+ // Automatic rule turned off automatically by app:
+ // - event ID: DND_TURNED_OFF
+ // - 0 rules active
+ // - is not a user action
+ // - package UID is the calling package
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(1));
+ assertEquals(0, mZenModeEventLogger.getNumRulesActive(1));
+ assertFalse(mZenModeEventLogger.getIsUserAction(1));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1));
+
+ // Automatic rule turned on automatically by app:
+ // - event ID: DND_TURNED_ON
+ // - 1 rule (newly) active
+ // - is not a user action
+ // - package UID is the calling package
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_ON.getId(),
+ mZenModeEventLogger.getEventId(2));
+ assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2));
+ assertEquals(1, mZenModeEventLogger.getNumRulesActive(2));
+ assertFalse(mZenModeEventLogger.getIsUserAction(2));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(2));
+
+ // Automatic rule turned off automatically by the user:
+ // - event ID: DND_TURNED_ON
+ // - 0 rules active
+ // - is a user action
+ // - package UID is the calling package
+ assertEquals(ZenModeEventLogger.ZenStateChangedEvent.DND_TURNED_OFF.getId(),
+ mZenModeEventLogger.getEventId(3));
+ assertEquals(0, mZenModeEventLogger.getNumRulesActive(3));
+ assertTrue(mZenModeEventLogger.getIsUserAction(3));
+ assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3));
+ }
+
+ @Test
+ public void testZenModeEventLog_policyChanges(@TestParameter ModesApiFlag modesApiFlag)
+ throws IllegalArgumentException {
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
// First just turn zen mode on
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
+ modesApiFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
// Now change the policy slightly; want to confirm that this'll be reflected in the logs
ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
newConfig.allowAlarms = true;
newConfig.allowRepeatCallers = false;
mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
+ modesApiFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
// Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
// is off.
@@ -2523,7 +2646,7 @@
newConfig.allowMessages = false;
newConfig.allowRepeatCallers = true;
mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
+ modesApiFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
// Total events: we only expect ones for turning on, changing policy, and turning off
assertEquals(3, mZenModeEventLogger.numLoggedChanges());
@@ -2556,7 +2679,9 @@
}
@Test
- public void testZenModeEventLog_ruleCounts() throws IllegalArgumentException {
+ public void testZenModeEventLog_ruleCounts(@TestParameter ModesApiFlag modesApiFlag)
+ throws IllegalArgumentException {
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
@@ -2659,8 +2784,10 @@
}
@Test
- public void testZenModeEventLog_noLogWithNoConfigChange() throws IllegalArgumentException {
+ public void testZenModeEventLog_noLogWithNoConfigChange(
+ @TestParameter ModesApiFlag modesApiFlag) throws IllegalArgumentException {
// If evaluateZenMode is called independently of a config change, don't log.
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
@@ -2677,9 +2804,11 @@
}
@Test
- public void testZenModeEventLog_reassignUid() throws IllegalArgumentException {
+ public void testZenModeEventLog_reassignUid(@TestParameter ModesApiFlag modesApiFlag)
+ throws IllegalArgumentException {
// Test that, only in specific cases, we reassign the calling UID to one associated with
// the automatic rule owner.
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
@@ -2691,7 +2820,7 @@
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
+ UPDATE_ORIGIN_APP, "test", Process.SYSTEM_UID);
// Rule 2, same as rule 1 but owned by the system
AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
@@ -2701,11 +2830,11 @@
null,
NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
- UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
+ modesApiFlag.mOriginForUserActionInSystemUi, "test", Process.SYSTEM_UID);
// Turn on rule 1; call looks like it's from the system. Because setting a condition is
// typically an automatic (non-user-initiated) action, expect the calling UID to be
- // re-evaluated to the one associat.d with CUSTOM_PKG_NAME.
+ // re-evaluated to the one associated with CUSTOM_PKG_NAME.
mZenModeHelper.setAutomaticZenRuleState(id,
new Condition(zenRule.getConditionId(), "", STATE_TRUE),
UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
@@ -2719,8 +2848,8 @@
// Disable rule 1. Because this looks like a user action, the UID should not be modified
// from the system-provided one.
zenRule.setEnabled(false);
- mZenModeHelper.updateAutomaticZenRule(id, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
- Process.SYSTEM_UID);
+ mZenModeHelper.updateAutomaticZenRule(id, zenRule,
+ modesApiFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
// Add a manual rule. Any manual rule changes should not get calling uids reassigned.
mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP,
@@ -2777,8 +2906,10 @@
}
@Test
- public void testZenModeEventLog_channelsBypassingChanges() {
+ public void testZenModeEventLog_channelsBypassingChanges(
+ @TestParameter ModesApiFlag modesApiFlag) {
// Verify that the right thing happens when the canBypassDnd value changes.
+ modesApiFlag.applyFlag(mSetFlagsRule);
mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
setupZenConfig();
@@ -2874,14 +3005,11 @@
// Second message where we change the policy:
// - DND_POLICY_CHANGED (indicates only the policy changed and nothing else)
// - rule type: unknown (it's a policy change, not a rule change)
- // - user action (because it comes from a "system" uid)
// - change is in allow channels, and final policy
assertThat(mZenModeEventLogger.getEventId(1))
.isEqualTo(ZenModeEventLogger.ZenStateChangedEvent.DND_POLICY_CHANGED.getId());
assertThat(mZenModeEventLogger.getChangedRuleType(1))
.isEqualTo(DNDProtoEnums.UNKNOWN_RULE);
- assertThat(mZenModeEventLogger.getIsUserAction(1)).isTrue();
- assertThat(mZenModeEventLogger.getPackageUid(1)).isEqualTo(Process.SYSTEM_UID);
DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1);
assertThat(dndProto.getAllowChannels().getNumber())
.isEqualTo(DNDProtoEnums.CHANNEL_TYPE_NONE);
diff --git a/services/tests/wmtests/src/com/android/server/wm/CompatModePackagesTests.java b/services/tests/wmtests/src/com/android/server/wm/CompatModePackagesTests.java
index 1f7b65e..c187263 100644
--- a/services/tests/wmtests/src/com/android/server/wm/CompatModePackagesTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/CompatModePackagesTests.java
@@ -20,10 +20,13 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import android.app.GameManagerInternal;
+import android.content.pm.ApplicationInfo;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
@@ -90,6 +93,14 @@
public void testGetCompatScale_noGameManager() {
assertEquals(mAtm.mCompatModePackages.getCompatScale(TEST_PACKAGE, TEST_USER_ID), 1f,
0.01f);
- }
+ final ApplicationInfo info = new ApplicationInfo();
+ // Any non-zero value without FLAG_SUPPORTS_*_SCREENS.
+ info.flags = ApplicationInfo.FLAG_HAS_CODE;
+ info.packageName = info.sourceDir = "legacy.app";
+ mAtm.mCompatModePackages.compatibilityInfoForPackageLocked(info);
+ assertTrue(mAtm.mCompatModePackages.useLegacyScreenCompatMode(info.packageName));
+ mAtm.mCompatModePackages.handlePackageUninstalledLocked(info.packageName);
+ assertFalse(mAtm.mCompatModePackages.useLegacyScreenCompatMode(info.packageName));
+ }
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
index 4720d27..f9fa9b7 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
@@ -106,96 +106,104 @@
@Override
public void onAttentionGained() {
Slog.v(TAG, "BinderCallback#onAttentionGained");
- mEgressingData = true;
- if (mAttentionListener == null) {
- return;
- }
- try {
- mAttentionListener.onAttentionGained();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error delivering attention gained event.", e);
- try {
- callback.onVisualQueryDetectionServiceFailure(
- new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_ATTENTION_STATE,
- "Attention listener failed to switch to GAINED state."));
- } catch (RemoteException ex) {
- Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
+ synchronized (mLock) {
+ mEgressingData = true;
+ if (mAttentionListener == null) {
+ return;
}
- return;
+ try {
+ mAttentionListener.onAttentionGained();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error delivering attention gained event.", e);
+ try {
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_ATTENTION_STATE,
+ "Attention listener fails to switch to GAINED state."));
+ } catch (RemoteException ex) {
+ Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
+ }
+ }
}
}
@Override
public void onAttentionLost() {
Slog.v(TAG, "BinderCallback#onAttentionLost");
- mEgressingData = false;
- if (mAttentionListener == null) {
- return;
- }
- try {
- mAttentionListener.onAttentionLost();
- } catch (RemoteException e) {
- Slog.e(TAG, "Error delivering attention lost event.", e);
- try {
- callback.onVisualQueryDetectionServiceFailure(
- new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_ATTENTION_STATE,
- "Attention listener failed to switch to LOST state."));
- } catch (RemoteException ex) {
- Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
+ synchronized (mLock) {
+ mEgressingData = false;
+ if (mAttentionListener == null) {
+ return;
}
- return;
+ try {
+ mAttentionListener.onAttentionLost();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error delivering attention lost event.", e);
+ try {
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_ATTENTION_STATE,
+ "Attention listener fails to switch to LOST state."));
+ } catch (RemoteException ex) {
+ Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
+ }
+ }
}
}
@Override
public void onQueryDetected(@NonNull String partialQuery) throws RemoteException {
- Objects.requireNonNull(partialQuery);
Slog.v(TAG, "BinderCallback#onQueryDetected");
- if (!mEgressingData) {
- Slog.v(TAG, "Query should not be egressed within the unattention state.");
- callback.onVisualQueryDetectionServiceFailure(
- new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot stream queries without attention signals."));
- return;
+ synchronized (mLock) {
+ Objects.requireNonNull(partialQuery);
+ if (!mEgressingData) {
+ Slog.v(TAG, "Query should not be egressed within the unattention state.");
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot stream queries without attention signals."));
+ return;
+ }
+ mQueryStreaming = true;
+ callback.onQueryDetected(partialQuery);
+ Slog.i(TAG, "Egressed from visual query detection process.");
}
- mQueryStreaming = true;
- callback.onQueryDetected(partialQuery);
- Slog.i(TAG, "Egressed from visual query detection process.");
}
@Override
public void onQueryFinished() throws RemoteException {
Slog.v(TAG, "BinderCallback#onQueryFinished");
- if (!mQueryStreaming) {
- Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
- + " no active query being streamed.");
- callback.onVisualQueryDetectionServiceFailure(
- new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot send FINISHED signal with no query streamed."));
- return;
+ synchronized (mLock) {
+ if (!mQueryStreaming) {
+ Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
+ + " no active query being streamed.");
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot send FINISHED signal with no query streamed."));
+ return;
+ }
+ callback.onQueryFinished();
+ mQueryStreaming = false;
}
- callback.onQueryFinished();
- mQueryStreaming = false;
}
@Override
public void onQueryRejected() throws RemoteException {
Slog.v(TAG, "BinderCallback#onQueryRejected");
- if (!mQueryStreaming) {
- Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
- + " no active query being streamed.");
- callback.onVisualQueryDetectionServiceFailure(
- new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot send REJECTED signal with no query streamed."));
- return;
+ synchronized (mLock) {
+ if (!mQueryStreaming) {
+ Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
+ + " no active query being streamed.");
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot send REJECTED signal with no query streamed."));
+ return;
+ }
+ callback.onQueryRejected();
+ mQueryStreaming = false;
}
- callback.onQueryRejected();
- mQueryStreaming = false;
}
};
return mRemoteDetectionService.run(
diff --git a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
index c49f8fe..be47ec7 100644
--- a/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
+++ b/tests/FlickerTests/IME/src/com/android/server/wm/flicker/ime/CloseImeToHomeOnFinishActivityTest.kt
@@ -19,12 +19,12 @@
import android.platform.test.annotations.PlatinumTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
+import android.tools.common.flicker.subject.layers.LayersTraceSubject.Companion.VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.LegacyFlickerTest
import android.tools.device.flicker.legacy.LegacyFlickerTestFactory
import android.tools.device.traces.parsers.toFlickerComponent
-import androidx.test.filters.FlakyTest
import com.android.server.wm.flicker.BaseTest
import com.android.server.wm.flicker.helpers.ImeAppHelper
import com.android.server.wm.flicker.helpers.SimpleAppHelper
@@ -58,9 +58,10 @@
}
transitions {
broadcastActionTrigger.doAction(ACTION_FINISH_ACTIVITY)
- wmHelper.StateSyncBuilder()
- .withActivityRemoved(ActivityOptions.Ime.Default.COMPONENT.toFlickerComponent())
- .waitForAndVerify()
+ wmHelper
+ .StateSyncBuilder()
+ .withActivityRemoved(ActivityOptions.Ime.Default.COMPONENT.toFlickerComponent())
+ .waitForAndVerify()
}
teardown { simpleApp.exit(wmHelper) }
}
@@ -69,10 +70,16 @@
@Presubmit @Test fun imeLayerBecomesInvisible() = flicker.imeLayerBecomesInvisible()
- @FlakyTest(bugId = 246284124)
+ @Presubmit
@Test
override fun visibleLayersShownMoreThanOneConsecutiveEntry() {
- super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ flicker.assertLayers {
+ this.visibleLayersShownMoreThanOneConsecutiveEntry(
+ VISIBLE_FOR_MORE_THAN_ONE_ENTRY_IGNORE_LAYERS.toMutableList().also {
+ it.add(simpleApp.componentMatcher)
+ }
+ )
+ }
}
@Presubmit
diff --git a/tests/testables/src/android/testing/TestWithLooperRule.java b/tests/testables/src/android/testing/TestWithLooperRule.java
index 99b303e..37b39c3 100644
--- a/tests/testables/src/android/testing/TestWithLooperRule.java
+++ b/tests/testables/src/android/testing/TestWithLooperRule.java
@@ -19,7 +19,6 @@
import android.testing.TestableLooper.LooperFrameworkMethod;
import android.testing.TestableLooper.RunWithLooper;
-import org.junit.internal.runners.statements.InvokeMethod;
import org.junit.rules.MethodRule;
import org.junit.runner.RunWith;
import org.junit.runners.model.FrameworkMethod;
@@ -79,13 +78,11 @@
while (next != null) {
switch (next.getClass().getSimpleName()) {
case "RunAfters":
- this.<List<FrameworkMethod>>wrapFieldMethodFor(next,
- next.getClass(), "afters", method, target);
+ this.wrapFieldMethodFor(next, "afters", method, target);
next = getNextStatement(next, "next");
break;
case "RunBefores":
- this.<List<FrameworkMethod>>wrapFieldMethodFor(next,
- next.getClass(), "befores", method, target);
+ this.wrapFieldMethodFor(next, "befores", method, target);
next = getNextStatement(next, "next");
break;
case "FailOnTimeout":
@@ -95,8 +92,10 @@
next = getNextStatement(next, "originalStatement");
break;
case "InvokeMethod":
- this.<FrameworkMethod>wrapFieldMethodFor(next,
- InvokeMethod.class, "testMethod", method, target);
+ this.wrapFieldMethodFor(next, "testMethod", method, target);
+ return;
+ case "InvokeParameterizedMethod":
+ this.wrapFieldMethodFor(next, "frameworkMethod", method, target);
return;
default:
throw new Exception(
@@ -112,12 +111,11 @@
// Wrapping the befores, afters, and InvokeMethods with LooperFrameworkMethod
// within the statement.
- private <T> void wrapFieldMethodFor(Statement base, Class<?> targetClass, String fieldStr,
- FrameworkMethod method, Object target)
- throws NoSuchFieldException, IllegalAccessException {
- Field field = targetClass.getDeclaredField(fieldStr);
+ private void wrapFieldMethodFor(Statement base, String fieldStr, FrameworkMethod method,
+ Object target) throws NoSuchFieldException, IllegalAccessException {
+ Field field = base.getClass().getDeclaredField(fieldStr);
field.setAccessible(true);
- T fieldInstance = (T) field.get(base);
+ Object fieldInstance = field.get(base);
if (fieldInstance instanceof FrameworkMethod) {
field.set(base, looperWrap(method, target, (FrameworkMethod) fieldInstance));
} else {