diff options
71 files changed, 1308 insertions, 806 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index ffbfe82be475..2dfda517b495 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -2277,12 +2277,12 @@ package android.os { method public int getMainDisplayIdAssignedToUser(); method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.Set<java.lang.String> getPreInstallableSystemPackages(@NonNull String); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType(); - method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean); + method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean isUserTypeEnabled(@NonNull String); method public boolean isVisibleBackgroundUsersOnDefaultDisplaySupported(); method public boolean isVisibleBackgroundUsersSupported(); - method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException; + method @Deprecated @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException; } public final class VibrationAttributes implements android.os.Parcelable { diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 9bf56b374576..99a7fa21b911 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -841,7 +841,8 @@ public final class PendingIntent implements Parcelable { /** * Perform the operation associated with this PendingIntent. * - * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -855,7 +856,8 @@ public final class PendingIntent implements Parcelable { * * @param code Result code to supply back to the PendingIntent's target. * - * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -875,7 +877,8 @@ public final class PendingIntent implements Parcelable { * original Intent. If flag {@link #FLAG_IMMUTABLE} was set when this * pending intent was created, this argument will be ignored. * - * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -892,6 +895,11 @@ public final class PendingIntent implements Parcelable { * @param options Additional options the caller would like to provide to modify the * sending behavior. May be built from an {@link ActivityOptions} to apply to an * activity start. + * + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String) + * + * @throws CanceledException Throws CanceledException if the PendingIntent + * is no longer allowing more intents to be sent through it. */ public void send(@Nullable Bundle options) throws CanceledException { send(null, 0, null, null, null, null, options); @@ -908,7 +916,8 @@ public final class PendingIntent implements Parcelable { * should happen. If null, the callback will happen from the thread * pool of the process. * - * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -942,11 +951,8 @@ public final class PendingIntent implements Parcelable { * should happen. If null, the callback will happen from the thread * pool of the process. * - * @see #send() - * @see #send(int) - * @see #send(Context, int, Intent) - * @see #send(int, android.app.PendingIntent.OnFinished, Handler) - * @see #send(Context, int, Intent, OnFinished, Handler, String) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -985,11 +991,8 @@ public final class PendingIntent implements Parcelable { * {@link Context#sendBroadcast(Intent, String) Context.sendOrderedBroadcast(Intent, String)}. * If null, no permission is required. * - * @see #send() - * @see #send(int) - * @see #send(Context, int, Intent) - * @see #send(int, android.app.PendingIntent.OnFinished, Handler) - * @see #send(Context, int, Intent, OnFinished, Handler) + * @see #send(Context, int, Intent, android.app.PendingIntent.OnFinished, Handler, String, + * Bundle) * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. @@ -1032,12 +1035,6 @@ public final class PendingIntent implements Parcelable { * @param options Additional options the caller would like to provide to modify the sending * behavior. May be built from an {@link ActivityOptions} to apply to an activity start. * - * @see #send() - * @see #send(int) - * @see #send(Context, int, Intent) - * @see #send(int, android.app.PendingIntent.OnFinished, Handler) - * @see #send(Context, int, Intent, OnFinished, Handler) - * * @throws CanceledException Throws CanceledException if the PendingIntent * is no longer allowing more intents to be sent through it. */ diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java index 81fc0293b685..23ba33698739 100644 --- a/core/java/android/content/pm/UserInfo.java +++ b/core/java/android/content/pm/UserInfo.java @@ -261,14 +261,17 @@ public class UserInfo implements Parcelable { public boolean guestToRemove; /** - * This is used to optimize the creation of an user, i.e. OEMs might choose to pre-create a + * This is used to optimize the creation of a user, i.e. OEMs might choose to pre-create a * number of users at the first boot, so the actual creation later is faster. * * <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular * user operations (other than user creation per se). * - * <p>Once the pre-created is used to create a "real" user later on, {@code preCreate} is set to - * {@code false}. + * <p>Once the pre-created is used to create a "real" user later on, {@code preCreated} is set + * to {@code false}. + * + * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize + * pre-created users in older versions, but will eventually be removed. */ public boolean preCreated; @@ -277,6 +280,9 @@ public class UserInfo implements Parcelable { * user. * * <p><b>NOTE: </b>only used for debugging purposes, it's not set when marshalled to a parcel. + * + * <p><b>NOTE: Pre-created users are deprecated. This field remains to be able to recognize + * pre-created users in older versions, but will eventually ve removed. */ public boolean convertedFromPreCreated; diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java index d2a6f03cc1a1..ac65933db136 100644 --- a/core/java/android/content/res/AssetFileDescriptor.java +++ b/core/java/android/content/res/AssetFileDescriptor.java @@ -21,20 +21,12 @@ import android.os.Bundle; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; -import android.system.ErrnoException; -import android.system.Os; import java.io.Closeable; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.channels.FileLock; -import java.nio.channels.ReadableByteChannel; -import java.nio.channels.WritableByteChannel; /** * File descriptor of an entry in the AssetManager. This provides your own @@ -211,26 +203,19 @@ public class AssetFileDescriptor implements Parcelable, Closeable { */ public static class AutoCloseInputStream extends ParcelFileDescriptor.AutoCloseInputStream { - /** Size of current file. */ - private long mTotalSize; - /** The absolute position of current file start point. */ - private final long mFileOffset; - /** The relative position where input stream is against mFileOffset. */ - private long mOffset; - private OffsetCorrectFileChannel mOffsetCorrectFileChannel; + private long mRemaining; public AutoCloseInputStream(AssetFileDescriptor fd) throws IOException { super(fd.getParcelFileDescriptor()); - mTotalSize = fd.getLength(); - mFileOffset = fd.getStartOffset(); + super.skip(fd.getStartOffset()); + mRemaining = (int) fd.getLength(); } @Override public int available() throws IOException { - long available = mTotalSize - mOffset; - return available >= 0 - ? (available < 0x7fffffff ? (int) available : 0x7fffffff) - : 0; + return mRemaining >= 0 + ? (mRemaining < 0x7fffffff ? (int) mRemaining : 0x7fffffff) + : super.available(); } @Override @@ -242,24 +227,15 @@ public class AssetFileDescriptor implements Parcelable, Closeable { @Override public int read(byte[] buffer, int offset, int count) throws IOException { - int available = available(); - if (available <= 0) { - return -1; - } - - if (count > available) count = available; - try { - int res = Os.pread(getFD(), buffer, offset, count, mFileOffset + mOffset); - // pread returns 0 at end of file, while java's InputStream interface requires -1 - if (res == 0) res = -1; - if (res > 0) { - mOffset += res; - updateChannelPosition(mOffset + mFileOffset); - } + if (mRemaining >= 0) { + if (mRemaining == 0) return -1; + if (count > mRemaining) count = (int) mRemaining; + int res = super.read(buffer, offset, count); + if (res >= 0) mRemaining -= res; return res; - } catch (ErrnoException e) { - throw new IOException(e); } + + return super.read(buffer, offset, count); } @Override @@ -269,185 +245,41 @@ public class AssetFileDescriptor implements Parcelable, Closeable { @Override public long skip(long count) throws IOException { - int available = available(); - if (available <= 0) { - return -1; + if (mRemaining >= 0) { + if (mRemaining == 0) return -1; + if (count > mRemaining) count = mRemaining; + long res = super.skip(count); + if (res >= 0) mRemaining -= res; + return res; } - if (count > available) count = available; - mOffset += count; - updateChannelPosition(mOffset + mFileOffset); - return count; + return super.skip(count); } @Override public void mark(int readlimit) { - // Not supported. - return; + if (mRemaining >= 0) { + // Not supported. + return; + } + super.mark(readlimit); } @Override public boolean markSupported() { - return false; + if (mRemaining >= 0) { + return false; + } + return super.markSupported(); } @Override public synchronized void reset() throws IOException { - // Not supported. - return; - } - - @Override - public FileChannel getChannel() { - if (mOffsetCorrectFileChannel == null) { - mOffsetCorrectFileChannel = new OffsetCorrectFileChannel(super.getChannel()); - } - try { - updateChannelPosition(mOffset + mFileOffset); - } catch (IOException e) { - throw new RuntimeException(e); - } - return mOffsetCorrectFileChannel; - } - - /** - * Update the position of mOffsetCorrectFileChannel only after it is constructed. - * - * @param newPosition The absolute position mOffsetCorrectFileChannel needs to be moved to. - */ - private void updateChannelPosition(long newPosition) throws IOException { - if (mOffsetCorrectFileChannel != null) { - mOffsetCorrectFileChannel.position(newPosition); - } - } - - /** - * A FileChannel wrapper that will update mOffset of the AutoCloseInputStream - * to correct position when using FileChannel to read. All occurrence of position - * should be using absolute solution and each override method just do Delegation - * besides additional check. All methods related to write mode have been disabled - * and will throw UnsupportedOperationException with customized message. - */ - private class OffsetCorrectFileChannel extends FileChannel { - private final FileChannel mDelegate; - private static final String METHOD_NOT_SUPPORTED_MESSAGE = - "This Method is not supported in AutoCloseInputStream FileChannel."; - - OffsetCorrectFileChannel(FileChannel fc) { - mDelegate = fc; - } - - @Override - public int read(ByteBuffer dst) throws IOException { - if (available() <= 0) return -1; - int bytesRead = mDelegate.read(dst); - if (bytesRead != -1) mOffset += bytesRead; - return bytesRead; - } - - @Override - public long read(ByteBuffer[] dsts, int offset, int length) throws IOException { - if (available() <= 0) return -1; - if (mOffset + length > mTotalSize) { - length = (int) (mTotalSize - mOffset); - } - long bytesRead = mDelegate.read(dsts, offset, length); - if (bytesRead != -1) mOffset += bytesRead; - return bytesRead; - } - - @Override - /**The only read method that does not move channel position*/ - public int read(ByteBuffer dst, long position) throws IOException { - if (position - mFileOffset > mTotalSize) return -1; - return mDelegate.read(dst, position); - } - - @Override - public long position() throws IOException { - return mDelegate.position(); - } - - @Override - public FileChannel position(long newPosition) throws IOException { - mOffset = newPosition - mFileOffset; - return mDelegate.position(newPosition); - } - - @Override - public long size() throws IOException { - return mTotalSize; - } - - @Override - public long transferTo(long position, long count, WritableByteChannel target) - throws IOException { - if (position - mFileOffset > mTotalSize) { - return 0; - } - if (position - mFileOffset + count > mTotalSize) { - count = mTotalSize - (position - mFileOffset); - } - return mDelegate.transferTo(position, count, target); - } - - @Override - public MappedByteBuffer map(MapMode mode, long position, long size) throws IOException { - if (position - mFileOffset > mTotalSize) { - throw new IOException( - "Cannot map to buffer because position exceed current file size."); - } - if (position - mFileOffset + size > mTotalSize) { - size = mTotalSize - (position - mFileOffset); - } - return mDelegate.map(mode, position, size); - } - - @Override - protected void implCloseChannel() throws IOException { - mDelegate.close(); - } - - @Override - public int write(ByteBuffer src) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public long write(ByteBuffer[] srcs, int offset, int length) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public int write(ByteBuffer src, long position) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public long transferFrom(ReadableByteChannel src, long position, long count) - throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public FileChannel truncate(long size) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public void force(boolean metaData) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public FileLock lock(long position, long size, boolean shared) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); - } - - @Override - public FileLock tryLock(long position, long size, boolean shared) throws IOException { - throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED_MESSAGE); + if (mRemaining >= 0) { + // Not supported. + return; } + super.reset(); } } diff --git a/core/java/android/hardware/biometrics/ComponentInfoInternal.java b/core/java/android/hardware/biometrics/ComponentInfoInternal.java index 3b61a56bd9f1..2e708de21762 100644 --- a/core/java/android/hardware/biometrics/ComponentInfoInternal.java +++ b/core/java/android/hardware/biometrics/ComponentInfoInternal.java @@ -19,6 +19,8 @@ package android.hardware.biometrics; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; +import android.util.IndentingPrintWriter; /** * The internal class for storing the component info for a subsystem of the biometric sensor, @@ -90,12 +92,19 @@ public class ComponentInfoInternal implements Parcelable { dest.writeString(softwareVersion); } - @Override - public String toString() { - return "ComponentId: " + componentId - + ", HardwareVersion: " + hardwareVersion - + ", FirmwareVersion: " + firmwareVersion - + ", SerialNumber " + serialNumber - + ", SoftwareVersion: " + softwareVersion; + /** + * Print the component info into the given stream. + * + * @param pw The stream to dump the info into. + * @hide + */ + public void dump(@NonNull IndentingPrintWriter pw) { + pw.println(TextUtils.formatSimple("componentId: %s", componentId)); + pw.increaseIndent(); + pw.println(TextUtils.formatSimple("hardwareVersion: %s", hardwareVersion)); + pw.println(TextUtils.formatSimple("firmwareVersion: %s", firmwareVersion)); + pw.println(TextUtils.formatSimple("serialNumber: %s", serialNumber)); + pw.println(TextUtils.formatSimple("softwareVersion: %s", softwareVersion)); + pw.decreaseIndent(); } } diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl index c88af5aad738..1a38c8897b76 100644 --- a/core/java/android/hardware/biometrics/IBiometricService.aidl +++ b/core/java/android/hardware/biometrics/IBiometricService.aidl @@ -58,10 +58,10 @@ interface IBiometricService { boolean hasEnrolledBiometrics(int userId, String opPackageName); // Registers an authenticator (e.g. face, fingerprint, iris). - // Id must be unique, whereas strength and modality don't need to be. + // Sensor Id in sensor props must be unique, whereas modality doesn't need to be. // TODO(b/123321528): Turn strength and modality into enums. @EnforcePermission("USE_BIOMETRIC_INTERNAL") - void registerAuthenticator(int id, int modality, int strength, + void registerAuthenticator(int modality, in SensorPropertiesInternal props, IBiometricAuthenticator authenticator); // Register callback for when keyguard biometric eligibility changes. diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index b3604da49f5e..24e28e95cd98 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -3706,17 +3706,24 @@ public class UserManager { * {@link android.Manifest.permission#CREATE_USERS} suffices if flags are in * com.android.server.pm.UserManagerService#ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION. * + * * @param userType the type of user, such as {@link UserManager#USER_TYPE_FULL_GUEST}. * @return the {@link UserInfo} object for the created user. * * @throws UserOperationException if the user could not be created. + * + * @deprecated Pre-created users are deprecated. This method should no longer be used, and will + * be removed once all the callers are removed. + * * @hide */ + @Deprecated @TestApi @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS, Manifest.permission.CREATE_USERS}) public @NonNull UserInfo preCreateUser(@NonNull String userType) throws UserOperationException { + Log.w(TAG, "preCreateUser(): Pre-created user is deprecated."); try { return mService.preCreateUserWithThrow(userType); } catch (ServiceSpecificException e) { @@ -4296,8 +4303,12 @@ public class UserManager { /** * Returns information for all users on this device, based on the filtering parameters. * + * @deprecated Pre-created users are deprecated and no longer supported. + * Use {@link #getUsers()}, {@link #getUsers(boolean)}, or {@link #getAliveUsers()} + * instead. * @hide */ + @Deprecated @TestApi @RequiresPermission(anyOf = { android.Manifest.permission.MANAGE_USERS, diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index c473d3f81823..7cb959dee245 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3431,7 +3431,7 @@ public final class Settings { + " type:" + mUri.getPath() + " in package:" + cr.getPackageName()); } - for (int i = 0; i < mValues.size(); ++i) { + for (int i = mValues.size() - 1; i >= 0; i--) { String key = mValues.keyAt(i); if (key.startsWith(prefix)) { mValues.remove(key); @@ -18125,12 +18125,6 @@ public final class Settings { public static final String WEAR_OS_VERSION_STRING = "wear_os_version_string"; /** - * Whether the physical button has been set. - * @hide - */ - public static final String BUTTON_SET = "button_set"; - - /** * Whether there is a side button. * @hide */ @@ -18302,6 +18296,12 @@ public final class Settings { public static final int COMPANION_OS_VERSION_UNDEFINED = -1; /** + * The companion App name. + * @hide + */ + public static final String COMPANION_APP_NAME = "wear_companion_app_name"; + + /** * A boolean value to indicate if we want to support all languages in LE edition on * wear. 1 for supporting, 0 for not supporting. * @hide @@ -18413,10 +18413,13 @@ public final class Settings { public static final String BURN_IN_PROTECTION_ENABLED = "burn_in_protection"; /** - * Whether the device has combined location setting enabled. + * + * @deprecated Use LocationManager as the source of truth for all location states. + * * @hide */ + @Deprecated public static final String COMBINED_LOCATION_ENABLED = "combined_location_enable"; /** @@ -18482,67 +18485,36 @@ public final class Settings { public static final String CLOCKWORK_LONG_PRESS_TO_ASSISTANT_ENABLED = "clockwork_long_press_to_assistant_enabled"; - /* + /** * Whether the device has Cooldown Mode enabled. * @hide */ public static final String COOLDOWN_MODE_ON = "cooldown_mode_on"; - /* + /** * Whether the device has Wet Mode/ Touch Lock Mode enabled. * @hide */ public static final String WET_MODE_ON = "wet_mode_on"; - /* + /** * Whether the RSB wake feature is enabled. * @hide */ public static final String RSB_WAKE_ENABLED = "rsb_wake_enabled"; - /* + /** * Whether the screen-unlock (keyguard) sound is enabled. * @hide */ public static final String SCREEN_UNLOCK_SOUND_ENABLED = "screen_unlock_sound_enabled"; - /* + /** * Whether charging sounds are enabled. * @hide */ public static final String CHARGING_SOUNDS_ENABLED = "wear_charging_sounds_enabled"; - /** The status of the early updates process. - * @hide - */ - public static final String EARLY_UPDATES_STATUS = "early_updates_status"; - - /** - * Early updates not started - * @hide - */ - public static final int EARLY_UPDATES_STATUS_NOT_STARTED = 0; - /** - * Early updates started and in progress - * @hide - */ - public static final int EARLY_UPDATES_STATUS_STARTED = 1; - /** - * Early updates completed and was successful - * @hide - */ - public static final int EARLY_UPDATES_STATUS_SUCCESS = 2; - /** - * Early updates skipped - * @hide - */ - public static final int EARLY_UPDATES_STATUS_SKIPPED = 3; - /** - * Early updates aborted due to timeout - * @hide - */ - public static final int EARLY_UPDATES_STATUS_ABORTED = 4; - /** * Whether dynamic color theming (e.g. Material You) is enabled for apps which support * it. @@ -18669,6 +18641,174 @@ public final class Settings { * @hide */ public static final int UPGRADE_DATA_MIGRATION_DONE = 2; + + /** + * Whether to disable AOD while plugged. + * (0 = false, 1 = true) + * @hide + */ + public static final String DISABLE_AOD_WHILE_PLUGGED = "disable_aod_while_plugged"; + + /** + * Whether the user has consented for network location provider (NLP). + * This setting key will only be used once during OOBE to set NLP initial value through + * the companion app ToS. This setting key will be synced over from Companion and + * corresponding toggle in GMS will be enabled. + * @hide + */ + public static final String NETWORK_LOCATION_OPT_IN = "network_location_opt_in"; + + /** + * The custom foreground color. + * @hide + */ + public static final String CUSTOM_COLOR_FOREGROUND = "custom_foreground_color"; + + /** + * The custom background color. + * @hide + */ + public static final String CUSTOM_COLOR_BACKGROUND = "custom_background_color"; + + /** The status of the phone switching process. + * @hide + */ + public static final String PHONE_SWITCHING_STATUS = "phone_switching_status"; + + /** + * Phone switching not started + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_NOT_STARTED = 0; + + /** + * Phone switching started + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_STARTED = 1; + + /** + * Phone switching completed and was successful + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_SUCCESS = 2; + + /** + * Phone switching was cancelled + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_CANCELLED = 3; + + /** + * Phone switching failed + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_FAILED = 4; + + /** + * Phone switching is in progress of advertising to new companion device. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_ADVERTISING = 5; + + /** + * Phone switching successfully bonded with new companion device. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_BONDED = 6; + + /** + * Phone switching successfully completed on phone side. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_PHONE_COMPLETE = 7; + + /** + * Connection config migration in progress. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_MIGRATION = 8; + + /** + * Connection config migration failed. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_MIGRATION_FAILED = 9; + + /** + * Connection config migration cancellation in progress. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_MIGRATION_CANCELLED = 10; + + /** + * Connection config migration success. + * @hide + */ + public static final int PHONE_SWITCHING_STATUS_IN_PROGRESS_MIGRATION_SUCCESS = 11; + + + /** + * Whether the device has enabled the feature to reduce motion and animation + * (0 = false, 1 = true) + * @hide + */ + public static final String REDUCE_MOTION = "reduce_motion"; + + /** + * Whether RTL swipe-to-dismiss is enabled by developer options. + * (0 = false, 1 = true) + * @hide + */ + public static final String RTL_SWIPE_TO_DISMISS_ENABLED_DEV = + "rtl_swipe_to_dismiss_enabled_dev"; + + /** + * Tethered Configuration state. + * @hide + */ + public static final String TETHER_CONFIG_STATE = "tethered_config_state"; + + /** + * Tethered configuration state is unknown. + * @hide + */ + public static final int TETHERED_CONFIG_UNKNOWN = 0; + + /** + * Device is set into standalone mode. + * @hide + */ + public static final int TETHERED_CONFIG_STANDALONE = 1; + + /** + * Device is set in tethered mode. + * @hide + */ + public static final int TETHERED_CONFIG_TETHERED = 2; + + + /** + * Whether phone switching is supported. + * + * (0 = false, 1 = true) + * @hide + */ + public static final String PHONE_SWITCHING_SUPPORTED = "phone_switching_supported"; + + /** + * Setting indicating the name of the Wear OS package that hosts the Media Controls UI. + * + * @hide + */ + public static final String WEAR_MEDIA_CONTROLS_PACKAGE = "wear_media_controls_package"; + + /** + * Setting indicating the name of the Wear OS package responsible for bridging media. + * + * @hide + */ + public static final String WEAR_MEDIA_SESSIONS_PACKAGE = "wear_media_sessions_package"; } } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 3ff63519572f..e4d74b5373e0 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -6067,6 +6067,12 @@ <!-- Wear OS: the name of the main activity of the device's sysui. --> <string name="config_wearSysUiMainActivity" translatable="false"/> + <!-- Wear OS: the name of the package containing the Media Controls Activity. --> + <string name="config_wearMediaControlsPackage" translatable="false"/> + + <!-- Wear OS: the name of the package containing the Media Sessions APK. --> + <string name="config_wearMediaSessionsPackage" translatable="false"/> + <bool name="config_secondaryBuiltInDisplayIsRound">@bool/config_windowIsRound</bool> <!-- The display round config for each display in a multi-display device. --> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7b582da836aa..cb021336c7cb 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4865,6 +4865,8 @@ <java-symbol type="string" name="config_wearSysUiPackage"/> <java-symbol type="string" name="config_wearSysUiMainActivity"/> + <java-symbol type="string" name="config_wearMediaControlsPackage"/> + <java-symbol type="string" name="config_wearMediaSessionsPackage"/> <java-symbol type="string" name="config_defaultQrCodeComponent"/> <java-symbol type="dimen" name="secondary_rounded_corner_radius" /> diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h index 01a93c7218d9..cce5468e68f0 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -53,7 +53,6 @@ public: void onStop() override; bool isSurfaceReady() override; bool isContextReady() override; - bool supportsExtendedRangeHdr() const override { return true; } void setTargetSdrHdrRatio(float ratio) override; const SkM44& getPixelSnapMatrix() const override; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 1b9d41a73f46..f60c1f3c6ad8 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -236,7 +236,6 @@ void CanvasContext::setupPipelineSurface() { if (mNativeSurface && !mNativeSurface->didSetExtraBuffers()) { setBufferCount(mNativeSurface->getNativeWindow()); - } mFrameNumber = 0; @@ -301,10 +300,6 @@ void CanvasContext::setOpaque(bool opaque) { float CanvasContext::setColorMode(ColorMode mode) { if (mode != mColorMode) { - const bool isHdr = mode == ColorMode::Hdr || mode == ColorMode::Hdr10; - if (isHdr && !mRenderPipeline->supportsExtendedRangeHdr()) { - mode = ColorMode::WideColorGamut; - } mColorMode = mode; mRenderPipeline->setSurfaceColorProperties(mode); setupPipelineSurface(); diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 4fb114b71bf5..94f35fd9eaf2 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -423,6 +423,7 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, EGLint attribs[] = {EGL_NONE, EGL_NONE, EGL_NONE}; EGLConfig config = mEglConfig; + bool overrideWindowDataSpaceForHdr = false; if (colorMode == ColorMode::A8) { // A8 doesn't use a color space if (!mEglConfigA8) { @@ -450,12 +451,13 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, case ColorMode::Default: attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR; break; - // Extended Range HDR requires being able to manipulate the dataspace in ways - // we cannot easily do while going through EGLSurface. Given this requires - // composer3 support, just treat HDR as equivalent to wide color gamut if - // the GLES path is still being hit + // We don't have an EGL colorspace for extended range P3 that's used for HDR + // So override it after configuring the EGL context case ColorMode::Hdr: case ColorMode::Hdr10: + overrideWindowDataSpaceForHdr = true; + attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT; + break; case ColorMode::WideColorGamut: { skcms_Matrix3x3 colorGamut; LOG_ALWAYS_FATAL_IF(!colorSpace->toXYZD50(&colorGamut), @@ -491,6 +493,16 @@ Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, (void*)window, eglErrorString()); } + if (overrideWindowDataSpaceForHdr) { + // This relies on knowing that EGL will not re-set the dataspace after the call to + // eglCreateWindowSurface. Since the handling of the colorspace extension is largely + // implemented in libEGL in the platform, we can safely assume this is the case + int32_t err = ANativeWindow_setBuffersDataSpace( + window, + static_cast<android_dataspace>(STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_EXTENDED)); + LOG_ALWAYS_FATAL_IF(err, "Failed to ANativeWindow_setBuffersDataSpace %d", err); + } + return surface; } diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h index 9ebad81c5c81..6c2cb9d71c55 100644 --- a/libs/hwui/renderthread/IRenderPipeline.h +++ b/libs/hwui/renderthread/IRenderPipeline.h @@ -95,7 +95,6 @@ public: virtual void setPictureCapturedCallback( const std::function<void(sk_sp<SkPicture>&&)>& callback) = 0; - virtual bool supportsExtendedRangeHdr() const { return false; } virtual void setTargetSdrHdrRatio(float ratio) = 0; virtual const SkM44& getPixelSnapMatrix() const = 0; diff --git a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt index 725401fb85bb..7bf1d1993906 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/DataConverter.kt @@ -210,7 +210,11 @@ class GetFlowUtils { appName = originName ?: getAppLabel(context.packageManager, requestInfo.appPackageName) ?: return null, - preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials + preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials, + preferIdentityDocUi = getCredentialRequest.data.getBoolean( + // TODO(b/276777444): replace with direct library constant reference once + // exposed. + "androidx.credentials.BUNDLE_KEY_PREFER_IDENTITY_DOC_UI"), ) } diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt index 7a8679038579..c9c62a48d130 100644 --- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt +++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetModel.kt @@ -42,7 +42,7 @@ internal fun hasContentToDisplay(state: GetCredentialUiState): Boolean { } internal fun isFallbackScreen(state: GetCredentialUiState): Boolean { - return false + return state.requestDisplayInfo.preferIdentityDocUi } internal fun findAutoSelectEntry(providerDisplayInfo: ProviderDisplayInfo): CredentialEntryInfo? { @@ -172,6 +172,7 @@ class ActionEntryInfo( data class RequestDisplayInfo( val appName: String, val preferImmediatelyAvailableCredentials: Boolean, + val preferIdentityDocUi: Boolean, ) /** diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 59cd7a051fad..a93cd62e6301 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -43,6 +43,8 @@ <bool name="def_install_non_market_apps">false</bool> <!-- 0 == off, 3 == on --> <integer name="def_location_mode">3</integer> + <!-- 0 == off, 1 == on--> + <integer name="def_paired_device_location_mode">1</integer> <bool name="assisted_gps_enabled">true</bool> <bool name="def_netstats_enabled">true</bool> <bool name="def_usb_mass_storage_enabled">true</bool> diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java index e50f52229a16..41ce58eb7b4e 100644 --- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java +++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java @@ -103,5 +103,7 @@ public class GlobalSettings { Settings.Global.Wearable.UPGRADE_DATA_MIGRATION_STATUS, Settings.Global.HDR_CONVERSION_MODE, Settings.Global.HDR_FORCE_CONVERSION_TYPE, + Settings.Global.Wearable.RTL_SWIPE_TO_DISMISS_ENABLED_DEV, + Settings.Global.Wearable.REDUCE_MOTION, }; } diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java index d5386c1d75ac..a1c01723ad55 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java @@ -285,7 +285,6 @@ public class GlobalSettingsValidators { })); VALIDATORS.put(Global.Wearable.MUTE_WHEN_OFF_BODY_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.SIDE_BUTTON, BOOLEAN_VALIDATOR); - VALIDATORS.put(Global.Wearable.BUTTON_SET, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.ANDROID_WEAR_VERSION, ANY_INTEGER_VALIDATOR); VALIDATORS.put(Global.Wearable.SYSTEM_CAPABILITIES, ANY_INTEGER_VALIDATOR); VALIDATORS.put(Global.Wearable.SYSTEM_EDITION, ANY_INTEGER_VALIDATOR); @@ -345,6 +344,7 @@ public class GlobalSettingsValidators { String.valueOf(Global.Wearable.HFP_CLIENT_DISABLED) })); VALIDATORS.put(Global.Wearable.COMPANION_OS_VERSION, ANY_INTEGER_VALIDATOR); + VALIDATORS.put(Global.Wearable.COMPANION_APP_NAME, ANY_STRING_VALIDATOR); VALIDATORS.put(Global.Wearable.ENABLE_ALL_LANGUAGES, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.OEM_SETUP_VERSION, ANY_INTEGER_VALIDATOR); VALIDATORS.put( @@ -404,16 +404,6 @@ public class GlobalSettingsValidators { VALIDATORS.put(Global.Wearable.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.BEDTIME_MODE, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.BEDTIME_HARD_MODE, BOOLEAN_VALIDATOR); - VALIDATORS.put( - Global.Wearable.EARLY_UPDATES_STATUS, - new DiscreteValueValidator( - new String[] { - String.valueOf(Global.Wearable.EARLY_UPDATES_STATUS_NOT_STARTED), - String.valueOf(Global.Wearable.EARLY_UPDATES_STATUS_STARTED), - String.valueOf(Global.Wearable.EARLY_UPDATES_STATUS_SUCCESS), - String.valueOf(Global.Wearable.EARLY_UPDATES_STATUS_SKIPPED), - String.valueOf(Global.Wearable.EARLY_UPDATES_STATUS_ABORTED), - })); VALIDATORS.put(Global.Wearable.DYNAMIC_COLOR_THEME_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.SCREENSHOT_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.Wearable.UPGRADE_DATA_MIGRATION_STATUS, @@ -423,5 +413,22 @@ public class GlobalSettingsValidators { String.valueOf(Global.Wearable.UPGRADE_DATA_MIGRATION_PENDING), String.valueOf(Global.Wearable.UPGRADE_DATA_MIGRATION_DONE) })); + VALIDATORS.put(Global.Wearable.DISABLE_AOD_WHILE_PLUGGED, BOOLEAN_VALIDATOR); + VALIDATORS.put(Global.Wearable.NETWORK_LOCATION_OPT_IN, BOOLEAN_VALIDATOR); + VALIDATORS.put(Global.Wearable.PHONE_SWITCHING_STATUS, + new InclusiveIntegerRangeValidator( + Global.Wearable.PHONE_SWITCHING_STATUS_NOT_STARTED, + Global.Wearable.PHONE_SWITCHING_STATUS_IN_PROGRESS_MIGRATION_SUCCESS)); + VALIDATORS.put(Global.Wearable.REDUCE_MOTION, BOOLEAN_VALIDATOR); + VALIDATORS.put(Global.Wearable.RTL_SWIPE_TO_DISMISS_ENABLED_DEV, BOOLEAN_VALIDATOR); + VALIDATORS.put( + Global.Wearable.TETHER_CONFIG_STATE, + new DiscreteValueValidator( + new String[] { + String.valueOf(Global.Wearable.TETHERED_CONFIG_UNKNOWN), + String.valueOf(Global.Wearable.TETHERED_CONFIG_STANDALONE), + String.valueOf(Global.Wearable.TETHERED_CONFIG_TETHERED) + })); + VALIDATORS.put(Global.Wearable.PHONE_SWITCHING_SUPPORTED, BOOLEAN_VALIDATOR); } } diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index b0a19270018a..284b06b86cb6 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -3748,7 +3748,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 217; + private static final int SETTINGS_VERSION = 218; private final int mUserId; @@ -5334,74 +5334,73 @@ public class SettingsProvider extends ContentProvider { if (currentVersion == 203) { // Version 203: initialize entries migrated from wear settings provide. - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.HAS_PAY_TOKENS, false); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.GMS_CHECKIN_TIMEOUT_MIN, 6); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.HOTWORD_DETECTION_ENABLED, getContext() .getResources() .getBoolean(R.bool.def_wearable_hotwordDetectionEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SMART_REPLIES_ENABLED, true); Setting locationMode = getSecureSettingsLocked(userId).getSettingLocked(Secure.LOCATION_MODE); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.OBTAIN_PAIRED_DEVICE_LOCATION, !locationMode.isNull() && !Integer.toString(Secure.LOCATION_MODE_OFF) .equals(locationMode.getValue())); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.PHONE_PLAY_STORE_AVAILABILITY, Global.Wearable.PHONE_PLAY_STORE_AVAILABILITY_UNKNOWN); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.BUG_REPORT, "user".equals(Build.TYPE) // is user build? ? Global.Wearable.BUG_REPORT_DISABLED : Global.Wearable.BUG_REPORT_ENABLED); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SMART_ILLUMINATE_ENABLED, getContext() .getResources() .getBoolean(R.bool.def_wearable_smartIlluminateEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.CLOCKWORK_AUTO_TIME, Global.Wearable.SYNC_TIME_FROM_PHONE); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.CLOCKWORK_AUTO_TIME_ZONE, Global.Wearable.SYNC_TIME_ZONE_FROM_PHONE); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.CLOCKWORK_24HR_TIME, false); - initGlobalSettingsDefaultValForWearLocked(Global.Wearable.AUTO_WIFI, true); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked(Global.Wearable.AUTO_WIFI, true); + initGlobalSettingsDefaultValLocked( Global.Wearable.WIFI_POWER_SAVE, getContext() .getResources() .getInteger( R.integer .def_wearable_offChargerWifiUsageLimitMinutes)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.ALT_BYPASS_WIFI_REQUIREMENT_TIME_MILLIS, 0L); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SETUP_SKIPPED, Global.Wearable.SETUP_SKIPPED_UNKNOWN); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.LAST_CALL_FORWARD_ACTION, Global.Wearable.CALL_FORWARD_NO_LAST_ACTION); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.MUTE_WHEN_OFF_BODY_ENABLED, getContext() .getResources() .getBoolean(R.bool.def_wearable_muteWhenOffBodyEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.WEAR_OS_VERSION_STRING, ""); - initGlobalSettingsDefaultValForWearLocked(Global.Wearable.BUTTON_SET, false); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SIDE_BUTTON, getContext() .getResources() .getBoolean(R.bool.def_wearable_sideButtonPresent)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.ANDROID_WEAR_VERSION, Long.parseLong( getContext() @@ -5410,55 +5409,55 @@ public class SettingsProvider extends ContentProvider { final int editionGlobal = 1; final int editionLocal = 2; boolean isLe = getContext().getPackageManager().hasSystemFeature("cn.google"); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SYSTEM_EDITION, isLe ? editionLocal : editionGlobal); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.SYSTEM_CAPABILITIES, getWearSystemCapabilities(isLe)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.WEAR_PLATFORM_MR_NUMBER, SystemProperties.getInt("ro.cw_build.platform_mr", 0)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.MOBILE_SIGNAL_DETECTOR, getContext() .getResources() .getBoolean(R.bool.def_wearable_mobileSignalDetectorAllowed)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.AMBIENT_ENABLED, getContext() .getResources() .getBoolean(R.bool.def_wearable_ambientEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.AMBIENT_TILT_TO_WAKE, getContext() .getResources() .getBoolean(R.bool.def_wearable_tiltToWakeEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.AMBIENT_LOW_BIT_ENABLED_DEV, false); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.AMBIENT_TOUCH_TO_WAKE, getContext() .getResources() .getBoolean(R.bool.def_wearable_touchToWakeEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.AMBIENT_TILT_TO_BRIGHT, getContext() .getResources() .getBoolean(R.bool.def_wearable_tiltToBrightEnabled)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Global.Wearable.DECOMPOSABLE_WATCHFACE, false); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.AMBIENT_FORCE_WHEN_DOCKED, SystemProperties.getBoolean("ro.ambient.force_when_docked", false)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.AMBIENT_LOW_BIT_ENABLED, SystemProperties.getBoolean("ro.ambient.low_bit_enabled", false)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.AMBIENT_PLUGGED_TIMEOUT_MIN, SystemProperties.getInt("ro.ambient.plugged_timeout_min", -1)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.PAIRED_DEVICE_OS_TYPE, Settings.Global.Wearable.PAIRED_DEVICE_OS_TYPE_UNKNOWN); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.USER_HFP_CLIENT_SETTING, Settings.Global.Wearable.HFP_CLIENT_UNSET); Setting disabledProfileSetting = @@ -5468,7 +5467,7 @@ public class SettingsProvider extends ContentProvider { disabledProfileSetting.isNull() ? 0 : Long.parseLong(disabledProfileSetting.getValue()); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.COMPANION_OS_VERSION, Settings.Global.Wearable.COMPANION_OS_VERSION_UNDEFINED); final boolean defaultBurnInProtectionEnabled = @@ -5482,17 +5481,17 @@ public class SettingsProvider extends ContentProvider { .config_enableBurnInProtection); final boolean forceBurnInProtection = SystemProperties.getBoolean("persist.debug.force_burn_in", false); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.BURN_IN_PROTECTION_ENABLED, defaultBurnInProtectionEnabled || forceBurnInProtection); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.CLOCKWORK_SYSUI_PACKAGE, getContext() .getResources() .getString( com.android.internal.R.string.config_wearSysUiPackage)); - initGlobalSettingsDefaultValForWearLocked( + initGlobalSettingsDefaultValLocked( Settings.Global.Wearable.CLOCKWORK_SYSUI_MAIN_ACTIVITY, getContext() .getResources() @@ -5622,63 +5621,16 @@ public class SettingsProvider extends ContentProvider { currentVersion = 210; } if (currentVersion == 210) { - final SettingsState secureSettings = getSecureSettingsLocked(userId); - final Setting currentSetting = secureSettings.getSettingLocked( - Secure.STATUS_BAR_SHOW_VIBRATE_ICON); - if (currentSetting.isNull()) { - final int defaultValueVibrateIconEnabled = getContext().getResources() - .getInteger(R.integer.def_statusBarVibrateIconEnabled); - secureSettings.insertSettingOverrideableByRestoreLocked( - Secure.STATUS_BAR_SHOW_VIBRATE_ICON, - String.valueOf(defaultValueVibrateIconEnabled), - null /* tag */, true /* makeDefault */, - SettingsState.SYSTEM_PACKAGE_NAME); - } + // Unused. Moved to version 217. currentVersion = 211; } if (currentVersion == 211) { - // Version 211: Set default value for - // Secure#LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS - final SettingsState secureSettings = getSecureSettingsLocked(userId); - final Setting lockScreenUnseenSetting = secureSettings - .getSettingLocked(Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS); - if (lockScreenUnseenSetting.isNull()) { - final boolean defSetting = getContext().getResources() - .getBoolean(R.bool.def_lock_screen_show_only_unseen_notifications); - secureSettings.insertSettingOverrideableByRestoreLocked( - Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, - defSetting ? "1" : "0", - null /* tag */, - true /* makeDefault */, - SettingsState.SYSTEM_PACKAGE_NAME); - } - + // Unused. Moved to version 217. currentVersion = 212; } if (currentVersion == 212) { - final SettingsState globalSettings = getGlobalSettingsLocked(); - final SettingsState secureSettings = getSecureSettingsLocked(userId); - - final Setting bugReportInPowerMenu = globalSettings.getSettingLocked( - Global.BUGREPORT_IN_POWER_MENU); - - if (!bugReportInPowerMenu.isNull()) { - Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to " - + bugReportInPowerMenu.getValue() + " in Secure settings."); - secureSettings.insertSettingLocked( - Secure.BUGREPORT_IN_POWER_MENU, - bugReportInPowerMenu.getValue(), null /* tag */, - false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); - - // set global bug_report_in_power_menu setting to null since it's deprecated - Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to null" - + " in Global settings since it's deprecated."); - globalSettings.insertSettingLocked( - Global.BUGREPORT_IN_POWER_MENU, null /* value */, null /* tag */, - true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); - } - + // Unused. Moved to version 217. currentVersion = 213; } @@ -5804,6 +5756,89 @@ public class SettingsProvider extends ContentProvider { currentVersion = 217; } + if (currentVersion == 217) { + // Version 217: merge and rebase wear settings init logic. + + final SettingsState secureSettings = getSecureSettingsLocked(userId); + final SettingsState globalSettings = getGlobalSettingsLocked(); + + // Following init logic is moved from version 210 to this version in order to + // resolve version conflict with wear branch. + final Setting currentSetting = secureSettings.getSettingLocked( + Secure.STATUS_BAR_SHOW_VIBRATE_ICON); + if (currentSetting.isNull()) { + final int defaultValueVibrateIconEnabled = getContext().getResources() + .getInteger(R.integer.def_statusBarVibrateIconEnabled); + secureSettings.insertSettingOverrideableByRestoreLocked( + Secure.STATUS_BAR_SHOW_VIBRATE_ICON, + String.valueOf(defaultValueVibrateIconEnabled), + null /* tag */, true /* makeDefault */, + SettingsState.SYSTEM_PACKAGE_NAME); + } + + // Set default value for Secure#LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS + // Following init logic is moved from version 211 to this version in order to + // resolve version conflict with wear branch. + final Setting lockScreenUnseenSetting = secureSettings + .getSettingLocked(Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS); + if (lockScreenUnseenSetting.isNull()) { + final boolean defSetting = getContext().getResources() + .getBoolean(R.bool.def_lock_screen_show_only_unseen_notifications); + secureSettings.insertSettingOverrideableByRestoreLocked( + Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, + defSetting ? "1" : "0", + null /* tag */, + true /* makeDefault */, + SettingsState.SYSTEM_PACKAGE_NAME); + } + + // Following init logic is moved from version 212 to this version in order to + // resolve version conflict with wear branch. + final Setting bugReportInPowerMenu = globalSettings.getSettingLocked( + Global.BUGREPORT_IN_POWER_MENU); + + if (!bugReportInPowerMenu.isNull()) { + Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to " + + bugReportInPowerMenu.getValue() + " in Secure settings."); + secureSettings.insertSettingLocked( + Secure.BUGREPORT_IN_POWER_MENU, + bugReportInPowerMenu.getValue(), null /* tag */, + false /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); + + // set global bug_report_in_power_menu setting to null since it's deprecated + Slog.i(LOG_TAG, "Setting bugreport_in_power_menu to null" + + " in Global settings since it's deprecated."); + globalSettings.insertSettingLocked( + Global.BUGREPORT_IN_POWER_MENU, null /* value */, null /* tag */, + true /* makeDefault */, SettingsState.SYSTEM_PACKAGE_NAME); + } + + // Following init logic is rebased from wear OS branch. + // Initialize default value of tether configuration to unknown. + initGlobalSettingsDefaultValLocked( + Settings.Global.Wearable.TETHER_CONFIG_STATE, + Global.Wearable.TETHERED_CONFIG_UNKNOWN); + // Init paired device location setting from resources. + initGlobalSettingsDefaultValLocked( + Global.Wearable.OBTAIN_PAIRED_DEVICE_LOCATION, + getContext() + .getResources() + .getInteger(R.integer.def_paired_device_location_mode)); + // Init media packages from resources. + final String mediaControlsPackage = getContext().getResources().getString( + com.android.internal.R.string.config_wearMediaControlsPackage); + final String mediaSessionsPackage = getContext().getResources().getString( + com.android.internal.R.string.config_wearMediaSessionsPackage); + initGlobalSettingsDefaultValLocked( + Global.Wearable.WEAR_MEDIA_CONTROLS_PACKAGE, + mediaControlsPackage); + initGlobalSettingsDefaultValLocked( + Global.Wearable.WEAR_MEDIA_SESSIONS_PACKAGE, + mediaSessionsPackage); + + currentVersion = 218; + } + // vXXX: Add new settings above this point. if (currentVersion != newVersion) { @@ -5821,19 +5856,19 @@ public class SettingsProvider extends ContentProvider { return currentVersion; } - private void initGlobalSettingsDefaultValForWearLocked(String key, boolean val) { - initGlobalSettingsDefaultValForWearLocked(key, val ? "1" : "0"); + private void initGlobalSettingsDefaultValLocked(String key, boolean val) { + initGlobalSettingsDefaultValLocked(key, val ? "1" : "0"); } - private void initGlobalSettingsDefaultValForWearLocked(String key, int val) { - initGlobalSettingsDefaultValForWearLocked(key, String.valueOf(val)); + private void initGlobalSettingsDefaultValLocked(String key, int val) { + initGlobalSettingsDefaultValLocked(key, String.valueOf(val)); } - private void initGlobalSettingsDefaultValForWearLocked(String key, long val) { - initGlobalSettingsDefaultValForWearLocked(key, String.valueOf(val)); + private void initGlobalSettingsDefaultValLocked(String key, long val) { + initGlobalSettingsDefaultValLocked(key, String.valueOf(val)); } - private void initGlobalSettingsDefaultValForWearLocked(String key, String val) { + private void initGlobalSettingsDefaultValLocked(String key, String val) { final SettingsState globalSettings = getGlobalSettingsLocked(); Setting currentSetting = globalSettings.getSettingLocked(key); if (currentSetting.isNull()) { diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 19f1a86ec90c..a202e1614b67 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -627,7 +627,6 @@ public class SettingsBackupTest { Settings.Global.Wearable.STEM_3_DATA, Settings.Global.Wearable.STEM_3_DEFAULT_DATA, Settings.Global.Wearable.WEAR_OS_VERSION_STRING, - Settings.Global.Wearable.BUTTON_SET, Settings.Global.Wearable.SIDE_BUTTON, Settings.Global.Wearable.ANDROID_WEAR_VERSION, Settings.Global.Wearable.SYSTEM_CAPABILITIES, @@ -643,6 +642,7 @@ public class SettingsBackupTest { Settings.Global.Wearable.PAIRED_DEVICE_OS_TYPE, Settings.Global.Wearable.COMPANION_BLE_ROLE, Settings.Global.Wearable.COMPANION_NAME, + Settings.Global.Wearable.COMPANION_APP_NAME, Settings.Global.Wearable.USER_HFP_CLIENT_SETTING, Settings.Global.Wearable.COMPANION_OS_VERSION, Settings.Global.Wearable.ENABLE_ALL_LANGUAGES, @@ -662,13 +662,21 @@ public class SettingsBackupTest { Settings.Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED, Settings.Global.Wearable.BEDTIME_MODE, Settings.Global.Wearable.BEDTIME_HARD_MODE, - Settings.Global.Wearable.EARLY_UPDATES_STATUS, Settings.Global.Wearable.RSB_WAKE_ENABLED, Settings.Global.Wearable.LOCK_SCREEN_STATE, Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_ENABLED, Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE, Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_SPEED, - Settings.Global.Wearable.SCREENSHOT_ENABLED); + Settings.Global.Wearable.SCREENSHOT_ENABLED, + Settings.Global.Wearable.DISABLE_AOD_WHILE_PLUGGED, + Settings.Global.Wearable.NETWORK_LOCATION_OPT_IN, + Settings.Global.Wearable.CUSTOM_COLOR_FOREGROUND, + Settings.Global.Wearable.CUSTOM_COLOR_BACKGROUND, + Settings.Global.Wearable.PHONE_SWITCHING_STATUS, + Settings.Global.Wearable.TETHER_CONFIG_STATE, + Settings.Global.Wearable.PHONE_SWITCHING_SUPPORTED, + Settings.Global.Wearable.WEAR_MEDIA_CONTROLS_PACKAGE, + Settings.Global.Wearable.WEAR_MEDIA_SESSIONS_PACKAGE); private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS = newHashSet( diff --git a/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml b/packages/SystemUI/res/drawable/ic_shade_no_calling_sms.xml index da581061370b..da581061370b 100644 --- a/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml +++ b/packages/SystemUI/res/drawable/ic_shade_no_calling_sms.xml diff --git a/packages/SystemUI/res/drawable/ic_qs_sim_card.xml b/packages/SystemUI/res/drawable/ic_shade_sim_card.xml index 6eda929b54d3..6eda929b54d3 100644 --- a/packages/SystemUI/res/drawable/ic_qs_sim_card.xml +++ b/packages/SystemUI/res/drawable/ic_shade_sim_card.xml diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml index dffe40b8454a..441f963a855a 100644 --- a/packages/SystemUI/res/layout/combined_qs_header.xml +++ b/packages/SystemUI/res/layout/combined_qs_header.xml @@ -94,7 +94,7 @@ <include android:id="@+id/carrier_group" - layout="@layout/qs_carrier_group" + layout="@layout/shade_carrier_group" app:layout_constraintHeight_min="@dimen/large_screen_shade_header_min_height" android:minHeight="@dimen/large_screen_shade_header_min_height" app:layout_constraintWidth_min="48dp" diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/shade_carrier.xml index a854660f64f8..0fed393a7ed3 100644 --- a/packages/SystemUI/res/layout/qs_carrier.xml +++ b/packages/SystemUI/res/layout/shade_carrier.xml @@ -14,7 +14,7 @@ ~ limitations under the License --> -<com.android.systemui.qs.carrier.QSCarrier +<com.android.systemui.shade.carrier.ShadeCarrier xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linear_carrier" android:layout_width="wrap_content" @@ -29,7 +29,7 @@ android:focusable="true" > <com.android.systemui.util.AutoMarqueeTextView - android:id="@+id/qs_carrier_text" + android:id="@+id/shade_carrier_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" @@ -53,4 +53,4 @@ android:layout_marginStart="@dimen/qs_carrier_margin_width" android:visibility="gone" /> -</com.android.systemui.qs.carrier.QSCarrier>
\ No newline at end of file +</com.android.systemui.shade.carrier.ShadeCarrier>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/shade_carrier_group.xml index 6e13ab972226..2e8f98cbd190 100644 --- a/packages/SystemUI/res/layout/qs_carrier_group.xml +++ b/packages/SystemUI/res/layout/shade_carrier_group.xml @@ -15,7 +15,7 @@ --> <!-- Extends LinearLayout --> -<com.android.systemui.qs.carrier.QSCarrierGroup +<com.android.systemui.shade.carrier.ShadeCarrierGroup xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/qs_mobile" android:layout_width="0dp" @@ -39,25 +39,25 @@ android:visibility="gone"/> <include - layout="@layout/qs_carrier" + layout="@layout/shade_carrier" android:id="@+id/carrier1" android:layout_weight="1"/> <View - android:id="@+id/qs_carrier_divider1" + android:id="@+id/shade_carrier_divider1" android:layout_width="@dimen/qs_header_carrier_separator_width" android:layout_height="match_parent" android:visibility="gone" android:importantForAccessibility="no"/> <include - layout="@layout/qs_carrier" + layout="@layout/shade_carrier" android:id="@+id/carrier2" android:layout_weight="1" android:visibility="gone"/> <View - android:id="@+id/qs_carrier_divider2" + android:id="@+id/shade_carrier_divider2" android:layout_width="@dimen/qs_header_carrier_separator_width" android:layout_height="match_parent" android:layout_weight="1" @@ -65,9 +65,9 @@ android:importantForAccessibility="no"/> <include - layout="@layout/qs_carrier" + layout="@layout/shade_carrier" android:id="@+id/carrier3" android:layout_weight="1" android:visibility="gone"/> -</com.android.systemui.qs.carrier.QSCarrierGroup>
\ No newline at end of file +</com.android.systemui.shade.carrier.ShadeCarrierGroup>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml index befbfab7dbc3..675ae326b5a2 100644 --- a/packages/SystemUI/res/values/integers.xml +++ b/packages/SystemUI/res/values/integers.xml @@ -36,7 +36,7 @@ fade_out_complete_frame --> <dimen name="percent_displacement_at_fade_out" format="float">0.1066</dimen> - <integer name="qs_carrier_max_em">7</integer> + <integer name="shade_carrier_max_em">7</integer> <!-- Maximum number of notification icons shown on the Always on Display (excluding overflow dot) --> diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 63a4fd2189d8..7945470b424a 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -85,6 +85,8 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection; import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider; import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper; +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider; import com.android.systemui.statusbar.notification.people.PeopleHubModule; import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent; @@ -116,16 +118,16 @@ import com.android.systemui.wallet.dagger.WalletModule; import com.android.systemui.wmshell.BubblesManager; import com.android.wm.shell.bubbles.Bubbles; -import java.util.Optional; -import java.util.concurrent.Executor; - -import javax.inject.Named; - import dagger.Binds; import dagger.BindsOptionalOf; import dagger.Module; import dagger.Provides; +import java.util.Optional; +import java.util.concurrent.Executor; + +import javax.inject.Named; + /** * A dagger module for injecting components of System UI that are required by System UI. * @@ -315,4 +317,11 @@ public abstract class SystemUIModule { @Binds abstract LargeScreenShadeInterpolator largeScreensShadeInterpolator( LargeScreenShadeInterpolatorImpl impl); + + @SysUISingleton + @Provides + static VisualInterruptionDecisionProvider provideVisualInterruptionDecisionProvider( + NotificationInterruptStateProvider innerProvider) { + return new NotificationInterruptStateProviderWrapper(innerProvider); + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java index 630f6b4239da..cffe45fadaa3 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java +++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java @@ -16,6 +16,7 @@ package com.android.systemui.recents; +import static android.content.Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_DOWN; @@ -392,6 +393,16 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final BroadcastReceiver mLauncherStateChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + StringBuilder extraComponentList = new StringBuilder(" components: "); + if (intent.hasExtra(EXTRA_CHANGED_COMPONENT_NAME_LIST)) { + String[] comps = intent.getStringArrayExtra(EXTRA_CHANGED_COMPONENT_NAME_LIST); + if (comps != null) { + for (String c : comps) { + extraComponentList.append(c).append(", "); + } + } + } + Log.d(TAG_OPS, "launcherStateChanged intent: " + intent + extraComponentList); updateEnabledState(); // Reconnect immediately, instead of waiting for resume to arrive. @@ -402,9 +413,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis private final ServiceConnection mOverviewServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { - if (SysUiState.DEBUG) { - Log.d(TAG_OPS, "Overview proxy service connected"); - } + Log.d(TAG_OPS, "Overview proxy service connected"); mConnectionBackoffAttempts = 0; mHandler.removeCallbacks(mDeferredConnectionCallback); try { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 6f85c45a6614..c9d1da38b196 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -289,7 +289,7 @@ public class ScreenshotController { if (DEBUG_INPUT) { Log.d(TAG, "Predictive Back callback dispatched"); } - respondToBack(); + respondToKeyDismissal(); }; private ScreenshotView mScreenshotView; @@ -581,7 +581,7 @@ public class ScreenshotController { } } - private void respondToBack() { + private void respondToKeyDismissal() { dismissScreenshot(SCREENSHOT_DISMISSED_OTHER); } @@ -641,11 +641,11 @@ public class ScreenshotController { mScreenshotView.setDefaultTimeoutMillis(mScreenshotHandler.getDefaultTimeoutMillis()); mScreenshotView.setOnKeyListener((v, keyCode, event) -> { - if (keyCode == KeyEvent.KEYCODE_BACK) { + if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) { if (DEBUG_INPUT) { - Log.d(TAG, "onKeyEvent: KeyEvent.KEYCODE_BACK"); + Log.d(TAG, "onKeyEvent: " + keyCode); } - respondToBack(); + respondToKeyDismissal(); return true; } return false; diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt index b79f32a6eae1..b4653bef766d 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt @@ -43,13 +43,13 @@ import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager import com.android.systemui.qs.ChipVisibilityListener import com.android.systemui.qs.HeaderPrivacyIconsController -import com.android.systemui.qs.carrier.QSCarrierGroup -import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.shade.ShadeHeaderController.Companion.HEADER_TRANSITION_ID import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_TRANSITION_ID import com.android.systemui.shade.ShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT +import com.android.systemui.shade.carrier.ShadeCarrierGroup +import com.android.systemui.shade.carrier.ShadeCarrierGroupController import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarLocation @@ -87,7 +87,7 @@ constructor( private val variableDateViewControllerFactory: VariableDateViewController.Factory, @Named(SHADE_HEADER) private val batteryMeterViewController: BatteryMeterViewController, private val dumpManager: DumpManager, - private val qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder, + private val shadeCarrierGroupControllerBuilder: ShadeCarrierGroupController.Builder, private val combinedShadeHeadersConstraintManager: CombinedShadeHeadersConstraintManager, private val demoModeController: DemoModeController, private val qsBatteryModeController: QsBatteryModeController, @@ -114,13 +114,13 @@ constructor( private lateinit var iconManager: StatusBarIconController.TintedIconManager private lateinit var carrierIconSlots: List<String> - private lateinit var qsCarrierGroupController: QSCarrierGroupController + private lateinit var mShadeCarrierGroupController: ShadeCarrierGroupController private val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon) private val clock: Clock = header.findViewById(R.id.clock) private val date: TextView = header.findViewById(R.id.date) private val iconContainer: StatusIconContainer = header.findViewById(R.id.statusIcons) - private val qsCarrierGroup: QSCarrierGroup = header.findViewById(R.id.carrier_group) + private val mShadeCarrierGroup: ShadeCarrierGroup = header.findViewById(R.id.carrier_group) private var roundedCorners = 0 private var cutout: DisplayCutout? = null @@ -243,7 +243,7 @@ constructor( override fun onDensityOrFontScaleChanged() { clock.setTextAppearance(R.style.TextAppearance_QS_Status) date.setTextAppearance(R.style.TextAppearance_QS_Status) - qsCarrierGroup.updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers) + mShadeCarrierGroup.updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers) loadConstraints() header.minHeight = resources.getDimensionPixelSize(R.dimen.large_screen_shade_header_min_height) @@ -266,8 +266,8 @@ constructor( carrierIconSlots = listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile)) - qsCarrierGroupController = - qsCarrierGroupControllerBuilder.setQSCarrierGroup(qsCarrierGroup).build() + mShadeCarrierGroupController = + shadeCarrierGroupControllerBuilder.setShadeCarrierGroup(mShadeCarrierGroup).build() privacyIconsController.onParentVisible() } @@ -284,7 +284,7 @@ constructor( v.pivotX = newPivot v.pivotY = v.height.toFloat() / 2 - qsCarrierGroup.setPaddingRelative((v.width * v.scaleX).toInt(), 0, 0, 0) + mShadeCarrierGroup.setPaddingRelative((v.width * v.scaleX).toInt(), 0, 0, 0) } dumpManager.registerDumpable(this) @@ -439,12 +439,14 @@ constructor( } private fun updateListeners() { - qsCarrierGroupController.setListening(visible) + mShadeCarrierGroupController.setListening(visible) if (visible) { - updateSingleCarrier(qsCarrierGroupController.isSingleCarrier) - qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) } + updateSingleCarrier(mShadeCarrierGroupController.isSingleCarrier) + mShadeCarrierGroupController.setOnSingleCarrierChangedListener { + updateSingleCarrier(it) + } } else { - qsCarrierGroupController.setOnSingleCarrierChangedListener(null) + mShadeCarrierGroupController.setOnSingleCarrierChangedListener(null) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt b/packages/SystemUI/src/com/android/systemui/shade/carrier/CellSignalState.kt index e925b5472c27..958230bbef99 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/CellSignalState.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier +package com.android.systemui.shade.carrier /** * Represents the state of cell signal for a particular slot. * - * To be used between [QSCarrierGroupController] and [QSCarrier]. + * To be used between [ShadeCarrierGroupController] and [ShadeCarrier]. */ data class CellSignalState( @JvmField val visible: Boolean = false, @@ -37,7 +37,6 @@ data class CellSignalState( * @return `this` if `this.visible == visible`. Else, a new copy with the visibility changed. */ fun changeVisibility(visible: Boolean): CellSignalState { - if (this.visible == visible) return this - else return copy(visible = visible) + if (this.visible == visible) return this else return copy(visible = visible) } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java index b5ceeaed4904..8586828af0cd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrier.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier; +package com.android.systemui.shade.carrier; import android.annotation.StyleRes; import android.content.Context; @@ -38,7 +38,7 @@ import com.android.systemui.util.LargeScreenUtils; import java.util.Objects; -public class QSCarrier extends LinearLayout { +public class ShadeCarrier extends LinearLayout { private View mMobileGroup; private TextView mCarrierText; @@ -50,19 +50,19 @@ public class QSCarrier extends LinearLayout { private boolean mMobileSignalInitialized = false; private boolean mIsSingleCarrier; - public QSCarrier(Context context) { + public ShadeCarrier(Context context) { super(context); } - public QSCarrier(Context context, AttributeSet attrs) { + public ShadeCarrier(Context context, AttributeSet attrs) { super(context, attrs); } - public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr) { + public ShadeCarrier(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } - public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + public ShadeCarrier(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @@ -72,7 +72,7 @@ public class QSCarrier extends LinearLayout { mMobileGroup = findViewById(R.id.mobile_combo); mMobileRoaming = findViewById(R.id.mobile_roaming); mMobileSignal = findViewById(R.id.mobile_signal); - mCarrierText = findViewById(R.id.qs_carrier_text); + mCarrierText = findViewById(R.id.shade_carrier_text); mSpacer = findViewById(R.id.spacer); updateResources(); } @@ -158,7 +158,7 @@ public class QSCarrier extends LinearLayout { mCarrierText.setMaxEms( useLargeScreenHeader ? Integer.MAX_VALUE - : getResources().getInteger(R.integer.qs_carrier_max_em) + : getResources().getInteger(R.integer.shade_carrier_max_em) ); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java index a36035b99b4f..68561d1cfd0f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroup.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier; +package com.android.systemui.shade.carrier; import android.annotation.StyleRes; import android.content.Context; @@ -27,10 +27,10 @@ import com.android.systemui.FontSizeUtils; import com.android.systemui.R; /** - * Displays Carrier name and network status in QS + * Displays Carrier name and network status in the shade header */ -public class QSCarrierGroup extends LinearLayout { - public QSCarrierGroup(Context context, AttributeSet attrs) { +public class ShadeCarrierGroup extends LinearLayout { + public ShadeCarrierGroup(Context context, AttributeSet attrs) { super(context, attrs); } @@ -38,24 +38,24 @@ public class QSCarrierGroup extends LinearLayout { return findViewById(R.id.no_carrier_text); } - QSCarrier getCarrier1View() { + ShadeCarrier getCarrier1View() { return findViewById(R.id.carrier1); } - QSCarrier getCarrier2View() { + ShadeCarrier getCarrier2View() { return findViewById(R.id.carrier2); } - QSCarrier getCarrier3View() { + ShadeCarrier getCarrier3View() { return findViewById(R.id.carrier3); } View getCarrierDivider1() { - return findViewById(R.id.qs_carrier_divider1); + return findViewById(R.id.shade_carrier_divider1); } View getCarrierDivider2() { - return findViewById(R.id.qs_carrier_divider2); + return findViewById(R.id.shade_carrier_divider2); } public void updateTextAppearance(@StyleRes int resId) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java index 6a8bf759a849..0ebcfa2a1876 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier; +package com.android.systemui.shade.carrier; import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES; @@ -52,8 +52,8 @@ import java.util.function.Consumer; import javax.inject.Inject; -public class QSCarrierGroupController { - private static final String TAG = "QSCarrierGroup"; +public class ShadeCarrierGroupController { + private static final String TAG = "ShadeCarrierGroup"; /** * Support up to 3 slots which is what's supported by {@link TelephonyManager#getPhoneCount} @@ -72,7 +72,7 @@ public class QSCarrierGroupController { private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS]; private View[] mCarrierDividers = new View[SIM_SLOTS - 1]; - private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS]; + private ShadeCarrier[] mCarrierGroups = new ShadeCarrier[SIM_SLOTS]; private int[] mLastSignalLevel = new int[SIM_SLOTS]; private String[] mLastSignalLevelDescription = new String[SIM_SLOTS]; private final CarrierConfigTracker mCarrierConfigTracker; @@ -129,7 +129,7 @@ public class QSCarrierGroupController { } } - private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter, + private ShadeCarrierGroupController(ShadeCarrierGroup view, ActivityStarter activityStarter, @Background Handler bgHandler, @Main Looper mainLooper, NetworkController networkController, CarrierTextManager.Builder carrierTextManagerBuilder, Context context, @@ -167,7 +167,7 @@ public class QSCarrierGroupController { for (int i = 0; i < SIM_SLOTS; i++) { mInfos[i] = new CellSignalState( true, - R.drawable.ic_qs_no_calling_sms, + R.drawable.ic_shade_no_calling_sms, context.getText(AccessibilityContentDescriptions.NO_CALLING).toString(), "", false); @@ -257,7 +257,7 @@ public class QSCarrierGroupController { if (singleCarrier) { for (int i = 0; i < SIM_SLOTS; i++) { if (mInfos[i].visible - && mInfos[i].mobileSignalIconId == R.drawable.ic_qs_sim_card) { + && mInfos[i].mobileSignalIconId == R.drawable.ic_shade_sim_card) { mInfos[i] = new CellSignalState(true, R.drawable.ic_blank, "", "", false); } } @@ -322,8 +322,8 @@ public class QSCarrierGroupController { Log.e(TAG, "Carrier information arrays not of same length"); } } else { - // No sims or airplane mode (but not WFC). Do not show QSCarrierGroup, instead just show - // info.carrierText in a different view. + // No sims or airplane mode (but not WFC). Do not show ShadeCarrierGroup, + // instead just show info.carrierText in a different view. for (int i = 0; i < SIM_SLOTS; i++) { mInfos[i] = mInfos[i].changeVisibility(false); mCarrierGroups[i].setCarrierText(""); @@ -368,7 +368,7 @@ public class QSCarrierGroupController { } public static class Builder { - private QSCarrierGroup mView; + private ShadeCarrierGroup mView; private final ActivityStarter mActivityStarter; private final Handler mHandler; private final Looper mLooper; @@ -393,13 +393,13 @@ public class QSCarrierGroupController { mSlotIndexResolver = slotIndexResolver; } - public Builder setQSCarrierGroup(QSCarrierGroup view) { + public Builder setShadeCarrierGroup(ShadeCarrierGroup view) { mView = view; return this; } - public QSCarrierGroupController build() { - return new QSCarrierGroupController(mView, mActivityStarter, mHandler, mLooper, + public ShadeCarrierGroupController build() { + return new ShadeCarrierGroupController(mView, mActivityStarter, mHandler, mLooper, mNetworkController, mCarrierTextControllerBuilder, mContext, mCarrierConfigTracker, mSlotIndexResolver); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java index 565c0a9426ab..34300c731343 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java @@ -38,8 +38,8 @@ import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteracto import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.qs.carrier.QSCarrierGroupController; import com.android.systemui.settings.DisplayTracker; +import com.android.systemui.shade.carrier.ShadeCarrierGroupController; import com.android.systemui.statusbar.ActionClickLogger; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.MediaArtworkProcessor; @@ -78,14 +78,14 @@ import com.android.systemui.tracing.ProtoTracer; import com.android.systemui.util.concurrency.DelayableExecutor; import com.android.systemui.util.time.SystemClock; +import java.util.Optional; +import java.util.concurrent.Executor; + import dagger.Binds; import dagger.Lazy; import dagger.Module; import dagger.Provides; -import java.util.Optional; -import java.util.concurrent.Executor; - /** * This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to * this separate from {@link CentralSurfacesModule} module so that components that wish to build @@ -271,8 +271,8 @@ public interface CentralSurfacesDependenciesModule { /** */ @Binds - QSCarrierGroupController.SlotIndexResolver provideSlotIndexResolver( - QSCarrierGroupController.SubscriptionManagerSlotIndexResolver impl); + ShadeCarrierGroupController.SlotIndexResolver provideSlotIndexResolver( + ShadeCarrierGroupController.SubscriptionManagerSlotIndexResolver impl); /** */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt new file mode 100644 index 000000000000..f2216fce6fef --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapper.kt @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.notification.interruption + +import com.android.internal.annotations.VisibleForTesting +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.Decision +import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.FullScreenIntentDecision + +/** + * Wraps a [NotificationInterruptStateProvider] to convert it to the new + * [VisualInterruptionDecisionProvider] interface. + */ +@SysUISingleton +class NotificationInterruptStateProviderWrapper( + private val wrapped: NotificationInterruptStateProvider +) : VisualInterruptionDecisionProvider { + + @VisibleForTesting + enum class DecisionImpl(override val shouldInterrupt: Boolean) : Decision { + SHOULD_INTERRUPT(shouldInterrupt = true), + SHOULD_NOT_INTERRUPT(shouldInterrupt = false); + + companion object { + fun of(booleanDecision: Boolean) = + if (booleanDecision) SHOULD_INTERRUPT else SHOULD_NOT_INTERRUPT + } + } + + @VisibleForTesting + class FullScreenIntentDecisionImpl( + val originalEntry: NotificationEntry, + val originalDecision: NotificationInterruptStateProvider.FullScreenIntentDecision + ) : FullScreenIntentDecision { + override val shouldInterrupt = originalDecision.shouldLaunch + override val wouldInterruptWithoutDnd = originalDecision == NO_FSI_SUPPRESSED_ONLY_BY_DND + } + + override fun addSuppressor(suppressor: NotificationInterruptSuppressor) { + wrapped.addSuppressor(suppressor) + } + + override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision = + wrapped.checkHeadsUp(entry, /* log= */ false).let { DecisionImpl.of(it) } + + override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision = + wrapped.checkHeadsUp(entry, /* log= */ true).let { DecisionImpl.of(it) } + + override fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry) = + wrapped.getFullScreenIntentDecision(entry).let { FullScreenIntentDecisionImpl(entry, it) } + + override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) { + (decision as FullScreenIntentDecisionImpl).let { + wrapped.logFullScreenIntentDecision(it.originalEntry, it.originalDecision) + } + } + + override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision = + wrapped.shouldBubbleUp(entry).let { DecisionImpl.of(it) } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt new file mode 100644 index 000000000000..c0f4fcda56bb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/VisualInterruptionDecisionProvider.kt @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.statusbar.notification.interruption + +import com.android.systemui.statusbar.notification.collection.NotificationEntry + +/** + * Decides whether a notification should visually interrupt the user in various ways. + * + * These include displaying the notification as heads-up (peeking while the device is awake or + * pulsing while the device is dozing), displaying the notification as a bubble, and launching a + * full-screen intent for the notification. + */ +interface VisualInterruptionDecisionProvider { + /** + * Represents the decision to visually interrupt or not. + * + * Used for heads-up and bubble decisions; subclassed by [FullScreenIntentDecision] for + * full-screen intent decisions. + * + * @property[shouldInterrupt] whether a visual interruption should be triggered + */ + interface Decision { + val shouldInterrupt: Boolean + } + + /** + * Represents the decision to launch a full-screen intent for a notification or not. + * + * @property[wouldInterruptWithoutDnd] whether a full-screen intent should not be launched only + * because Do Not Disturb has suppressed it + */ + interface FullScreenIntentDecision : Decision { + val wouldInterruptWithoutDnd: Boolean + } + + /** + * Adds a [component][suppressor] that can suppress visual interruptions. + * + * This class may call suppressors in any order. + * + * @param[suppressor] the suppressor to add + */ + fun addSuppressor(suppressor: NotificationInterruptSuppressor) + + /** + * Decides whether a [notification][entry] should display as heads-up or not, but does not log + * that decision. + * + * @param[entry] the notification that this decision is about + * @return the decision to display that notification as heads-up or not + */ + fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision + + /** + * Decides whether a [notification][entry] should display as heads-up or not, and logs that + * decision. + * + * If the device is awake, the decision will consider whether the notification should "peek" + * (slide in from the top of the screen over the current activity). + * + * If the device is dozing, the decision will consider whether the notification should "pulse" + * (wake the screen up and display the ambient view of the notification). + * + * @see[makeUnloggedHeadsUpDecision] + * + * @param[entry] the notification that this decision is about + * @return the decision to display that notification as heads-up or not + */ + fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision + + /** + * Decides whether a [notification][entry] should launch a full-screen intent or not, but does + * not log that decision. + * + * The returned decision can be logged by passing it to [logFullScreenIntentDecision]. + * + * @see[makeAndLogHeadsUpDecision] + * + * @param[entry] the notification that this decision is about + * @return the decision to launch a full-screen intent for that notification or not + */ + fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry): FullScreenIntentDecision + + /** + * Logs a previous [decision] to launch a full-screen intent or not. + * + * @param[decision] the decision to log + */ + fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) + + /** + * Decides whether a [notification][entry] should display as a bubble or not. + * + * @param[entry] the notification that this decision is about + * @return the decision to display that notification as a bubble or not + */ + fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index de7bf3c021dd..d731f8886536 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -230,7 +230,7 @@ public class StatusBarSignalPolicy implements SignalCallback, if (state == null) { return; } - if (statusIcon.icon == R.drawable.ic_qs_no_calling_sms) { + if (statusIcon.icon == R.drawable.ic_shade_no_calling_sms) { state.isNoCalling = statusIcon.visible; state.noCallingDescription = statusIcon.contentDescription; } else { @@ -422,7 +422,7 @@ public class StatusBarSignalPolicy implements SignalCallback, private CallIndicatorIconState(int subId) { this.subId = subId; - this.noCallingResId = R.drawable.ic_qs_no_calling_sms; + this.noCallingResId = R.drawable.ic_shade_no_calling_sms; this.callStrengthResId = TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[0]; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java index 5fcf414f0251..8fdc4918b9fd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/ComplicationCollectionLiveDataTest.java @@ -18,8 +18,8 @@ package com.android.systemui.dreams.complication; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -29,23 +29,45 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.dreams.DreamOverlayStateController; +import com.android.systemui.flags.FakeFeatureFlags; +import com.android.systemui.flags.Flags; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import java.util.Collection; import java.util.HashSet; @SmallTest @RunWith(AndroidTestingRunner.class) -@TestableLooper.RunWithLooper +@TestableLooper.RunWithLooper(setAsMainLooper = true) public class ComplicationCollectionLiveDataTest extends SysuiTestCase { + + private FakeExecutor mExecutor; + private DreamOverlayStateController mStateController; + private ComplicationCollectionLiveData mLiveData; + private FakeFeatureFlags mFeatureFlags; + @Mock + private Observer mObserver; + @Before - public void setUp() throws Exception { - allowTestableLooperAsMainThread(); + public void setUp() { + MockitoAnnotations.initMocks(this); + mFeatureFlags = new FakeFeatureFlags(); + mExecutor = new FakeExecutor(new FakeSystemClock()); + mFeatureFlags.set(Flags.ALWAYS_SHOW_HOME_CONTROLS_ON_DREAMS, true); + mStateController = new DreamOverlayStateController( + mExecutor, + /* overlayEnabled= */ true, + mFeatureFlags); + mLiveData = new ComplicationCollectionLiveData(mStateController); } @Test @@ -53,45 +75,41 @@ public class ComplicationCollectionLiveDataTest extends SysuiTestCase { * Ensures registration and callback lifecycles are respected. */ public void testLifecycle() { - getContext().getMainExecutor().execute(() -> { - final DreamOverlayStateController stateController = - Mockito.mock(DreamOverlayStateController.class); - final ComplicationCollectionLiveData liveData = - new ComplicationCollectionLiveData(stateController); - final HashSet<Complication> complications = new HashSet<>(); - final Observer<Collection<Complication>> observer = Mockito.mock(Observer.class); - complications.add(Mockito.mock(Complication.class)); - - when(stateController.getComplications()).thenReturn(complications); - - liveData.observeForever(observer); - ArgumentCaptor<DreamOverlayStateController.Callback> callbackCaptor = - ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class); - - verify(stateController).addCallback(callbackCaptor.capture()); - verifyUpdate(observer, complications); - - complications.add(Mockito.mock(Complication.class)); - callbackCaptor.getValue().onComplicationsChanged(); - - verifyUpdate(observer, complications); - - callbackCaptor.getValue().onAvailableComplicationTypesChanged(); - - verifyUpdate(observer, complications); - }); + final HashSet<Complication> complications = new HashSet<>(); + mLiveData.observeForever(mObserver); + mExecutor.runAllReady(); + // Verify observer called with empty complications + assertObserverCalledWith(complications); + + addComplication(mock(Complication.class), complications); + assertObserverCalledWith(complications); + + addComplication(mock(Complication.class), complications); + assertObserverCalledWith(complications); + + mStateController.setAvailableComplicationTypes(0); + mExecutor.runAllReady(); + assertObserverCalledWith(complications); + mLiveData.removeObserver(mObserver); } - void verifyUpdate(Observer<Collection<Complication>> observer, - Collection<Complication> targetCollection) { + private void assertObserverCalledWith(Collection<Complication> targetCollection) { ArgumentCaptor<Collection<Complication>> collectionCaptor = ArgumentCaptor.forClass(Collection.class); - verify(observer).onChanged(collectionCaptor.capture()); + verify(mObserver).onChanged(collectionCaptor.capture()); + + final Collection<Complication> collection = collectionCaptor.getValue(); - final Collection collection = collectionCaptor.getValue(); assertThat(collection.containsAll(targetCollection) && targetCollection.containsAll(collection)).isTrue(); - Mockito.clearInvocations(observer); + Mockito.clearInvocations(mObserver); + } + + private void addComplication(Complication complication, + Collection<Complication> complications) { + complications.add(complication); + mStateController.addComplication(complication); + mExecutor.runAllReady(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt index 543875dc31cf..aace5661862b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt @@ -101,6 +101,7 @@ import dagger.Lazy import junit.framework.Assert.assertTrue import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -2199,6 +2200,7 @@ public class MediaControlPanelTest : SysuiTestCase() { } @Test + @Ignore("b/276920368") fun bindRecommendation_carouselNotFitThreeRecs() { useRealConstraintSets() setupUpdatedRecommendationViewHolder() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt index d5308298202d..b043e97f1054 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeHeaderControllerTest.kt @@ -42,11 +42,11 @@ import com.android.systemui.demomode.DemoModeController import com.android.systemui.dump.DumpManager import com.android.systemui.qs.ChipVisibilityListener import com.android.systemui.qs.HeaderPrivacyIconsController -import com.android.systemui.qs.carrier.QSCarrierGroup -import com.android.systemui.qs.carrier.QSCarrierGroupController import com.android.systemui.shade.ShadeHeaderController.Companion.LARGE_SCREEN_HEADER_CONSTRAINT import com.android.systemui.shade.ShadeHeaderController.Companion.QQS_HEADER_CONSTRAINT import com.android.systemui.shade.ShadeHeaderController.Companion.QS_HEADER_CONSTRAINT +import com.android.systemui.shade.carrier.ShadeCarrierGroup +import com.android.systemui.shade.carrier.ShadeCarrierGroupController import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusIconContainer @@ -88,11 +88,12 @@ class ShadeHeaderControllerTest : SysuiTestCase() { @Mock private lateinit var statusBarIconController: StatusBarIconController @Mock private lateinit var iconManagerFactory: StatusBarIconController.TintedIconManager.Factory @Mock private lateinit var iconManager: StatusBarIconController.TintedIconManager - @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController - @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder + @Mock private lateinit var mShadeCarrierGroupController: ShadeCarrierGroupController + @Mock + private lateinit var mShadeCarrierGroupControllerBuilder: ShadeCarrierGroupController.Builder @Mock private lateinit var clock: Clock @Mock private lateinit var date: VariableDateView - @Mock private lateinit var carrierGroup: QSCarrierGroup + @Mock private lateinit var carrierGroup: ShadeCarrierGroup @Mock private lateinit var batteryMeterView: BatteryMeterView @Mock private lateinit var batteryMeterViewController: BatteryMeterViewController @Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController @@ -131,7 +132,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() { whenever<TextView>(view.findViewById(R.id.date)).thenReturn(date) whenever(date.context).thenReturn(mockedContext) - whenever<QSCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup) + whenever<ShadeCarrierGroup>(view.findViewById(R.id.carrier_group)).thenReturn(carrierGroup) whenever<BatteryMeterView>(view.findViewById(R.id.batteryRemainingIcon)) .thenReturn(batteryMeterView) @@ -142,9 +143,10 @@ class ShadeHeaderControllerTest : SysuiTestCase() { whenever(view.context).thenReturn(viewContext) whenever(view.resources).thenReturn(context.resources) whenever(statusIcons.context).thenReturn(context) - whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any())) - .thenReturn(qsCarrierGroupControllerBuilder) - whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) + whenever(mShadeCarrierGroupControllerBuilder.setShadeCarrierGroup(any())) + .thenReturn(mShadeCarrierGroupControllerBuilder) + whenever(mShadeCarrierGroupControllerBuilder.build()) + .thenReturn(mShadeCarrierGroupController) whenever(view.setVisibility(anyInt())).then { viewVisibility = it.arguments[0] as Int null @@ -175,7 +177,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() { variableDateViewControllerFactory, batteryMeterViewController, dumpManager, - qsCarrierGroupControllerBuilder, + mShadeCarrierGroupControllerBuilder, combinedShadeHeadersConstraintManager, demoModeController, qsBatteryModeController, @@ -189,7 +191,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() { @Test fun updateListeners_registersWhenVisible() { makeShadeVisible() - verify(qsCarrierGroupController).setListening(true) + verify(mShadeCarrierGroupController).setListening(true) verify(statusBarIconController).addIconGroup(any()) } @@ -213,7 +215,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() { @Test fun singleCarrier_enablesCarrierIconsInStatusIcons() { - whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true) + whenever(mShadeCarrierGroupController.isSingleCarrier).thenReturn(true) makeShadeVisible() @@ -222,7 +224,7 @@ class ShadeHeaderControllerTest : SysuiTestCase() { @Test fun dualCarrier_disablesCarrierIconsInStatusIcons() { - whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false) + whenever(mShadeCarrierGroupController.isSingleCarrier).thenReturn(false) makeShadeVisible() @@ -349,9 +351,9 @@ class ShadeHeaderControllerTest : SysuiTestCase() { verify(batteryMeterViewController).init() verify(batteryMeterViewController).ignoreTunerUpdates() - val inOrder = Mockito.inOrder(qsCarrierGroupControllerBuilder) - inOrder.verify(qsCarrierGroupControllerBuilder).setQSCarrierGroup(carrierGroup) - inOrder.verify(qsCarrierGroupControllerBuilder).build() + val inOrder = Mockito.inOrder(mShadeCarrierGroupControllerBuilder) + inOrder.verify(mShadeCarrierGroupControllerBuilder).setShadeCarrierGroup(carrierGroup) + inOrder.verify(mShadeCarrierGroupControllerBuilder).build() } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/CellSignalStateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt index 75be74b13c87..7a9ef62278a4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/CellSignalStateTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/CellSignalStateTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier +package com.android.systemui.shade.carrier import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest @@ -45,4 +45,4 @@ class CellSignalStateTest : SysuiTestCase() { assertNotSame(c, other) } -}
\ No newline at end of file +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java index 1e7722ae8395..2ef3d60c7754 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierGroupControllerTest.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier; +package com.android.systemui.shade.carrier; import static com.google.common.truth.Truth.assertThat; @@ -63,13 +63,13 @@ import org.mockito.MockitoAnnotations; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest -public class QSCarrierGroupControllerTest extends LeakCheckedTest { +public class ShadeCarrierGroupControllerTest extends LeakCheckedTest { - private QSCarrierGroupController mQSCarrierGroupController; + private ShadeCarrierGroupController mShadeCarrierGroupController; private SignalCallback mSignalCallback; private CarrierTextManager.CarrierTextCallback mCallback; @Mock - private QSCarrierGroup mQSCarrierGroup; + private ShadeCarrierGroup mShadeCarrierGroup; @Mock private ActivityStarter mActivityStarter; @Mock @@ -81,14 +81,14 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { @Mock private CarrierConfigTracker mCarrierConfigTracker; @Mock - private QSCarrier mQSCarrier1; + private ShadeCarrier mShadeCarrier1; @Mock - private QSCarrier mQSCarrier2; + private ShadeCarrier mShadeCarrier2; @Mock - private QSCarrier mQSCarrier3; + private ShadeCarrier mShadeCarrier3; private TestableLooper mTestableLooper; @Mock - private QSCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener; + private ShadeCarrierGroupController.OnSingleCarrierChangedListener mOnSingleCarrierChangedListener; private FakeSlotIndexResolver mSlotIndexResolver; private ClickListenerTextView mNoCarrierTextView; @@ -116,28 +116,28 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { .setListening(any(CarrierTextManager.CarrierTextCallback.class)); mNoCarrierTextView = new ClickListenerTextView(mContext); - when(mQSCarrierGroup.getNoSimTextView()).thenReturn(mNoCarrierTextView); - when(mQSCarrierGroup.getCarrier1View()).thenReturn(mQSCarrier1); - when(mQSCarrierGroup.getCarrier2View()).thenReturn(mQSCarrier2); - when(mQSCarrierGroup.getCarrier3View()).thenReturn(mQSCarrier3); - when(mQSCarrierGroup.getCarrierDivider1()).thenReturn(new View(mContext)); - when(mQSCarrierGroup.getCarrierDivider2()).thenReturn(new View(mContext)); + when(mShadeCarrierGroup.getNoSimTextView()).thenReturn(mNoCarrierTextView); + when(mShadeCarrierGroup.getCarrier1View()).thenReturn(mShadeCarrier1); + when(mShadeCarrierGroup.getCarrier2View()).thenReturn(mShadeCarrier2); + when(mShadeCarrierGroup.getCarrier3View()).thenReturn(mShadeCarrier3); + when(mShadeCarrierGroup.getCarrierDivider1()).thenReturn(new View(mContext)); + when(mShadeCarrierGroup.getCarrierDivider2()).thenReturn(new View(mContext)); mSlotIndexResolver = new FakeSlotIndexResolver(); - mQSCarrierGroupController = new QSCarrierGroupController.Builder( + mShadeCarrierGroupController = new ShadeCarrierGroupController.Builder( mActivityStarter, handler, TestableLooper.get(this).getLooper(), mNetworkController, mCarrierTextControllerBuilder, mContext, mCarrierConfigTracker, mSlotIndexResolver) - .setQSCarrierGroup(mQSCarrierGroup) + .setShadeCarrierGroup(mShadeCarrierGroup) .build(); - mQSCarrierGroupController.setListening(true); + mShadeCarrierGroupController.setListening(true); } @Test public void testInitiallyMultiCarrier() { - assertFalse(mQSCarrierGroupController.isSingleCarrier()); + assertFalse(mShadeCarrierGroupController.isSingleCarrier()); } @Test // throws no Exception @@ -257,12 +257,12 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { true /* airplaneMode */); mCallback.updateCarrierInfo(info); mTestableLooper.processAllMessages(); - assertEquals(View.GONE, mQSCarrierGroup.getNoSimTextView().getVisibility()); + assertEquals(View.GONE, mShadeCarrierGroup.getNoSimTextView().getVisibility()); } @Test public void testListenerNotCalledOnRegistreation() { - mQSCarrierGroupController + mShadeCarrierGroupController .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); verify(mOnSingleCarrierChangedListener, never()).onSingleCarrierChanged(anyBoolean()); @@ -282,9 +282,9 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(info); mTestableLooper.processAllMessages(); - verify(mQSCarrier1).updateState(any(), eq(true)); - verify(mQSCarrier2).updateState(any(), eq(true)); - verify(mQSCarrier3).updateState(any(), eq(true)); + verify(mShadeCarrier1).updateState(any(), eq(true)); + verify(mShadeCarrier2).updateState(any(), eq(true)); + verify(mShadeCarrier3).updateState(any(), eq(true)); } @Test @@ -301,9 +301,9 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(info); mTestableLooper.processAllMessages(); - verify(mQSCarrier1).updateState(any(), eq(false)); - verify(mQSCarrier2).updateState(any(), eq(false)); - verify(mQSCarrier3).updateState(any(), eq(false)); + verify(mShadeCarrier1).updateState(any(), eq(false)); + verify(mShadeCarrier2).updateState(any(), eq(false)); + verify(mShadeCarrier3).updateState(any(), eq(false)); } @Test @@ -327,7 +327,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(singleCarrierInfo); mTestableLooper.processAllMessages(); - mQSCarrierGroupController + mShadeCarrierGroupController .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); reset(mOnSingleCarrierChangedListener); @@ -353,7 +353,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(singleCarrierInfo); mTestableLooper.processAllMessages(); - mQSCarrierGroupController + mShadeCarrierGroupController .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); mCallback.updateCarrierInfo(singleCarrierInfo); @@ -375,7 +375,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { mCallback.updateCarrierInfo(multiCarrierInfo); mTestableLooper.processAllMessages(); - mQSCarrierGroupController + mShadeCarrierGroupController .setOnSingleCarrierChangedListener(mOnSingleCarrierChangedListener); mCallback.updateCarrierInfo(multiCarrierInfo); @@ -389,12 +389,12 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { ArgumentCaptor<View.OnClickListener> captor = ArgumentCaptor.forClass(View.OnClickListener.class); - verify(mQSCarrier1).setOnClickListener(captor.capture()); - verify(mQSCarrier2).setOnClickListener(captor.getValue()); - verify(mQSCarrier3).setOnClickListener(captor.getValue()); + verify(mShadeCarrier1).setOnClickListener(captor.capture()); + verify(mShadeCarrier2).setOnClickListener(captor.getValue()); + verify(mShadeCarrier3).setOnClickListener(captor.getValue()); assertThat(mNoCarrierTextView.getOnClickListener()).isSameInstanceAs(captor.getValue()); - verify(mQSCarrierGroup, never()).setOnClickListener(any()); + verify(mShadeCarrierGroup, never()).setOnClickListener(any()); } @Test @@ -402,10 +402,10 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { ArgumentCaptor<View.OnClickListener> captor = ArgumentCaptor.forClass(View.OnClickListener.class); - verify(mQSCarrier1).setOnClickListener(captor.capture()); - when(mQSCarrier1.isVisibleToUser()).thenReturn(false); + verify(mShadeCarrier1).setOnClickListener(captor.capture()); + when(mShadeCarrier1.isVisibleToUser()).thenReturn(false); - captor.getValue().onClick(mQSCarrier1); + captor.getValue().onClick(mShadeCarrier1); verifyZeroInteractions(mActivityStarter); } @@ -415,17 +415,17 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest { ArgumentCaptor.forClass(View.OnClickListener.class); ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); - verify(mQSCarrier1).setOnClickListener(listenerCaptor.capture()); - when(mQSCarrier1.isVisibleToUser()).thenReturn(true); + verify(mShadeCarrier1).setOnClickListener(listenerCaptor.capture()); + when(mShadeCarrier1.isVisibleToUser()).thenReturn(true); - listenerCaptor.getValue().onClick(mQSCarrier1); + listenerCaptor.getValue().onClick(mShadeCarrier1); verify(mActivityStarter) .postStartActivityDismissingKeyguard(intentCaptor.capture(), anyInt()); assertThat(intentCaptor.getValue().getAction()) .isEqualTo(Settings.ACTION_WIRELESS_SETTINGS); } - private class FakeSlotIndexResolver implements QSCarrierGroupController.SlotIndexResolver { + private class FakeSlotIndexResolver implements ShadeCarrierGroupController.SlotIndexResolver { public boolean overrideInvalid; @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java index 9115ab3bacca..44613103a5b2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/carrier/ShadeCarrierTest.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * Copyright (C) 2023 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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, @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.qs.carrier; +package com.android.systemui.shade.carrier; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -39,9 +39,9 @@ import org.junit.runner.RunWith; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper @SmallTest -public class QSCarrierTest extends SysuiTestCase { +public class ShadeCarrierTest extends SysuiTestCase { - private QSCarrier mQSCarrier; + private ShadeCarrier mShadeCarrier; private TestableLooper mTestableLooper; private int mSignalIconId; @@ -51,7 +51,7 @@ public class QSCarrierTest extends SysuiTestCase { LayoutInflater inflater = LayoutInflater.from(mContext); mContext.ensureTestableResources(); mTestableLooper.runWithLooper(() -> - mQSCarrier = (QSCarrier) inflater.inflate(R.layout.qs_carrier, null)); + mShadeCarrier = (ShadeCarrier) inflater.inflate(R.layout.shade_carrier, null)); // In this case, the id is an actual drawable id mSignalIconId = TelephonyIcons.MOBILE_CALL_STRENGTH_ICONS[0]; @@ -61,76 +61,76 @@ public class QSCarrierTest extends SysuiTestCase { public void testUpdateState_first() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - assertTrue(mQSCarrier.updateState(c, false)); + assertTrue(mShadeCarrier.updateState(c, false)); } @Test public void testUpdateState_same() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - assertTrue(mQSCarrier.updateState(c, false)); - assertFalse(mQSCarrier.updateState(c, false)); + assertTrue(mShadeCarrier.updateState(c, false)); + assertFalse(mShadeCarrier.updateState(c, false)); } @Test public void testUpdateState_changed() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - assertTrue(mQSCarrier.updateState(c, false)); + assertTrue(mShadeCarrier.updateState(c, false)); CellSignalState other = c.changeVisibility(false); - assertTrue(mQSCarrier.updateState(other, false)); + assertTrue(mShadeCarrier.updateState(other, false)); } @Test public void testUpdateState_singleCarrier_first() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - assertTrue(mQSCarrier.updateState(c, true)); + assertTrue(mShadeCarrier.updateState(c, true)); } @Test public void testUpdateState_singleCarrier_noShowIcon() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - mQSCarrier.updateState(c, true); + mShadeCarrier.updateState(c, true); - assertEquals(View.GONE, mQSCarrier.getRSSIView().getVisibility()); + assertEquals(View.GONE, mShadeCarrier.getRSSIView().getVisibility()); } @Test public void testUpdateState_multiCarrier_showIcon() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - mQSCarrier.updateState(c, false); + mShadeCarrier.updateState(c, false); - assertEquals(View.VISIBLE, mQSCarrier.getRSSIView().getVisibility()); + assertEquals(View.VISIBLE, mShadeCarrier.getRSSIView().getVisibility()); } @Test public void testUpdateState_changeSingleMultiSingle() { CellSignalState c = new CellSignalState(true, mSignalIconId, "", "", false); - mQSCarrier.updateState(c, true); - assertEquals(View.GONE, mQSCarrier.getRSSIView().getVisibility()); + mShadeCarrier.updateState(c, true); + assertEquals(View.GONE, mShadeCarrier.getRSSIView().getVisibility()); - mQSCarrier.updateState(c, false); - assertEquals(View.VISIBLE, mQSCarrier.getRSSIView().getVisibility()); + mShadeCarrier.updateState(c, false); + assertEquals(View.VISIBLE, mShadeCarrier.getRSSIView().getVisibility()); - mQSCarrier.updateState(c, true); - assertEquals(View.GONE, mQSCarrier.getRSSIView().getVisibility()); + mShadeCarrier.updateState(c, true); + assertEquals(View.GONE, mShadeCarrier.getRSSIView().getVisibility()); } @Test public void testCarrierNameMaxWidth_smallScreen_fromResource() { int maxEms = 10; - mContext.getOrCreateTestableResources().addOverride(R.integer.qs_carrier_max_em, maxEms); + mContext.getOrCreateTestableResources().addOverride(R.integer.shade_carrier_max_em, maxEms); mContext.getOrCreateTestableResources() .addOverride(R.bool.config_use_large_screen_shade_header, false); - TextView carrierText = mQSCarrier.requireViewById(R.id.qs_carrier_text); + TextView carrierText = mShadeCarrier.requireViewById(R.id.shade_carrier_text); - mQSCarrier.onConfigurationChanged(mContext.getResources().getConfiguration()); + mShadeCarrier.onConfigurationChanged(mContext.getResources().getConfiguration()); assertEquals(maxEms, carrierText.getMaxEms()); } @@ -138,12 +138,12 @@ public class QSCarrierTest extends SysuiTestCase { @Test public void testCarrierNameMaxWidth_largeScreen_maxInt() { int maxEms = 10; - mContext.getOrCreateTestableResources().addOverride(R.integer.qs_carrier_max_em, maxEms); + mContext.getOrCreateTestableResources().addOverride(R.integer.shade_carrier_max_em, maxEms); mContext.getOrCreateTestableResources() .addOverride(R.bool.config_use_large_screen_shade_header, true); - TextView carrierText = mQSCarrier.requireViewById(R.id.qs_carrier_text); + TextView carrierText = mShadeCarrier.requireViewById(R.id.shade_carrier_text); - mQSCarrier.onConfigurationChanged(mContext.getResources().getConfiguration()); + mShadeCarrier.onConfigurationChanged(mContext.getResources().getConfiguration()); assertEquals(Integer.MAX_VALUE, carrierText.getMaxEms()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt new file mode 100644 index 000000000000..cbb08946a1b0 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderWrapperTest.kt @@ -0,0 +1,78 @@ +package com.android.systemui.statusbar.notification.interruption + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_NOT_IMPORTANT_ENOUGH +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.DecisionImpl +import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.FullScreenIntentDecisionImpl +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class NotificationInterruptStateProviderWrapperTest : SysuiTestCase() { + + @Test + fun decisionOfTrue() { + assertTrue(DecisionImpl.of(true).shouldInterrupt) + } + + @Test + fun decisionOfFalse() { + assertFalse(DecisionImpl.of(false).shouldInterrupt) + } + + @Test + fun decisionOfTrueInterned() { + assertEquals(DecisionImpl.of(true), DecisionImpl.of(true)) + } + + @Test + fun decisionOfFalseInterned() { + assertEquals(DecisionImpl.of(false), DecisionImpl.of(false)) + } + + @Test + fun fullScreenIntentDecisionShouldInterrupt() { + makeFsiDecision(FSI_DEVICE_NOT_INTERACTIVE).let { + assertTrue(it.shouldInterrupt) + assertFalse(it.wouldInterruptWithoutDnd) + } + } + + @Test + fun fullScreenIntentDecisionShouldNotInterrupt() { + makeFsiDecision(NO_FSI_NOT_IMPORTANT_ENOUGH).let { + assertFalse(it.shouldInterrupt) + assertFalse(it.wouldInterruptWithoutDnd) + } + } + + @Test + fun fullScreenIntentDecisionWouldInterruptWithoutDnd() { + makeFsiDecision(NO_FSI_SUPPRESSED_ONLY_BY_DND).let { + assertFalse(it.shouldInterrupt) + assertTrue(it.wouldInterruptWithoutDnd) + } + } + + @Test + fun fullScreenIntentDecisionWouldNotInterruptEvenWithoutDnd() { + makeFsiDecision(NO_FSI_SUPPRESSED_BY_DND).let { + assertFalse(it.shouldInterrupt) + assertFalse(it.wouldInterruptWithoutDnd) + } + } + + private fun makeFsiDecision(originalDecision: FullScreenIntentDecision) = + FullScreenIntentDecisionImpl(NotificationEntryBuilder().build(), originalDecision) +} diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 78cbf2bd80d8..7b618b11bd45 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -88,6 +88,7 @@ import static com.android.internal.messages.nano.SystemMessageProto.SystemMessag import static com.android.internal.util.FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED; import static com.android.internal.util.FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER; import static com.android.internal.util.FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT; +import static com.android.internal.util.FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__TIMED_OUT; import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED; import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL; import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED; @@ -3240,6 +3241,12 @@ public final class ActiveServices { return; } Slog.e(TAG_SERVICE, "Short FGS timed out: " + sr); + final long now = SystemClock.uptimeMillis(); + logFGSStateChangeLocked(sr, + FOREGROUND_SERVICE_STATE_CHANGED__STATE__TIMED_OUT, + now > sr.mFgsEnterTime ? (int) (now - sr.mFgsEnterTime) : 0, + FGS_STOP_REASON_UNKNOWN, + FGS_TYPE_POLICY_CHECK_UNKNOWN); try { sr.app.getThread().scheduleTimeoutService(sr, sr.getShortFgsInfo().getStartId()); } catch (RemoteException e) { @@ -7897,7 +7904,8 @@ public final class ActiveServices { boolean allowWhileInUsePermissionInFgs; @PowerExemptionManager.ReasonCode int fgsStartReasonCode; if (state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER - || state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT) { + || state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__EXIT + || state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__TIMED_OUT) { allowWhileInUsePermissionInFgs = r.mAllowWhileInUsePermissionInFgsAtEntering; fgsStartReasonCode = r.mAllowStartForegroundAtEntering; } else { @@ -7931,9 +7939,9 @@ public final class ActiveServices { r.mFgsDelegation != null ? r.mFgsDelegation.mOptions.mClientUid : INVALID_UID, r.mFgsDelegation != null ? r.mFgsDelegation.mOptions.mDelegationService : ForegroundServiceDelegationOptions.DELEGATION_SERVICE_DEFAULT, - 0, - null, - null); + 0 /* api_sate */, + null /* api_type */, + null /* api_timestamp */); int event = 0; if (state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__ENTER) { @@ -7942,7 +7950,9 @@ public final class ActiveServices { event = EventLogTags.AM_FOREGROUND_SERVICE_STOP; } else if (state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED) { event = EventLogTags.AM_FOREGROUND_SERVICE_DENIED; - } else { + } else if (state == FOREGROUND_SERVICE_STATE_CHANGED__STATE__TIMED_OUT) { + event = EventLogTags.AM_FOREGROUND_SERVICE_TIMED_OUT; + }else { // Unknown event. return; } diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index dbb351b23c85..bfc8251d97bb 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -441,17 +441,17 @@ class BroadcastProcessQueue { } public int getPreferredSchedulingGroupLocked() { - if (mCountForeground > mCountForegroundDeferred) { + if (!isActive()) { + return ProcessList.SCHED_GROUP_UNDEFINED; + } else if (mCountForeground > mCountForegroundDeferred) { // We have a foreground broadcast somewhere down the queue, so // boost priority until we drain them all return ProcessList.SCHED_GROUP_DEFAULT; } else if ((mActive != null) && mActive.isForeground()) { // We have a foreground broadcast right now, so boost priority return ProcessList.SCHED_GROUP_DEFAULT; - } else if (!isIdle()) { - return ProcessList.SCHED_GROUP_BACKGROUND; } else { - return ProcessList.SCHED_GROUP_UNDEFINED; + return ProcessList.SCHED_GROUP_BACKGROUND; } } diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 78edbba2e569..568997bb2667 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -178,6 +178,7 @@ public final class CachedAppOptimizer { private static final String ATRACE_FREEZER_TRACK = "Freezer"; private static final int FREEZE_BINDER_TIMEOUT_MS = 100; + private static final int FREEZE_DEADLOCK_TIMEOUT_MS = 1000; @VisibleForTesting static final boolean ENABLE_FILE_COMPACT = false; @@ -244,6 +245,7 @@ public final class CachedAppOptimizer { static final int REPORT_UNFREEZE_MSG = 4; static final int COMPACT_NATIVE_MSG = 5; static final int UID_FROZEN_STATE_CHANGED_MSG = 6; + static final int DEADLOCK_WATCHDOG_MSG = 7; // When free swap falls below this percentage threshold any full (file + anon) // compactions will be downgraded to file only compactions to reduce pressure @@ -1947,29 +1949,15 @@ public final class CachedAppOptimizer { public void handleMessage(Message msg) { switch (msg.what) { case SET_FROZEN_PROCESS_MSG: - { ProcessRecord proc = (ProcessRecord) msg.obj; - int pid = proc.getPid(); - final String name = proc.processName; synchronized (mAm) { freezeProcess(proc); } - try { - // post-check to prevent deadlock - mProcLocksReader.handleBlockingFileLocks(this); - } catch (Exception e) { - Slog.e(TAG_AM, "Unable to check file locks for " - + name + "(" + pid + "): " + e); - synchronized (mAm) { - synchronized (mProcLock) { - unfreezeAppLSP(proc, UNFREEZE_REASON_FILE_LOCK_CHECK_FAILURE); - } - } - } if (proc.mOptRecord.isFrozen()) { onProcessFrozen(proc); + removeMessages(DEADLOCK_WATCHDOG_MSG); + sendEmptyMessageDelayed(DEADLOCK_WATCHDOG_MSG, FREEZE_DEADLOCK_TIMEOUT_MS); } - } break; case REPORT_UNFREEZE_MSG: int pid = msg.arg1; @@ -1981,8 +1969,18 @@ public final class CachedAppOptimizer { reportUnfreeze(pid, frozenDuration, processName, reason); break; case UID_FROZEN_STATE_CHANGED_MSG: - ProcessRecord proc = (ProcessRecord) msg.obj; - reportOneUidFrozenStateChanged(proc.uid, true); + reportOneUidFrozenStateChanged(((ProcessRecord) msg.obj).uid, true); + break; + case DEADLOCK_WATCHDOG_MSG: + try { + // post-check to prevent deadlock + if (DEBUG_FREEZER) { + Slog.d(TAG_AM, "Freezer deadlock watchdog"); + } + mProcLocksReader.handleBlockingFileLocks(this); + } catch (IOException e) { + Slog.w(TAG_AM, "Unable to check file locks"); + } break; default: return; diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags index 81b242155bac..9e9db6aff699 100644 --- a/services/core/java/com/android/server/am/EventLogTags.logtags +++ b/services/core/java/com/android/server/am/EventLogTags.logtags @@ -121,10 +121,11 @@ option java_package com.android.server.am # Similarly, tags below are used by UserManagerService 30091 um_user_visibility_changed (userId|1|5),(visible|1) -# Foreground service start/stop events. +# Foreground service start/stop/denied/timed_out events. 30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3),(fgsType|1) 30101 am_foreground_service_denied (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3),(fgsType|1) 30102 am_foreground_service_stop (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3),(fgsType|1) +30103 am_foreground_service_timed_out (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3),(fgsType|1) # Intent Sender redirect for UserHandle.USER_CURRENT 30110 am_intent_sender_redirect_user (userId|1|5) diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java index 60a7f9371837..22e2c9fd889b 100644 --- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java +++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java @@ -83,6 +83,7 @@ public class SettingsToPropertiesMapper { DeviceConfig.NAMESPACE_CAMERA_NATIVE, DeviceConfig.NAMESPACE_CONFIGURATION, DeviceConfig.NAMESPACE_CONNECTIVITY, + DeviceConfig.NAMESPACE_EDGETPU_NATIVE, DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT, DeviceConfig.NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS, DeviceConfig.NAMESPACE_LMKD_NATIVE, diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java index 937e3f8f8668..bac44809883f 100644 --- a/services/core/java/com/android/server/biometrics/BiometricSensor.java +++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java @@ -22,14 +22,20 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricConstants; +import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; +import android.hardware.biometrics.SensorPropertiesInternal; import android.os.IBinder; import android.os.RemoteException; +import android.text.TextUtils; +import android.util.IndentingPrintWriter; import android.util.Slog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Collections; +import java.util.List; /** * Wraps IBiometricAuthenticator implementation and stores information about the authenticator, @@ -67,6 +73,7 @@ public abstract class BiometricSensor { public final int id; public final @Authenticators.Types int oemStrength; // strength as configured by the OEM public final int modality; + @NonNull public final List<ComponentInfoInternal> componentInfo; public final IBiometricAuthenticator impl; private @Authenticators.Types int mUpdatedStrength; // updated by BiometricStrengthController @@ -86,15 +93,16 @@ public abstract class BiometricSensor { */ abstract boolean confirmationSupported(); - BiometricSensor(@NonNull Context context, int id, int modality, - @Authenticators.Types int strength, IBiometricAuthenticator impl) { + BiometricSensor(@NonNull Context context, int modality, @NonNull SensorPropertiesInternal props, + IBiometricAuthenticator impl) { this.mContext = context; - this.id = id; + this.id = props.sensorId; this.modality = modality; - this.oemStrength = strength; + this.oemStrength = Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength); + this.componentInfo = Collections.unmodifiableList(props.componentInfo); this.impl = impl; - mUpdatedStrength = strength; + mUpdatedStrength = oemStrength; goToStateUnknown(); } @@ -178,8 +186,25 @@ public abstract class BiometricSensor { return "ID(" + id + ")" + ", oemStrength: " + oemStrength + ", updatedStrength: " + mUpdatedStrength - + ", modality " + modality + + ", modality: " + modality + ", state: " + mSensorState + ", cookie: " + mCookie; } + + protected void dump(@NonNull IndentingPrintWriter pw) { + pw.println(TextUtils.formatSimple("ID: %d", id)); + pw.increaseIndent(); + pw.println(TextUtils.formatSimple("oemStrength: %d", oemStrength)); + pw.println(TextUtils.formatSimple("updatedStrength: %d", mUpdatedStrength)); + pw.println(TextUtils.formatSimple("modality: %d", modality)); + pw.println("componentInfo:"); + for (ComponentInfoInternal info : componentInfo) { + pw.increaseIndent(); + info.dump(pw); + pw.decreaseIndent(); + } + pw.println(TextUtils.formatSimple("state: %d", mSensorState)); + pw.println(TextUtils.formatSimple("cookie: %d", mCookie)); + pw.decreaseIndent(); + } } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index ffa5d2055e92..f44d14bfa12c 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -62,6 +62,7 @@ import android.provider.Settings; import android.security.KeyStore; import android.text.TextUtils; import android.util.ArraySet; +import android.util.IndentingPrintWriter; import android.util.Pair; import android.util.Slog; import android.util.proto.ProtoOutputStream; @@ -638,13 +639,16 @@ public class BiometricService extends SystemService { @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL) @Override - public synchronized void registerAuthenticator(int id, int modality, - @Authenticators.Types int strength, + public synchronized void registerAuthenticator(int modality, + @NonNull SensorPropertiesInternal props, @NonNull IBiometricAuthenticator authenticator) { super.registerAuthenticator_enforcePermission(); - Slog.d(TAG, "Registering ID: " + id + @Authenticators.Types final int strength = + Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength); + + Slog.d(TAG, "Registering ID: " + props.sensorId + " Modality: " + modality + " Strength: " + strength); @@ -665,12 +669,12 @@ public class BiometricService extends SystemService { } for (BiometricSensor sensor : mSensors) { - if (sensor.id == id) { + if (sensor.id == props.sensorId) { throw new IllegalStateException("Cannot register duplicate authenticator"); } } - mSensors.add(new BiometricSensor(getContext(), id, modality, strength, authenticator) { + mSensors.add(new BiometricSensor(getContext(), modality, props, authenticator) { @Override boolean confirmationAlwaysRequired(int userId) { return mSettingObserver.getConfirmationAlwaysRequired(modality, userId); @@ -1360,13 +1364,17 @@ public class BiometricService extends SystemService { return null; } - private void dumpInternal(PrintWriter pw) { + private void dumpInternal(PrintWriter printWriter) { + IndentingPrintWriter pw = new IndentingPrintWriter(printWriter); + pw.println("Legacy Settings: " + mSettingObserver.mUseLegacyFaceOnlySettings); pw.println(); pw.println("Sensors:"); for (BiometricSensor sensor : mSensors) { - pw.println(" " + sensor); + pw.increaseIndent(); + sensor.dump(pw); + pw.decreaseIndent(); } pw.println(); pw.println("CurrentSession: " + mAuthSession); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java index 0f0a81d24473..d43045b4450f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceServiceRegistry.java @@ -20,7 +20,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import android.annotation.NonNull; import android.annotation.Nullable; -import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.IBiometricService; import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.face.IFaceAuthenticatorsRegisteredCallback; @@ -28,7 +27,6 @@ import android.hardware.face.IFaceService; import android.os.RemoteException; import android.util.Slog; -import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.BiometricServiceRegistry; import java.util.List; @@ -53,10 +51,8 @@ public class FaceServiceRegistry extends BiometricServiceRegistry<ServiceProvide @Override protected void registerService(@NonNull IBiometricService service, @NonNull FaceSensorPropertiesInternal props) { - @BiometricManager.Authenticators.Types final int strength = - Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength); try { - service.registerAuthenticator(props.sensorId, TYPE_FACE, strength, + service.registerAuthenticator(TYPE_FACE, props, new FaceAuthenticator(mService, props.sensorId)); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java index 33810b764f23..6d210eac542b 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistry.java @@ -20,7 +20,6 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN import android.annotation.NonNull; import android.annotation.Nullable; -import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.IBiometricService; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; @@ -28,7 +27,6 @@ import android.hardware.fingerprint.IFingerprintService; import android.os.RemoteException; import android.util.Slog; -import com.android.server.biometrics.Utils; import com.android.server.biometrics.sensors.BiometricServiceRegistry; import java.util.List; @@ -53,10 +51,8 @@ public class FingerprintServiceRegistry extends BiometricServiceRegistry<Service @Override protected void registerService(@NonNull IBiometricService service, @NonNull FingerprintSensorPropertiesInternal props) { - @BiometricManager.Authenticators.Types final int strength = - Utils.propertyStrengthToAuthenticatorStrength(props.sensorStrength); try { - service.registerAuthenticator(props.sensorId, TYPE_FINGERPRINT, strength, + service.registerAuthenticator(TYPE_FINGERPRINT, props, new FingerprintAuthenticator(mService, props.sensorId)); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when registering sensorId: " + props.sensorId); diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java index 35ea36c5d56f..f27761fd644c 100644 --- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java +++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java @@ -16,12 +16,10 @@ package com.android.server.biometrics.sensors.iris; -import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_IRIS; import android.annotation.NonNull; import android.content.Context; -import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.iris.IIrisService; @@ -33,7 +31,6 @@ import android.util.Slog; import com.android.server.ServiceThread; import com.android.server.SystemService; -import com.android.server.biometrics.Utils; import java.util.List; @@ -75,17 +72,12 @@ public class IrisService extends SystemService { ServiceManager.getService(Context.BIOMETRIC_SERVICE)); for (SensorPropertiesInternal hidlSensor : hidlSensors) { - final int sensorId = hidlSensor.sensorId; - final @BiometricManager.Authenticators.Types int strength = - Utils.propertyStrengthToAuthenticatorStrength( - hidlSensor.sensorStrength); - final IrisAuthenticator authenticator = new IrisAuthenticator(mServiceWrapper, - sensorId); try { - biometricService.registerAuthenticator(sensorId, TYPE_IRIS, strength, - authenticator); + biometricService.registerAuthenticator(TYPE_IRIS, hidlSensor, + new IrisAuthenticator(mServiceWrapper, hidlSensor.sensorId)); } catch (RemoteException e) { - Slog.e(TAG, "Remote exception when registering sensorId: " + sensorId); + Slog.e(TAG, "Remote exception when registering sensorId: " + + hidlSensor.sensorId); } } }); diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 0da94ff6aa0f..ee4a6fea8ad4 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -1516,11 +1516,6 @@ public class LockSettingsService extends ILockSettings.Stub { && !getSeparateProfileChallengeEnabledInternal(userId); } - private boolean isProfileWithSeparatedLock(int userId) { - return isCredentialSharableWithParent(userId) - && getSeparateProfileChallengeEnabledInternal(userId); - } - /** * Send credentials for user {@code userId} to {@link RecoverableKeyStoreManager} during an * unlock operation. @@ -2784,9 +2779,19 @@ public class LockSettingsService extends ILockSettings.Stub { activateEscrowTokens(sp, userId); - if (isProfileWithSeparatedLock(userId)) { - setDeviceUnlockedForUser(userId); + if (isCredentialSharableWithParent(userId)) { + if (getSeparateProfileChallengeEnabledInternal(userId)) { + setDeviceUnlockedForUser(userId); + } else { + // Here only clear StrongAuthFlags for a profile that has a unified challenge. + // StrongAuth for a profile with a separate challenge is handled differently and + // is cleared after the user successfully confirms the separate challenge to enter + // the profile. StrongAuth for the full user (e.g. userId 0) is also handled + // separately by Keyguard. + mStrongAuth.reportUnlock(userId); + } } + mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); onSyntheticPasswordUnlocked(userId, sp); diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java index 93233dd4bda8..ff1deaf415b3 100644 --- a/services/core/java/com/android/server/wm/LetterboxUiController.java +++ b/services/core/java/com/android/server/wm/LetterboxUiController.java @@ -1597,11 +1597,10 @@ final class LetterboxUiController { inheritConfiguration(firstOpaqueActivityBeneath); mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation( mActivityRecord, firstOpaqueActivityBeneath, - (opaqueConfig, transparentConfig) -> { - final Configuration mutatedConfiguration = - fromOriginalTranslucentConfig(transparentConfig); + (opaqueConfig, transparentOverrideConfig) -> { + resetTranslucentOverrideConfig(transparentOverrideConfig); final Rect parentBounds = parent.getWindowConfiguration().getBounds(); - final Rect bounds = mutatedConfiguration.windowConfiguration.getBounds(); + final Rect bounds = transparentOverrideConfig.windowConfiguration.getBounds(); final Rect letterboxBounds = opaqueConfig.windowConfiguration.getBounds(); // We cannot use letterboxBounds directly here because the position relies on // letterboxing. Using letterboxBounds directly, would produce a double offset. @@ -1610,9 +1609,9 @@ final class LetterboxUiController { parentBounds.top + letterboxBounds.height()); // We need to initialize appBounds to avoid NPE. The actual value will // be set ahead when resolving the Configuration for the activity. - mutatedConfiguration.windowConfiguration.setAppBounds(new Rect()); + transparentOverrideConfig.windowConfiguration.setAppBounds(new Rect()); inheritConfiguration(firstOpaqueActivityBeneath); - return mutatedConfiguration; + return transparentOverrideConfig; }); } @@ -1691,20 +1690,16 @@ final class LetterboxUiController { true /* traverseTopToBottom */)); } - // When overriding translucent activities configuration we need to keep some of the - // original properties - private Configuration fromOriginalTranslucentConfig(Configuration translucentConfig) { - final Configuration configuration = new Configuration(translucentConfig); + /** Resets the screen size related fields so they can be resolved by requested bounds later. */ + private static void resetTranslucentOverrideConfig(Configuration config) { // The values for the following properties will be defined during the configuration // resolution in {@link ActivityRecord#resolveOverrideConfiguration} using the // properties inherited from the first not finishing opaque activity beneath. - configuration.orientation = ORIENTATION_UNDEFINED; - configuration.screenWidthDp = configuration.compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED; - configuration.screenHeightDp = - configuration.compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED; - configuration.smallestScreenWidthDp = - configuration.compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; - return configuration; + config.orientation = ORIENTATION_UNDEFINED; + config.screenWidthDp = config.compatScreenWidthDp = SCREEN_WIDTH_DP_UNDEFINED; + config.screenHeightDp = config.compatScreenHeightDp = SCREEN_HEIGHT_DP_UNDEFINED; + config.smallestScreenWidthDp = config.compatSmallestScreenWidthDp = + SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; } private void inheritConfiguration(ActivityRecord firstOpaque) { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index 41176410a789..cf6efd28acb7 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -4047,7 +4047,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< final Configuration mergedConfiguration = configurationMerger != null ? configurationMerger.merge(mergedOverrideConfig, - receiver.getConfiguration()) + receiver.getRequestedOverrideConfiguration()) : supplier.getConfiguration(); receiver.onRequestedOverrideConfigurationChanged(mergedConfiguration); } diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java index 9320dd247380..06b96eb46ac1 100644 --- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java +++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java @@ -796,7 +796,7 @@ public final class CredentialManagerService return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_CREDENTIAL, DEVICE_CONFIG_ENABLE_CREDENTIAL_MANAGER, - false); + true); } finally { Binder.restoreCallingIdentity(origId); } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 318067ee8681..8211d6fc03a2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -406,7 +406,7 @@ public final class BroadcastQueueModernImplTest { assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason()); - assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked()); + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); } /** @@ -434,13 +434,13 @@ public final class BroadcastQueueModernImplTest { queue.setProcessAndUidCached(null, false); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); - assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); queue.setProcessAndUidCached(null, true); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); - assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); } @@ -1154,6 +1154,41 @@ public final class BroadcastQueueModernImplTest { times(1)); } + @Test + public void testGetPreferredSchedulingGroup() throws Exception { + final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, + PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); + + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); + + final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK) + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(timeTick, + List.of(makeMockRegisteredReceiver())), 0, false); + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); + + // Make the foreground broadcast as active. + queue.makeActiveNextPending(); + assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); + + queue.makeActiveIdle(); + assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); + + final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(airplane, + List.of(makeMockRegisteredReceiver())), 0, false); + + // Make the background broadcast as active. + queue.makeActiveNextPending(); + assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked()); + + queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(timeTick, + List.of(makeMockRegisteredReceiver())), 0, false); + // Even though the active broadcast is not a foreground one, scheduling group will be + // DEFAULT since there is a foreground broadcast waiting to be delivered. + assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); + } + private Intent createPackageChangedIntent(int uid, List<String> componentNameList) { final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED); packageChangedIntent.putExtra(Intent.EXTRA_UID, uid); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java index 6216c66aa54f..4b86dd048cd1 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java @@ -152,8 +152,7 @@ public class AuthServiceTest { verify(mBiometricService, never()).registerAuthenticator( anyInt(), - anyInt(), - anyInt(), + any(), any()); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java index 4cdca268fc4b..dbf5021d3c6b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java @@ -44,13 +44,14 @@ import android.app.admin.DevicePolicyManager; import android.app.trust.ITrustManager; import android.content.Context; import android.hardware.biometrics.BiometricManager.Authenticators; -import android.hardware.biometrics.ComponentInfoInternal; import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorProperties; +import android.hardware.face.FaceSensorProperties; +import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Binder; @@ -458,9 +459,16 @@ public class AuthSessionTest { IBiometricAuthenticator fingerprintAuthenticator = mock(IBiometricAuthenticator.class); when(fingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); when(fingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - mSensors.add(new BiometricSensor(mContext, id, + + final FingerprintSensorPropertiesInternal props = new FingerprintSensorPropertiesInternal( + id, SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, type, + false /* resetLockoutRequiresHardwareAuthToken */); + mFingerprintSensorProps.add(props); + + mSensors.add(new BiometricSensor(mContext, TYPE_FINGERPRINT /* modality */, - Authenticators.BIOMETRIC_STRONG /* strength */, + props, fingerprintAuthenticator) { @Override boolean confirmationAlwaysRequired(int userId) { @@ -473,21 +481,6 @@ public class AuthSessionTest { } }); - final List<ComponentInfoInternal> componentInfo = new ArrayList<>(); - componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */, - "vendor/model/revision" /* hardwareVersion */, "1.01" /* firmwareVersion */, - "00000001" /* serialNumber */, "" /* softwareVersion */)); - componentInfo.add(new ComponentInfoInternal("matchingAlgorithm" /* componentId */, - "" /* hardwareVersion */, "" /* firmwareVersion */, "" /* serialNumber */, - "vendor/version/revision" /* softwareVersion */)); - - mFingerprintSensorProps.add(new FingerprintSensorPropertiesInternal(id, - SensorProperties.STRENGTH_STRONG, - 5 /* maxEnrollmentsPerUser */, - componentInfo, - type, - false /* resetLockoutRequiresHardwareAuthToken */)); - when(mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true); } @@ -495,9 +488,13 @@ public class AuthSessionTest { IBiometricAuthenticator authenticator) throws RemoteException { when(authenticator.isHardwareDetected(any())).thenReturn(true); when(authenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - mSensors.add(new BiometricSensor(mContext, id, + mSensors.add(new BiometricSensor(mContext, TYPE_FACE /* modality */, - Authenticators.BIOMETRIC_STRONG /* strength */, + new FaceSensorPropertiesInternal(id, + SensorProperties.STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, FaceSensorProperties.TYPE_UNKNOWN, + true /* supportsFace Detection */, true /* supportsSelfIllumination */, + false /* resetLockoutRequiresHardwareAuthToken */), authenticator) { @Override boolean confirmationAlwaysRequired(int userId) { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java index 168642e3533f..b51a8c4e1b6c 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java @@ -19,6 +19,7 @@ package com.android.server.biometrics; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT; +import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI; @@ -66,7 +67,11 @@ import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.PromptInfo; import android.hardware.display.DisplayManagerGlobal; +import android.hardware.face.FaceSensorProperties; +import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintManager; +import android.hardware.fingerprint.FingerprintSensorProperties; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; @@ -93,6 +98,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.List; import java.util.Random; @Presubmit @@ -114,6 +120,7 @@ public class BiometricServiceTest { private static final int SENSOR_ID_FINGERPRINT = 0; private static final int SENSOR_ID_FACE = 1; + private FingerprintSensorPropertiesInternal mFingerprintProps; private BiometricService mBiometricService; @@ -193,6 +200,11 @@ public class BiometricServiceTest { }; when(mInjector.getConfiguration(any())).thenReturn(config); + + mFingerprintProps = new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT, + STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UNKNOWN, + false /* resetLockoutRequiresHardwareAuthToken */); } @Test @@ -328,8 +340,7 @@ public class BiometricServiceTest { mBiometricService = new BiometricService(mContext, mInjector); mBiometricService.onStart(); - mBiometricService.mImpl.registerAuthenticator(0 /* id */, - TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps, mFingerprintAuthenticator); invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */, @@ -401,8 +412,7 @@ public class BiometricServiceTest { mBiometricService = new BiometricService(mContext, mInjector); mBiometricService.onStart(); - mBiometricService.mImpl.registerAuthenticator(0 /* id */, - TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps, mFingerprintAuthenticator); invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */, @@ -1334,9 +1344,13 @@ public class BiometricServiceTest { for (int i = 0; i < testCases.length; i++) { final BiometricSensor sensor = - new BiometricSensor(mContext, 0 /* id */, + new BiometricSensor(mContext, TYPE_FINGERPRINT, - testCases[i][0], + new FingerprintSensorPropertiesInternal(i /* id */, + Utils.authenticatorStrengthToPropertyStrength(testCases[i][0]), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UNKNOWN, + false /* resetLockoutRequiresHardwareAuthToken */), mock(IBiometricAuthenticator.class)) { @Override boolean confirmationAlwaysRequired(int userId) { @@ -1364,8 +1378,7 @@ public class BiometricServiceTest { when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())) .thenReturn(true); when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); - mBiometricService.mImpl.registerAuthenticator(0 /* testId */, - TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps, mFingerprintAuthenticator); verify(mBiometricService.mBiometricStrengthController).updateStrengths(); @@ -1376,15 +1389,14 @@ public class BiometricServiceTest { mBiometricService = new BiometricService(mContext, mInjector); mBiometricService.onStart(); - final int testId = 0; - when(mBiometricService.mSettingObserver.getEnabledForApps(anyInt())).thenReturn(true); when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())) .thenReturn(true); when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); - mBiometricService.mImpl.registerAuthenticator(testId /* id */, - TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + + final int testId = SENSOR_ID_FINGERPRINT; + mBiometricService.mImpl.registerAuthenticator(TYPE_FINGERPRINT, mFingerprintProps, mFingerprintAuthenticator); // Downgrade the authenticator @@ -1484,11 +1496,9 @@ public class BiometricServiceTest { mBiometricService.onStart(); mBiometricService.mImpl.registerAuthenticator( - 0 /* id */, 2 /* modality */, 15 /* strength */, - mFingerprintAuthenticator); + 2 /* modality */, mFingerprintProps, mFingerprintAuthenticator); mBiometricService.mImpl.registerAuthenticator( - 0 /* id */, 2 /* modality */, 15 /* strength */, - mFingerprintAuthenticator); + 2 /* modality */, mFingerprintProps, mFingerprintAuthenticator); } @Test(expected = IllegalArgumentException.class) @@ -1498,9 +1508,7 @@ public class BiometricServiceTest { mBiometricService.onStart(); mBiometricService.mImpl.registerAuthenticator( - 0 /* id */, 2 /* modality */, - Authenticators.BIOMETRIC_STRONG /* strength */, - null /* authenticator */); + 2 /* modality */, mFingerprintProps, null /* authenticator */); } @Test @@ -1511,8 +1519,13 @@ public class BiometricServiceTest { for (String s : mInjector.getConfiguration(null)) { SensorConfig config = new SensorConfig(s); - mBiometricService.mImpl.registerAuthenticator(config.id, config.modality, - config.strength, mFingerprintAuthenticator); + mBiometricService.mImpl.registerAuthenticator(config.modality, + new FingerprintSensorPropertiesInternal(config.id, + Utils.authenticatorStrengthToPropertyStrength(config.strength), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UNKNOWN, + false /* resetLockoutRequiresHardwareAuthToken */), + mFingerprintAuthenticator); } } @@ -1609,7 +1622,12 @@ public class BiometricServiceTest { when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); when(mFingerprintAuthenticator.getLockoutModeForUser(anyInt())) .thenReturn(LockoutTracker.LOCKOUT_NONE); - mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality, strength, + mBiometricService.mImpl.registerAuthenticator(modality, + new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT, + Utils.authenticatorStrengthToPropertyStrength(strength), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UNKNOWN, + false /* resetLockoutRequiresHardwareAuthToken */), mFingerprintAuthenticator); } @@ -1618,7 +1636,13 @@ public class BiometricServiceTest { when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true); when(mFaceAuthenticator.getLockoutModeForUser(anyInt())) .thenReturn(LockoutTracker.LOCKOUT_NONE); - mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality, strength, + mBiometricService.mImpl.registerAuthenticator(modality, + new FaceSensorPropertiesInternal(SENSOR_ID_FACE, + Utils.authenticatorStrengthToPropertyStrength(strength), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FaceSensorProperties.TYPE_UNKNOWN, true /* supportsFace Detection */, + true /* supportsSelfIllumination */, + false /* resetLockoutRequiresHardwareAuthToken */), mFaceAuthenticator); } } @@ -1641,15 +1665,27 @@ public class BiometricServiceTest { when(mFingerprintAuthenticator.hasEnrolledTemplates(anyInt(), any())) .thenReturn(true); when(mFingerprintAuthenticator.isHardwareDetected(any())).thenReturn(true); - mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FINGERPRINT, modality, - strength, mFingerprintAuthenticator); + mBiometricService.mImpl.registerAuthenticator(modality, + new FingerprintSensorPropertiesInternal(SENSOR_ID_FINGERPRINT, + Utils.authenticatorStrengthToPropertyStrength(strength), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UNKNOWN, + false /* resetLockoutRequiresHardwareAuthToken */), + mFingerprintAuthenticator); } if ((modality & BiometricAuthenticator.TYPE_FACE) != 0) { when(mFaceAuthenticator.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); when(mFaceAuthenticator.isHardwareDetected(any())).thenReturn(true); - mBiometricService.mImpl.registerAuthenticator(SENSOR_ID_FACE, modality, - strength, mFaceAuthenticator); + mBiometricService.mImpl.registerAuthenticator(modality, + new FaceSensorPropertiesInternal(SENSOR_ID_FACE, + Utils.authenticatorStrengthToPropertyStrength(strength), + 5 /* maxEnrollmentsPerUser */, List.of() /* componentInfo */, + FaceSensorProperties.TYPE_UNKNOWN, + true /* supportsFace Detection */, + true /* supportsSelfIllumination */, + false /* resetLockoutRequiresHardwareAuthToken */), + mFaceAuthenticator); } } } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java index ee5ab92065ee..f7539bd27c9d 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java @@ -16,6 +16,9 @@ package com.android.server.biometrics; +import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; +import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -27,9 +30,13 @@ import static org.mockito.Mockito.when; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.BiometricAuthenticator; -import android.hardware.biometrics.BiometricManager.Authenticators; import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IInvalidationCallback; +import android.hardware.biometrics.SensorPropertiesInternal; +import android.hardware.face.FaceSensorProperties; +import android.hardware.face.FaceSensorPropertiesInternal; +import android.hardware.fingerprint.FingerprintSensorProperties; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; @@ -42,6 +49,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; +import java.util.List; @Presubmit @SmallTest @@ -59,26 +67,54 @@ public class InvalidationTrackerTest { public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception { final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class); when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - final TestSensor sensor1 = new TestSensor(mContext, 0 /* id */, - BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + final TestSensor sensor1 = new TestSensor(mContext, + BiometricAuthenticator.TYPE_FINGERPRINT, + new FingerprintSensorPropertiesInternal(0 /* id */, + STRENGTH_STRONG, + 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, + false /* resetLockoutRequiresHardwareAuthToken */), authenticator1); final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class); when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - final TestSensor sensor2 = new TestSensor(mContext, 1 /* id */, - BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG, + final TestSensor sensor2 = new TestSensor(mContext, + BiometricAuthenticator.TYPE_FINGERPRINT, + new FingerprintSensorPropertiesInternal(1 /* id */, + STRENGTH_STRONG, + 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, + FingerprintSensorProperties.TYPE_REAR, + false /* resetLockoutRequiresHardwareAuthToken */), authenticator2); final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class); when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - final TestSensor sensor3 = new TestSensor(mContext, 2 /* id */, - BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG, + final TestSensor sensor3 = new TestSensor(mContext, + BiometricAuthenticator.TYPE_FACE, + new FaceSensorPropertiesInternal(2 /* id */, + STRENGTH_STRONG, + 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, + FaceSensorProperties.TYPE_RGB, + true /* supportsFace Detection */, + true /* supportsSelfIllumination */, + false /* resetLockoutRequiresHardwareAuthToken */), authenticator3); final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class); when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true); - final TestSensor sensor4 = new TestSensor(mContext, 3 /* id */, - BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK, + final TestSensor sensor4 = new TestSensor(mContext, + BiometricAuthenticator.TYPE_FACE, + new FaceSensorPropertiesInternal(3 /* id */, + STRENGTH_WEAK, + 5 /* maxEnrollmentsPerUser */, + List.of() /* componentInfo */, + FaceSensorProperties.TYPE_IR, + true /* supportsFace Detection */, + true /* supportsSelfIllumination */, + false /* resetLockoutRequiresHardwareAuthToken */), authenticator4); final ArrayList<BiometricSensor> sensors = new ArrayList<>(); @@ -113,9 +149,9 @@ public class InvalidationTrackerTest { private static class TestSensor extends BiometricSensor { - TestSensor(@NonNull Context context, int id, int modality, int strength, + TestSensor(@NonNull Context context, int modality, @NonNull SensorPropertiesInternal props, @NonNull IBiometricAuthenticator impl) { - super(context, id, modality, strength, impl); + super(context, modality, props, impl); } @Override diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java index 903ed9082481..d3f04dfcfa17 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceRegistryTest.java @@ -17,8 +17,6 @@ package com.android.server.biometrics.sensors.face; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; -import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK; import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK; @@ -70,9 +68,7 @@ public class FaceServiceRegistryTest { @Mock private ServiceProvider mProvider2; @Captor - private ArgumentCaptor<Integer> mIdCaptor; - @Captor - private ArgumentCaptor<Integer> mStrengthCaptor; + private ArgumentCaptor<FaceSensorPropertiesInternal> mPropsCaptor; private FaceSensorPropertiesInternal mProvider1Props; private FaceSensorPropertiesInternal mProvider2Props; @@ -82,13 +78,13 @@ public class FaceServiceRegistryTest { public void setup() { mProvider1Props = new FaceSensorPropertiesInternal(SENSOR_ID_1, STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */, - List.of(), FaceSensorProperties.TYPE_RGB, + List.of() /* componentInfo */, FaceSensorProperties.TYPE_RGB, true /* supportsFace Detection */, true /* supportsSelfIllumination */, false /* resetLockoutRequiresHardwareAuthToken */); mProvider2Props = new FaceSensorPropertiesInternal(SENSOR_ID_2, STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, - List.of(), FaceSensorProperties.TYPE_IR, + List.of() /* componentInfo */, FaceSensorProperties.TYPE_IR, true /* supportsFace Detection */, true /* supportsSelfIllumination */, false /* resetLockoutRequiresHardwareAuthToken */); @@ -107,10 +103,9 @@ public class FaceServiceRegistryTest { assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2); assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props); verify(mBiometricService, times(2)).registerAuthenticator( - mIdCaptor.capture(), eq(TYPE_FACE), mStrengthCaptor.capture(), any()); - assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2); - assertThat(mStrengthCaptor.getAllValues()) - .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG); + eq(TYPE_FACE), mPropsCaptor.capture(), any()); + assertThat(mPropsCaptor.getAllValues()) + .containsExactly(mProvider1Props, mProvider2Props); } @Test diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java index 13c3f64fec93..6e09069e654b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceRegistryTest.java @@ -17,8 +17,6 @@ package com.android.server.biometrics.sensors.fingerprint; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; -import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static android.hardware.biometrics.BiometricManager.Authenticators.BIOMETRIC_WEAK; import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG; import static android.hardware.biometrics.SensorProperties.STRENGTH_WEAK; @@ -70,9 +68,7 @@ public class FingerprintServiceRegistryTest { @Mock private ServiceProvider mProvider2; @Captor - private ArgumentCaptor<Integer> mIdCaptor; - @Captor - private ArgumentCaptor<Integer> mStrengthCaptor; + private ArgumentCaptor<FingerprintSensorPropertiesInternal> mPropsCaptor; private FingerprintSensorPropertiesInternal mProvider1Props; private FingerprintSensorPropertiesInternal mProvider2Props; @@ -82,11 +78,11 @@ public class FingerprintServiceRegistryTest { public void setup() { mProvider1Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_1, STRENGTH_WEAK, 5 /* maxEnrollmentsPerUser */, - List.of(), FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, + List.of() /* componentInfo */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL, false /* resetLockoutRequiresHardwareAuthToken */); mProvider2Props = new FingerprintSensorPropertiesInternal(SENSOR_ID_2, STRENGTH_STRONG, 5 /* maxEnrollmentsPerUser */, - List.of(), FingerprintSensorProperties.TYPE_UNKNOWN, + List.of() /* componentInfo */, FingerprintSensorProperties.TYPE_UNKNOWN, false /* resetLockoutRequiresHardwareAuthToken */); when(mProvider1.getSensorProperties()).thenReturn(List.of(mProvider1Props)); @@ -103,10 +99,9 @@ public class FingerprintServiceRegistryTest { assertThat(mRegistry.getProviders()).containsExactly(mProvider1, mProvider2); assertThat(mRegistry.getAllProperties()).containsExactly(mProvider1Props, mProvider2Props); verify(mBiometricService, times(2)).registerAuthenticator( - mIdCaptor.capture(), eq(TYPE_FINGERPRINT), mStrengthCaptor.capture(), any()); - assertThat(mIdCaptor.getAllValues()).containsExactly(SENSOR_ID_1, SENSOR_ID_2); - assertThat(mStrengthCaptor.getAllValues()) - .containsExactly(BIOMETRIC_WEAK, BIOMETRIC_STRONG); + eq(TYPE_FINGERPRINT), mPropsCaptor.capture(), any()); + assertThat(mPropsCaptor.getAllValues()) + .containsExactly(mProvider1Props, mProvider2Props); } @Test diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java index 25a700a5275f..1089c07e6787 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java @@ -110,15 +110,17 @@ public class FingerprintServiceTest { private final FingerprintSensorPropertiesInternal mSensorPropsDefault = new FingerprintSensorPropertiesInternal(ID_DEFAULT, STRENGTH_STRONG, 2 /* maxEnrollmentsPerUser */, - List.of(), + List.of() /* componentInfo */, TYPE_REAR, false /* resetLockoutRequiresHardwareAuthToken */); private final FingerprintSensorPropertiesInternal mSensorPropsVirtual = new FingerprintSensorPropertiesInternal(ID_VIRTUAL, STRENGTH_STRONG, 2 /* maxEnrollmentsPerUser */, - List.of(), + List.of() /* componentInfo */, TYPE_UDFPS_OPTICAL, false /* resetLockoutRequiresHardwareAuthToken */); + @Captor + private ArgumentCaptor<FingerprintSensorPropertiesInternal> mPropsCaptor; private FingerprintService mService; @Before @@ -166,7 +168,8 @@ public class FingerprintServiceTest { mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS); waitForRegistration(); - verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any()); + verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any()); + assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsDefault); } @Test @@ -178,7 +181,8 @@ public class FingerprintServiceTest { mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS); waitForRegistration(); - verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any()); + verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any()); + assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsVirtual); } @Test @@ -188,7 +192,8 @@ public class FingerprintServiceTest { mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS); waitForRegistration(); - verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any()); + verify(mIBiometricService).registerAuthenticator(anyInt(), mPropsCaptor.capture(), any()); + assertThat(mPropsCaptor.getAllValues()).containsExactly(mSensorPropsVirtual); } private void waitForRegistration() throws Exception { diff --git a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java index 82bc6f6c5263..06fc01738967 100644 --- a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java +++ b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java @@ -87,6 +87,7 @@ public class UiServiceTestCase { Mockito.doReturn(new Intent()).when(mContext).registerReceiverAsUser( any(), any(), any(), any(), any()); Mockito.doReturn(new Intent()).when(mContext).registerReceiver(any(), any()); + Mockito.doReturn(new Intent()).when(mContext).registerReceiver(any(), any(), anyInt()); Mockito.doNothing().when(mContext).unregisterReceiver(any()); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java index b1a9f081253c..34bb664c9598 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java @@ -96,8 +96,6 @@ public class RoleObserverTest extends UiServiceTestCase { private TestableNotificationManagerService mService; private NotificationManagerService.RoleObserver mRoleObserver; - private TestableContext mContext = spy(getContext()); - @Mock private PreferencesHelper mPreferencesHelper; @Mock diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index e96d1abf9ced..de943d240084 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -17,6 +17,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; +import static android.app.WindowConfiguration.ROTATION_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; @@ -428,20 +429,24 @@ public class SizeCompatTests extends WindowTestsBase { .setLaunchedFromUid(mActivity.getUid()) .build(); doReturn(false).when(translucentActivity).fillsParent(); - WindowConfiguration translucentWinConf = translucentActivity.getWindowConfiguration(); - translucentActivity.setActivityType(ACTIVITY_TYPE_STANDARD); - translucentActivity.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - translucentActivity.setDisplayWindowingMode(WINDOWING_MODE_MULTI_WINDOW); - translucentActivity.setAlwaysOnTop(true); + final Configuration requestedConfig = + translucentActivity.getRequestedOverrideConfiguration(); + final WindowConfiguration translucentWinConf = requestedConfig.windowConfiguration; + translucentWinConf.setActivityType(ACTIVITY_TYPE_STANDARD); + translucentWinConf.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + translucentWinConf.setDisplayWindowingMode(WINDOWING_MODE_MULTI_WINDOW); + translucentWinConf.setAlwaysOnTop(true); + translucentActivity.onRequestedOverrideConfigurationChanged(requestedConfig); mTask.addChild(translucentActivity); - // We check the WIndowConfiguration properties - translucentWinConf = translucentActivity.getWindowConfiguration(); + // The original override of WindowConfiguration should keep. assertEquals(ACTIVITY_TYPE_STANDARD, translucentActivity.getActivityType()); assertEquals(WINDOWING_MODE_MULTI_WINDOW, translucentWinConf.getWindowingMode()); assertEquals(WINDOWING_MODE_MULTI_WINDOW, translucentWinConf.getDisplayWindowingMode()); assertTrue(translucentWinConf.isAlwaysOnTop()); + // Unless display is going to be rotated, it should always inherit from parent. + assertEquals(ROTATION_UNDEFINED, translucentWinConf.getDisplayRotation()); } @Test |