Merge "System MR2: Fix bug on onTransfer and on getting initial routes" into sc-dev
diff --git a/core/api/current.txt b/core/api/current.txt
index 4aa38d6..97f9855 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -52401,6 +52401,17 @@
method @Nullable @WorkerThread public android.view.translation.TranslationResponse translate(@NonNull android.view.translation.TranslationRequest);
}
+ public final class UiTranslationManager {
+ method public void registerUiTranslationStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.view.translation.UiTranslationStateCallback);
+ method public void unregisterUiTranslationStateCallback(@NonNull android.view.translation.UiTranslationStateCallback);
+ }
+
+ public interface UiTranslationStateCallback {
+ method public void onFinished();
+ method public void onPaused();
+ method public void onStarted(@NonNull String, @NonNull String);
+ }
+
public final class ViewTranslationRequest implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.view.autofill.AutofillId getAutofillId();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 39e259d..1d1303f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1795,6 +1795,7 @@
public final class UsageStats implements android.os.Parcelable {
method public int getAppLaunchCount();
+ method public long getLastTimeComponentUsed();
}
public final class UsageStatsManager {
@@ -3070,6 +3071,7 @@
field public final float reduceBrightColorsOffset;
field public final int reduceBrightColorsStrength;
field public final long timeStamp;
+ field @NonNull public final String uniqueDisplayId;
}
public final class BrightnessConfiguration implements android.os.Parcelable {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 1587475..d4b3f16 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -28,6 +28,7 @@
field public static final String NETWORK_SETTINGS = "android.permission.NETWORK_SETTINGS";
field public static final String NETWORK_STACK = "android.permission.NETWORK_STACK";
field public static final String OVERRIDE_DISPLAY_MODE_REQUESTS = "android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS";
+ field public static final String QUERY_AUDIO_STATE = "android.permission.QUERY_AUDIO_STATE";
field public static final String QUERY_USERS = "android.permission.QUERY_USERS";
field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS";
field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index dcecd90..5d50c5d7 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -20,6 +20,7 @@
import static android.app.usage.UsageEvents.Event.ACTIVITY_PAUSED;
import static android.app.usage.UsageEvents.Event.ACTIVITY_RESUMED;
import static android.app.usage.UsageEvents.Event.ACTIVITY_STOPPED;
+import static android.app.usage.UsageEvents.Event.APP_COMPONENT_USED;
import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE;
import static android.app.usage.UsageEvents.Event.DEVICE_SHUTDOWN;
import static android.app.usage.UsageEvents.Event.END_OF_DAY;
@@ -109,6 +110,13 @@
public long mTotalTimeForegroundServiceUsed;
/**
+ * Last time this package's component is used, measured in milliseconds since the epoch.
+ * See {@link UsageEvents.Event#APP_COMPONENT_USED}
+ * @hide
+ */
+ public long mLastTimeComponentUsed;
+
+ /**
* {@hide}
*/
@UnsupportedAppUsage
@@ -166,6 +174,7 @@
mEndTimeStamp = stats.mEndTimeStamp;
mLastTimeUsed = stats.mLastTimeUsed;
mLastTimeVisible = stats.mLastTimeVisible;
+ mLastTimeComponentUsed = stats.mLastTimeComponentUsed;
mLastTimeForegroundServiceUsed = stats.mLastTimeForegroundServiceUsed;
mTotalTimeInForeground = stats.mTotalTimeInForeground;
mTotalTimeVisible = stats.mTotalTimeVisible;
@@ -265,6 +274,16 @@
}
/**
+ * Get the last time this package's component was used, measured in milliseconds since the
+ * epoch.
+ * @hide
+ */
+ @SystemApi
+ public long getLastTimeComponentUsed() {
+ return mLastTimeComponentUsed;
+ }
+
+ /**
* Returns the number of times the app was launched as an activity from outside of the app.
* Excludes intra-app activity transitions.
* @hide
@@ -323,6 +342,7 @@
mergeEventMap(mForegroundServices, right.mForegroundServices);
mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed);
mLastTimeVisible = Math.max(mLastTimeVisible, right.mLastTimeVisible);
+ mLastTimeComponentUsed = Math.max(mLastTimeComponentUsed, right.mLastTimeComponentUsed);
mLastTimeForegroundServiceUsed = Math.max(mLastTimeForegroundServiceUsed,
right.mLastTimeForegroundServiceUsed);
}
@@ -598,6 +618,9 @@
mLastTimeVisible = timeStamp;
}
break;
+ case APP_COMPONENT_USED:
+ mLastTimeComponentUsed = timeStamp;
+ break;
default:
break;
}
@@ -620,6 +643,7 @@
dest.writeLong(mEndTimeStamp);
dest.writeLong(mLastTimeUsed);
dest.writeLong(mLastTimeVisible);
+ dest.writeLong(mLastTimeComponentUsed);
dest.writeLong(mLastTimeForegroundServiceUsed);
dest.writeLong(mTotalTimeInForeground);
dest.writeLong(mTotalTimeVisible);
@@ -674,6 +698,7 @@
stats.mEndTimeStamp = in.readLong();
stats.mLastTimeUsed = in.readLong();
stats.mLastTimeVisible = in.readLong();
+ stats.mLastTimeComponentUsed = in.readLong();
stats.mLastTimeForegroundServiceUsed = in.readLong();
stats.mTotalTimeInForeground = in.readLong();
stats.mTotalTimeVisible = in.readLong();
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5cf83ac..adf9ff3 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1954,8 +1954,8 @@
/**
* Activity action: Launch UI to show information about the usage
- * of a given permission. This action would be handled by apps that
- * want to show details about how and why given permission is being
+ * of a given permission group. This action would be handled by apps that
+ * want to show details about how and why given permission group is being
* used.
* <p>
* <strong>Important:</strong>You must protect the activity that handles
@@ -1965,7 +1965,7 @@
* activities that are not properly protected.
*
* <p>
- * Input: {@code android.intent.extra.PERMISSION_NAME} specifies the permission
+ * Input: {@link android.Manifest.permission_group} specifies the permission group
* for which the launched UI would be targeted.
* </p>
* <p>
diff --git a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
index 0b81c6c..909f456 100644
--- a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
+++ b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java
@@ -31,23 +31,31 @@
public final int sensorId;
@SensorProperties.Strength public final int sensorStrength;
public final int maxEnrollmentsPerUser;
+ public final boolean resetLockoutRequiresHardwareAuthToken;
+ public final boolean resetLockoutRequiresChallenge;
public static SensorPropertiesInternal from(@NonNull SensorPropertiesInternal prop) {
return new SensorPropertiesInternal(prop.sensorId, prop.sensorStrength,
- prop.maxEnrollmentsPerUser);
+ prop.maxEnrollmentsPerUser, prop.resetLockoutRequiresHardwareAuthToken,
+ prop.resetLockoutRequiresChallenge);
}
protected SensorPropertiesInternal(int sensorId, @SensorProperties.Strength int sensorStrength,
- int maxEnrollmentsPerUser) {
+ int maxEnrollmentsPerUser, boolean resetLockoutRequiresHardwareAuthToken,
+ boolean resetLockoutRequiresChallenge) {
this.sensorId = sensorId;
this.sensorStrength = sensorStrength;
this.maxEnrollmentsPerUser = maxEnrollmentsPerUser;
+ this.resetLockoutRequiresHardwareAuthToken = resetLockoutRequiresHardwareAuthToken;
+ this.resetLockoutRequiresChallenge = resetLockoutRequiresChallenge;
}
protected SensorPropertiesInternal(Parcel in) {
sensorId = in.readInt();
sensorStrength = in.readInt();
maxEnrollmentsPerUser = in.readInt();
+ resetLockoutRequiresHardwareAuthToken = in.readBoolean();
+ resetLockoutRequiresChallenge = in.readBoolean();
}
public static final Creator<SensorPropertiesInternal> CREATOR =
@@ -73,6 +81,8 @@
dest.writeInt(sensorId);
dest.writeInt(sensorStrength);
dest.writeInt(maxEnrollmentsPerUser);
+ dest.writeBoolean(resetLockoutRequiresHardwareAuthToken);
+ dest.writeBoolean(resetLockoutRequiresChallenge);
}
@Override
diff --git a/core/java/android/hardware/display/BrightnessChangeEvent.java b/core/java/android/hardware/display/BrightnessChangeEvent.java
index a6c6b46..6b7d8c3 100644
--- a/core/java/android/hardware/display/BrightnessChangeEvent.java
+++ b/core/java/android/hardware/display/BrightnessChangeEvent.java
@@ -47,6 +47,10 @@
* @hide */
public final int userId;
+ /** The unique id of the screen on which the brightness was changed */
+ @NonNull
+ public final String uniqueDisplayId;
+
/** Lux values of recent sensor data */
public final float[] luxValues;
@@ -120,15 +124,16 @@
/** @hide */
private BrightnessChangeEvent(float brightness, long timeStamp, String packageName,
- int userId, float[] luxValues, long[] luxTimestamps, float batteryLevel,
- float powerBrightnessFactor, boolean nightMode, int colorTemperature,
- boolean reduceBrightColors, int reduceBrightColorsStrength,
+ int userId, String uniqueDisplayId, float[] luxValues, long[] luxTimestamps,
+ float batteryLevel, float powerBrightnessFactor, boolean nightMode,
+ int colorTemperature, boolean reduceBrightColors, int reduceBrightColorsStrength,
float reduceBrightColorsOffset, float lastBrightness, boolean isDefaultBrightnessConfig,
boolean isUserSetBrightness, long[] colorValueBuckets, long colorSampleDuration) {
this.brightness = brightness;
this.timeStamp = timeStamp;
this.packageName = packageName;
this.userId = userId;
+ this.uniqueDisplayId = uniqueDisplayId;
this.luxValues = luxValues;
this.luxTimestamps = luxTimestamps;
this.batteryLevel = batteryLevel;
@@ -151,6 +156,7 @@
this.timeStamp = other.timeStamp;
this.packageName = redactPackage ? null : other.packageName;
this.userId = other.userId;
+ this.uniqueDisplayId = other.uniqueDisplayId;
this.luxValues = other.luxValues;
this.luxTimestamps = other.luxTimestamps;
this.batteryLevel = other.batteryLevel;
@@ -172,6 +178,7 @@
timeStamp = source.readLong();
packageName = source.readString();
userId = source.readInt();
+ uniqueDisplayId = source.readString();
luxValues = source.createFloatArray();
luxTimestamps = source.createLongArray();
batteryLevel = source.readFloat();
@@ -209,6 +216,7 @@
dest.writeLong(timeStamp);
dest.writeString(packageName);
dest.writeInt(userId);
+ dest.writeString(uniqueDisplayId);
dest.writeFloatArray(luxValues);
dest.writeLongArray(luxTimestamps);
dest.writeFloat(batteryLevel);
@@ -231,6 +239,7 @@
private long mTimeStamp;
private String mPackageName;
private int mUserId;
+ private String mUniqueDisplayId;
private float[] mLuxValues;
private long[] mLuxTimestamps;
private float mBatteryLevel;
@@ -270,6 +279,12 @@
return this;
}
+ /** {@see BrightnessChangeEvent#uniqueScreenId} */
+ public Builder setUniqueDisplayId(String uniqueId) {
+ mUniqueDisplayId = uniqueId;
+ return this;
+ }
+
/** {@see BrightnessChangeEvent#luxValues} */
public Builder setLuxValues(float[] luxValues) {
mLuxValues = luxValues;
@@ -354,11 +369,11 @@
/** Builds a BrightnessChangeEvent */
public BrightnessChangeEvent build() {
return new BrightnessChangeEvent(mBrightness, mTimeStamp,
- mPackageName, mUserId, mLuxValues, mLuxTimestamps, mBatteryLevel,
- mPowerBrightnessFactor, mNightMode, mColorTemperature, mReduceBrightColors,
- mReduceBrightColorsStrength, mReduceBrightColorsOffset, mLastBrightness,
- mIsDefaultBrightnessConfig, mIsUserSetBrightness, mColorValueBuckets,
- mColorSampleDuration);
+ mPackageName, mUserId, mUniqueDisplayId, mLuxValues, mLuxTimestamps,
+ mBatteryLevel, mPowerBrightnessFactor, mNightMode, mColorTemperature,
+ mReduceBrightColors, mReduceBrightColorsStrength, mReduceBrightColorsOffset,
+ mLastBrightness, mIsDefaultBrightnessConfig, mIsUserSetBrightness,
+ mColorValueBuckets, mColorSampleDuration);
}
}
}
diff --git a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
index b9c0d12..34cbcb4 100644
--- a/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
+++ b/core/java/android/hardware/face/FaceSensorPropertiesInternal.java
@@ -41,8 +41,11 @@
*/
public FaceSensorPropertiesInternal(int sensorId, @SensorProperties.Strength int strength,
int maxEnrollmentsPerUser, boolean supportsFaceDetection,
- boolean supportsSelfIllumination) {
- super(sensorId, strength, maxEnrollmentsPerUser);
+ boolean supportsSelfIllumination, boolean resetLockoutRequiresChallenge) {
+ // resetLockout is managed by the HAL and requires a HardwareAuthToken for all face
+ // HAL interfaces (IBiometricsFace@1.0 HIDL and IFace@1.0 AIDL).
+ super(sensorId, strength, maxEnrollmentsPerUser,
+ true /* resetLockoutRequiresHardwareAuthToken */, resetLockoutRequiresChallenge);
this.supportsFaceDetection = supportsFaceDetection;
this.supportsSelfIllumination = supportsSelfIllumination;
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
index 51addc9..adc61a7 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorPropertiesInternal.java
@@ -36,12 +36,6 @@
public final @FingerprintSensorProperties.SensorType int sensorType;
/**
- * IBiometricsFingerprint@2.1 does not manage timeout below the HAL, so the Gatekeeper HAT
- * cannot be checked
- */
- public final boolean resetLockoutRequiresHardwareAuthToken;
-
- /**
* The location of the center of the sensor if applicable. For example, sensors of type
* {@link FingerprintSensorProperties#TYPE_UDFPS_OPTICAL} would report this value as the
* distance in pixels, measured from the left edge of the screen.
@@ -68,9 +62,13 @@
@FingerprintSensorProperties.SensorType int sensorType,
boolean resetLockoutRequiresHardwareAuthToken, int sensorLocationX, int sensorLocationY,
int sensorRadius) {
- super(sensorId, strength, maxEnrollmentsPerUser);
+ // IBiometricsFingerprint@2.1 handles lockout in the framework, so the challenge is not
+ // required as it can only be generated/attested/verified by TEE components.
+ // IFingerprint@1.0 handles lockout below the HAL, but does not require a challenge. See
+ // the HAL interface for more details.
+ super(sensorId, strength, maxEnrollmentsPerUser, resetLockoutRequiresHardwareAuthToken,
+ false /* resetLockoutRequiresChallenge */);
this.sensorType = sensorType;
- this.resetLockoutRequiresHardwareAuthToken = resetLockoutRequiresHardwareAuthToken;
this.sensorLocationX = sensorLocationX;
this.sensorLocationY = sensorLocationY;
this.sensorRadius = sensorRadius;
@@ -98,9 +96,9 @@
@SensorProperties.Strength int strength, int maxEnrollmentsPerUser,
@FingerprintSensorProperties.SensorType int sensorType,
boolean resetLockoutRequiresHardwareAuthToken) {
- super(sensorId, strength, maxEnrollmentsPerUser);
+ super(sensorId, strength, maxEnrollmentsPerUser, resetLockoutRequiresHardwareAuthToken,
+ false /* resetLockoutRequiresChallenge */);
this.sensorType = sensorType;
- this.resetLockoutRequiresHardwareAuthToken = resetLockoutRequiresHardwareAuthToken;
int[] props = context.getResources().getIntArray(
com.android.internal.R.array.config_udfps_sensor_props);
@@ -119,7 +117,6 @@
protected FingerprintSensorPropertiesInternal(Parcel in) {
super(in);
sensorType = in.readInt();
- resetLockoutRequiresHardwareAuthToken = in.readBoolean();
sensorLocationX = in.readInt();
sensorLocationY = in.readInt();
sensorRadius = in.readInt();
@@ -147,7 +144,6 @@
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(sensorType);
- dest.writeBoolean(resetLockoutRequiresHardwareAuthToken);
dest.writeInt(sensorLocationX);
dest.writeInt(sensorLocationY);
dest.writeInt(sensorRadius);
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index df4ade0..d89c3d5 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -21,6 +21,7 @@
import android.util.Slog;
import java.io.PrintWriter;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
@@ -354,6 +355,23 @@
}
/**
+ * Performs {@code action} on each callback and associated cookie, calling {@link
+ * #beginBroadcast()}/{@link #finishBroadcast()} before/after looping.
+ *
+ * @hide
+ */
+ public <C> void broadcast(BiConsumer<E, C> action) {
+ int itemCount = beginBroadcast();
+ try {
+ for (int i = 0; i < itemCount; i++) {
+ action.accept(getBroadcastItem(i), (C) getBroadcastCookie(i));
+ }
+ } finally {
+ finishBroadcast();
+ }
+ }
+
+ /**
* Returns the number of registered callbacks. Note that the number of registered
* callbacks may differ from the value returned by {@link #beginBroadcast()} since
* the former returns the number of callbacks registered at the time of the call
diff --git a/core/java/android/view/translation/ITranslationManager.aidl b/core/java/android/view/translation/ITranslationManager.aidl
index 7f6c4b4..d347f31 100644
--- a/core/java/android/view/translation/ITranslationManager.aidl
+++ b/core/java/android/view/translation/ITranslationManager.aidl
@@ -17,6 +17,7 @@
package android.view.translation;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.view.autofill.AutofillId;
import android.view.translation.TranslationSpec;
import com.android.internal.os.IResultReceiver;
@@ -40,4 +41,7 @@
void updateUiTranslationStateByTaskId(int state, in TranslationSpec sourceSpec,
in TranslationSpec destSpec, in List<AutofillId> viewIds, int taskId,
int userId);
+
+ void registerUiTranslationStateCallback(in IRemoteCallback callback, int userId);
+ void unregisterUiTranslationStateCallback(in IRemoteCallback callback, int userId);
}
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index 7c73e70..9fba95f 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -16,28 +16,36 @@
package android.view.translation;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.assist.ActivityId;
import android.content.Context;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IRemoteCallback;
import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;
+import com.android.internal.annotations.GuardedBy;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.concurrent.Executor;
+// TODO(b/178044703): Describe what UI Translation is.
/**
* The {@link UiTranslationManager} class provides ways for apps to use the ui translation
* function in framework.
- *
- * @hide
*/
-@SystemApi
public final class UiTranslationManager {
private static final String TAG = "UiTranslationManager";
@@ -88,6 +96,14 @@
public @interface UiTranslationState {
}
+ // Keys for the data transmitted in the internal UI Translation state callback.
+ /** @hide */
+ public static final String EXTRA_STATE = "state";
+ /** @hide */
+ public static final String EXTRA_SOURCE_LOCALE = "source_locale";
+ /** @hide */
+ public static final String EXTRA_TARGET_LOCALE = "target_locale";
+
@NonNull
private final Context mContext;
@@ -111,9 +127,12 @@
* @param destSpec {@link TranslationSpec} for the translated data.
* @param viewIds A list of the {@link View}'s {@link AutofillId} which needs to be translated
* @param taskId the Activity Task id which needs ui translation
+ *
+ * @hide
*/
// TODO, hide the APIs
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void startTranslation(@NonNull TranslationSpec sourceSpec,
@NonNull TranslationSpec destSpec, @NonNull List<AutofillId> viewIds,
int taskId) {
@@ -141,8 +160,11 @@
* @throws IllegalArgumentException if the no {@link View}'s {@link AutofillId} in the list
* @throws NullPointerException the sourceSpec, destSpec, viewIds, activityId or
* {@link android.app.assist.ActivityId#getToken()} is {@code null}
+ *
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void startTranslation(@NonNull TranslationSpec sourceSpec,
@NonNull TranslationSpec destSpec, @NonNull List<AutofillId> viewIds,
@NonNull ActivityId activityId) {
@@ -171,9 +193,12 @@
* NOTE: Please use {@code finishTranslation(ActivityId)} instead.
*
* @param taskId the Activity Task id which needs ui translation
+ *
+ * @hide
*/
// TODO, hide the APIs
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void finishTranslation(int taskId) {
try {
mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_FINISHED,
@@ -191,8 +216,11 @@
* @param activityId the identifier for the Activity which needs ui translation
* @throws NullPointerException the activityId or
* {@link android.app.assist.ActivityId#getToken()} is {@code null}
+ *
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void finishTranslation(@NonNull ActivityId activityId) {
try {
Objects.requireNonNull(activityId);
@@ -212,9 +240,12 @@
* NOTE: Please use {@code pauseTranslation(ActivityId)} instead.
*
* @param taskId the Activity Task id which needs ui translation
+ *
+ * @hide
*/
// TODO, hide the APIs
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void pauseTranslation(int taskId) {
try {
mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_PAUSED,
@@ -232,8 +263,11 @@
* @param activityId the identifier for the Activity which needs ui translation
* @throws NullPointerException the activityId or
* {@link android.app.assist.ActivityId#getToken()} is {@code null}
+ *
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void pauseTranslation(@NonNull ActivityId activityId) {
try {
Objects.requireNonNull(activityId);
@@ -253,9 +287,12 @@
* NOTE: Please use {@code resumeTranslation(ActivityId)} instead.
*
* @param taskId the Activity Task id which needs ui translation
+ *
+ * @hide
*/
// TODO, hide the APIs
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void resumeTranslation(int taskId) {
try {
mService.updateUiTranslationStateByTaskId(STATE_UI_TRANSLATION_RESUMED,
@@ -273,8 +310,11 @@
* @param activityId the identifier for the Activity which needs ui translation
* @throws NullPointerException the activityId or
* {@link android.app.assist.ActivityId#getToken()} is {@code null}
+ *
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_UI_TRANSLATION)
+ @SystemApi
public void resumeTranslation(@NonNull ActivityId activityId) {
try {
Objects.requireNonNull(activityId);
@@ -286,4 +326,104 @@
throw e.rethrowFromSystemServer();
}
}
+
+ // TODO(b/178044703): Fix the View API link when it becomes public.
+ /**
+ * Register for notifications of UI Translation state changes on the foreground activity. This
+ * is available to the owning application itself and also the current input method.
+ * <p>
+ * The application whose UI is being translated can use this to customize the UI Translation
+ * behavior in ways that aren't made easy by methods like
+ * View#onCreateTranslationRequest().
+ * <p>
+ * Input methods can use this to offer complementary features to UI Translation; for example,
+ * enabling outgoing message translation when the system is translating incoming messages in a
+ * communication app.
+ *
+ * @param callback the callback to register for receiving the state change
+ * notifications
+ */
+ public void registerUiTranslationStateCallback(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull UiTranslationStateCallback callback) {
+ Objects.requireNonNull(executor);
+ Objects.requireNonNull(callback);
+ synchronized (mCallbacks) {
+ if (mCallbacks.containsKey(callback)) {
+ Log.w(TAG, "registerUiTranslationStateCallback: callback already registered;"
+ + " ignoring.");
+ return;
+ }
+ final IRemoteCallback remoteCallback =
+ new UiTranslationStateRemoteCallback(executor, callback);
+ try {
+ mService.registerUiTranslationStateCallback(remoteCallback, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mCallbacks.put(callback, remoteCallback);
+ }
+ }
+
+ /**
+ * Unregister {@code callback}.
+ *
+ * @see #registerUiTranslationStateCallback(Executor, UiTranslationStateCallback)
+ */
+ public void unregisterUiTranslationStateCallback(@NonNull UiTranslationStateCallback callback) {
+ Objects.requireNonNull(callback);
+
+ synchronized (mCallbacks) {
+ final IRemoteCallback remoteCallback = mCallbacks.get(callback);
+ if (remoteCallback == null) {
+ Log.w(TAG, "unregisterUiTranslationStateCallback: callback not found; ignoring.");
+ return;
+ }
+ try {
+ mService.unregisterUiTranslationStateCallback(remoteCallback, mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mCallbacks.remove(callback);
+ }
+ }
+
+ @NonNull
+ @GuardedBy("mCallbacks")
+ private final Map<UiTranslationStateCallback, IRemoteCallback> mCallbacks = new ArrayMap<>();
+
+ private static class UiTranslationStateRemoteCallback extends IRemoteCallback.Stub {
+ private final Executor mExecutor;
+ private final UiTranslationStateCallback mCallback;
+
+ UiTranslationStateRemoteCallback(Executor executor,
+ UiTranslationStateCallback callback) {
+ mExecutor = executor;
+ mCallback = callback;
+ }
+
+ @Override
+ public void sendResult(Bundle bundle) {
+ Binder.clearCallingIdentity();
+ mExecutor.execute(() -> {
+ int state = bundle.getInt(EXTRA_STATE);
+ switch (state) {
+ case STATE_UI_TRANSLATION_STARTED:
+ case STATE_UI_TRANSLATION_RESUMED:
+ mCallback.onStarted(
+ bundle.getString(EXTRA_SOURCE_LOCALE),
+ bundle.getString(EXTRA_TARGET_LOCALE));
+ break;
+ case STATE_UI_TRANSLATION_PAUSED:
+ mCallback.onPaused();
+ break;
+ case STATE_UI_TRANSLATION_FINISHED:
+ mCallback.onFinished();
+ break;
+ default:
+ Log.wtf(TAG, "Unexpected translation state:" + state);
+ }
+ });
+ }
+ }
}
diff --git a/core/java/android/view/translation/UiTranslationStateCallback.java b/core/java/android/view/translation/UiTranslationStateCallback.java
new file mode 100644
index 0000000..1946b70
--- /dev/null
+++ b/core/java/android/view/translation/UiTranslationStateCallback.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.translation;
+
+import android.annotation.NonNull;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Callback for listening to UI Translation state changes. See {@link
+ * UiTranslationManager#registerUiTranslationStateCallback(Executor, UiTranslationStateCallback)}.
+ */
+public interface UiTranslationStateCallback {
+
+ /**
+ * The system is requesting translation of the UI from {@code sourceLocale} to {@code
+ * targetLocale}.
+ * <p>
+ * This is also called if either the requested {@code sourceLocale} or {@code targetLocale} has
+ * changed; or called again after {@link #onPaused()}.
+ */
+ void onStarted(@NonNull String sourceLocale, @NonNull String targetLocale);
+
+ /**
+ * The system is requesting that the application temporarily show the UI contents in their
+ * original language.
+ */
+ void onPaused();
+
+ /**
+ * The UI Translation session has ended.
+ */
+ void onFinished();
+}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 21589c9..d02dd8c 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -4426,8 +4426,7 @@
/**
* Sets an OutlineProvider on the view whose corner radius is a dimension calculated using
- * {@link TypedValue#applyDimension(int, float, DisplayMetrics)}. This outline may change shape
- * during system transitions.
+ * {@link TypedValue#applyDimension(int, float, DisplayMetrics)}.
*
* <p>NOTE: It is recommended to use {@link TypedValue#COMPLEX_UNIT_PX} only for 0.
* Setting margins in pixels will behave poorly when the RemoteViews object is used on a
@@ -4440,7 +4439,7 @@
/**
* Sets an OutlineProvider on the view whose corner radius is a dimension resource with
- * {@code resId}. This outline may change shape during system transitions.
+ * {@code resId}.
*/
public void setViewOutlinePreferredRadiusDimen(@IdRes int viewId, @DimenRes int resId) {
addAction(new SetViewOutlinePreferredRadiusAction(viewId, resId));
diff --git a/core/proto/android/server/usagestatsservice.proto b/core/proto/android/server/usagestatsservice.proto
index e32c07f..3a959f1 100644
--- a/core/proto/android/server/usagestatsservice.proto
+++ b/core/proto/android/server/usagestatsservice.proto
@@ -57,6 +57,8 @@
// Time attributes stored as an offset of the IntervalStats's beginTime.
optional int64 last_time_visible_ms = 10;
optional int64 total_time_visible_ms = 11;
+ // Time attributes stored as an offset of the IntervalStats's beginTime.
+ optional int64 last_time_component_used_ms = 12;
}
// Stores the relevant information an IntervalStats will have about a Configuration
diff --git a/core/proto/android/server/usagestatsservice_v2.proto b/core/proto/android/server/usagestatsservice_v2.proto
index 664c22d..3e5cd92 100644
--- a/core/proto/android/server/usagestatsservice_v2.proto
+++ b/core/proto/android/server/usagestatsservice_v2.proto
@@ -81,6 +81,7 @@
optional int64 total_time_service_used_ms = 9;
optional int64 last_time_visible_ms = 10;
optional int64 total_time_visible_ms = 11;
+ optional int64 last_time_component_used_ms = 12;
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d783b44..f135d67 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4365,6 +4365,11 @@
<permission android:name="android.permission.MODIFY_AUDIO_ROUTING"
android:protectionLevel="signature|privileged" />
+ <!-- @TestApi Allows an application to query audio related state.
+ @hide -->
+ <permission android:name="android.permission.QUERY_AUDIO_STATE"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to modify what effects are applied to all audio
(matching certain criteria) from any application.
<p>Not for use by third-party applications.</p>
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
index 8de9454..083e37a 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsPersistenceTest.java
@@ -46,7 +46,8 @@
private static final String[] USAGESTATS_PERSISTED_FIELDS = {"mBeginTimeStamp", "mEndTimeStamp",
"mPackageName", "mPackageToken", "mLastEvent", "mAppLaunchCount", "mChooserCounts",
"mLastTimeUsed", "mTotalTimeInForeground", "mLastTimeForegroundServiceUsed",
- "mTotalTimeForegroundServiceUsed", "mLastTimeVisible", "mTotalTimeVisible"};
+ "mTotalTimeForegroundServiceUsed", "mLastTimeVisible", "mTotalTimeVisible",
+ "mLastTimeComponentUsed"};
// All fields in this list are defined in UsageStats but not persisted
private static final String[] USAGESTATS_IGNORED_FIELDS = {"CREATOR", "mActivities",
"mForegroundServices", "mLaunchCount", "mChooserCountsObfuscated"};
diff --git a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
index 0ac00b8..858bbd2 100644
--- a/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
+++ b/core/tests/coretests/src/android/app/usage/UsageStatsTest.java
@@ -20,6 +20,7 @@
import static android.app.usage.UsageEvents.Event.ACTIVITY_PAUSED;
import static android.app.usage.UsageEvents.Event.ACTIVITY_RESUMED;
import static android.app.usage.UsageEvents.Event.ACTIVITY_STOPPED;
+import static android.app.usage.UsageEvents.Event.APP_COMPONENT_USED;
import static android.app.usage.UsageEvents.Event.CONTINUING_FOREGROUND_SERVICE;
import static android.app.usage.UsageEvents.Event.DEVICE_SHUTDOWN;
import static android.app.usage.UsageEvents.Event.END_OF_DAY;
@@ -137,6 +138,7 @@
left.mPackageName = "com.test";
left.mBeginTimeStamp = 100000;
left.mTotalTimeInForeground = 10;
+ left.mLastTimeComponentUsed = 200000;
left.mActivities.put(1, Event.ACTIVITY_RESUMED);
left.mActivities.put(2, Event.ACTIVITY_RESUMED);
@@ -542,6 +544,19 @@
}
@Test
+ public void testEvent_APP_COMPONENT_USED() {
+ left.mPackageName = "com.test";
+ left.mBeginTimeStamp = 100000;
+ final String className = "com.test.component1";
+
+ left.update(className, 200000, APP_COMPONENT_USED, 0);
+ assertEquals(left.mLastTimeComponentUsed, 200000);
+
+ left.update(className, 300000, APP_COMPONENT_USED, 0);
+ assertEquals(left.mLastTimeComponentUsed, 300000);
+ }
+
+ @Test
public void testEvent_DEVICE_SHUTDOWN() {
testClosingEvent(DEVICE_SHUTDOWN);
}
@@ -586,6 +601,7 @@
assertEquals(us1.mBeginTimeStamp, us2.mBeginTimeStamp);
assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed);
assertEquals(us1.mLastTimeVisible, us2.mLastTimeVisible);
+ assertEquals(us1.mLastTimeComponentUsed, us2.mLastTimeComponentUsed);
assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed);
assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground);
assertEquals(us1.mTotalTimeForegroundServiceUsed, us2.mTotalTimeForegroundServiceUsed);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
index 1770943..58bf22a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java
@@ -85,7 +85,8 @@
@Override
public void onDisplayAdded(int displayId) {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Display added: %d", displayId);
- final Context context = mDisplayController.getDisplayContext(displayId);
+ final Context context = mDisplayController.getDisplayContext(displayId)
+ .createWindowContext(TYPE_APPLICATION_OVERLAY, null);
final WindowManager wm = context.getSystemService(WindowManager.class);
// TODO(b/169894807): Figure out the right layer for this, needs to be below the task bar
diff --git a/media/jni/tuner/DvrClient.cpp b/media/jni/tuner/DvrClient.cpp
index 7793180..0476216 100644
--- a/media/jni/tuner/DvrClient.cpp
+++ b/media/jni/tuner/DvrClient.cpp
@@ -314,6 +314,11 @@
}
Result DvrClient::close() {
+ if (mDvrMQEventFlag != NULL) {
+ EventFlag::deleteEventFlag(&mDvrMQEventFlag);
+ }
+ mDvrMQ = NULL;
+
if (mTunerDvr != NULL) {
Status s = mTunerDvr->close();
mTunerDvr = NULL;
diff --git a/media/jni/tuner/FilterClient.cpp b/media/jni/tuner/FilterClient.cpp
index f31d465..8846e4d6 100644
--- a/media/jni/tuner/FilterClient.cpp
+++ b/media/jni/tuner/FilterClient.cpp
@@ -259,6 +259,11 @@
}
Result FilterClient::close() {
+ if (mFilterMQEventFlag != NULL) {
+ EventFlag::deleteEventFlag(&mFilterMQEventFlag);
+ }
+ mFilterMQ = NULL;
+
if (mTunerFilter != NULL) {
Status s = mTunerFilter->close();
closeAvSharedMemory();
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index b4194fd..cf66bad 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -187,6 +187,7 @@
<uses-permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS" />
<uses-permission android:name="android.permission.MANAGE_SENSORS" />
<uses-permission android:name="android.permission.MANAGE_AUDIO_POLICY" />
+ <uses-permission android:name="android.permission.QUERY_AUDIO_STATE" />
<uses-permission android:name="android.permission.MANAGE_CAMERA" />
<!-- Permissions needed to test system only camera devices -->
<uses-permission android:name="android.permission.CAMERA" />
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index d02ff91f..123ccee 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -324,6 +324,7 @@
/** */
@Provides
+ @SysUISingleton
public AlwaysOnDisplayPolicy provideAlwaysOnDisplayPolicy(Context context) {
return new AlwaysOnDisplayPolicy(context);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 97803c1..5cc0e65 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -71,7 +71,7 @@
* @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
*/
private static boolean sEnableRemoteKeyguardAnimation =
- SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false);
+ SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, true);
private final KeyguardViewMediator mKeyguardViewMediator;
private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b9d8d27..e35e987 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -195,7 +195,8 @@
when(mFaceSensorProperties.get(anyInt())).thenReturn(new FaceSensorPropertiesInternal(
0 /* id */,
FaceSensorProperties.STRENGTH_STRONG, 1 /* maxTemplatesAllowed */,
- false /* supportsFaceDetection */, true /* supportsSelfIllumination */));
+ false /* supportsFaceDetection */, true /* supportsSelfIllumination */,
+ false /* resetLockoutRequiresChallenge */));
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 68f10a5..1950710 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -61,6 +61,8 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.database.ContentObserver;
+import android.hardware.SensorPrivacyManager;
+import android.hardware.SensorPrivacyManagerInternal;
import android.hardware.hdmi.HdmiAudioSystemClient;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
@@ -520,6 +522,7 @@
/** Interface for UserManagerService. */
private final UserManagerInternal mUserManagerInternal;
private final ActivityManagerInternal mActivityManagerInternal;
+ private final SensorPrivacyManagerInternal mSensorPrivacyManagerInternal;
private final UserRestrictionsListener mUserRestrictionsListener =
new AudioServiceUserRestrictionsListener();
@@ -720,9 +723,12 @@
private String mEnabledSurroundFormats;
private boolean mSurroundModeChanged;
+ private boolean mSupportsMicPrivacyToggle;
+
private boolean mMicMuteFromSwitch;
private boolean mMicMuteFromApi;
private boolean mMicMuteFromRestrictions;
+ private boolean mMicMuteFromPrivacyToggle;
// caches the value returned by AudioSystem.isMicrophoneMuted()
private boolean mMicMuteFromSystemCached;
@@ -822,6 +828,8 @@
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mSensorPrivacyManagerInternal =
+ LocalServices.getService(SensorPrivacyManagerInternal.class);
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mAudioEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "handleAudioEvent");
@@ -831,6 +839,9 @@
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
+ mSupportsMicPrivacyToggle = mContext.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_MICROPHONE_TOGGLE);
+
// Initialize volume
// Priority 1 - Android Property
// Priority 2 - Audio Policy Service
@@ -1106,6 +1117,16 @@
}
}
+ if (mSupportsMicPrivacyToggle) {
+ mSensorPrivacyManagerInternal.addSensorPrivacyListenerForAllUsers(
+ SensorPrivacyManager.Sensors.MICROPHONE, (userId, enabled) -> {
+ if (userId == getCurrentUserId()) {
+ mMicMuteFromPrivacyToggle = enabled;
+ setMicrophoneMuteNoCallerCheck(getCurrentUserId());
+ }
+ });
+ }
+
mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
sendMsg(mAudioHandler,
@@ -3840,11 +3861,12 @@
* @return true if microphone is reported as muted by primary HAL
*/
public boolean isMicrophoneMuted() {
- return mMicMuteFromSystemCached;
+ return mMicMuteFromSystemCached && !mMicMuteFromPrivacyToggle;
}
private boolean isMicrophoneSupposedToBeMuted() {
- return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi;
+ return mMicMuteFromSwitch || mMicMuteFromRestrictions || mMicMuteFromApi
+ || mMicMuteFromPrivacyToggle;
}
private void setMicrophoneMuteNoCallerCheck(int userId) {
@@ -7474,6 +7496,13 @@
// the current audio focus owner is no longer valid
mMediaFocusControl.discardAudioFocusOwner();
+ if (mSupportsMicPrivacyToggle) {
+ mMicMuteFromPrivacyToggle = mSensorPrivacyManagerInternal
+ .isSensorPrivacyEnabled(getCurrentUserId(),
+ SensorPrivacyManager.Sensors.MICROPHONE);
+ setMicrophoneMuteNoCallerCheck(getCurrentUserId());
+ }
+
// load volume settings for new user
readAudioSettings(true /*userSwitch*/);
// preserve STREAM_MUSIC volume from one user to the next.
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 1d8f210..07a653f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -137,7 +137,7 @@
final FaceSensorPropertiesInternal internalProp = new FaceSensorPropertiesInternal(
prop.commonProps.sensorId, prop.commonProps.sensorStrength,
prop.commonProps.maxEnrollmentsPerUser, false /* supportsFaceDetection */,
- prop.halControlsPreview);
+ prop.halControlsPreview, false /* resetLockoutRequiresChallenge */);
final Sensor sensor = new Sensor(getTag() + "/" + sensorId, this, mContext, mHandler,
internalProp);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 1b9bd7f..afe7f24 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -332,7 +332,8 @@
@NonNull BiometricScheduler scheduler) {
mSensorProperties = new FaceSensorPropertiesInternal(sensorId,
Utils.authenticatorStrengthToPropertyStrength(strength),
- maxTemplatesAllowed, false /* supportsFaceDetect */, supportsSelfIllumination);
+ maxTemplatesAllowed, false /* supportsFaceDetect */, supportsSelfIllumination,
+ true /* resetLockoutRequiresChallenge */);
mContext = context;
mSensorId = sensorId;
mScheduler = scheduler;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 6e22a79..cc3b569a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -347,7 +347,8 @@
final @FingerprintSensorProperties.SensorType int sensorType =
mIsUdfps ? FingerprintSensorProperties.TYPE_UDFPS_OPTICAL
: FingerprintSensorProperties.TYPE_REAR;
- // resetLockout is controlled by the framework, so hardwareAuthToken is not required
+ // IBiometricsFingerprint@2.1 does not manage timeout below the HAL, so the Gatekeeper HAT
+ // cannot be checked
final boolean resetLockoutRequiresHardwareAuthToken = false;
final int maxEnrollmentsPerUser = mContext.getResources()
.getInteger(R.integer.config_fingerprintMaxTemplatesPerUser);
diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java
index 06010f5..251b579 100644
--- a/services/core/java/com/android/server/display/BrightnessTracker.java
+++ b/services/core/java/com/android/server/display/BrightnessTracker.java
@@ -110,6 +110,7 @@
private static final String ATTR_TIMESTAMP = "timestamp";
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_USER = "user";
+ private static final String ATTR_UNIQUE_DISPLAY_ID = "uniqueDisplayId";
private static final String ATTR_LUX = "lux";
private static final String ATTR_LUX_TIMESTAMPS = "luxTimestamps";
private static final String ATTR_BATTERY_LEVEL = "batteryLevel";
@@ -217,6 +218,9 @@
}
private void backgroundStart(float initialBrightness) {
+ if (DEBUG) {
+ Slog.d(TAG, "Background start");
+ }
readEvents();
readAmbientBrightnessStats();
@@ -311,7 +315,7 @@
*/
public void notifyBrightnessChanged(float brightness, boolean userInitiated,
float powerBrightnessFactor, boolean isUserSetBrightness,
- boolean isDefaultBrightnessConfig) {
+ boolean isDefaultBrightnessConfig, String uniqueDisplayId) {
if (DEBUG) {
Slog.d(TAG, String.format("notifyBrightnessChanged(brightness=%f, userInitiated=%b)",
brightness, userInitiated));
@@ -319,13 +323,13 @@
Message m = mBgHandler.obtainMessage(MSG_BRIGHTNESS_CHANGED,
userInitiated ? 1 : 0, 0 /*unused*/, new BrightnessChangeValues(brightness,
powerBrightnessFactor, isUserSetBrightness, isDefaultBrightnessConfig,
- mInjector.currentTimeMillis()));
+ mInjector.currentTimeMillis(), uniqueDisplayId));
m.sendToTarget();
}
private void handleBrightnessChanged(float brightness, boolean userInitiated,
float powerBrightnessFactor, boolean isUserSetBrightness,
- boolean isDefaultBrightnessConfig, long timestamp) {
+ boolean isDefaultBrightnessConfig, long timestamp, String uniqueDisplayId) {
BrightnessChangeEvent.Builder builder;
synchronized (mDataCollectionLock) {
@@ -350,6 +354,7 @@
builder.setPowerBrightnessFactor(powerBrightnessFactor);
builder.setUserBrightnessPoint(isUserSetBrightness);
builder.setIsDefaultBrightnessConfig(isDefaultBrightnessConfig);
+ builder.setUniqueDisplayId(uniqueDisplayId);
final int readingCount = mLastSensorReadings.size();
if (readingCount == 0) {
@@ -562,6 +567,7 @@
out.attributeLong(null, ATTR_TIMESTAMP, toWrite[i].timeStamp);
out.attribute(null, ATTR_PACKAGE_NAME, toWrite[i].packageName);
out.attributeInt(null, ATTR_USER, userSerialNo);
+ out.attribute(null, ATTR_UNIQUE_DISPLAY_ID, toWrite[i].uniqueDisplayId);
out.attributeFloat(null, ATTR_BATTERY_LEVEL, toWrite[i].batteryLevel);
out.attributeBoolean(null, ATTR_NIGHT_MODE, toWrite[i].nightMode);
out.attributeInt(null, ATTR_COLOR_TEMPERATURE,
@@ -646,6 +652,8 @@
builder.setPackageName(parser.getAttributeValue(null, ATTR_PACKAGE_NAME));
builder.setUserId(mInjector.getUserId(mUserManager,
parser.getAttributeInt(null, ATTR_USER)));
+ builder.setUniqueDisplayId(
+ parser.getAttributeValue(null, ATTR_UNIQUE_DISPLAY_ID));
builder.setBatteryLevel(parser.getAttributeFloat(null, ATTR_BATTERY_LEVEL));
builder.setNightMode(parser.getAttributeBoolean(null, ATTR_NIGHT_MODE));
builder.setColorTemperature(
@@ -980,7 +988,8 @@
boolean userInitiatedChange = (msg.arg1 == 1);
handleBrightnessChanged(values.brightness, userInitiatedChange,
values.powerBrightnessFactor, values.isUserSetBrightness,
- values.isDefaultBrightnessConfig, values.timestamp);
+ values.isDefaultBrightnessConfig, values.timestamp,
+ values.uniqueDisplayId);
break;
case MSG_START_SENSOR_LISTENER:
startSensorListener();
@@ -1007,20 +1016,22 @@
}
private static class BrightnessChangeValues {
- final float brightness;
- final float powerBrightnessFactor;
- final boolean isUserSetBrightness;
- final boolean isDefaultBrightnessConfig;
- final long timestamp;
+ public final float brightness;
+ public final float powerBrightnessFactor;
+ public final boolean isUserSetBrightness;
+ public final boolean isDefaultBrightnessConfig;
+ public final long timestamp;
+ public final String uniqueDisplayId;
BrightnessChangeValues(float brightness, float powerBrightnessFactor,
boolean isUserSetBrightness, boolean isDefaultBrightnessConfig,
- long timestamp) {
+ long timestamp, String uniqueDisplayId) {
this.brightness = brightness;
this.powerBrightnessFactor = powerBrightnessFactor;
this.isUserSetBrightness = isUserSetBrightness;
this.isDefaultBrightnessConfig = isDefaultBrightnessConfig;
this.timestamp = timestamp;
+ this.uniqueDisplayId = uniqueDisplayId;
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 96a7416..82ca820 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -376,6 +376,8 @@
private final ColorSpace mWideColorSpace;
private SensorManager mSensorManager;
+ private BrightnessTracker mBrightnessTracker;
+
// Whether minimal post processing is allowed by the user.
@GuardedBy("mSyncRoot")
@@ -1162,7 +1164,7 @@
DisplayPowerController dpc = mDisplayPowerControllers.get(displayId);
if (dpc != null) {
- dpc.onDisplayChanged();
+ dpc.onDisplayChangedLocked();
}
}
@@ -1851,7 +1853,10 @@
for (int i = 0; i < displayPowerControllerCount; i++) {
mDisplayPowerControllers.valueAt(i).dump(pw);
}
-
+ if (mBrightnessTracker != null) {
+ pw.println();
+ mBrightnessTracker.dump(pw);
+ }
pw.println();
mPersistentDataStore.dump(pw);
}
@@ -1937,9 +1942,12 @@
// initPowerManagement has not yet been called.
return;
}
+ if (mBrightnessTracker == null) {
+ mBrightnessTracker = new BrightnessTracker(mContext, null);
+ }
final DisplayPowerController displayPowerController = new DisplayPowerController(
mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager,
- mDisplayBlanker, display);
+ mDisplayBlanker, display, mBrightnessTracker);
mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index e44ecac..7110d3e 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -174,6 +174,9 @@
// The ID of the LogicalDisplay tied to this DisplayPowerController.
private final int mDisplayId;
+ // The unique ID of the primary display device currently tied to this logical display
+ private String mUniqueDisplayId;
+
// Tracker for brightness changes.
@Nullable
private final BrightnessTracker mBrightnessTracker;
@@ -416,16 +419,15 @@
*/
public DisplayPowerController(Context context,
DisplayPowerCallbacks callbacks, Handler handler,
- SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay) {
+ SensorManager sensorManager, DisplayBlanker blanker, LogicalDisplay logicalDisplay,
+ BrightnessTracker brightnessTracker) {
mLogicalDisplay = logicalDisplay;
mDisplayId = mLogicalDisplay.getDisplayIdLocked();
mHandler = new DisplayControllerHandler(handler.getLooper());
if (mDisplayId == Display.DEFAULT_DISPLAY) {
- mBrightnessTracker = new BrightnessTracker(context, null);
mBatteryStats = BatteryStatsService.getService();
} else {
- mBrightnessTracker = null;
mBatteryStats = null;
}
@@ -435,6 +437,7 @@
mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
mBlanker = blanker;
mContext = context;
+ mBrightnessTracker = brightnessTracker;
PowerManager pm = context.getSystemService(PowerManager.class);
@@ -756,8 +759,10 @@
* when displays get swapped on foldable devices. For example, different brightness properties
* of each display need to be properly reflected in AutomaticBrightnessController.
*/
- public void onDisplayChanged() {
+ public void onDisplayChangedLocked() {
// TODO: b/175821789 - Support high brightness on multiple (folding) displays
+
+ mUniqueDisplayId = mLogicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId();
}
/**
@@ -780,10 +785,6 @@
mAutomaticBrightnessController.stop();
}
- if (mBrightnessTracker != null) {
- mBrightnessTracker.stop();
- }
-
mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
}
}
@@ -1899,7 +1900,7 @@
: 1.0f;
mBrightnessTracker.notifyBrightnessChanged(brightnessInNits, userInitiated,
powerFactor, hadUserDataPoint,
- mAutomaticBrightnessController.isDefaultConfig());
+ mAutomaticBrightnessController.isDefaultConfig(), mUniqueDisplayId);
}
}
@@ -2067,11 +2068,6 @@
mAutomaticBrightnessController.dump(pw);
}
- if (mBrightnessTracker != null) {
- pw.println();
- mBrightnessTracker.dump(pw);
- }
-
pw.println();
if (mDisplayWhiteBalanceController != null) {
mDisplayWhiteBalanceController.dump(pw);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index aaec89a..2546118 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -853,14 +853,6 @@
// Do not lock when calling these SurfaceControl methods because they are sync
// operations that may block for a while when setting display power mode.
mSurfaceControlProxy.setDesiredDisplayModeSpecs(displayToken, modeSpecs);
-
- final int sfActiveModeId = mSurfaceControlProxy
- .getDynamicDisplayInfo(displayToken).activeDisplayModeId;
- synchronized (getSyncRoot()) {
- if (updateActiveModeLocked(sfActiveModeId)) {
- updateDeviceInfoLocked();
- }
- }
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index e6e2f96..03a8338 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -431,6 +431,13 @@
private final SelectRequestBuffer mSelectRequestBuffer = new SelectRequestBuffer();
+ @VisibleForTesting HdmiControlService(Context context, List<Integer> deviceTypes) {
+ super(context);
+ mLocalDevices = deviceTypes;
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mHdmiCecConfig = new HdmiCecConfig(context);
+ }
+
public HdmiControlService(Context context) {
super(context);
List<Integer> deviceTypes = HdmiProperties.device_type();
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index db3d7ad..89dac05 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -664,13 +664,16 @@
// naturally.
private boolean mInSizeCompatModeForBounds = false;
- // Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
- // orientation then aspect ratio restrictions are also already respected.
+ // Bounds populated in resolveFixedOrientationConfiguration when this activity is letterboxed
+ // for fixed orientation. If not null, they are used as parent container in
+ // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. If
+ // letterboxed due to fixed orientation then aspect ratio restrictions are also respected.
// This happens when an activity has fixed orientation which doesn't match orientation of the
// parent because a display is ignoring orientation request or fixed to user rotation.
// See WindowManagerService#getIgnoreOrientationRequest and
// WindowManagerService#getFixedToUserRotation for more context.
- private boolean mIsLetterboxedForFixedOrientationAndAspectRatio = false;
+ @Nullable
+ private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
// activity is not displayed?
// TODO: rename to mNoDisplay
@@ -6863,7 +6866,7 @@
}
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
- private void updateCompatDisplayInsets(@Nullable Rect fixedOrientationBounds) {
+ private void updateCompatDisplayInsets() {
if (mCompatDisplayInsets != null || !shouldCreateCompatDisplayInsets()) {
// The override configuration is set only once in size compatibility mode.
return;
@@ -6891,7 +6894,8 @@
// The role of CompatDisplayInsets is like the override bounds.
mCompatDisplayInsets =
- new CompatDisplayInsets(mDisplayContent, this, fixedOrientationBounds);
+ new CompatDisplayInsets(
+ mDisplayContent, this, mLetterboxBoundsForFixedOrientationAndAspectRatio);
}
@VisibleForTesting
@@ -6945,8 +6949,6 @@
|| windowingMode == WINDOWING_MODE_FULLSCREEN) {
resolveFixedOrientationConfiguration(newParentConfiguration);
}
- final Rect fixedOrientationBounds = isLetterboxedForFixedOrientationAndAspectRatio()
- ? new Rect(resolvedConfig.windowConfiguration.getBounds()) : null;
if (mCompatDisplayInsets != null) {
resolveSizeCompatModeConfiguration(newParentConfiguration);
@@ -6966,7 +6968,7 @@
}
if (mVisibleRequested) {
- updateCompatDisplayInsets(fixedOrientationBounds);
+ updateCompatDisplayInsets();
}
// TODO(b/175212232): Consolidate position logic from each "resolve" method above here.
@@ -7001,7 +7003,7 @@
* WindowManagerService#getIgnoreOrientationRequest} for more context.
*/
boolean isLetterboxedForFixedOrientationAndAspectRatio() {
- return mIsLetterboxedForFixedOrientationAndAspectRatio;
+ return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
}
/**
@@ -7012,7 +7014,7 @@
* in this methiod.
*/
private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig) {
- mIsLetterboxedForFixedOrientationAndAspectRatio = false;
+ mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
if (handlesOrientationChangeFromDescendant()) {
// No need to letterbox because of fixed orientation. Display will handle
// fixed-orientation requests.
@@ -7089,7 +7091,7 @@
// Calculate app bounds using fixed orientation bounds because they will be needed later
// for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
task.computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
- mIsLetterboxedForFixedOrientationAndAspectRatio = true;
+ mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
}
/**
@@ -7635,6 +7637,12 @@
if (getConfiguration().equals(mTmpConfig) && !forceNewConfig && !displayChanged) {
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Configuration & display "
+ "unchanged in %s", this);
+ // It's possible that resolveOverrideConfiguration was called before mVisibleRequested
+ // became true and mCompatDisplayInsets may not have been created so ensure
+ // that mCompatDisplayInsets is created here.
+ if (mVisibleRequested) {
+ updateCompatDisplayInsets();
+ }
return true;
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 01f0359..d929d50 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -448,7 +448,8 @@
final Looper looper = UiThread.getHandler().getLooper();
mHandler = new PolicyHandler(looper);
- mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,
+ // TODO(b/181821798) Migrate SystemGesturesPointerEventListener to use window context.
+ mSystemGestures = new SystemGesturesPointerEventListener(mUiContext, mHandler,
new SystemGesturesPointerEventListener.Callbacks() {
@Override
public void onSwipeFromTop() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ec012fc3..73b0555 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -431,7 +431,7 @@
* @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY
*/
public static boolean sEnableRemoteKeyguardAnimation =
- SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false);
+ SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, true);
private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY =
"ro.sf.disable_triple_buffer";
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ac2281a..ffae3ab 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -14699,24 +14699,25 @@
private void sendNetworkLoggingNotificationLocked() {
ensureLocked();
- final ActiveAdmin activeAdmin = getNetworkLoggingControllingAdminLocked();
- if (activeAdmin == null || !activeAdmin.isNetworkLoggingEnabled) {
+ // Send a network logging notification if the admin is a device owner, not profile owner.
+ final ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked();
+ if (deviceOwner == null || !deviceOwner.isNetworkLoggingEnabled) {
return;
}
- if (activeAdmin.numNetworkLoggingNotifications
+ if (deviceOwner.numNetworkLoggingNotifications
>= ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) {
return;
}
final long now = System.currentTimeMillis();
- if (now - activeAdmin.lastNetworkLoggingNotificationTimeMs < MS_PER_DAY) {
+ if (now - deviceOwner.lastNetworkLoggingNotificationTimeMs < MS_PER_DAY) {
return;
}
- activeAdmin.numNetworkLoggingNotifications++;
- if (activeAdmin.numNetworkLoggingNotifications
+ deviceOwner.numNetworkLoggingNotifications++;
+ if (deviceOwner.numNetworkLoggingNotifications
>= ActiveAdmin.DEF_MAXIMUM_NETWORK_LOGGING_NOTIFICATIONS_SHOWN) {
- activeAdmin.lastNetworkLoggingNotificationTimeMs = 0;
+ deviceOwner.lastNetworkLoggingNotificationTimeMs = 0;
} else {
- activeAdmin.lastNetworkLoggingNotificationTimeMs = now;
+ deviceOwner.lastNetworkLoggingNotificationTimeMs = now;
}
final PackageManagerInternal pm = mInjector.getPackageManagerInternal();
final Intent intent = new Intent(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
@@ -14736,7 +14737,7 @@
.bigText(mContext.getString(R.string.network_logging_notification_text)))
.build();
mInjector.getNotificationManager().notify(SystemMessage.NOTE_NETWORK_LOGGING, notification);
- saveSettingsLocked(activeAdmin.getUserHandle().getIdentifier());
+ saveSettingsLocked(deviceOwner.getUserHandle().getIdentifier());
}
/**
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index c38d0b3..e3fbedd 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -86,6 +86,9 @@
static constexpr auto maxBindDelay = 10000s;
static constexpr auto bindDelayMultiplier = 10;
static constexpr auto bindDelayJitterDivider = 10;
+
+ // Max interval after system invoked the DL when readlog collection can be enabled.
+ static constexpr auto readLogsMaxInterval = 2h;
};
static const Constants& constants() {
@@ -290,6 +293,14 @@
::rmdir(path::c_str(root));
}
+void IncrementalService::IncFsMount::setReadLogsEnabled(bool value) {
+ if (value) {
+ flags |= StorageFlags::ReadLogsEnabled;
+ } else {
+ flags &= ~StorageFlags::ReadLogsEnabled;
+ }
+}
+
IncrementalService::IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir)
: mVold(sm.getVoldService()),
mDataLoaderManager(sm.getDataLoaderManager()),
@@ -406,7 +417,7 @@
}
bool IncrementalService::needStartDataLoaderLocked(IncFsMount& ifs) {
- if (ifs.dataLoaderStub->params().packageName == Constants::systemPackage) {
+ if (ifs.dataLoaderStub->isSystemDataLoader()) {
return true;
}
@@ -658,7 +669,7 @@
return storageId;
}
-bool IncrementalService::startLoading(StorageId storage,
+bool IncrementalService::startLoading(StorageId storageId,
content::pm::DataLoaderParamsParcel&& dataLoaderParams,
const DataLoaderStatusListener& statusListener,
StorageHealthCheckParams&& healthCheckParams,
@@ -666,12 +677,12 @@
const std::vector<PerUidReadTimeouts>& perUidReadTimeouts) {
// Per Uid timeouts.
if (!perUidReadTimeouts.empty()) {
- setUidReadTimeouts(storage, perUidReadTimeouts);
+ setUidReadTimeouts(storageId, perUidReadTimeouts);
}
// Re-initialize DataLoader.
std::unique_lock l(mLock);
- const auto ifs = getIfsLocked(storage);
+ const auto ifs = getIfsLocked(storageId);
if (!ifs) {
return false;
}
@@ -686,6 +697,32 @@
std::move(healthCheckParams), &healthListener);
CHECK(dataLoaderStub);
+ if (dataLoaderStub->isSystemDataLoader()) {
+ // Readlogs from system dataloader (adb) can always be collected.
+ ifs->startLoadingTs = TimePoint::max();
+ } else {
+ // Assign time when installation wants the DL to start streaming.
+ const auto startLoadingTs = mClock->now();
+ ifs->startLoadingTs = startLoadingTs;
+ // Setup a callback to disable the readlogs after max interval.
+ addTimedJob(*mTimedQueue, storageId, Constants::readLogsMaxInterval,
+ [this, storageId, startLoadingTs]() {
+ const auto ifs = getIfs(storageId);
+ if (!ifs) {
+ LOG(WARNING) << "Can't disable the readlogs, invalid storageId: "
+ << storageId;
+ return;
+ }
+ if (ifs->startLoadingTs != startLoadingTs) {
+ LOG(INFO) << "Can't disable the readlogs, timestamp mismatch (new "
+ "installation?): "
+ << storageId;
+ return;
+ }
+ setStorageParams(*ifs, storageId, /*enableReadLogs=*/false);
+ });
+ }
+
return dataLoaderStub->requestStart();
}
@@ -735,11 +772,16 @@
LOG(ERROR) << "setStorageParams failed, invalid storageId: " << storageId;
return -EINVAL;
}
+ return setStorageParams(*ifs, storageId, enableReadLogs);
+}
- const auto& params = ifs->dataLoaderStub->params();
+int IncrementalService::setStorageParams(IncFsMount& ifs, StorageId storageId,
+ bool enableReadLogs) {
+ const auto& params = ifs.dataLoaderStub->params();
if (enableReadLogs) {
- if (!ifs->readLogsAllowed()) {
- LOG(ERROR) << "setStorageParams failed, readlogs disabled for storageId: " << storageId;
+ if (!ifs.readLogsAllowed()) {
+ LOG(ERROR) << "setStorageParams failed, readlogs disallowed for storageId: "
+ << storageId;
return -EPERM;
}
@@ -760,9 +802,19 @@
<< " check failed: " << status.toString8();
return fromBinderStatus(status);
}
+
+ // Check installation time.
+ const auto now = mClock->now();
+ const auto startLoadingTs = ifs.startLoadingTs;
+ if (startLoadingTs <= now && now - startLoadingTs > Constants::readLogsMaxInterval) {
+ LOG(ERROR) << "setStorageParams failed, readlogs can't be enabled at this time, "
+ "storageId: "
+ << storageId;
+ return -EPERM;
+ }
}
- if (auto status = applyStorageParams(*ifs, enableReadLogs); !status.isOk()) {
+ if (auto status = applyStorageParams(ifs, enableReadLogs); !status.isOk()) {
LOG(ERROR) << "applyStorageParams failed: " << status.toString8();
return fromBinderStatus(status);
}
@@ -2222,6 +2274,10 @@
return dataloader;
}
+bool IncrementalService::DataLoaderStub::isSystemDataLoader() const {
+ return (params().packageName == Constants::systemPackage);
+}
+
bool IncrementalService::DataLoaderStub::requestCreate() {
return setTargetStatus(IDataLoaderStatusListener::DATA_LOADER_CREATED);
}
diff --git a/services/incremental/IncrementalService.h b/services/incremental/IncrementalService.h
index 4eb5138..bc441c7 100644
--- a/services/incremental/IncrementalService.h
+++ b/services/incremental/IncrementalService.h
@@ -231,6 +231,7 @@
MountId id() const { return mId.load(std::memory_order_relaxed); }
const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
+ bool isSystemDataLoader() const;
void setHealthListener(StorageHealthCheckParams&& healthCheckParams,
const StorageHealthListener* healthListener);
long elapsedMsSinceOldestPendingRead();
@@ -330,6 +331,7 @@
StorageMap storages;
BindMap bindPoints;
DataLoaderStubPtr dataLoaderStub;
+ TimePoint startLoadingTs = {};
std::atomic<int> nextStorageDirNo{0};
const IncrementalService& incrementalService;
@@ -348,12 +350,7 @@
void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; }
int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); }
- void setReadLogsEnabled(bool value) {
- if (value)
- flags |= StorageFlags::ReadLogsEnabled;
- else
- flags &= ~StorageFlags::ReadLogsEnabled;
- }
+ void setReadLogsEnabled(bool value);
int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
static void cleanupFilesystem(std::string_view root);
@@ -411,6 +408,8 @@
IncFsMount::StorageMap::const_iterator storageIt,
std::string_view path) const;
int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
+
+ int setStorageParams(IncFsMount& ifs, StorageId storageId, bool enableReadLogs);
binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const;
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 25b34b56..bf798273 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -908,7 +908,7 @@
EXPECT_CALL(*mDataLoader, start(_)).Times(6);
EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
- EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(3);
TemporaryDir tempDir;
int storageId =
mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
@@ -1119,7 +1119,7 @@
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(2);
EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(2);
- EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(4);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(5);
sp<NiceMock<MockStorageHealthListener>> listener{new NiceMock<MockStorageHealthListener>};
NiceMock<MockStorageHealthListener>* listenerMock = listener.get();
@@ -1292,6 +1292,147 @@
ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
}
+TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndTimedOut) {
+ mVold->setIncFsMountOptionsSuccess();
+ mAppOpsManager->checkPermissionSuccess();
+
+ const auto readLogsMaxInterval = 2h;
+
+ EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ // Enabling and then disabling readlogs.
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(2);
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
+ // After setIncFsMountOptions succeeded expecting to start watching.
+ EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
+ // Not expecting callback removal.
+ EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+ {}, {}));
+
+ // Disable readlogs callback present.
+ ASSERT_EQ(storageId, mTimedQueue->mId);
+ ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
+ auto callback = mTimedQueue->mWhat;
+ mTimedQueue->clearJob(storageId);
+
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now advance clock for 1hr.
+ mClock->advance(1h);
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now call the timed callback, it should turn off the readlogs.
+ callback();
+ // Now advance clock for 2hrs.
+ mClock->advance(readLogsMaxInterval);
+ ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
+}
+
+TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNoTimedOutForSystem) {
+ mVold->setIncFsMountOptionsSuccess();
+ mAppOpsManager->checkPermissionSuccess();
+
+ const auto readLogsMaxInterval = 2h;
+
+ EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_));
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ // Enabling and then disabling readlogs.
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(0);
+ // After setIncFsMountOptions succeeded expecting to start watching.
+ EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
+ // Not expecting callback removal.
+ EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
+ // System data loader.
+ mDataLoaderParcel.packageName = "android";
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+ {}, {}));
+
+ // No readlogs callback.
+ ASSERT_EQ(mTimedQueue->mAfter, 0ms);
+ ASSERT_EQ(mTimedQueue->mWhat, nullptr);
+
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now advance clock for 1hr.
+ mClock->advance(1h);
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now advance clock for 2hrs.
+ mClock->advance(readLogsMaxInterval);
+ ASSERT_EQ(mDataLoader->setStorageParams(true), 0);
+}
+
+TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndNewInstall) {
+ mVold->setIncFsMountOptionsSuccess();
+ mAppOpsManager->checkPermissionSuccess();
+
+ const auto readLogsMaxInterval = 2h;
+
+ EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
+ EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
+ // Enabling and then disabling readlogs.
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, true)).Times(3);
+ EXPECT_CALL(*mVold, setIncFsMountOptions(_, false)).Times(1);
+ // After setIncFsMountOptions succeeded expecting to start watching.
+ EXPECT_CALL(*mAppOpsManager, startWatchingMode(_, _, _)).Times(1);
+ // Not expecting callback removal.
+ EXPECT_CALL(*mAppOpsManager, stopWatchingMode(_)).Times(0);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(2);
+ TemporaryDir tempDir;
+ int storageId =
+ mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
+ IncrementalService::CreateOptions::CreateNew);
+ ASSERT_GE(storageId, 0);
+
+ auto dataLoaderParcel = mDataLoaderParcel;
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(dataLoaderParcel), {}, {},
+ {}, {}));
+
+ // Disable readlogs callback present.
+ ASSERT_EQ(storageId, mTimedQueue->mId);
+ ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
+ auto callback = mTimedQueue->mWhat;
+ mTimedQueue->clearJob(storageId);
+
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+ // Now advance clock for 1.5hrs.
+ mClock->advance(90min);
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+
+ // New installation.
+ ASSERT_TRUE(mIncrementalService->startLoading(storageId, std::move(mDataLoaderParcel), {}, {},
+ {}, {}));
+
+ // New callback present.
+ ASSERT_EQ(storageId, mTimedQueue->mId);
+ ASSERT_EQ(mTimedQueue->mAfter, readLogsMaxInterval);
+ auto callback2 = mTimedQueue->mWhat;
+ mTimedQueue->clearJob(storageId);
+
+ // Old callback should not disable readlogs (setIncFsMountOptions should be called only once).
+ callback();
+ // Advance clock for another 1.5hrs.
+ mClock->advance(90min);
+ // Still success even it's 3hrs past first install.
+ ASSERT_GE(mDataLoader->setStorageParams(true), 0);
+
+ // New one should disable.
+ callback2();
+ // And timeout.
+ mClock->advance(90min);
+ ASSERT_EQ(mDataLoader->setStorageParams(true), -EPERM);
+}
+
TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) {
mVold->setIncFsMountOptionsSuccess();
mAppOpsManager->checkPermissionSuccess();
@@ -1675,7 +1816,7 @@
EXPECT_CALL(*mDataLoader, start(_)).Times(1);
EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
EXPECT_CALL(*mIncFs, setUidReadTimeouts(_, _)).Times(0);
- EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(0);
+ EXPECT_CALL(*mTimedQueue, addJob(_, _, _)).Times(1);
EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
TemporaryDir tempDir;
int storageId =
@@ -1702,6 +1843,9 @@
// Empty storage.
mIncFs->countFilledBlocksEmpty();
+ // Mark DataLoader as 'system' so that readlogs don't pollute the timed queue.
+ mDataLoaderParcel.packageName = "android";
+
TemporaryDir tempDir;
int storageId =
mIncrementalService->createStorage(tempDir.path, mDataLoaderParcel,
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
index 893ce9e..bdf94f3 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java
@@ -81,6 +81,7 @@
public class BrightnessTrackerTest {
private static final float DEFAULT_INITIAL_BRIGHTNESS = 2.5f;
private static final boolean DEFAULT_COLOR_SAMPLING_ENABLED = true;
+ private static final String DEFAULT_DISPLAY_ID = "123";
private static final float FLOAT_DELTA = 0.01f;
private BrightnessTracker mTracker;
@@ -285,18 +286,20 @@
@Test
public void testBrightnessEvent() {
- final int brightness = 20;
+ final float brightness = 0.5f;
+ final String displayId = "1234";
startTracker(mTracker);
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1.0f));
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
- notifyBrightnessChanged(mTracker, brightness);
+ notifyBrightnessChanged(mTracker, brightness, displayId);
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
mTracker.stop();
assertEquals(1, events.size());
BrightnessChangeEvent event = events.get(0);
assertEquals(mInjector.currentTimeMillis(), event.timeStamp);
+ assertEquals(displayId, event.uniqueDisplayId);
assertEquals(1, event.luxValues.length);
assertEquals(1.0f, event.luxValues[0], FLOAT_DELTA);
assertEquals(mInjector.currentTimeMillis() - TimeUnit.SECONDS.toMillis(2),
@@ -314,6 +317,7 @@
public void testBrightnessFullPopulatedEvent() {
final int initialBrightness = 230;
final int brightness = 130;
+ final String displayId = "1234";
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3333);
@@ -326,7 +330,7 @@
batteryChangeEvent(30, 60));
mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
final long sensorTime = mInjector.currentTimeMillis();
- notifyBrightnessChanged(mTracker, brightness);
+ notifyBrightnessChanged(mTracker, brightness, displayId);
List<BrightnessChangeEvent> eventsNoPackage
= mTracker.getEvents(0, false).getList();
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
@@ -335,6 +339,7 @@
assertEquals(1, events.size());
BrightnessChangeEvent event = events.get(0);
assertEquals(event.timeStamp, mInjector.currentTimeMillis());
+ assertEquals(displayId, event.uniqueDisplayId);
assertArrayEquals(new float[] {1000.0f}, event.luxValues, 0.01f);
assertArrayEquals(new long[] {sensorTime}, event.luxTimestamps);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
@@ -364,7 +369,7 @@
final int systemUpdatedBrightness = 20;
notifyBrightnessChanged(mTracker, systemUpdatedBrightness, false /*userInitiated*/,
0.5f /*powerBrightnessFactor(*/, false /*isUserSetBrightness*/,
- false /*isDefaultBrightnessConfig*/);
+ false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID);
List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
// No events because we filtered out our change.
assertEquals(0, events.size());
@@ -455,6 +460,7 @@
+ "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" "
+ "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" "
+ "reduceBrightColorsOffset=\"0\"\n"
+ + "uniqueDisplayId=\"123\""
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+ "defaultConfig=\"true\" powerSaveFactor=\"0.5\" userPoint=\"true\" />"
@@ -465,6 +471,7 @@
+ "batteryLevel=\"0.5\" nightMode=\"true\" colorTemperature=\"3235\" "
+ "reduceBrightColors=\"true\" reduceBrightColorsStrength=\"40\" "
+ "reduceBrightColorsOffset=\"0\"\n"
+ + "uniqueDisplayId=\"456\""
+ "lux=\"132.2,131.1\" luxTimestamps=\""
+ Long.toString(someTimeAgo) + "," + Long.toString(someTimeAgo) + "\""
+ "colorSampleDuration=\"3456\" colorValueBuckets=\"123,598,23,19\"/>"
@@ -476,6 +483,7 @@
+ "batteryLevel=\"1.0\" nightMode=\"false\" colorTemperature=\"0\" "
+ "reduceBrightColors=\"false\" reduceBrightColorsStrength=\"40\" "
+ "reduceBrightColorsOffset=\"0\"\n"
+ + "uniqueDisplayId=\"789\""
+ "lux=\"32.2,31.1\" luxTimestamps=\""
+ Long.toString(twoMonthsAgo) + "," + Long.toString(twoMonthsAgo) + "\"/>"
+ "</events>";
@@ -485,6 +493,7 @@
BrightnessChangeEvent event = events.get(0);
assertEquals(someTimeAgo, event.timeStamp);
assertEquals(194.2, event.brightness, FLOAT_DELTA);
+ assertEquals("123", event.uniqueDisplayId);
assertArrayEquals(new float[] {32.2f, 31.1f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
assertEquals(32.333, event.lastBrightness, FLOAT_DELTA);
@@ -503,6 +512,7 @@
event = events.get(0);
assertEquals(someTimeAgo, event.timeStamp);
assertEquals(71, event.brightness, FLOAT_DELTA);
+ assertEquals("456", event.uniqueDisplayId);
assertArrayEquals(new float[] {132.2f, 131.1f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {someTimeAgo, someTimeAgo}, event.luxTimestamps);
assertEquals(32, event.lastBrightness, FLOAT_DELTA);
@@ -575,6 +585,7 @@
@Test
public void testWriteThenRead() throws Exception {
final int brightness = 20;
+ final String displayId = "1234";
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_ACTIVATED, 1);
mInjector.mSecureIntSettings.put(Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, 3339);
@@ -593,7 +604,7 @@
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(3));
notifyBrightnessChanged(mTracker, brightness, true /*userInitiated*/,
0.5f /*powerBrightnessFactor*/, true /*hasUserBrightnessPoints*/,
- false /*isDefaultBrightnessConfig*/);
+ false /*isDefaultBrightnessConfig*/, displayId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
mTracker.writeEventsLocked(baos);
mTracker.stop();
@@ -607,6 +618,7 @@
assertEquals(1, events.size());
BrightnessChangeEvent event = events.get(0);
+ assertEquals(displayId, event.uniqueDisplayId);
assertArrayEquals(new float[] {2000.0f, 3000.0f}, event.luxValues, FLOAT_DELTA);
assertArrayEquals(new long[] {firstSensorTime, secondSensorTime}, event.luxTimestamps);
assertEquals(brightness, event.brightness, FLOAT_DELTA);
@@ -678,6 +690,7 @@
builder.setTimeStamp(345L);
builder.setPackageName("com.example");
builder.setUserId(12);
+ builder.setUniqueDisplayId("9876");
float[] luxValues = new float[2];
luxValues[0] = 3000.0f;
luxValues[1] = 4000.0f;
@@ -710,6 +723,7 @@
assertEquals(event.timeStamp, event2.timeStamp);
assertEquals(event.packageName, event2.packageName);
assertEquals(event.userId, event2.userId);
+ assertEquals(event.uniqueDisplayId, event2.uniqueDisplayId);
assertArrayEquals(event.luxValues, event2.luxValues, FLOAT_DELTA);
assertArrayEquals(event.luxTimestamps, event2.luxTimestamps);
assertEquals(event.batteryLevel, event2.batteryLevel, FLOAT_DELTA);
@@ -773,7 +787,7 @@
long eventTime = mInjector.currentTimeMillis();
mTracker.notifyBrightnessChanged(brightness, true /*userInitiated*/,
1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/,
- false /*isDefaultBrightnessConfig*/);
+ false /*isDefaultBrightnessConfig*/, DEFAULT_DISPLAY_ID);
// Time passes before handler can run.
mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
@@ -791,6 +805,35 @@
assertEquals(eventTime, event.timeStamp);
}
+ @Test
+ public void testDisplayIdChange() {
+ float firstBrightness = 0.5f;
+ float secondBrightness = 0.75f;
+ String firstDisplayId = "123";
+ String secondDisplayId = "456";
+
+ startTracker(mTracker);
+ mInjector.mSensorListener.onSensorChanged(createSensorEvent(1000.0f));
+
+ notifyBrightnessChanged(mTracker, firstBrightness, firstDisplayId);
+ mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
+ List<BrightnessChangeEvent> events = mTracker.getEvents(0, true).getList();
+ assertEquals(1, events.size());
+ BrightnessChangeEvent firstEvent = events.get(0);
+ assertEquals(firstDisplayId, firstEvent.uniqueDisplayId);
+ assertEquals(firstBrightness, firstEvent.brightness, 0.001f);
+
+ notifyBrightnessChanged(mTracker, secondBrightness, secondDisplayId);
+ mInjector.incrementTime(TimeUnit.SECONDS.toMillis(2));
+ events = mTracker.getEvents(0, true).getList();
+ assertEquals(2, events.size());
+ BrightnessChangeEvent secondEvent = events.get(1);
+ assertEquals(secondDisplayId, secondEvent.uniqueDisplayId);
+ assertEquals(secondBrightness, secondEvent.brightness, 0.001f);
+
+ mTracker.stop();
+ }
+
private InputStream getInputStream(String data) {
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
}
@@ -831,16 +874,21 @@
}
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness) {
+ notifyBrightnessChanged(tracker, brightness, DEFAULT_DISPLAY_ID);
+ }
+
+ private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
+ String displayId) {
notifyBrightnessChanged(tracker, brightness, true /*userInitiated*/,
1.0f /*powerBrightnessFactor*/, false /*isUserSetBrightness*/,
- false /*isDefaultBrightnessConfig*/);
+ false /*isDefaultBrightnessConfig*/, displayId);
}
private void notifyBrightnessChanged(BrightnessTracker tracker, float brightness,
boolean userInitiated, float powerBrightnessFactor, boolean isUserSetBrightness,
- boolean isDefaultBrightnessConfig) {
+ boolean isDefaultBrightnessConfig, String displayId) {
tracker.notifyBrightnessChanged(brightness, userInitiated, powerBrightnessFactor,
- isUserSetBrightness, isDefaultBrightnessConfig);
+ isUserSetBrightness, isDefaultBrightnessConfig, displayId);
mInjector.waitForHandler();
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
index 605f781..53b4b49 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
@@ -19,7 +19,6 @@
import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_2;
-import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.google.common.truth.Truth.assertThat;
@@ -51,6 +50,7 @@
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.concurrent.TimeUnit;
/** Tests for {@link ActiveSourceAction} */
@@ -84,7 +84,8 @@
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- mHdmiControlService = new HdmiControlService(mContextSpy) {
+ mHdmiControlService = new HdmiControlService(mContextSpy,
+ Collections.singletonList(HdmiDeviceInfo.DEVICE_TV)) {
@Override
AudioManager getAudioManager() {
return new AudioManager() {
@@ -140,6 +141,7 @@
mNativeWrapper.setPhysicalAddress(mPhysicalAddress);
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
+ mNativeWrapper.clearResultMessages();
}
@Test
@@ -152,7 +154,7 @@
mTestLooper.dispatchAll();
HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_1);
assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
@@ -191,7 +193,7 @@
mTestLooper.dispatchAll();
HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_1);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus);
@@ -220,12 +222,12 @@
mTestLooper.dispatchAll();
HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_1);
assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
HdmiCecMessage giveDevicePowerStatus2 = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_2);
assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus2);
}
@@ -245,13 +247,13 @@
mTestLooper.dispatchAll();
HdmiCecMessage giveDevicePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_1);
assertThat(mNativeWrapper.getResultMessages()).contains(giveDevicePowerStatus);
HdmiCecMessage giveDevicePowerStatus2 = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
- ADDR_TV,
+ mTvDevice.mAddress,
ADDR_PLAYBACK_2);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(giveDevicePowerStatus2);
@@ -265,7 +267,7 @@
}
private void reportPowerStatus(int logicalAddress, boolean broadcast, int powerStatus) {
- int destination = broadcast ? ADDR_BROADCAST : ADDR_TV;
+ int destination = broadcast ? ADDR_BROADCAST : mTvDevice.mAddress;
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
logicalAddress, destination,
powerStatus);
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index 60390dc..b2dacab 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -261,6 +261,7 @@
// mEndTimeStamp is based on the enclosing IntervalStats, don't bother checking
assertEquals(us1.mLastTimeUsed, us2.mLastTimeUsed);
assertEquals(us1.mLastTimeVisible, us2.mLastTimeVisible);
+ assertEquals(us1.mLastTimeComponentUsed, us2.mLastTimeComponentUsed);
assertEquals(us1.mTotalTimeInForeground, us2.mTotalTimeInForeground);
assertEquals(us1.mTotalTimeVisible, us2.mTotalTimeVisible);
assertEquals(us1.mLastTimeForegroundServiceUsed, us2.mLastTimeForegroundServiceUsed);
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerService.java b/services/translation/java/com/android/server/translation/TranslationManagerService.java
index 8874e0a..72e1e33 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerService.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerService.java
@@ -27,6 +27,7 @@
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
@@ -203,6 +204,28 @@
}
}
+ @Override
+ public void registerUiTranslationStateCallback(IRemoteCallback callback, int userId) {
+ TranslationManagerServiceImpl service;
+ synchronized (mLock) {
+ service = getServiceForUserLocked(userId);
+ }
+ if (service != null) {
+ service.registerUiTranslationStateCallback(callback, Binder.getCallingUid());
+ }
+ }
+
+ @Override
+ public void unregisterUiTranslationStateCallback(IRemoteCallback callback, int userId) {
+ TranslationManagerServiceImpl service;
+ synchronized (mLock) {
+ service = getServiceForUserLocked(userId);
+ }
+ if (service != null) {
+ service.unregisterUiTranslationStateCallback(callback);
+ }
+ }
+
/**
* Dump the service state into the given stream. You run "adb shell dumpsys translation".
*/
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index ab6ac12..1ca07cb 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -17,17 +17,24 @@
package com.android.server.translation;
import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_SUCCESS;
+import static android.view.translation.UiTranslationManager.EXTRA_SOURCE_LOCALE;
+import static android.view.translation.UiTranslationManager.EXTRA_STATE;
+import static android.view.translation.UiTranslationManager.EXTRA_TARGET_LOCALE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.IRemoteCallback;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.service.translation.TranslationServiceInfo;
import android.util.Slog;
import android.view.autofill.AutofillId;
+import android.view.inputmethod.InputMethodInfo;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationManager.UiTranslationState;
@@ -36,6 +43,7 @@
import com.android.internal.util.SyncResultReceiver;
import com.android.server.LocalServices;
import com.android.server.infra.AbstractPerUserSystemService;
+import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens;
@@ -174,5 +182,50 @@
} catch (RemoteException e) {
Slog.w(TAG, "Update UiTranslationState fail: " + e);
}
+ invokeCallbacks(state, sourceSpec, destSpec);
}
+
+ private void invokeCallbacks(
+ int state, TranslationSpec sourceSpec, TranslationSpec targetSpec) {
+ Bundle res = new Bundle();
+ res.putInt(EXTRA_STATE, state);
+ // TODO(177500482): Store the locale pair so it can be sent for RESUME events.
+ if (sourceSpec != null) {
+ res.putString(EXTRA_SOURCE_LOCALE, sourceSpec.getLanguage());
+ res.putString(EXTRA_TARGET_LOCALE, targetSpec.getLanguage());
+ }
+ // TODO(177500482): Only support the *current* Input Method.
+ List<InputMethodInfo> enabledInputMethods =
+ LocalServices.getService(InputMethodManagerInternal.class)
+ .getEnabledInputMethodListAsUser(mUserId);
+ mCallbacks.broadcast((callback, uid) -> {
+ // Code here is non-optimal since it's temporary..
+ boolean isIme = false;
+ for (InputMethodInfo inputMethod : enabledInputMethods) {
+ if ((int) uid == inputMethod.getServiceInfo().applicationInfo.uid) {
+ isIme = true;
+ }
+ }
+ // TODO(177500482): Invoke it for the application being translated too.
+ if (!isIme) {
+ return;
+ }
+ try {
+ callback.sendResult(res);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to invoke UiTranslationStateCallback: " + e);
+ }
+ });
+ }
+
+ public void registerUiTranslationStateCallback(IRemoteCallback callback, int sourceUid) {
+ mCallbacks.register(callback, sourceUid);
+ // TODO(177500482): trigger the callback here if we're already translating the UI.
+ }
+
+ public void unregisterUiTranslationStateCallback(IRemoteCallback callback) {
+ mCallbacks.unregister(callback);
+ }
+
+ private final RemoteCallbackList<IRemoteCallback> mCallbacks = new RemoteCallbackList<>();
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProto.java b/services/usage/java/com/android/server/usage/UsageStatsProto.java
index 78b1477..ec4c5fc 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProto.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProto.java
@@ -147,6 +147,10 @@
stats.mTotalTimeVisible = proto.readLong(
IntervalStatsProto.UsageStats.TOTAL_TIME_VISIBLE_MS);
break;
+ case (int) IntervalStatsProto.UsageStats.LAST_TIME_COMPONENT_USED_MS:
+ stats.mLastTimeComponentUsed = statsOut.beginTime + proto.readLong(
+ IntervalStatsProto.UsageStats.LAST_TIME_COMPONENT_USED_MS);
+ break;
}
}
proto.end(token);
@@ -345,6 +349,9 @@
usageStats.mLastTimeVisible, stats.beginTime);
proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_VISIBLE_MS,
usageStats.mTotalTimeVisible);
+ UsageStatsProtoV2.writeOffsetTimestamp(proto,
+ IntervalStatsProto.UsageStats.LAST_TIME_COMPONENT_USED_MS,
+ usageStats.mLastTimeComponentUsed, stats.beginTime);
proto.write(IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT, usageStats.mAppLaunchCount);
try {
writeChooserCounts(proto, usageStats);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
index e6d2841..5c5667c 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsProtoV2.java
@@ -90,6 +90,10 @@
stats.mTotalTimeVisible = proto.readLong(
UsageStatsObfuscatedProto.TOTAL_TIME_VISIBLE_MS);
break;
+ case (int) UsageStatsObfuscatedProto.LAST_TIME_COMPONENT_USED_MS:
+ stats.mLastTimeComponentUsed = beginTime + proto.readLong(
+ UsageStatsObfuscatedProto.LAST_TIME_COMPONENT_USED_MS);
+ break;
case ProtoInputStream.NO_MORE_FIELDS:
return stats;
}
@@ -312,6 +316,8 @@
writeOffsetTimestamp(proto, UsageStatsObfuscatedProto.LAST_TIME_VISIBLE_MS,
stats.mLastTimeVisible, beginTime);
proto.write(UsageStatsObfuscatedProto.TOTAL_TIME_VISIBLE_MS, stats.mTotalTimeVisible);
+ writeOffsetTimestamp(proto, UsageStatsObfuscatedProto.LAST_TIME_COMPONENT_USED_MS,
+ stats.mLastTimeComponentUsed, beginTime);
proto.write(UsageStatsObfuscatedProto.APP_LAUNCH_COUNT, stats.mAppLaunchCount);
try {
writeChooserCounts(proto, stats);
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index f35b9e2..22b4f4e 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -1003,6 +1003,8 @@
formatElapsedTime(usageStats.mTotalTimeVisible, prettyDates));
pw.printPair("lastTimeVisible",
formatDateTime(usageStats.mLastTimeVisible, prettyDates));
+ pw.printPair("lastTimeComponentUsed",
+ formatDateTime(usageStats.mLastTimeComponentUsed, prettyDates));
pw.printPair("totalTimeFS",
formatElapsedTime(usageStats.mTotalTimeForegroundServiceUsed, prettyDates));
pw.printPair("lastTimeFS",
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index c92d40c..3c12aaa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.close
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -49,7 +50,12 @@
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index 1f880f6..8359ccf 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.close
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -49,7 +50,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
index f7e7493..fad25b4 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerExtensions.kt
@@ -16,31 +16,13 @@
package com.android.server.wm.flicker.helpers
-import android.os.RemoteException
-import android.view.Surface
import com.android.server.wm.flicker.Flicker
+import com.android.server.wm.flicker.rules.ChangeDisplayOrientationRule
/**
* Changes the device [rotation] and wait for the rotation animation to complete
*
* @param rotation New device rotation
*/
-fun Flicker.setRotation(rotation: Int) {
- try {
- when (rotation) {
- Surface.ROTATION_270 -> device.setOrientationRight()
- Surface.ROTATION_90 -> device.setOrientationLeft()
- Surface.ROTATION_0 -> device.setOrientationNatural()
- else -> device.setOrientationNatural()
- }
-
- wmHelper.waitForRotation(rotation)
- wmHelper.waitForNavBarStatusBarVisible()
- wmHelper.waitForAppTransitionIdle()
-
- // Ensure WindowManagerService wait until all animations have completed
- instrumentation.uiAutomation.syncInputTransactions()
- } catch (e: RemoteException) {
- throw RuntimeException(e)
- }
-}
\ No newline at end of file
+fun Flicker.setRotation(rotation: Int) =
+ ChangeDisplayOrientationRule.setRotation(rotation, instrumentation, wmHelper)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index 47eaddf..0dcc8c9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -20,6 +20,7 @@
import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -164,7 +165,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 26afb79..7a1bb11 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -19,6 +19,7 @@
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -178,7 +179,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 2c4c627..2d09d23 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -19,6 +19,7 @@
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.FlickerBuilderProvider
@@ -141,7 +142,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 2bcdcd9..73760c5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -19,6 +19,7 @@
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -162,8 +163,13 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5,
- supportedRotations = listOf(Surface.ROTATION_0))
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedRotations = listOf(Surface.ROTATION_0),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index 6b2b930..2815e05 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -19,6 +19,7 @@
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -168,8 +169,13 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5,
- supportedRotations = listOf(Surface.ROTATION_0))
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedRotations = listOf(Surface.ROTATION_0),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 0cd5d79..7ca985e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -19,6 +19,7 @@
import android.app.Instrumentation
import android.platform.test.annotations.Presubmit
import android.view.Surface
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
@@ -184,7 +185,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 1)
+ .getConfigNonRotationTests(
+ repetitions = 1,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 56ed21b..417a5c5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.launch
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -60,7 +61,12 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
- return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests()
+ return FlickerTestParameterFactory.getInstance()
+ .getConfigNonRotationTests(
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 4a32a9e..fee01d2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.launch
import android.platform.test.annotations.Presubmit
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -136,7 +137,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 5)
+ .getConfigNonRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index a8b5ea1..bdae810 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -16,6 +16,7 @@
package com.android.server.wm.flicker.launch
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -72,7 +73,12 @@
@Parameterized.Parameters(name = "{0}")
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
- return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests()
+ return FlickerTestParameterFactory.getInstance()
+ .getConfigNonRotationTests(
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 6985b36..80b2237 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Presubmit
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
import com.android.server.wm.flicker.FlickerTestParameter
@@ -70,7 +71,12 @@
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigRotationTests(repetitions = 5)
+ .getConfigRotationTests(
+ repetitions = 5,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ )
}
}
}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 45d3006..dd7103c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -17,6 +17,7 @@
package com.android.server.wm.flicker.rotation
import android.platform.test.annotations.Presubmit
+import android.view.WindowManagerPolicyConstants
import androidx.test.filters.FlakyTest
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.FlickerParametersRunnerFactory
@@ -103,7 +104,12 @@
@JvmStatic
private fun getConfigurations(): List<FlickerTestParameter> {
- return testFactory.getConfigRotationTests(repetitions = 2).flatMap {
+ return testFactory.getConfigRotationTests(
+ repetitions = 2,
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
+ )
+ ).flatMap {
val defaultRun = it.createConfig(starveUiThread = false)
val busyUiRun = it.createConfig(starveUiThread = true)
listOf(