Merge "Revert "Track update count of IMMS#mMethodMap"" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 244cad0..bbb3932 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -34055,6 +34055,7 @@
field public static final String DISALLOW_BLUETOOTH_SHARING = "no_bluetooth_sharing";
field public static final String DISALLOW_CAMERA_TOGGLE = "disallow_camera_toggle";
field public static final String DISALLOW_CELLULAR_2G = "no_cellular_2g";
+ field @FlaggedApi("android.nfc.enable_nfc_user_restriction") public static final String DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO = "no_change_near_field_communication_radio";
field public static final String DISALLOW_CHANGE_WIFI_STATE = "no_change_wifi_state";
field public static final String DISALLOW_CONFIG_BLUETOOTH = "no_config_bluetooth";
field public static final String DISALLOW_CONFIG_BRIGHTNESS = "no_config_brightness";
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 2d78317..73ac263 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -199,3 +199,11 @@
description: "redacts notifications on the lockscreen if they have the 'sensitiveContent' flag"
bug: "343631648"
}
+
+flag {
+ name: "api_rich_ongoing"
+ is_exported: true
+ namespace: "systemui"
+ description: "Guards new android.app.richongoingnotification api"
+ bug: "337261753"
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/location/ISignificantPlaceProvider.aidl b/core/java/android/hardware/location/ISignificantPlaceProvider.aidl
index e02169e..992dbff 100644
--- a/core/java/android/hardware/location/ISignificantPlaceProvider.aidl
+++ b/core/java/android/hardware/location/ISignificantPlaceProvider.aidl
@@ -7,4 +7,5 @@
*/
oneway interface ISignificantPlaceProvider {
void setSignificantPlaceProviderManager(in ISignificantPlaceProviderManager manager);
+ void onSignificantPlaceCheck();
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index fdce476..20522fa 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1907,6 +1907,31 @@
"no_near_field_communication_radio";
/**
+ * This user restriction specifies if Near-field communication is disallowed to change
+ * on the device. If Near-field communication is disallowed it cannot be changed via Settings.
+ *
+ * <p>This restriction can only be set by a device owner or a profile owner of an
+ * organization-owned managed profile on the parent profile.
+ * In both cases, the restriction applies globally on the device and will not allow Near-field
+ * communication state being changed.
+ *
+ * <p>
+ * Near-field communication (NFC) is a radio technology that allows two devices (like your phone
+ * and a payments terminal) to communicate with each other when they're close together.
+ *
+ * <p>Default is <code>false</code>.
+ *
+ * <p>Key for user restrictions.
+ * <p>Type: Boolean
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ */
+ @FlaggedApi(Flags.FLAG_ENABLE_NFC_USER_RESTRICTION)
+ public static final String DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO =
+ "no_change_near_field_communication_radio";
+
+ /**
* This user restriction specifies if Thread network is disallowed on the device. If Thread
* network is disallowed it cannot be turned on via Settings.
*
@@ -2007,6 +2032,7 @@
DISALLOW_CAMERA,
DISALLOW_CAMERA_TOGGLE,
DISALLOW_CELLULAR_2G,
+ DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO,
DISALLOW_CHANGE_WIFI_STATE,
DISALLOW_CONFIG_BLUETOOTH,
DISALLOW_CONFIG_BRIGHTNESS,
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
index 4f9b269..4c3d4e3 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
@@ -16,8 +16,6 @@
package android.hardware.radio;
-import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -36,6 +34,8 @@
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArrayMap;
+import com.google.common.truth.Expect;
+
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -155,6 +155,9 @@
private RadioManager mRadioManager;
private final ApplicationInfo mApplicationInfo = new ApplicationInfo();
+ @Rule
+ public final Expect mExpect = Expect.create();
+
@Mock
private IRadioService mRadioServiceMock;
@Mock
@@ -175,7 +178,7 @@
() -> new RadioManager.AmBandDescriptor(REGION, /* type= */ 100, AM_LOWER_LIMIT,
AM_UPPER_LIMIT, AM_SPACING, STEREO_SUPPORTED));
- assertWithMessage("Unsupported band type exception")
+ mExpect.withMessage("Unsupported band type exception")
.that(thrown).hasMessageThat().contains("Unsupported band");
}
@@ -183,7 +186,7 @@
public void getType_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createAmBandDescriptor();
- assertWithMessage("AM Band Descriptor type")
+ mExpect.withMessage("AM Band Descriptor type")
.that(bandDescriptor.getType()).isEqualTo(RadioManager.BAND_AM);
}
@@ -191,7 +194,7 @@
public void getRegion_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createFmBandDescriptor();
- assertWithMessage("FM Band Descriptor region")
+ mExpect.withMessage("FM Band Descriptor region")
.that(bandDescriptor.getRegion()).isEqualTo(REGION);
}
@@ -199,7 +202,7 @@
public void getLowerLimit_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createFmBandDescriptor();
- assertWithMessage("FM Band Descriptor lower limit")
+ mExpect.withMessage("FM Band Descriptor lower limit")
.that(bandDescriptor.getLowerLimit()).isEqualTo(FM_LOWER_LIMIT);
}
@@ -207,7 +210,7 @@
public void getUpperLimit_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createAmBandDescriptor();
- assertWithMessage("AM Band Descriptor upper limit")
+ mExpect.withMessage("AM Band Descriptor upper limit")
.that(bandDescriptor.getUpperLimit()).isEqualTo(AM_UPPER_LIMIT);
}
@@ -215,7 +218,7 @@
public void getSpacing_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createAmBandDescriptor();
- assertWithMessage("AM Band Descriptor spacing")
+ mExpect.withMessage("AM Band Descriptor spacing")
.that(bandDescriptor.getSpacing()).isEqualTo(AM_SPACING);
}
@@ -223,7 +226,7 @@
public void describeContents_forBandDescriptor() {
RadioManager.BandDescriptor bandDescriptor = createFmBandDescriptor();
- assertWithMessage("Band Descriptor contents")
+ mExpect.withMessage("Band Descriptor contents")
.that(bandDescriptor.describeContents()).isEqualTo(0);
}
@@ -237,7 +240,7 @@
RadioManager.BandDescriptor bandDescriptorFromParcel =
RadioManager.BandDescriptor.CREATOR.createFromParcel(parcel);
- assertWithMessage("Band Descriptor created from parcel")
+ mExpect.withMessage("Band Descriptor created from parcel")
.that(bandDescriptorFromParcel).isEqualTo(bandDescriptor);
}
@@ -246,14 +249,14 @@
RadioManager.BandDescriptor[] bandDescriptors =
RadioManager.BandDescriptor.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("Band Descriptors").that(bandDescriptors).hasLength(CREATOR_ARRAY_SIZE);
+ mExpect.withMessage("Band Descriptors").that(bandDescriptors).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
public void isAmBand_forAmBandDescriptor_returnsTrue() {
RadioManager.BandDescriptor bandDescriptor = createAmBandDescriptor();
- assertWithMessage("Is AM Band Descriptor an AM band")
+ mExpect.withMessage("Is AM Band Descriptor an AM band")
.that(bandDescriptor.isAmBand()).isTrue();
}
@@ -261,43 +264,43 @@
public void isFmBand_forAmBandDescriptor_returnsFalse() {
RadioManager.BandDescriptor bandDescriptor = createAmBandDescriptor();
- assertWithMessage("Is AM Band Descriptor an FM band")
+ mExpect.withMessage("Is AM Band Descriptor an FM band")
.that(bandDescriptor.isFmBand()).isFalse();
}
@Test
public void isStereoSupported_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor stereo")
+ mExpect.withMessage("FM Band Descriptor stereo")
.that(FM_BAND_DESCRIPTOR.isStereoSupported()).isEqualTo(STEREO_SUPPORTED);
}
@Test
public void isRdsSupported_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor RDS or RBDS")
+ mExpect.withMessage("FM Band Descriptor RDS or RBDS")
.that(FM_BAND_DESCRIPTOR.isRdsSupported()).isEqualTo(RDS_SUPPORTED);
}
@Test
public void isTaSupported_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor traffic announcement")
+ mExpect.withMessage("FM Band Descriptor traffic announcement")
.that(FM_BAND_DESCRIPTOR.isTaSupported()).isEqualTo(TA_SUPPORTED);
}
@Test
public void isAfSupported_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor alternate frequency")
+ mExpect.withMessage("FM Band Descriptor alternate frequency")
.that(FM_BAND_DESCRIPTOR.isAfSupported()).isEqualTo(AF_SUPPORTED);
}
@Test
public void isEaSupported_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor emergency announcement")
+ mExpect.withMessage("FM Band Descriptor emergency announcement")
.that(FM_BAND_DESCRIPTOR.isEaSupported()).isEqualTo(EA_SUPPORTED);
}
@Test
public void describeContents_forFmBandDescriptor() {
- assertWithMessage("FM Band Descriptor contents")
+ mExpect.withMessage("FM Band Descriptor contents")
.that(FM_BAND_DESCRIPTOR.describeContents()).isEqualTo(0);
}
@@ -310,7 +313,7 @@
RadioManager.FmBandDescriptor fmBandDescriptorFromParcel =
RadioManager.FmBandDescriptor.CREATOR.createFromParcel(parcel);
- assertWithMessage("FM Band Descriptor created from parcel")
+ mExpect.withMessage("FM Band Descriptor created from parcel")
.that(fmBandDescriptorFromParcel).isEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -319,19 +322,19 @@
RadioManager.FmBandDescriptor[] fmBandDescriptors =
RadioManager.FmBandDescriptor.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("FM Band Descriptors")
+ mExpect.withMessage("FM Band Descriptors")
.that(fmBandDescriptors).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
public void isStereoSupported_forAmBandDescriptor() {
- assertWithMessage("AM Band Descriptor stereo")
+ mExpect.withMessage("AM Band Descriptor stereo")
.that(AM_BAND_DESCRIPTOR.isStereoSupported()).isEqualTo(STEREO_SUPPORTED);
}
@Test
public void describeContents_forAmBandDescriptor() {
- assertWithMessage("AM Band Descriptor contents")
+ mExpect.withMessage("AM Band Descriptor contents")
.that(AM_BAND_DESCRIPTOR.describeContents()).isEqualTo(0);
}
@@ -344,7 +347,7 @@
RadioManager.AmBandDescriptor amBandDescriptorFromParcel =
RadioManager.AmBandDescriptor.CREATOR.createFromParcel(parcel);
- assertWithMessage("FM Band Descriptor created from parcel")
+ mExpect.withMessage("FM Band Descriptor created from parcel")
.that(amBandDescriptorFromParcel).isEqualTo(AM_BAND_DESCRIPTOR);
}
@@ -353,7 +356,7 @@
RadioManager.AmBandDescriptor[] amBandDescriptors =
RadioManager.AmBandDescriptor.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("AM Band Descriptors")
+ mExpect.withMessage("AM Band Descriptors")
.that(amBandDescriptors).hasLength(CREATOR_ARRAY_SIZE);
}
@@ -361,7 +364,7 @@
public void equals_withSameFmBandDescriptors_returnsTrue() {
RadioManager.FmBandDescriptor fmBandDescriptorCompared = createFmBandDescriptor();
- assertWithMessage("The same FM Band Descriptor")
+ mExpect.withMessage("The same FM Band Descriptor")
.that(FM_BAND_DESCRIPTOR).isEqualTo(fmBandDescriptorCompared);
}
@@ -369,19 +372,19 @@
public void equals_withSameAmBandDescriptors_returnsTrue() {
RadioManager.AmBandDescriptor amBandDescriptorCompared = createAmBandDescriptor();
- assertWithMessage("The same AM Band Descriptor")
+ mExpect.withMessage("The same AM Band Descriptor")
.that(AM_BAND_DESCRIPTOR).isEqualTo(amBandDescriptorCompared);
}
@Test
public void equals_withAmBandDescriptorsAndOtherTypeObject() {
- assertWithMessage("AM Band Descriptor")
+ mExpect.withMessage("AM Band Descriptor")
.that(AM_BAND_DESCRIPTOR).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@Test
public void equals_withFmBandDescriptorsAndOtherTypeObject() {
- assertWithMessage("FM Band Descriptor")
+ mExpect.withMessage("FM Band Descriptor")
.that(FM_BAND_DESCRIPTOR).isNotEqualTo(AM_BAND_DESCRIPTOR);
}
@@ -391,7 +394,7 @@
new RadioManager.AmBandDescriptor(REGION, RadioManager.BAND_AM, AM_LOWER_LIMIT,
AM_UPPER_LIMIT + AM_SPACING, AM_SPACING, STEREO_SUPPORTED);
- assertWithMessage("AM Band Descriptor of different upper limit")
+ mExpect.withMessage("AM Band Descriptor of different upper limit")
.that(AM_BAND_DESCRIPTOR).isNotEqualTo(amBandDescriptorCompared);
}
@@ -401,7 +404,7 @@
new RadioManager.AmBandDescriptor(REGION, RadioManager.BAND_AM, AM_LOWER_LIMIT,
AM_UPPER_LIMIT, AM_SPACING, !STEREO_SUPPORTED);
- assertWithMessage("AM Band Descriptor of different stereo support values")
+ mExpect.withMessage("AM Band Descriptor of different stereo support values")
.that(AM_BAND_DESCRIPTOR).isNotEqualTo(amBandDescriptorCompared);
}
@@ -411,7 +414,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING * 2,
STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different support limit values")
+ mExpect.withMessage("FM Band Descriptors of different support limit values")
.that(FM_BAND_DESCRIPTOR).isNotEqualTo(fmBandDescriptorCompared);
}
@@ -421,7 +424,7 @@
REGION + 1, RadioManager.BAND_AM_HD, AM_LOWER_LIMIT, AM_UPPER_LIMIT, AM_SPACING,
STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different region values")
+ mExpect.withMessage("FM Band Descriptors of different region values")
.that(FM_BAND_DESCRIPTOR).isNotEqualTo(fmBandDescriptorCompared);
}
@@ -431,7 +434,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
!STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different stereo support values")
+ mExpect.withMessage("FM Band Descriptors of different stereo support values")
.that(fmBandDescriptorCompared).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -441,7 +444,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
STEREO_SUPPORTED, !RDS_SUPPORTED, TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different rds support values")
+ mExpect.withMessage("FM Band Descriptors of different rds support values")
.that(fmBandDescriptorCompared).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -451,7 +454,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
STEREO_SUPPORTED, RDS_SUPPORTED, !TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different ta support values")
+ mExpect.withMessage("FM Band Descriptors of different ta support values")
.that(fmBandDescriptorCompared).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -461,7 +464,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, !AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different af support values")
+ mExpect.withMessage("FM Band Descriptors of different af support values")
.that(fmBandDescriptorCompared).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -471,7 +474,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, AF_SUPPORTED, !EA_SUPPORTED);
- assertWithMessage("FM Band Descriptors of different ea support values")
+ mExpect.withMessage("FM Band Descriptors of different ea support values")
.that(fmBandDescriptorCompared).isNotEqualTo(FM_BAND_DESCRIPTOR);
}
@@ -479,7 +482,7 @@
public void hashCode_withSameFmBandDescriptors_equals() {
RadioManager.FmBandDescriptor fmBandDescriptorCompared = createFmBandDescriptor();
- assertWithMessage("Hash code of the same FM Band Descriptor")
+ mExpect.withMessage("Hash code of the same FM Band Descriptor")
.that(fmBandDescriptorCompared.hashCode()).isEqualTo(FM_BAND_DESCRIPTOR.hashCode());
}
@@ -487,7 +490,7 @@
public void hashCode_withSameAmBandDescriptors_equals() {
RadioManager.AmBandDescriptor amBandDescriptorCompared = createAmBandDescriptor();
- assertWithMessage("Hash code of the same AM Band Descriptor")
+ mExpect.withMessage("Hash code of the same AM Band Descriptor")
.that(amBandDescriptorCompared.hashCode()).isEqualTo(AM_BAND_DESCRIPTOR.hashCode());
}
@@ -497,7 +500,7 @@
REGION, RadioManager.BAND_FM, FM_LOWER_LIMIT, FM_UPPER_LIMIT, FM_SPACING,
STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED, !AF_SUPPORTED, EA_SUPPORTED);
- assertWithMessage("Hash code of FM Band Descriptor of different spacing")
+ mExpect.withMessage("Hash code of FM Band Descriptor of different spacing")
.that(fmBandDescriptorCompared.hashCode())
.isNotEqualTo(FM_BAND_DESCRIPTOR.hashCode());
}
@@ -508,7 +511,7 @@
new RadioManager.AmBandDescriptor(REGION, RadioManager.BAND_AM, AM_LOWER_LIMIT,
AM_UPPER_LIMIT, AM_SPACING * 2, STEREO_SUPPORTED);
- assertWithMessage("Hash code of AM Band Descriptor of different spacing")
+ mExpect.withMessage("Hash code of AM Band Descriptor of different spacing")
.that(amBandDescriptorCompared.hashCode())
.isNotEqualTo(AM_BAND_DESCRIPTOR.hashCode());
}
@@ -517,7 +520,7 @@
public void getType_forBandConfig() {
RadioManager.BandConfig fmBandConfig = createFmBandConfig();
- assertWithMessage("FM Band Config type")
+ mExpect.withMessage("FM Band Config type")
.that(fmBandConfig.getType()).isEqualTo(RadioManager.BAND_FM);
}
@@ -525,7 +528,7 @@
public void getRegion_forBandConfig() {
RadioManager.BandConfig amBandConfig = createAmBandConfig();
- assertWithMessage("AM Band Config region")
+ mExpect.withMessage("AM Band Config region")
.that(amBandConfig.getRegion()).isEqualTo(REGION);
}
@@ -533,7 +536,7 @@
public void getLowerLimit_forBandConfig() {
RadioManager.BandConfig amBandConfig = createAmBandConfig();
- assertWithMessage("AM Band Config lower limit")
+ mExpect.withMessage("AM Band Config lower limit")
.that(amBandConfig.getLowerLimit()).isEqualTo(AM_LOWER_LIMIT);
}
@@ -541,7 +544,7 @@
public void getUpperLimit_forBandConfig() {
RadioManager.BandConfig fmBandConfig = createFmBandConfig();
- assertWithMessage("FM Band Config upper limit")
+ mExpect.withMessage("FM Band Config upper limit")
.that(fmBandConfig.getUpperLimit()).isEqualTo(FM_UPPER_LIMIT);
}
@@ -549,7 +552,7 @@
public void getSpacing_forBandConfig() {
RadioManager.BandConfig fmBandConfig = createFmBandConfig();
- assertWithMessage("FM Band Config spacing")
+ mExpect.withMessage("FM Band Config spacing")
.that(fmBandConfig.getSpacing()).isEqualTo(FM_SPACING);
}
@@ -557,7 +560,7 @@
public void describeContents_forBandConfig() {
RadioManager.BandConfig bandConfig = createFmBandConfig();
- assertWithMessage("FM Band Config contents")
+ mExpect.withMessage("FM Band Config contents")
.that(bandConfig.describeContents()).isEqualTo(0);
}
@@ -571,7 +574,7 @@
RadioManager.BandConfig bandConfigFromParcel =
RadioManager.BandConfig.CREATOR.createFromParcel(parcel);
- assertWithMessage("Band Config created from parcel")
+ mExpect.withMessage("Band Config created from parcel")
.that(bandConfigFromParcel).isEqualTo(bandConfig);
}
@@ -580,42 +583,42 @@
RadioManager.BandConfig[] bandConfigs =
RadioManager.BandConfig.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("Band Configs").that(bandConfigs).hasLength(CREATOR_ARRAY_SIZE);
+ mExpect.withMessage("Band Configs").that(bandConfigs).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
public void getStereo_forFmBandConfig() {
- assertWithMessage("FM Band Config stereo")
+ mExpect.withMessage("FM Band Config stereo")
.that(FM_BAND_CONFIG.getStereo()).isEqualTo(STEREO_SUPPORTED);
}
@Test
public void getRds_forFmBandConfig() {
- assertWithMessage("FM Band Config RDS or RBDS")
+ mExpect.withMessage("FM Band Config RDS or RBDS")
.that(FM_BAND_CONFIG.getRds()).isEqualTo(RDS_SUPPORTED);
}
@Test
public void getTa_forFmBandConfig() {
- assertWithMessage("FM Band Config traffic announcement")
+ mExpect.withMessage("FM Band Config traffic announcement")
.that(FM_BAND_CONFIG.getTa()).isEqualTo(TA_SUPPORTED);
}
@Test
public void getAf_forFmBandConfig() {
- assertWithMessage("FM Band Config alternate frequency")
+ mExpect.withMessage("FM Band Config alternate frequency")
.that(FM_BAND_CONFIG.getAf()).isEqualTo(AF_SUPPORTED);
}
@Test
public void getEa_forFmBandConfig() {
- assertWithMessage("FM Band Config emergency Announcement")
+ mExpect.withMessage("FM Band Config emergency Announcement")
.that(FM_BAND_CONFIG.getEa()).isEqualTo(EA_SUPPORTED);
}
@Test
public void describeContents_forFmBandConfig() {
- assertWithMessage("FM Band Config contents")
+ mExpect.withMessage("FM Band Config contents")
.that(FM_BAND_CONFIG.describeContents()).isEqualTo(0);
}
@@ -628,7 +631,7 @@
RadioManager.FmBandConfig fmBandConfigFromParcel =
RadioManager.FmBandConfig.CREATOR.createFromParcel(parcel);
- assertWithMessage("FM Band Config created from parcel")
+ mExpect.withMessage("FM Band Config created from parcel")
.that(fmBandConfigFromParcel).isEqualTo(FM_BAND_CONFIG);
}
@@ -637,18 +640,18 @@
RadioManager.FmBandConfig[] fmBandConfigs =
RadioManager.FmBandConfig.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("FM Band Configs").that(fmBandConfigs).hasLength(CREATOR_ARRAY_SIZE);
+ mExpect.withMessage("FM Band Configs").that(fmBandConfigs).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
public void getStereo_forAmBandConfig() {
- assertWithMessage("AM Band Config stereo")
+ mExpect.withMessage("AM Band Config stereo")
.that(AM_BAND_CONFIG.getStereo()).isEqualTo(STEREO_SUPPORTED);
}
@Test
public void describeContents_forAmBandConfig() {
- assertWithMessage("AM Band Config contents")
+ mExpect.withMessage("AM Band Config contents")
.that(AM_BAND_CONFIG.describeContents()).isEqualTo(0);
}
@@ -661,7 +664,7 @@
RadioManager.AmBandConfig amBandConfigFromParcel =
RadioManager.AmBandConfig.CREATOR.createFromParcel(parcel);
- assertWithMessage("AM Band Config created from parcel")
+ mExpect.withMessage("AM Band Config created from parcel")
.that(amBandConfigFromParcel).isEqualTo(AM_BAND_CONFIG);
}
@@ -670,7 +673,7 @@
RadioManager.AmBandConfig[] amBandConfigs =
RadioManager.AmBandConfig.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("AM Band Configs").that(amBandConfigs).hasLength(CREATOR_ARRAY_SIZE);
+ mExpect.withMessage("AM Band Configs").that(amBandConfigs).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
@@ -679,7 +682,7 @@
new RadioManager.FmBandConfig.Builder(FM_BAND_CONFIG);
RadioManager.FmBandConfig fmBandConfigCompared = builder.build();
- assertWithMessage("The same FM Band Config")
+ mExpect.withMessage("The same FM Band Config")
.that(FM_BAND_CONFIG).isEqualTo(fmBandConfigCompared);
}
@@ -690,7 +693,7 @@
AM_LOWER_LIMIT, AM_UPPER_LIMIT, AM_SPACING, STEREO_SUPPORTED, RDS_SUPPORTED,
TA_SUPPORTED, AF_SUPPORTED, EA_SUPPORTED));
- assertWithMessage("FM Band Config of different regions")
+ mExpect.withMessage("FM Band Config of different regions")
.that(FM_BAND_CONFIG).isNotEqualTo(fmBandConfigCompared);
}
@@ -701,7 +704,7 @@
FM_UPPER_LIMIT, FM_SPACING, !STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED,
AF_SUPPORTED, EA_SUPPORTED));
- assertWithMessage("FM Band Config with different stereo support values")
+ mExpect.withMessage("FM Band Config with different stereo support values")
.that(fmBandConfigCompared).isNotEqualTo(FM_BAND_CONFIG);
}
@@ -712,7 +715,7 @@
FM_UPPER_LIMIT, FM_SPACING, STEREO_SUPPORTED, !RDS_SUPPORTED, TA_SUPPORTED,
AF_SUPPORTED, EA_SUPPORTED));
- assertWithMessage("FM Band Config with different RDS support values")
+ mExpect.withMessage("FM Band Config with different RDS support values")
.that(fmBandConfigCompared).isNotEqualTo(FM_BAND_CONFIG);
}
@@ -723,7 +726,7 @@
FM_UPPER_LIMIT, FM_SPACING, STEREO_SUPPORTED, RDS_SUPPORTED, !TA_SUPPORTED,
AF_SUPPORTED, EA_SUPPORTED));
- assertWithMessage("FM Band Configs with different ta values")
+ mExpect.withMessage("FM Band Configs with different ta values")
.that(fmBandConfigCompared).isNotEqualTo(FM_BAND_CONFIG);
}
@@ -734,7 +737,7 @@
.setTa(TA_SUPPORTED).setAf(!AF_SUPPORTED).setEa(EA_SUPPORTED);
RadioManager.FmBandConfig fmBandConfigCompared = builder.build();
- assertWithMessage("FM Band Config of different af support value")
+ mExpect.withMessage("FM Band Config of different af support value")
.that(FM_BAND_CONFIG).isNotEqualTo(fmBandConfigCompared);
}
@@ -745,19 +748,19 @@
FM_UPPER_LIMIT, FM_SPACING, STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED,
AF_SUPPORTED, !EA_SUPPORTED));
- assertWithMessage("FM Band Configs with different ea support values")
+ mExpect.withMessage("FM Band Configs with different ea support values")
.that(fmBandConfigCompared).isNotEqualTo(FM_BAND_CONFIG);
}
@Test
public void equals_withAmBandConfigsAndOtherTypeObject() {
- assertWithMessage("AM Band Config")
+ mExpect.withMessage("AM Band Config")
.that(AM_BAND_CONFIG).isNotEqualTo(FM_BAND_CONFIG);
}
@Test
public void equals_withFmBandConfigsAndOtherTypeObject() {
- assertWithMessage("FM Band Config")
+ mExpect.withMessage("FM Band Config")
.that(FM_BAND_CONFIG).isNotEqualTo(AM_BAND_CONFIG);
}
@@ -767,7 +770,7 @@
new RadioManager.AmBandConfig.Builder(AM_BAND_CONFIG);
RadioManager.AmBandConfig amBandConfigCompared = builder.build();
- assertWithMessage("The same AM Band Config")
+ mExpect.withMessage("The same AM Band Config")
.that(AM_BAND_CONFIG).isEqualTo(amBandConfigCompared);
}
@@ -777,7 +780,7 @@
new RadioManager.AmBandDescriptor(REGION, RadioManager.BAND_AM_HD, AM_LOWER_LIMIT,
AM_UPPER_LIMIT, AM_SPACING, STEREO_SUPPORTED));
- assertWithMessage("AM Band Config of different type")
+ mExpect.withMessage("AM Band Config of different type")
.that(AM_BAND_CONFIG).isNotEqualTo(amBandConfigCompared);
}
@@ -787,7 +790,7 @@
createAmBandDescriptor()).setStereo(!STEREO_SUPPORTED);
RadioManager.AmBandConfig amBandConfigFromBuilder = builder.build();
- assertWithMessage("AM Band Config of different stereo value")
+ mExpect.withMessage("AM Band Config of different stereo value")
.that(AM_BAND_CONFIG).isNotEqualTo(amBandConfigFromBuilder);
}
@@ -795,7 +798,7 @@
public void hashCode_withSameFmBandConfigs_equals() {
RadioManager.FmBandConfig fmBandConfigCompared = createFmBandConfig();
- assertWithMessage("Hash code of the same FM Band Config")
+ mExpect.withMessage("Hash code of the same FM Band Config")
.that(FM_BAND_CONFIG.hashCode()).isEqualTo(fmBandConfigCompared.hashCode());
}
@@ -803,7 +806,7 @@
public void hashCode_withSameAmBandConfigs_equals() {
RadioManager.AmBandConfig amBandConfigCompared = createAmBandConfig();
- assertWithMessage("Hash code of the same AM Band Config")
+ mExpect.withMessage("Hash code of the same AM Band Config")
.that(amBandConfigCompared.hashCode()).isEqualTo(AM_BAND_CONFIG.hashCode());
}
@@ -814,7 +817,7 @@
FM_UPPER_LIMIT, FM_SPACING, STEREO_SUPPORTED, RDS_SUPPORTED, TA_SUPPORTED,
AF_SUPPORTED, EA_SUPPORTED));
- assertWithMessage("Hash code of FM Band Config with different type")
+ mExpect.withMessage("Hash code of FM Band Config with different type")
.that(fmBandConfigCompared.hashCode()).isNotEqualTo(FM_BAND_CONFIG.hashCode());
}
@@ -824,87 +827,87 @@
new RadioManager.AmBandDescriptor(REGION, RadioManager.BAND_AM, AM_LOWER_LIMIT,
AM_UPPER_LIMIT, AM_SPACING, !STEREO_SUPPORTED));
- assertWithMessage("Hash code of AM Band Config with different stereo support")
+ mExpect.withMessage("Hash code of AM Band Config with different stereo support")
.that(amBandConfigCompared.hashCode()).isNotEqualTo(AM_BAND_CONFIG.hashCode());
}
@Test
public void getId_forModuleProperties() {
- assertWithMessage("Properties id")
+ mExpect.withMessage("Properties id")
.that(AMFM_PROPERTIES.getId()).isEqualTo(PROPERTIES_ID);
}
@Test
public void getServiceName_forModuleProperties() {
- assertWithMessage("Properties service name")
+ mExpect.withMessage("Properties service name")
.that(AMFM_PROPERTIES.getServiceName()).isEqualTo(SERVICE_NAME);
}
@Test
public void getClassId_forModuleProperties() {
- assertWithMessage("Properties class ID")
+ mExpect.withMessage("Properties class ID")
.that(AMFM_PROPERTIES.getClassId()).isEqualTo(CLASS_ID);
}
@Test
public void getImplementor_forModuleProperties() {
- assertWithMessage("Properties implementor")
+ mExpect.withMessage("Properties implementor")
.that(AMFM_PROPERTIES.getImplementor()).isEqualTo(IMPLEMENTOR);
}
@Test
public void getProduct_forModuleProperties() {
- assertWithMessage("Properties product")
+ mExpect.withMessage("Properties product")
.that(AMFM_PROPERTIES.getProduct()).isEqualTo(PRODUCT);
}
@Test
public void getVersion_forModuleProperties() {
- assertWithMessage("Properties version")
+ mExpect.withMessage("Properties version")
.that(AMFM_PROPERTIES.getVersion()).isEqualTo(VERSION);
}
@Test
public void getSerial_forModuleProperties() {
- assertWithMessage("Serial properties")
+ mExpect.withMessage("Serial properties")
.that(AMFM_PROPERTIES.getSerial()).isEqualTo(SERIAL);
}
@Test
public void getNumTuners_forModuleProperties() {
- assertWithMessage("Number of tuners in properties")
+ mExpect.withMessage("Number of tuners in properties")
.that(AMFM_PROPERTIES.getNumTuners()).isEqualTo(NUM_TUNERS);
}
@Test
public void getNumAudioSources_forModuleProperties() {
- assertWithMessage("Number of audio sources in properties")
+ mExpect.withMessage("Number of audio sources in properties")
.that(AMFM_PROPERTIES.getNumAudioSources()).isEqualTo(NUM_AUDIO_SOURCES);
}
@Test
public void isInitializationRequired_forModuleProperties() {
- assertWithMessage("Initialization required in properties")
+ mExpect.withMessage("Initialization required in properties")
.that(AMFM_PROPERTIES.isInitializationRequired())
.isEqualTo(IS_INITIALIZATION_REQUIRED);
}
@Test
public void isCaptureSupported_forModuleProperties() {
- assertWithMessage("Capture support in properties")
+ mExpect.withMessage("Capture support in properties")
.that(AMFM_PROPERTIES.isCaptureSupported()).isEqualTo(IS_CAPTURE_SUPPORTED);
}
@Test
public void isBackgroundScanningSupported_forModuleProperties() {
- assertWithMessage("Background scan support in properties")
+ mExpect.withMessage("Background scan support in properties")
.that(AMFM_PROPERTIES.isBackgroundScanningSupported())
.isEqualTo(IS_BG_SCAN_SUPPORTED);
}
@Test
public void isProgramTypeSupported_withSupportedType_forModuleProperties() {
- assertWithMessage("AM/FM frequency type radio support in properties")
+ mExpect.withMessage("AM/FM frequency type radio support in properties")
.that(AMFM_PROPERTIES.isProgramTypeSupported(
ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY))
.isTrue();
@@ -912,28 +915,28 @@
@Test
public void isProgramTypeSupported_withNonSupportedType_forModuleProperties() {
- assertWithMessage("DAB frequency type radio support in properties")
+ mExpect.withMessage("DAB frequency type radio support in properties")
.that(AMFM_PROPERTIES.isProgramTypeSupported(
ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY)).isFalse();
}
@Test
public void isProgramIdentifierSupported_withSupportedIdentifier_forModuleProperties() {
- assertWithMessage("AM/FM frequency identifier radio support in properties")
+ mExpect.withMessage("AM/FM frequency identifier radio support in properties")
.that(AMFM_PROPERTIES.isProgramIdentifierSupported(
ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY)).isTrue();
}
@Test
public void isProgramIdentifierSupported_withNonSupportedIdentifier_forModuleProperties() {
- assertWithMessage("DAB frequency identifier radio support in properties")
+ mExpect.withMessage("DAB frequency identifier radio support in properties")
.that(AMFM_PROPERTIES.isProgramIdentifierSupported(
ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY)).isFalse();
}
@Test
public void getDabFrequencyTable_forModulePropertiesInitializedWithNullTable() {
- assertWithMessage("Properties DAB frequency table")
+ mExpect.withMessage("Properties DAB frequency table")
.that(AMFM_PROPERTIES.getDabFrequencyTable()).isNull();
}
@@ -941,32 +944,32 @@
public void getDabFrequencyTable_forModulePropertiesInitializedWithEmptyTable() {
RadioManager.ModuleProperties properties = createAmFmProperties(new ArrayMap<>());
- assertWithMessage("Properties DAB frequency table")
+ mExpect.withMessage("Properties DAB frequency table")
.that(properties.getDabFrequencyTable()).isNull();
}
@Test
public void getVendorInfo_forModuleProperties() {
- assertWithMessage("Properties vendor info")
+ mExpect.withMessage("Properties vendor info")
.that(AMFM_PROPERTIES.getVendorInfo()).isEmpty();
}
@Test
public void getBands_forModuleProperties() {
- assertWithMessage("Properties bands")
+ mExpect.withMessage("Properties bands")
.that(AMFM_PROPERTIES.getBands()).asList()
.containsExactly(AM_BAND_DESCRIPTOR, FM_BAND_DESCRIPTOR);
}
@Test
public void describeContents_forModuleProperties() {
- assertWithMessage("Module properties contents")
+ mExpect.withMessage("Module properties contents")
.that(AMFM_PROPERTIES.describeContents()).isEqualTo(0);
}
@Test
public void toString_forModuleProperties() {
- assertWithMessage("Module properties string").that(AMFM_PROPERTIES.toString())
+ mExpect.withMessage("Module properties string").that(AMFM_PROPERTIES.toString())
.contains(AM_BAND_DESCRIPTOR.toString() + ", " + FM_BAND_DESCRIPTOR.toString());
}
@@ -979,7 +982,7 @@
RadioManager.ModuleProperties modulePropertiesFromParcel =
RadioManager.ModuleProperties.CREATOR.createFromParcel(parcel);
- assertWithMessage("Module properties created from parcel")
+ mExpect.withMessage("Module properties created from parcel")
.that(modulePropertiesFromParcel).isEqualTo(AMFM_PROPERTIES);
}
@@ -994,7 +997,7 @@
RadioManager.ModuleProperties modulePropertiesFromParcel =
RadioManager.ModuleProperties.CREATOR.createFromParcel(parcel);
- assertWithMessage("Module properties created from parcel")
+ mExpect.withMessage("Module properties created from parcel")
.that(modulePropertiesFromParcel).isEqualTo(propertiesToParcel);
}
@@ -1003,7 +1006,7 @@
RadioManager.ModuleProperties propertiesCompared =
createAmFmProperties(/* dabFrequencyTable= */ null);
- assertWithMessage("The same module properties")
+ mExpect.withMessage("The same module properties")
.that(AMFM_PROPERTIES).isEqualTo(propertiesCompared);
}
@@ -1016,7 +1019,7 @@
SUPPORTED_PROGRAM_TYPES, SUPPORTED_IDENTIFIERS_TYPES, Map.of("5A", 174928),
/* vendorInfo= */ null);
- assertWithMessage("Module properties of different id")
+ mExpect.withMessage("Module properties of different id")
.that(AMFM_PROPERTIES).isNotEqualTo(propertiesDab);
}
@@ -1025,7 +1028,7 @@
RadioManager.ModuleProperties propertiesCompared =
createAmFmProperties(/* dabFrequencyTable= */ null);
- assertWithMessage("Hash code of the same module properties")
+ mExpect.withMessage("Hash code of the same module properties")
.that(propertiesCompared.hashCode()).isEqualTo(AMFM_PROPERTIES.hashCode());
}
@@ -1034,86 +1037,86 @@
RadioManager.ModuleProperties[] modulePropertiesArray =
RadioManager.ModuleProperties.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("Module properties array")
+ mExpect.withMessage("Module properties array")
.that(modulePropertiesArray).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
public void getSelector_forProgramInfo() {
- assertWithMessage("Selector of DAB program info")
+ mExpect.withMessage("Selector of DAB program info")
.that(DAB_PROGRAM_INFO.getSelector()).isEqualTo(DAB_SELECTOR);
}
@Test
public void getLogicallyTunedTo_forProgramInfo() {
- assertWithMessage("Identifier logically tuned to in DAB program info")
+ mExpect.withMessage("Identifier logically tuned to in DAB program info")
.that(DAB_PROGRAM_INFO.getLogicallyTunedTo()).isEqualTo(DAB_SID_EXT_IDENTIFIER);
}
@Test
public void getPhysicallyTunedTo_forProgramInfo() {
- assertWithMessage("Identifier physically tuned to DAB program info")
+ mExpect.withMessage("Identifier physically tuned to DAB program info")
.that(DAB_PROGRAM_INFO.getPhysicallyTunedTo()).isEqualTo(DAB_FREQUENCY_IDENTIFIER);
}
@Test
public void getRelatedContent_forProgramInfo() {
- assertWithMessage("DAB program info contents")
+ mExpect.withMessage("DAB program info contents")
.that(DAB_PROGRAM_INFO.getRelatedContent())
.containsExactly(DAB_SID_EXT_IDENTIFIER_RELATED);
}
@Test
public void getChannel_forProgramInfo() {
- assertWithMessage("Main channel of DAB program info")
+ mExpect.withMessage("Main channel of DAB program info")
.that(DAB_PROGRAM_INFO.getChannel()).isEqualTo(0);
}
@Test
public void getSubChannel_forProgramInfo() {
- assertWithMessage("Sub channel of DAB program info")
+ mExpect.withMessage("Sub channel of DAB program info")
.that(DAB_PROGRAM_INFO.getSubChannel()).isEqualTo(0);
}
@Test
public void isTuned_forProgramInfo() {
- assertWithMessage("Tuned status of DAB program info")
+ mExpect.withMessage("Tuned status of DAB program info")
.that(DAB_PROGRAM_INFO.isTuned()).isTrue();
}
@Test
public void isStereo_forProgramInfo() {
- assertWithMessage("Stereo support in DAB program info")
+ mExpect.withMessage("Stereo support in DAB program info")
.that(DAB_PROGRAM_INFO.isStereo()).isTrue();
}
@Test
public void isDigital_forProgramInfo() {
- assertWithMessage("Digital DAB program info")
+ mExpect.withMessage("Digital DAB program info")
.that(DAB_PROGRAM_INFO.isDigital()).isTrue();
}
@Test
public void isLive_forProgramInfo() {
- assertWithMessage("Live status of DAB program info")
+ mExpect.withMessage("Live status of DAB program info")
.that(DAB_PROGRAM_INFO.isLive()).isTrue();
}
@Test
public void isMuted_forProgramInfo() {
- assertWithMessage("Muted status of DAB program info")
+ mExpect.withMessage("Muted status of DAB program info")
.that(DAB_PROGRAM_INFO.isMuted()).isFalse();
}
@Test
public void isTrafficProgram_forProgramInfo() {
- assertWithMessage("Traffic program support in DAB program info")
+ mExpect.withMessage("Traffic program support in DAB program info")
.that(DAB_PROGRAM_INFO.isTrafficProgram()).isFalse();
}
@Test
public void isTrafficAnnouncementActive_forProgramInfo() {
- assertWithMessage("Active traffic announcement for DAB program info")
+ mExpect.withMessage("Active traffic announcement for DAB program info")
.that(DAB_PROGRAM_INFO.isTrafficAnnouncementActive()).isFalse();
}
@@ -1121,7 +1124,7 @@
public void isSignalAcquired_forProgramInfo() {
mSetFlagsRule.enableFlags(Flags.FLAG_HD_RADIO_IMPROVED);
- assertWithMessage("Signal acquisition status for HD program info")
+ mExpect.withMessage("Signal acquisition status for HD program info")
.that(HD_PROGRAM_INFO.isSignalAcquired()).isTrue();
}
@@ -1129,7 +1132,7 @@
public void isHdSisAvailable_forProgramInfo() {
mSetFlagsRule.enableFlags(Flags.FLAG_HD_RADIO_IMPROVED);
- assertWithMessage("SIS information acquisition status for HD program")
+ mExpect.withMessage("SIS information acquisition status for HD program")
.that(HD_PROGRAM_INFO.isHdSisAvailable()).isTrue();
}
@@ -1137,31 +1140,31 @@
public void isHdAudioAvailable_forProgramInfo() {
mSetFlagsRule.enableFlags(Flags.FLAG_HD_RADIO_IMPROVED);
- assertWithMessage("Audio acquisition status for HD program")
+ mExpect.withMessage("Audio acquisition status for HD program")
.that(HD_PROGRAM_INFO.isHdAudioAvailable()).isFalse();
}
@Test
public void getSignalStrength_forProgramInfo() {
- assertWithMessage("Signal strength of DAB program info")
+ mExpect.withMessage("Signal strength of DAB program info")
.that(DAB_PROGRAM_INFO.getSignalStrength()).isEqualTo(SIGNAL_QUALITY);
}
@Test
public void getMetadata_forProgramInfo() {
- assertWithMessage("Metadata of DAB program info")
+ mExpect.withMessage("Metadata of DAB program info")
.that(DAB_PROGRAM_INFO.getMetadata()).isEqualTo(METADATA);
}
@Test
public void getVendorInfo_forProgramInfo() {
- assertWithMessage("Vendor info of DAB program info")
+ mExpect.withMessage("Vendor info of DAB program info")
.that(DAB_PROGRAM_INFO.getVendorInfo()).isEmpty();
}
@Test
public void describeContents_forProgramInfo() {
- assertWithMessage("Program info contents")
+ mExpect.withMessage("Program info contents")
.that(DAB_PROGRAM_INFO.describeContents()).isEqualTo(0);
}
@@ -1170,7 +1173,7 @@
RadioManager.ProgramInfo[] programInfoArray =
RadioManager.ProgramInfo.CREATOR.newArray(CREATOR_ARRAY_SIZE);
- assertWithMessage("Program infos").that(programInfoArray).hasLength(CREATOR_ARRAY_SIZE);
+ mExpect.withMessage("Program infos").that(programInfoArray).hasLength(CREATOR_ARRAY_SIZE);
}
@Test
@@ -1182,7 +1185,7 @@
RadioManager.ProgramInfo programInfoFromParcel =
RadioManager.ProgramInfo.CREATOR.createFromParcel(parcel);
- assertWithMessage("Program info created from parcel")
+ mExpect.withMessage("Program info created from parcel")
.that(programInfoFromParcel).isEqualTo(DAB_PROGRAM_INFO);
}
@@ -1190,7 +1193,7 @@
public void equals_withSameProgramInfo_returnsTrue() {
RadioManager.ProgramInfo dabProgramInfoCompared = createDabProgramInfo(DAB_SELECTOR);
- assertWithMessage("The same program info")
+ mExpect.withMessage("The same program info")
.that(dabProgramInfoCompared).isEqualTo(DAB_PROGRAM_INFO);
}
@@ -1202,7 +1205,7 @@
/* vendorIds= */ null);
RadioManager.ProgramInfo dabProgramInfoCompared = createDabProgramInfo(dabSelectorCompared);
- assertWithMessage("Program info with different secondary id selectors")
+ mExpect.withMessage("Program info with different secondary id selectors")
.that(DAB_PROGRAM_INFO).isNotEqualTo(dabProgramInfoCompared);
}
@@ -1213,7 +1216,7 @@
mRadioManager.listModules(modules);
- assertWithMessage("Modules in radio manager")
+ mExpect.withMessage("Modules in radio manager")
.that(modules).containsExactly(AMFM_PROPERTIES);
}
@@ -1221,7 +1224,7 @@
public void listModules_forRadioManagerWithNullListAsInput_fails() throws Exception {
createRadioManager();
- assertWithMessage("Status when listing module with empty list input")
+ mExpect.withMessage("Status when listing module with empty list input")
.that(mRadioManager.listModules(null)).isEqualTo(RadioManager.STATUS_BAD_VALUE);
}
@@ -1231,7 +1234,7 @@
when(mRadioServiceMock.listModules()).thenReturn(null);
List<RadioManager.ModuleProperties> modules = new ArrayList<>();
- assertWithMessage("Status for listing module when getting null list from HAL client")
+ mExpect.withMessage("Status for listing module when getting null list from HAL client")
.that(mRadioManager.listModules(modules)).isEqualTo(RadioManager.STATUS_ERROR);
}
@@ -1241,7 +1244,7 @@
when(mRadioServiceMock.listModules()).thenThrow(new RemoteException());
List<RadioManager.ModuleProperties> modules = new ArrayList<>();
- assertWithMessage("Status for listing module when HAL client service is dead")
+ mExpect.withMessage("Status for listing module when HAL client service is dead")
.that(mRadioManager.listModules(modules))
.isEqualTo(RadioManager.STATUS_DEAD_OBJECT);
}
@@ -1267,7 +1270,21 @@
RadioTuner nullTuner = mRadioManager.openTuner(/* moduleId= */ 0, FM_BAND_CONFIG,
/* withAudio= */ true, mCallbackMock, /* handler= */ null);
- assertWithMessage("Radio tuner when service is dead").that(nullTuner).isNull();
+ mExpect.withMessage("Radio tuner when service is dead").that(nullTuner).isNull();
+ }
+
+ @Test
+ public void openTuner_withNullCallback() throws Exception {
+ createRadioManager();
+ int moduleId = 0;
+ boolean withAudio = true;
+
+ IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
+ () -> mRadioManager.openTuner(moduleId, FM_BAND_CONFIG, withAudio,
+ /* callback= */ null, /* handler= */ null));
+
+ mExpect.withMessage("Null tuner callback exception").that(thrown)
+ .hasMessageThat().contains("callback must not be empty");
}
@Test
@@ -1323,7 +1340,7 @@
RuntimeException thrown = assertThrows(RuntimeException.class,
() -> mRadioManager.addAnnouncementListener(enableTypeSet, mEventListener));
- assertWithMessage("Exception for adding announcement listener with dead service")
+ mExpect.withMessage("Exception for adding announcement listener with dead service")
.that(thrown).hasMessageThat().contains(exceptionMessage);
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AnnouncementAggregatorTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AnnouncementAggregatorTest.java
index 0e0dbec..2bf0aa3 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AnnouncementAggregatorTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/AnnouncementAggregatorTest.java
@@ -16,11 +16,11 @@
package com.android.server.broadcastradio.aidl;
-import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -33,7 +33,10 @@
import android.os.IBinder;
import android.os.RemoteException;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -54,6 +57,9 @@
private AnnouncementAggregator mAnnouncementAggregator;
private IBinder.DeathRecipient mDeathRecipient;
+ @Rule
+ public final Expect mExpect = Expect.create();
+
@Mock
private IAnnouncementListener mListenerMock;
@Mock
@@ -75,6 +81,18 @@
}
@Test
+ public void constructor_withBinderDied() throws Exception {
+ RemoteException remoteException = new RemoteException("Binder is died");
+ doThrow(remoteException).when(mBinderMock).linkToDeath(any(), anyInt());
+
+ RuntimeException thrown = assertThrows(RuntimeException.class, () ->
+ new AnnouncementAggregator(mListenerMock, mLock));
+
+ mExpect.withMessage("Exception for dead binder").that(thrown).hasMessageThat()
+ .contains(remoteException.getMessage());
+ }
+
+ @Test
public void onListUpdated_withOneModuleWatcher() throws Exception {
ArgumentCaptor<IAnnouncementListener> moduleWatcherCaptor =
ArgumentCaptor.forClass(IAnnouncementListener.class);
@@ -103,7 +121,7 @@
moduleWatcherCaptor.getValue().onListUpdated(Arrays.asList(mAnnouncementMocks[index]));
verify(mListenerMock, times(index + 1)).onListUpdated(announcementsCaptor.capture());
- assertWithMessage("Number of announcements %s after %s announcements were updated",
+ mExpect.withMessage("Number of announcements %s after %s announcements were updated",
announcementsCaptor.getValue(), index + 1)
.that(announcementsCaptor.getValue().size()).isEqualTo(index + 1);
}
@@ -131,7 +149,7 @@
() -> mAnnouncementAggregator.watchModule(mRadioModuleMocks[0],
TEST_ENABLED_TYPES));
- assertWithMessage("Exception for watching module after aggregator has been closed")
+ mExpect.withMessage("Exception for watching module after aggregator has been closed")
.that(thrown).hasMessageThat()
.contains("announcement aggregator has already been closed");
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 8d9fad9..5f78b2a 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -622,6 +622,12 @@
.isEqualTo(TEST_ALBUM_ART);
}
+ @Test
+ public void getBands_withInvalidFrequency() {
+ expect.withMessage("Band for invalid frequency")
+ .that(Utils.getBand(/* freq= */ 110000)).isEqualTo(Utils.FrequencyBand.UNKNOWN);
+ }
+
private static RadioManager.ModuleProperties convertToModuleProperties() {
AmFmRegionConfig amFmConfig = createAmFmRegionConfig();
DabTableEntry[] dabTableEntries = new DabTableEntry[]{
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
index ce27bc1..d64fcaf 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ProgramInfoCacheTest.java
@@ -440,6 +440,29 @@
TEST_DAB_UNIQUE_ID_ALTERNATIVE);
}
+ @Test
+ public void filterAndApplyChunkInternal_withInvalidProgramInfoAndIdentifiers()
+ throws RemoteException {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null,
+ /* complete= */ false, TEST_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO);
+ ProgramInfo[] halModified = new android.hardware.broadcastradio.ProgramInfo[1];
+ halModified[0] = AidlTestUtils.makeHalProgramInfo(
+ ConversionUtils.programSelectorToHalProgramSelector(TEST_DAB_SELECTOR_ALTERNATIVE),
+ ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
+ ConversionUtils.identifierToHalProgramIdentifier(TEST_DAB_FREQUENCY_ID_ALTERNATIVE),
+ TEST_SIGNAL_QUALITY);
+ ProgramIdentifier[] halRemoved = new android.hardware.broadcastradio.ProgramIdentifier[1];
+ halRemoved[0] = new android.hardware.broadcastradio.ProgramIdentifier();
+ ProgramListChunk halChunk = AidlTestUtils.makeHalChunk(/* purge= */ false,
+ /* complete= */ true, halModified, halRemoved);
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
+ TEST_MAX_NUM_MODIFIED_PER_CHUNK, TEST_MAX_NUM_REMOVED_PER_CHUNK);
+
+ expect.withMessage("Program list chunk applied with invalid program and identifiers")
+ .that(programListChunks).isEmpty();
+ }
+
private void verifyChunkListPurge(List<ProgramList.Chunk> chunks, boolean purge) {
if (chunks.isEmpty()) {
return;
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/AnnouncementAggregatorHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/AnnouncementAggregatorHidlTest.java
index 5e99b28..8e0abff 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/AnnouncementAggregatorHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/AnnouncementAggregatorHidlTest.java
@@ -16,11 +16,11 @@
package com.android.server.broadcastradio.hal2;
-import static com.google.common.truth.Truth.assertWithMessage;
-
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -33,7 +33,10 @@
import android.os.IBinder;
import android.os.RemoteException;
+import com.google.common.truth.Expect;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -55,6 +58,9 @@
private AnnouncementAggregator mAnnouncementAggregator;
private IBinder.DeathRecipient mDeathRecipient;
+ @Rule
+ public final Expect mExpect = Expect.create();
+
@Mock
private IAnnouncementListener mListenerMock;
@Mock
@@ -76,6 +82,19 @@
}
@Test
+ public void constructor_withBinderDied() throws Exception {
+ RemoteException remoteException = new RemoteException("Binder is died");
+ doThrow(remoteException).when(mBinderMock).linkToDeath(any(), anyInt());
+
+ RuntimeException thrown = assertThrows(RuntimeException.class,
+ () -> new com.android.server.broadcastradio.aidl.AnnouncementAggregator(
+ mListenerMock, mLock));
+
+ mExpect.withMessage("Exception for dead binder").that(thrown).hasMessageThat()
+ .contains(remoteException.getMessage());
+ }
+
+ @Test
public void onListUpdated_withOneModuleWatcher() throws Exception {
ArgumentCaptor<IAnnouncementListener> moduleWatcherCaptor =
ArgumentCaptor.forClass(IAnnouncementListener.class);
@@ -104,7 +123,7 @@
moduleWatcherCaptor.getValue().onListUpdated(Arrays.asList(mAnnouncementMocks[index]));
verify(mListenerMock, times(index + 1)).onListUpdated(announcementsCaptor.capture());
- assertWithMessage("Number of announcements %s after %s announcements were updated",
+ mExpect.withMessage("Number of announcements %s after %s announcements were updated",
announcementsCaptor.getValue(), index + 1)
.that(announcementsCaptor.getValue().size()).isEqualTo(index + 1);
}
@@ -132,7 +151,7 @@
() -> mAnnouncementAggregator.watchModule(mRadioModuleMocks[0],
TEST_ENABLED_TYPES));
- assertWithMessage("Exception for watching module after aggregator has been closed")
+ mExpect.withMessage("Exception for watching module after aggregator has been closed")
.that(thrown).hasMessageThat()
.contains("announcement aggregator has already been closed");
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
index 3de4f5d..123e02c 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ConvertTest.java
@@ -173,6 +173,12 @@
.that(ANNOUNCEMENT.getVendorInfo()).isEmpty();
}
+ @Test
+ public void getBands_withInvalidFrequency() {
+ expect.withMessage("Band for invalid frequency")
+ .that(Utils.getBand(/* freq= */ 110000)).isEqualTo(FrequencyBand.UNKNOWN);
+ }
+
private static RadioManager.ModuleProperties convertToModuleProperties() {
AmFmRegionConfig amFmConfig = createAmFmRegionConfig();
List<DabTableEntry> dabTableEntries = Arrays.asList(
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
index 36a6430..015e9c0 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/ProgramInfoCacheTest.java
@@ -17,6 +17,7 @@
import static org.junit.Assert.*;
+import android.hardware.broadcastradio.V2_0.ProgramIdentifier;
import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
@@ -34,6 +35,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -261,6 +263,25 @@
verifyChunkListRemoved(chunks, 1, TEST_DAB_UNIQUE_ID, TEST_VENDOR_UNIQUE_ID);
}
+ @Test
+ public void filterAndApplyChunkInternal_withInvalidIdentifier() {
+ ProgramInfoCache cache = new ProgramInfoCache(/* filter= */ null, /* complete= */ false,
+ TEST_AM_FM_INFO, TEST_RDS_INFO, TEST_DAB_INFO, TEST_VENDOR_INFO);
+ ArrayList<ProgramIdentifier> halRemoved = new ArrayList<>();
+ halRemoved.add(new ProgramIdentifier());
+ ProgramListChunk halChunk = new ProgramListChunk();
+ halChunk.complete = true;
+ halChunk.purge = false;
+ halChunk.modified = new ArrayList<>();
+ halChunk.removed = halRemoved;
+
+ List<ProgramList.Chunk> programListChunks = cache.filterAndApplyChunkInternal(halChunk,
+ /* maxNumModifiedPerChunk= */ 1, /* maxNumRemovedPerChunk= */ 1);
+
+ expect.withMessage("Program list chunk applied with invalid identifier")
+ .that(programListChunks).isEmpty();
+ }
+
// Verifies that:
// - The first chunk's purge flag matches expectPurge.
// - The last chunk's complete flag matches expectComplete.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index 579a794..a09720d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -22,6 +22,7 @@
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
+import android.graphics.Rect
import android.os.RemoteException
import android.os.SystemProperties
import android.util.DisplayMetrics
@@ -138,6 +139,30 @@
}
}
+
+ /**
+ * Returns a fake source rect hint for animation purposes when app-provided one is invalid.
+ * Resulting adjusted source rect hint lets the app icon in the content overlay to stay visible.
+ */
+ @JvmStatic
+ fun getEnterPipWithOverlaySrcRectHint(appBounds: Rect, aspectRatio: Float): Rect {
+ val appBoundsAspRatio = appBounds.width().toFloat() / appBounds.height()
+ val width: Int
+ val height: Int
+ var left = 0
+ var top = 0
+ if (appBoundsAspRatio < aspectRatio) {
+ width = appBounds.width()
+ height = Math.round(width / aspectRatio)
+ top = (appBounds.height() - height) / 2
+ } else {
+ height = appBounds.height()
+ width = Math.round(height * aspectRatio)
+ left = (appBounds.width() - width) / 2
+ }
+ return Rect(left, top, left + width, top + height)
+ }
+
private var isPip2ExperimentEnabled: Boolean? = null
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index 57c0732..0a3c15b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -40,6 +40,7 @@
import com.android.internal.protolog.common.ProtoLog;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.animation.Interpolators;
+import com.android.wm.shell.common.pip.PipUtils;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;
@@ -619,19 +620,8 @@
// This is done for entering case only.
if (isInPipDirection(direction)) {
final float aspectRatio = endValue.width() / (float) endValue.height();
- if ((startValue.width() / (float) startValue.height()) > aspectRatio) {
- // use the full height.
- adjustedSourceRectHint.set(0, 0,
- (int) (startValue.height() * aspectRatio), startValue.height());
- adjustedSourceRectHint.offset(
- (startValue.width() - adjustedSourceRectHint.width()) / 2, 0);
- } else {
- // use the full width.
- adjustedSourceRectHint.set(0, 0,
- startValue.width(), (int) (startValue.width() / aspectRatio));
- adjustedSourceRectHint.offset(
- 0, (startValue.height() - adjustedSourceRectHint.height()) / 2);
- }
+ adjustedSourceRectHint.set(PipUtils.getEnterPipWithOverlaySrcRectHint(
+ startValue, aspectRatio));
}
} else {
adjustedSourceRectHint.set(sourceRectHint);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index 8c9206c..e4420d7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -999,7 +999,6 @@
private void onEndOfSwipePipToHomeTransition() {
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- mPipTransitionController.setEnterAnimationType(ANIM_TYPE_BOUNDS);
return;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index dbf18fa..3cae72d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -1083,6 +1083,8 @@
mSurfaceTransactionHelper
.crop(finishTransaction, leash, destinationBounds)
.round(finishTransaction, leash, true /* applyCornerRadius */);
+ // Always reset to bounds animation type afterwards.
+ setEnterAnimationType(ANIM_TYPE_BOUNDS);
} else {
throw new RuntimeException("Unrecognized animation type: " + enterAnimationType);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
index 3e298e5..895c2ae 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/animation/PipAlphaAnimator.java
@@ -19,11 +19,13 @@
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
+import android.content.Context;
import android.view.SurfaceControl;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.wm.shell.R;
import com.android.wm.shell.pip2.PipSurfaceTransactionHelper;
import java.lang.annotation.Retention;
@@ -45,6 +47,7 @@
public static final int FADE_IN = 0;
public static final int FADE_OUT = 1;
+ private final int mEnterAnimationDuration;
private final SurfaceControl mLeash;
private final SurfaceControl.Transaction mStartTransaction;
@@ -55,7 +58,8 @@
private final PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
mSurfaceControlTransactionFactory;
- public PipAlphaAnimator(SurfaceControl leash,
+ public PipAlphaAnimator(Context context,
+ SurfaceControl leash,
SurfaceControl.Transaction tx,
@Fade int direction) {
mLeash = leash;
@@ -67,6 +71,9 @@
}
mSurfaceControlTransactionFactory =
new PipSurfaceTransactionHelper.VsyncSurfaceControlTransactionFactory();
+ mEnterAnimationDuration = context.getResources()
+ .getInteger(R.integer.config_pipEnterAnimationDuration);
+ setDuration(mEnterAnimationDuration);
addListener(this);
addUpdateListener(this);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 3e215d9..0b2db6c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -293,37 +293,32 @@
return false;
}
+ SurfaceControl overlayLeash = mPipTransitionState.getSwipePipToHomeOverlay();
PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams;
- Rect srcRectHint = params.getSourceRectHint();
- Rect startBounds = pipChange.getStartAbsBounds();
+
+ Rect appBounds = mPipTransitionState.getSwipePipToHomeAppBounds();
Rect destinationBounds = pipChange.getEndAbsBounds();
+ float aspectRatio = pipChange.getTaskInfo().pictureInPictureParams.getAspectRatioFloat();
+
+ // We fake the source rect hint when the one prvided by the app is invalid for
+ // the animation with an app icon overlay.
+ Rect animationSrcRectHint = overlayLeash == null ? params.getSourceRectHint()
+ : PipUtils.getEnterPipWithOverlaySrcRectHint(appBounds, aspectRatio);
+
WindowContainerTransaction finishWct = new WindowContainerTransaction();
SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
- if (PipBoundsAlgorithm.isSourceRectHintValidForEnterPip(srcRectHint, destinationBounds)) {
- final float scale = (float) destinationBounds.width() / srcRectHint.width();
- startTransaction.setWindowCrop(pipLeash, srcRectHint);
- startTransaction.setPosition(pipLeash,
- destinationBounds.left - srcRectHint.left * scale,
- destinationBounds.top - srcRectHint.top * scale);
+ final float scale = (float) destinationBounds.width() / animationSrcRectHint.width();
+ startTransaction.setWindowCrop(pipLeash, animationSrcRectHint);
+ startTransaction.setPosition(pipLeash,
+ destinationBounds.left - animationSrcRectHint.left * scale,
+ destinationBounds.top - animationSrcRectHint.top * scale);
+ startTransaction.setScale(pipLeash, scale, scale);
- // Reset the scale in case we are in the multi-activity case.
- // TO_FRONT transition already scales down the task in single-activity case, but
- // in multi-activity case, reparenting yields new reset scales coming from pinned task.
- startTransaction.setScale(pipLeash, scale, scale);
- } else {
- final float scaleX = (float) destinationBounds.width() / startBounds.width();
- final float scaleY = (float) destinationBounds.height() / startBounds.height();
+ if (overlayLeash != null) {
final int overlaySize = PipContentOverlay.PipAppIconOverlay.getOverlaySize(
mPipTransitionState.getSwipePipToHomeAppBounds(), destinationBounds);
- SurfaceControl overlayLeash = mPipTransitionState.getSwipePipToHomeOverlay();
-
- startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
- .setScale(pipLeash, scaleX, scaleY)
- .setWindowCrop(pipLeash, startBounds)
- .reparent(overlayLeash, pipLeash)
- .setLayer(overlayLeash, Integer.MAX_VALUE);
// Overlay needs to be adjusted once a new draw comes in resetting surface transform.
tx.setScale(overlayLeash, 1f, 1f);
@@ -390,15 +385,23 @@
if (pipChange == null) {
return false;
}
- // cache the PiP task token and leash
- WindowContainerToken pipTaskToken = pipChange.getContainer();
- Preconditions.checkNotNull(mPipLeash, "Leash is null for alpha transition.");
- // start transition with 0 alpha
- startTransaction.setAlpha(mPipLeash, 0f);
- PipAlphaAnimator animator = new PipAlphaAnimator(mPipLeash,
- startTransaction, PipAlphaAnimator.FADE_IN);
- animator.setAnimationEndCallback(() -> finishCallback.onTransitionFinished(null));
+ Rect destinationBounds = pipChange.getEndAbsBounds();
+ SurfaceControl pipLeash = mPipTransitionState.mPinnedTaskLeash;
+ Preconditions.checkNotNull(pipLeash, "Leash is null for alpha transition.");
+
+ // Start transition with 0 alpha at the entry bounds.
+ startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
+ .setWindowCrop(pipLeash, destinationBounds.width(), destinationBounds.height())
+ .setAlpha(pipLeash, 0f);
+
+ PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction,
+ PipAlphaAnimator.FADE_IN);
+ animator.setAnimationEndCallback(() -> {
+ finishCallback.onTransitionFinished(null);
+ // This should update the pip transition state accordingly after we stop playing.
+ onClientDrawAtTransitionEnd();
+ });
animator.start();
return true;
@@ -480,10 +483,10 @@
private boolean isLegacyEnter(@NonNull TransitionInfo info) {
TransitionInfo.Change pipChange = getPipChange(info);
- // If the only change in the changes list is a TO_FRONT mode PiP task,
+ // If the only change in the changes list is a opening type PiP task,
// then this is legacy-enter PiP.
- return pipChange != null && pipChange.getMode() == TRANSIT_TO_FRONT
- && info.getChanges().size() == 1;
+ return pipChange != null && info.getChanges().size() == 1
+ && (pipChange.getMode() == TRANSIT_TO_FRONT || pipChange.getMode() == TRANSIT_OPEN);
}
private boolean isRemovePipTransition(@NonNull TransitionInfo info) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index 01a479f..3dcdc0b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -831,12 +831,12 @@
// We want handle to remain pressed if the pointer moves outside of it during a drag.
handle.setPressed((inHandle && action == ACTION_DOWN)
|| (handle.isPressed() && action != ACTION_UP && action != ACTION_CANCEL));
- if (isHandleMenuActive() && !isMenuAboveStatusBar()) {
+ if (isHandleMenuActive() && !isHandleMenuAboveStatusBar()) {
mHandleMenu.checkMotionEvent(ev);
}
}
- private boolean isMenuAboveStatusBar() {
+ private boolean isHandleMenuAboveStatusBar() {
return Flags.enableAdditionalWindowsAboveStatusBar() && !mTaskInfo.isFreeform();
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
index bfc4e0d..df0836c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
@@ -24,6 +24,7 @@
import static android.view.MotionEvent.ACTION_UP;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
+import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -35,6 +36,7 @@
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
+import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.view.MotionEvent;
@@ -70,8 +72,14 @@
private final DesktopModeWindowDecoration mParentDecor;
@VisibleForTesting
AdditionalViewContainer mHandleMenuViewContainer;
+ // Position of the handle menu used for laying out the handle view.
@VisibleForTesting
final PointF mHandleMenuPosition = new PointF();
+ // With the introduction of {@link AdditionalSystemViewContainer}, {@link mHandleMenuPosition}
+ // may be in a different coordinate space than the input coordinates. Therefore, we still care
+ // about the menu's coordinates relative to the display as a whole, so we need to maintain
+ // those as well.
+ final Point mGlobalMenuPosition = new Point();
private final boolean mShouldShowWindowingPill;
private final Bitmap mAppIconBitmap;
private final CharSequence mAppName;
@@ -244,39 +252,23 @@
private void updateHandleMenuPillPositions() {
int menuX;
final int menuY;
+ final Rect taskBounds = mTaskInfo.getConfiguration().windowConfiguration.getBounds();
+ updateGlobalMenuPosition(taskBounds);
if (mLayoutResId == R.layout.desktop_mode_app_header) {
// Align the handle menu to the left side of the caption.
menuX = mMarginMenuStart;
menuY = mMarginMenuTop;
} else {
- final int handleWidth = loadDimensionPixelSize(mContext.getResources(),
- R.dimen.desktop_mode_fullscreen_decor_caption_width);
- final int handleOffset = (mMenuWidth / 2) - (handleWidth / 2);
- final int captionX = mParentDecor.getCaptionX();
- // TODO(b/343561161): This needs to be calculated differently if the task is in
- // top/bottom split.
if (Flags.enableAdditionalWindowsAboveStatusBar()) {
- final Rect leftOrTopStageBounds = new Rect();
- if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
- == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
- mSplitScreenController.getStageBounds(leftOrTopStageBounds, new Rect());
- }
// In a focused decor, we use global coordinates for handle menu. Therefore we
// need to account for other factors like split stage and menu/handle width to
// center the menu.
final DisplayLayout layout = mDisplayController
.getDisplayLayout(mTaskInfo.displayId);
- menuX = captionX + handleOffset - (layout.width() / 2);
- if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
- == SPLIT_POSITION_BOTTOM_OR_RIGHT && layout.isLandscape()) {
- // If this task in the right stage, we need to offset by left stage's width
- menuX += leftOrTopStageBounds.width();
- }
- menuY = mMarginMenuStart - ((layout.height() - mMenuHeight) / 2);
+ menuX = mGlobalMenuPosition.x + ((mMenuWidth - layout.width()) / 2);
+ menuY = mGlobalMenuPosition.y + ((mMenuHeight - layout.height()) / 2);
} else {
- final int captionWidth = mTaskInfo.getConfiguration()
- .windowConfiguration.getBounds().width();
- menuX = (captionWidth / 2) - (mMenuWidth / 2);
+ menuX = (taskBounds.width() / 2) - (mMenuWidth / 2);
menuY = mMarginMenuTop;
}
}
@@ -284,6 +276,36 @@
mHandleMenuPosition.set(menuX, menuY);
}
+ private void updateGlobalMenuPosition(Rect taskBounds) {
+ if (mTaskInfo.isFreeform()) {
+ mGlobalMenuPosition.set(taskBounds.left + mMarginMenuStart,
+ taskBounds.top + mMarginMenuTop);
+ } else if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+ mGlobalMenuPosition.set(
+ (taskBounds.width() / 2) - (mMenuWidth / 2) + mMarginMenuStart,
+ mMarginMenuTop
+ );
+ } else if (mTaskInfo.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW) {
+ final int splitPosition = mSplitScreenController.getSplitPosition(mTaskInfo.taskId);
+ final Rect leftOrTopStageBounds = new Rect();
+ final Rect rightOrBottomStageBounds = new Rect();
+ mSplitScreenController.getStageBounds(leftOrTopStageBounds,
+ rightOrBottomStageBounds);
+ // TODO(b/343561161): This needs to be calculated differently if the task is in
+ // top/bottom split.
+ if (splitPosition == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ mGlobalMenuPosition.set(leftOrTopStageBounds.width()
+ + (rightOrBottomStageBounds.width() / 2)
+ - (mMenuWidth / 2) + mMarginMenuStart,
+ mMarginMenuTop);
+ } else if (splitPosition == SPLIT_POSITION_TOP_OR_LEFT) {
+ mGlobalMenuPosition.set((leftOrTopStageBounds.width() / 2)
+ - (mMenuWidth / 2) + mMarginMenuStart,
+ mMarginMenuTop);
+ }
+ }
+ }
+
/**
* Update pill layout, in case task changes have caused positioning to change.
*/
@@ -302,6 +324,8 @@
* @param ev the MotionEvent to compare against.
*/
void checkMotionEvent(MotionEvent ev) {
+ // If the menu view is above status bar, we can let the views handle input directly.
+ if (isViewAboveStatusBar()) return;
final View handleMenu = mHandleMenuViewContainer.getView();
final HandleMenuImageButton collapse = handleMenu.findViewById(R.id.collapse_menu_button);
final PointF inputPoint = translateInputToLocalSpace(ev);
@@ -314,6 +338,11 @@
}
}
+ private boolean isViewAboveStatusBar() {
+ return Flags.enableAdditionalWindowsAboveStatusBar()
+ && !mTaskInfo.isFreeform();
+ }
+
// Translate the input point from display coordinates to the same space as the handle menu.
private PointF translateInputToLocalSpace(MotionEvent ev) {
return new PointF(ev.getX() - mHandleMenuPosition.x,
@@ -329,10 +358,33 @@
*/
boolean isValidMenuInput(PointF inputPoint) {
if (!viewsLaidOut()) return true;
- return pointInView(
- mHandleMenuViewContainer.getView(),
- inputPoint.x - mHandleMenuPosition.x,
- inputPoint.y - mHandleMenuPosition.y);
+ if (!isViewAboveStatusBar()) {
+ return pointInView(
+ mHandleMenuViewContainer.getView(),
+ inputPoint.x - mHandleMenuPosition.x,
+ inputPoint.y - mHandleMenuPosition.y);
+ } else {
+ // Handle menu exists in a different coordinate space when added to WindowManager.
+ // Therefore we must compare the provided input coordinates to global menu coordinates.
+ // This includes factoring for split stage as input coordinates are relative to split
+ // stage position, not relative to the display as a whole.
+ PointF inputRelativeToMenu = new PointF(
+ inputPoint.x - mGlobalMenuPosition.x,
+ inputPoint.y - mGlobalMenuPosition.y
+ );
+ if (mSplitScreenController.getSplitPosition(mTaskInfo.taskId)
+ == SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+ // TODO(b/343561161): This also needs to be calculated differently if
+ // the task is in top/bottom split.
+ Rect leftStageBounds = new Rect();
+ mSplitScreenController.getStageBounds(leftStageBounds, new Rect());
+ inputRelativeToMenu.x += leftStageBounds.width();
+ }
+ return pointInView(
+ mHandleMenuViewContainer.getView(),
+ inputRelativeToMenu.x,
+ inputRelativeToMenu.y);
+ }
}
private boolean pointInView(View v, float x, float y) {
diff --git a/location/lib/java/com/android/location/provider/SignificantPlaceProvider.java b/location/lib/java/com/android/location/provider/SignificantPlaceProvider.java
index 0b39a9a..df4b903 100644
--- a/location/lib/java/com/android/location/provider/SignificantPlaceProvider.java
+++ b/location/lib/java/com/android/location/provider/SignificantPlaceProvider.java
@@ -21,17 +21,22 @@
import android.hardware.location.ISignificantPlaceProvider;
import android.hardware.location.ISignificantPlaceProviderManager;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
+import android.util.Log;
import com.android.internal.annotations.GuardedBy;
/** @hide */
-public class SignificantPlaceProvider {
+public abstract class SignificantPlaceProvider {
public static final String ACTION = TrustManager.ACTION_BIND_SIGNIFICANT_PLACE_PROVIDER;
+ private static final String TAG = "SignificantPlaceProvider";
+
private final IBinder mBinder;
// write locked on mBinder, read lock is optional depending on atomicity requirements
@@ -69,6 +74,9 @@
}
}
+ /** Invoked when some client has checked whether the device is in a significant place. */
+ public abstract void onSignificantPlaceCheck();
+
private final class Service extends ISignificantPlaceProvider.Stub {
Service() {}
@@ -76,7 +84,7 @@
@Override
public void setSignificantPlaceProviderManager(ISignificantPlaceProviderManager manager) {
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
- return;
+ throw new SecurityException();
}
synchronized (mBinder) {
@@ -91,5 +99,22 @@
mManager = manager;
}
}
+
+ @Override
+ public void onSignificantPlaceCheck() {
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ throw new SecurityException();
+ }
+
+ try {
+ SignificantPlaceProvider.this.onSignificantPlaceCheck();
+ } catch (RuntimeException e) {
+ // exceptions on one-way binder threads are dropped - move to a different thread
+ Log.w(TAG, e);
+ new Handler(Looper.getMainLooper()).post(() -> {
+ throw new AssertionError(e);
+ });
+ }
+ }
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
index 9891b5b..3295dde 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
@@ -17,6 +17,7 @@
package com.android.systemui.volume.panel.component.spatialaudio.ui.composable
import android.view.Gravity
+import androidx.annotation.VisibleForTesting
import androidx.compose.foundation.basicMarquee
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
@@ -71,7 +72,8 @@
}
@Composable
- private fun Content(dialog: SystemUIDialog) {
+ @VisibleForTesting
+ fun Content(dialog: SystemUIDialog) {
val isAvailable by viewModel.isAvailable.collectAsStateWithLifecycle()
if (!isAvailable) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
index 04b930e..07d8890 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/ambient/touch/ShadeTouchHandlerTest.java
@@ -25,12 +25,15 @@
import static org.mockito.Mockito.when;
import android.app.DreamManager;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
import android.view.GestureDetector;
import android.view.MotionEvent;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.InputChannelCompat;
@@ -87,7 +90,7 @@
assertThat(captured).isTrue();
}
- // Verifies that a swipe in the upward direction is not catpured.
+ // Verifies that a swipe in the upward direction is not captured.
@Test
public void testSwipeUp_notCaptured() {
final boolean captured = swipe(Direction.UP);
@@ -98,34 +101,58 @@
// Verifies that a swipe down forwards captured touches to central surfaces for handling.
@Test
- public void testSwipeDown_sentToCentralSurfaces() {
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+ public void testSwipeDown_communalEnabled_sentToCentralSurfaces() {
swipe(Direction.DOWN);
- // Both motion events are sent for the shade window to process.
+ // Both motion events are sent for central surfaces to process.
verify(mCentralSurfaces, times(2)).handleExternalShadeWindowTouch(any());
}
- // Verifies that a swipe down forwards captured touches to central surfaces for handling.
+ // Verifies that a swipe down forwards captured touches to the shade view for handling.
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+ public void testSwipeDown_communalDisabled_sentToShadeView() {
+ swipe(Direction.DOWN);
+
+ // Both motion events are sent for the shade view to process.
+ verify(mShadeViewController, times(2)).handleExternalTouch(any());
+ }
+
+ // Verifies that a swipe down while dreaming forwards captured touches to the shade view for
+ // handling.
@Test
public void testSwipeDown_dreaming_sentToShadeView() {
when(mDreamManager.isDreaming()).thenReturn(true);
swipe(Direction.DOWN);
- // Both motion events are sent for the shade window to process.
+ // Both motion events are sent for the shade view to process.
verify(mShadeViewController, times(2)).handleExternalTouch(any());
}
- // Verifies that a swipe down is not forwarded to the shade window.
+ // Verifies that a swipe up is not forwarded to central surfaces.
@Test
- public void testSwipeUp_touchesNotSent() {
+ @EnableFlags(Flags.FLAG_COMMUNAL_HUB)
+ public void testSwipeUp_communalEnabled_touchesNotSent() {
swipe(Direction.UP);
- // Motion events are not sent for the shade window to process as the swipe is going in the
+ // Motion events are not sent for central surfaces to process as the swipe is going in the
// wrong direction.
verify(mCentralSurfaces, never()).handleExternalShadeWindowTouch(any());
}
+ // Verifies that a swipe up is not forwarded to the shade view.
+ @Test
+ @DisableFlags(Flags.FLAG_COMMUNAL_HUB)
+ public void testSwipeUp_communalDisabled_touchesNotSent() {
+ swipe(Direction.UP);
+
+ // Motion events are not sent for the shade view to process as the swipe is going in the
+ // wrong direction.
+ verify(mShadeViewController, never()).handleExternalTouch(any());
+ }
+
/**
* Simulates a swipe in the given direction and returns true if the touch was intercepted by the
* touch handler's gesture listener.
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
index 426f484..50477b1 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt
@@ -70,8 +70,6 @@
private var shouldOpenWidgetPickerOnStart = false
- private var lockOnDestroy = false
-
private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> =
registerForActivityResult(StartActivityForResult()) { result ->
when (result.resultCode) {
@@ -97,8 +95,7 @@
run { Log.w(TAG, "No AppWidgetProviderInfo found in result.") }
}
}
- }
- ?: run { Log.w(TAG, "No data in result.") }
+ } ?: run { Log.w(TAG, "No data in result.") }
}
else ->
Log.w(
@@ -160,9 +157,9 @@
// Wait for the current scene to be idle on communal.
communalViewModel.isIdleOnCommunal.first { it }
- // Then finish the activity (this helps to avoid a flash of lockscreen when locking
- // in onDestroy()).
- lockOnDestroy = true
+
+ // Lock to go back to the hub after exiting.
+ lockNow()
finish()
}
}
@@ -196,8 +193,6 @@
override fun onDestroy() {
super.onDestroy()
communalViewModel.setEditModeOpen(false)
-
- if (lockOnDestroy) lockNow()
}
private fun lockNow() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepository.kt
index d38e834..1d08f2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepository.kt
@@ -25,6 +25,9 @@
* given mobile data subscription.
*/
interface DeviceBasedSatelliteRepository {
+ /** The current status of satellite provisioning. If not false, we don't want to show an icon */
+ val isSatelliteProvisioned: StateFlow<Boolean>
+
/** See [SatelliteConnectionState] for available states */
val connectionState: StateFlow<SatelliteConnectionState>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcher.kt
index 6b1bc65..58c30e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/DeviceBasedSatelliteRepositorySwitcher.kt
@@ -97,6 +97,11 @@
}
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl)
+ override val isSatelliteProvisioned: StateFlow<Boolean> =
+ activeRepo
+ .flatMapLatest { it.isSatelliteProvisioned }
+ .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.isSatelliteProvisioned.value)
+
override val connectionState: StateFlow<SatelliteConnectionState> =
activeRepo
.flatMapLatest { it.connectionState }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepository.kt
index 56034f0..6ad295e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/demo/DemoDeviceBasedSatelliteRepository.kt
@@ -36,6 +36,7 @@
) : DeviceBasedSatelliteRepository {
private var demoCommandJob: Job? = null
+ override val isSatelliteProvisioned = MutableStateFlow(true)
override val connectionState = MutableStateFlow(SatelliteConnectionState.Unknown)
override val signalStrength = MutableStateFlow(0)
override val isSatelliteAllowedForCurrentLocation = MutableStateFlow(true)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
index 1449e53..ec3af87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
@@ -23,6 +23,7 @@
import android.telephony.satellite.SatelliteManager
import android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS
import android.telephony.satellite.SatelliteModemStateCallback
+import android.telephony.satellite.SatelliteProvisionStateCallback
import android.telephony.satellite.SatelliteSupportedStateCallback
import androidx.annotation.VisibleForTesting
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -337,6 +338,43 @@
}
}
+ override val isSatelliteProvisioned: StateFlow<Boolean> =
+ satelliteSupport
+ .whenSupported(
+ supported = ::satelliteProvisioned,
+ orElse = flowOf(false),
+ retrySignal = telephonyProcessCrashedEvent,
+ )
+ .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+
+ private fun satelliteProvisioned(sm: SupportedSatelliteManager): Flow<Boolean> =
+ conflatedCallbackFlow {
+ val callback = SatelliteProvisionStateCallback { provisioned ->
+ logBuffer.i {
+ "onSatelliteProvisionStateChanged: " +
+ if (provisioned) "provisioned" else "not provisioned"
+ }
+ trySend(provisioned)
+ }
+
+ var registered = false
+ try {
+ sm.registerForProvisionStateChanged(
+ bgDispatcher.asExecutor(),
+ callback,
+ )
+ registered = true
+ } catch (e: Exception) {
+ logBuffer.e("error registering for provisioning state callback", e)
+ }
+
+ awaitClose {
+ if (registered) {
+ sm.unregisterForProvisionStateChanged(callback)
+ }
+ }
+ }
+
/**
* Signal that we should start polling [checkIsSatelliteAllowed]. We only need to poll if there
* are active listeners to [isSatelliteAllowedForCurrentLocation]
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index b66ace6..03f88c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -27,7 +27,6 @@
import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -45,7 +44,6 @@
constructor(
val repo: DeviceBasedSatelliteRepository,
iconsInteractor: MobileIconsInteractor,
- deviceProvisioningInteractor: DeviceProvisioningInteractor,
wifiInteractor: WifiInteractor,
@Application scope: CoroutineScope,
@DeviceBasedSatelliteInputLog private val logBuffer: LogBuffer,
@@ -78,7 +76,7 @@
}
.stateIn(scope, SharingStarted.WhileSubscribed(), 0)
- val isDeviceProvisioned: Flow<Boolean> = deviceProvisioningInteractor.isDeviceProvisioned
+ val isSatelliteProvisioned = repo.isSatelliteProvisioned
val isWifiActive: Flow<Boolean> =
wifiInteractor.wifiNetwork.map { it is WifiNetworkModel.Active }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
index 0ed1b9b..48278d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
@@ -79,11 +79,11 @@
} else {
combine(
interactor.isSatelliteAllowed,
- interactor.isDeviceProvisioned,
+ interactor.isSatelliteProvisioned,
interactor.isWifiActive,
airplaneModeRepository.isAirplaneMode
- ) { isSatelliteAllowed, isDeviceProvisioned, isWifiActive, isAirplaneMode ->
- isSatelliteAllowed && isDeviceProvisioned && !isWifiActive && !isAirplaneMode
+ ) { isSatelliteAllowed, isSatelliteProvisioned, isWifiActive, isAirplaneMode ->
+ isSatelliteAllowed && isSatelliteProvisioned && !isWifiActive && !isAirplaneMode
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
index 6c6a1cc..324579d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
@@ -57,7 +57,7 @@
.toViewModel(
isChecked = isEnabled is SpatialAudioEnabledModel.SpatialAudioEnabled,
isHeadTrackingAvailable =
- isAvailable is SpatialAudioAvailabilityModel.SpatialAudio,
+ isAvailable is SpatialAudioAvailabilityModel.HeadTracking,
)
.copy(label = context.getString(R.string.volume_panel_spatial_audio_title))
}
@@ -69,7 +69,7 @@
// head tracking availability means there are three possible states for the spatial
// audio: disabled, enabled regular, enabled with head tracking.
// Show popup in this case instead of a togglealbe button.
- it is SpatialAudioAvailabilityModel.SpatialAudio
+ it is SpatialAudioAvailabilityModel.HeadTracking
}
.stateIn(scope, SharingStarted.Eagerly, false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
index d24d87c6..890a2e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImplTest.kt
@@ -34,6 +34,7 @@
import android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN
import android.telephony.satellite.SatelliteManager.SatelliteException
import android.telephony.satellite.SatelliteModemStateCallback
+import android.telephony.satellite.SatelliteProvisionStateCallback
import android.telephony.satellite.SatelliteSupportedStateCallback
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -326,6 +327,98 @@
}
@Test
+ fun satelliteProvisioned_notSupported_defaultFalse() =
+ testScope.runTest {
+ // GIVEN satellite is not supported
+ setUpRepo(
+ uptime = MIN_UPTIME,
+ satMan = satelliteManager,
+ satelliteSupported = false,
+ )
+
+ assertThat(underTest.isSatelliteProvisioned.value).isFalse()
+ }
+
+ @Test
+ fun satelliteProvisioned_supported_defaultFalse() =
+ testScope.runTest {
+ // GIVEN satellite is supported
+ setUpRepo(
+ uptime = MIN_UPTIME,
+ satMan = satelliteManager,
+ satelliteSupported = true,
+ )
+
+ // THEN default provisioned state is false
+ assertThat(underTest.isSatelliteProvisioned.value).isFalse()
+ }
+
+ @Test
+ fun satelliteProvisioned_supported_tracksCallback() =
+ testScope.runTest {
+ // GIVEN satellite is not supported
+ setUpRepo(
+ uptime = MIN_UPTIME,
+ satMan = satelliteManager,
+ satelliteSupported = true,
+ )
+
+ val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+ runCurrent()
+
+ val callback =
+ withArgCaptor<SatelliteProvisionStateCallback> {
+ verify(satelliteManager).registerForProvisionStateChanged(any(), capture())
+ }
+
+ // WHEN provisioning state changes
+ callback.onSatelliteProvisionStateChanged(true)
+
+ // THEN the value is reflected in the repo
+ assertThat(provisioned).isTrue()
+ }
+
+ @Test
+ fun satelliteProvisioned_supported_tracksCallback_reRegistersOnCrash() =
+ testScope.runTest {
+ // GIVEN satellite is supported
+ setUpRepo(
+ uptime = MIN_UPTIME,
+ satMan = satelliteManager,
+ satelliteSupported = true,
+ )
+
+ val provisioned by collectLastValue(underTest.isSatelliteProvisioned)
+
+ runCurrent()
+
+ val callback =
+ withArgCaptor<SatelliteProvisionStateCallback> {
+ verify(satelliteManager).registerForProvisionStateChanged(any(), capture())
+ }
+ val telephonyCallback =
+ MobileTelephonyHelpers.getTelephonyCallbackForType<
+ TelephonyCallback.RadioPowerStateListener
+ >(
+ telephonyManager
+ )
+
+ // GIVEN satellite is currently provisioned
+ callback.onSatelliteProvisionStateChanged(true)
+
+ assertThat(provisioned).isTrue()
+
+ // WHEN a crash event happens (detected by radio state change)
+ telephonyCallback.onRadioPowerStateChanged(TelephonyManager.RADIO_POWER_ON)
+ runCurrent()
+ telephonyCallback.onRadioPowerStateChanged(TelephonyManager.RADIO_POWER_OFF)
+ runCurrent()
+
+ // THEN listeners are re-registered
+ verify(satelliteManager, times(2)).registerForProvisionStateChanged(any(), any())
+ }
+
+ @Test
fun satelliteNotSupported_listenersAreNotRegistered() =
testScope.runTest {
// GIVEN satellite is not supported
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
index 5fa2d33..55460bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/FakeDeviceBasedSatelliteRepository.kt
@@ -21,6 +21,8 @@
import kotlinx.coroutines.flow.MutableStateFlow
class FakeDeviceBasedSatelliteRepository() : DeviceBasedSatelliteRepository {
+ override val isSatelliteProvisioned = MutableStateFlow(true)
+
override val connectionState = MutableStateFlow(Off)
override val signalStrength = MutableStateFlow(0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index d303976..2e5ebb3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -31,8 +31,6 @@
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
-import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -55,9 +53,6 @@
)
private val repo = FakeDeviceBasedSatelliteRepository()
- private val deviceProvisionedRepository = FakeDeviceProvisioningRepository()
- private val deviceProvisioningInteractor =
- DeviceProvisioningInteractor(deviceProvisionedRepository)
private val connectivityRepository = FakeConnectivityRepository()
private val wifiRepository = FakeWifiRepository()
private val wifiInteractor =
@@ -69,7 +64,6 @@
DeviceBasedSatelliteInteractor(
repo,
iconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
@@ -113,7 +107,6 @@
DeviceBasedSatelliteInteractor(
repo,
iconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
@@ -162,7 +155,6 @@
DeviceBasedSatelliteInteractor(
repo,
iconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
@@ -219,7 +211,6 @@
DeviceBasedSatelliteInteractor(
repo,
iconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
@@ -538,7 +529,6 @@
DeviceBasedSatelliteInteractor(
repo,
iconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index 43b9568..c39e301 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -32,8 +32,6 @@
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
-import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
-import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
@@ -55,9 +53,6 @@
private val mobileIconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
- private val deviceProvisionedRepository = FakeDeviceProvisioningRepository()
- private val deviceProvisioningInteractor =
- DeviceProvisioningInteractor(deviceProvisionedRepository)
private val connectivityRepository = FakeConnectivityRepository()
private val wifiRepository = FakeWifiRepository()
private val wifiInteractor =
@@ -72,7 +67,6 @@
DeviceBasedSatelliteInteractor(
repo,
mobileIconsInteractor,
- deviceProvisioningInteractor,
wifiInteractor,
testScope.backgroundScope,
FakeLogBuffer.Factory.create(),
@@ -252,14 +246,14 @@
// GIVEN apm is disabled
airplaneModeRepository.setIsAirplaneMode(false)
- // GIVEN device is not provisioned
- deviceProvisionedRepository.setDeviceProvisioned(false)
+ // GIVEN satellite is not provisioned
+ repo.isSatelliteProvisioned.value = false
// THEN icon is null because the device is not provisioned
assertThat(latest).isNull()
- // GIVEN device becomes provisioned
- deviceProvisionedRepository.setDeviceProvisioned(true)
+ // GIVEN satellite becomes provisioned
+ repo.isSatelliteProvisioned.value = true
// Wait for delay to be completed
advanceTimeBy(10.seconds)
@@ -285,8 +279,8 @@
// GIVEN apm is disabled
airplaneModeRepository.setIsAirplaneMode(false)
- // GIVEN device is provisioned
- deviceProvisionedRepository.setDeviceProvisioned(true)
+ // GIVEN satellite is provisioned
+ repo.isSatelliteProvisioned.value = true
// GIVEN wifi network is active
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(networkId = 0, level = 1))
@@ -474,14 +468,14 @@
// GIVEN apm is disabled
airplaneModeRepository.setIsAirplaneMode(false)
- // GIVEN device is not provisioned
- deviceProvisionedRepository.setDeviceProvisioned(false)
+ // GIVEN satellite is not provisioned
+ repo.isSatelliteProvisioned.value = false
// THEN carrier text is null because the device is not provisioned
assertThat(latest).isNull()
- // GIVEN device becomes provisioned
- deviceProvisionedRepository.setDeviceProvisioned(true)
+ // GIVEN satellite becomes provisioned
+ repo.isSatelliteProvisioned.value = true
// Wait for delay to be completed
advanceTimeBy(10.seconds)
@@ -508,8 +502,8 @@
// GIVEN apm is disabled
airplaneModeRepository.setIsAirplaneMode(false)
- // GIVEN device is provisioned
- deviceProvisionedRepository.setDeviceProvisioned(true)
+ // GIVEN satellite is provisioned
+ repo.isSatelliteProvisioned.value = true
// GIVEN wifi network is active
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(networkId = 0, level = 1))
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
index 5a092f3..62e56be 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/animation/DialogTransitionAnimatorKosmos.kt
@@ -16,16 +16,16 @@
package com.android.systemui.animation
+import android.content.applicationContext
import com.android.systemui.jank.interactionJankMonitor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.testCase
val Kosmos.dialogTransitionAnimator by Fixture {
fakeDialogTransitionAnimator(
// The main thread is checked in a bunch of places inside the different transitions
// animators, so we have to pass the real main executor here.
- mainExecutor = testCase.context.mainExecutor,
+ mainExecutor = applicationContext.mainExecutor,
interactionJankMonitor = interactionJankMonitor,
)
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopupKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopupKosmos.kt
new file mode 100644
index 0000000..49170d8
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopupKosmos.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.panel.component.popup.ui.composable
+
+import com.android.systemui.animation.dialogTransitionAnimator
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.phone.systemUIDialogFactory
+
+val Kosmos.volumePanelPopup: VolumePanelPopup by
+ Kosmos.Fixture { VolumePanelPopup(systemUIDialogFactory, dialogTransitionAnimator) }
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 167c384..53730e3 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -227,6 +227,7 @@
"connectivity_flags_lib",
"dreams_flags_lib",
"aconfig_new_storage_flags_lib",
+ "powerstats_flags_lib",
],
javac_shard_size: 50,
javacflags: [
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 60290bc..e424ffa 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3892,9 +3892,10 @@
return;
}
- final long lastTopTime = sr.app.mState.getLastTopTime();
- final long constantTimeLimit = getTimeLimitForFgsType(fgsType);
+ final boolean currentlyTop = sr.app.mState.getCurProcState() <= PROCESS_STATE_TOP;
final long nowUptime = SystemClock.uptimeMillis();
+ final long lastTopTime = currentlyTop ? nowUptime : sr.app.mState.getLastTopTime();
+ final long constantTimeLimit = getTimeLimitForFgsType(fgsType);
if (lastTopTime != Long.MIN_VALUE && constantTimeLimit > (nowUptime - lastTopTime)) {
// Discard any other messages for this service
mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_FGS_TIMEOUT_MSG, sr);
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
index e6de14b..16514fa 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
@@ -29,6 +29,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -121,8 +122,7 @@
+ " without permission " + Manifest.permission.DUMP);
return;
}
- android.util.IndentingPrintWriter radioPrintWriter =
- new android.util.IndentingPrintWriter(printWriter);
+ IndentingPrintWriter radioPrintWriter = new IndentingPrintWriter(printWriter);
radioPrintWriter.printf("BroadcastRadioService\n");
radioPrintWriter.increaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index 93fb7b2..ab08342 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -26,6 +26,7 @@
import android.hardware.radio.RadioManager;
import android.os.Binder;
import android.os.RemoteException;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
@@ -138,7 +139,7 @@
+ " without permission " + Manifest.permission.DUMP);
return;
}
- android.util.IndentingPrintWriter radioPw = new android.util.IndentingPrintWriter(pw);
+ IndentingPrintWriter radioPw = new IndentingPrintWriter(pw);
radioPw.printf("BroadcastRadioService\n");
radioPw.increaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java
index 2c8f499..b71589c 100644
--- a/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java
+++ b/services/core/java/com/android/server/broadcastradio/RadioEventLogger.java
@@ -17,6 +17,7 @@
package com.android.server.broadcastradio;
import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;
@@ -54,7 +55,7 @@
* Dump broadcast radio service event
* @param pw Indenting print writer for dump
*/
- public void dump(android.util.IndentingPrintWriter pw) {
+ public void dump(IndentingPrintWriter pw) {
mEventLogger.dump(pw);
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java
index 9654a93..b618aa3 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/AnnouncementAggregator.java
@@ -22,6 +22,7 @@
import android.hardware.radio.ICloseHandle;
import android.os.IBinder;
import android.os.RemoteException;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
@@ -93,7 +94,7 @@
if (mCloseHandle != null) mCloseHandle.close();
}
- public void dumpInfo(android.util.IndentingPrintWriter pw) {
+ public void dumpInfo(IndentingPrintWriter pw) {
pw.printf("ModuleWatcher:\n");
pw.increaseIndent();
@@ -191,8 +192,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
- android.util.IndentingPrintWriter announcementPrintWriter =
- new android.util.IndentingPrintWriter(printWriter);
+ IndentingPrintWriter announcementPrintWriter = new IndentingPrintWriter(printWriter);
announcementPrintWriter.printf("AnnouncementAggregator\n");
announcementPrintWriter.increaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
index 1c42161..d9f8588 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
@@ -29,6 +29,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.SparseArray;
@@ -128,7 +129,7 @@
if (entry.getValue() == mModuleId) {
Slogf.w(TAG, "Service %s died, removed RadioModule with ID %d",
entry.getKey(), mModuleId);
- return;
+ break;
}
}
}
@@ -260,7 +261,7 @@
*
* @param pw The file to which {@link BroadcastRadioServiceImpl} state is dumped.
*/
- public void dumpInfo(android.util.IndentingPrintWriter pw) {
+ public void dumpInfo(IndentingPrintWriter pw) {
synchronized (mLock) {
pw.printf("Next module id available: %d\n", mNextModuleId);
pw.printf("ServiceName to module id map:\n");
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index 0cac356..03e347a 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -38,6 +38,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -524,7 +525,7 @@
return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
}
- void dumpInfo(android.util.IndentingPrintWriter pw) {
+ void dumpInfo(IndentingPrintWriter pw) {
pw.printf("RadioModule\n");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index 925f149..e90a1dd 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -29,6 +29,7 @@
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
import com.android.server.broadcastradio.RadioEventLogger;
@@ -434,7 +435,7 @@
}
}
- void dumpInfo(android.util.IndentingPrintWriter pw) {
+ void dumpInfo(IndentingPrintWriter pw) {
pw.printf("TunerSession\n");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index e1650c2..a4efa2e 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -30,6 +30,7 @@
import android.os.IHwBinder.DeathRecipient;
import android.os.RemoteException;
import android.util.ArrayMap;
+import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -115,7 +116,7 @@
if (entry.getValue() == moduleId) {
Slogf.i(TAG, "service " + entry.getKey()
+ " died; removed RadioModule with ID " + moduleId);
- return;
+ break;
}
}
}
@@ -221,7 +222,7 @@
*
* @param pw The file to which BroadcastRadioService state is dumped.
*/
- public void dumpInfo(android.util.IndentingPrintWriter pw) {
+ public void dumpInfo(IndentingPrintWriter pw) {
synchronized (mLock) {
pw.printf("Next module id available: %d\n", mNextModuleId);
pw.printf("ServiceName to module id map:\n");
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 7269f24..d3b2448 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -40,6 +40,7 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import android.util.MutableInt;
import com.android.internal.annotations.GuardedBy;
@@ -453,7 +454,7 @@
return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
}
- void dumpInfo(android.util.IndentingPrintWriter pw) {
+ void dumpInfo(IndentingPrintWriter pw) {
pw.printf("RadioModule\n");
pw.increaseIndent();
pw.printf("BroadcastRadioService: %s\n", mService);
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index b1b5d34..80efacd 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -31,6 +31,7 @@
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import android.util.MutableBoolean;
import android.util.MutableInt;
@@ -324,9 +325,7 @@
try {
isConfigFlagSet(flag);
return true;
- } catch (IllegalStateException ex) {
- return true;
- } catch (UnsupportedOperationException ex) {
+ } catch (IllegalStateException | UnsupportedOperationException ex) {
return false;
}
}
@@ -389,7 +388,7 @@
}
}
- void dumpInfo(android.util.IndentingPrintWriter pw) {
+ void dumpInfo(IndentingPrintWriter pw) {
pw.printf("TunerSession\n");
pw.increaseIndent();
pw.printf("HIDL HAL Session: %s\n", mHwSession);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d4aa683..9f7f550 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -227,6 +227,16 @@
}
/**
+ * Indicates that the annotated field is shared by all the users.
+ *
+ * <p>See b/305849394 for details.</p>
+ */
+ @Retention(SOURCE)
+ @Target({ElementType.FIELD})
+ private @interface SharedByAllUsersField {
+ }
+
+ /**
* Indicates that the annotated field is not yet ready for concurrent multi-user support.
*
* <p>See b/305849394 for details.</p>
@@ -272,6 +282,7 @@
* {@link LayoutParams#SOFT_INPUT_STATE_ALWAYS_VISIBLE SOFT_INPUT_STATE_ALWAYS_VISIBLE}
* starting from {@link android.os.Build.VERSION_CODES#P}.
*/
+ @SharedByAllUsersField
private final boolean mPreventImeStartupUnlessTextEditor;
/**
@@ -279,6 +290,7 @@
* from the IME startup avoidance behavior that is enabled by
* {@link #mPreventImeStartupUnlessTextEditor}.
*/
+ @SharedByAllUsersField
@NonNull
private final String[] mNonPreemptibleInputMethods;
@@ -286,6 +298,7 @@
* See {@link #shouldEnableExperimentalConcurrentMultiUserMode(Context)} about when set to be
* {@code true}.
*/
+ @SharedByAllUsersField
private final boolean mExperimentalConcurrentMultiUserModeEnabled;
/**
@@ -327,6 +340,7 @@
final PackageManagerInternal mPackageManagerInternal;
final InputManagerInternal mInputManagerInternal;
final ImePlatformCompatUtils mImePlatformCompatUtils;
+ @SharedByAllUsersField
final InputMethodDeviceConfigs mInputMethodDeviceConfigs;
private final UserManagerInternal mUserManagerInternal;
@@ -339,6 +353,7 @@
private final ImeVisibilityStateComputer mVisibilityStateComputer;
@GuardedBy("ImfLock.class")
+ @SharedByAllUsersField
@NonNull
private final DefaultImeVisibilityApplier mVisibilityApplier;
@@ -355,7 +370,7 @@
// Mapping from deviceId to the device-specific imeId for that device.
@GuardedBy("ImfLock.class")
- @MultiUserUnawareField
+ @SharedByAllUsersField
private final SparseArray<String> mVirtualDeviceMethodMap = new SparseArray<>();
// TODO: Instantiate mSwitchingController for each user.
@@ -373,12 +388,13 @@
@Nullable
private StatusBarManagerInternal mStatusBarManagerInternal;
+ @SharedByAllUsersField
private boolean mShowOngoingImeSwitcherForPhones;
@GuardedBy("ImfLock.class")
@MultiUserUnawareField
private final HandwritingModeController mHwController;
@GuardedBy("ImfLock.class")
- @MultiUserUnawareField
+ @SharedByAllUsersField
private IntArray mStylusIds;
@GuardedBy("ImfLock.class")
@@ -457,6 +473,7 @@
/**
* Manages the IME clients.
*/
+ @SharedByAllUsersField
private final ClientController mClientController;
/**
@@ -468,6 +485,7 @@
/**
* Set once the system is ready to run third party code.
*/
+ @SharedByAllUsersField
boolean mSystemReady;
@GuardedBy("ImfLock.class")
@@ -504,6 +522,7 @@
/**
* The client that is currently bound to an input method.
*/
+ @MultiUserUnawareField
@Nullable
private ClientState mCurClient;
@@ -555,6 +574,7 @@
* {@link android.view.InsetsController} for the given window.
*/
@GuardedBy("ImfLock.class")
+ @SharedByAllUsersField
private final WeakHashMap<IBinder, Boolean> mFocusedWindowPerceptible = new WeakHashMap<>();
/**
@@ -659,28 +679,36 @@
@MultiUserUnawareField
int mImeWindowVis;
+ @SharedByAllUsersField
private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor();
+
+ @SharedByAllUsersField
private final String mSlotIme;
/**
* Registered {@link InputMethodListListener}.
* This variable can be accessed from both of MainThread and BinderThread.
*/
+ @SharedByAllUsersField
private final CopyOnWriteArrayList<InputMethodListListener> mInputMethodListListeners =
new CopyOnWriteArrayList<>();
@GuardedBy("ImfLock.class")
+ @SharedByAllUsersField
private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
@GuardedBy("ImfLock.class")
+ @SharedByAllUsersField
@NonNull
private final StartInputHistory mStartInputHistory = new StartInputHistory();
@GuardedBy("ImfLock.class")
+ @SharedByAllUsersField
@NonNull
private final SoftInputShowHideHistory mSoftInputShowHideHistory =
new SoftInputShowHideHistory();
+ @SharedByAllUsersField
@NonNull
private final ImeTrackerService mImeTrackerService;
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index 2081f73..0acadb1 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -16,7 +16,12 @@
package com.android.server.pm;
+import static android.content.pm.PackageManager.GET_RESOLVED_FILTER;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.os.Process.INVALID_UID;
+import static android.os.Process.SYSTEM_UID;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -25,6 +30,7 @@
import android.app.ActivityManager;
import android.app.admin.SecurityLog;
import android.content.ComponentName;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.Flags;
import android.content.pm.PackageManager;
@@ -376,7 +382,30 @@
mCallingUid = callingUid;
}
- public boolean isSameComponent(ActivityInfo activityInfo) {
+ public boolean isLauncherActivity(@NonNull Computer computer, @UserIdInt int userId) {
+ if (mIsForWholeApp) {
+ return false;
+ }
+ // Query the launcher activities with the package name.
+ final Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setPackage(mPackageName);
+ List<ResolveInfo> launcherActivities = computer.queryIntentActivitiesInternal(
+ intent, null,
+ MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE | GET_RESOLVED_FILTER
+ | MATCH_DISABLED_COMPONENTS, SYSTEM_UID, userId);
+ final int launcherActivitiesSize =
+ launcherActivities != null ? launcherActivities.size() : 0;
+ for (int i = 0; i < launcherActivitiesSize; i++) {
+ ResolveInfo resolveInfo = launcherActivities.get(i);
+ if (isSameComponent(resolveInfo.activityInfo)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean isSameComponent(ActivityInfo activityInfo) {
if (activityInfo == null) {
return false;
}
@@ -395,25 +424,13 @@
Slog.d(TAG, "Fail to report component state due to metrics is empty");
return;
}
- boolean isLauncher = false;
- final List<ResolveInfo> resolveInfosForLauncher = getHomeActivitiesResolveInfoAsUser(
- computer, userId);
- final int resolveInfosForLauncherSize =
- resolveInfosForLauncher != null ? resolveInfosForLauncher.size() : 0;
final int metricsSize = componentStateMetricsList.size();
for (int i = 0; i < metricsSize; i++) {
final ComponentStateMetrics componentStateMetrics = componentStateMetricsList.get(i);
- for (int j = 0; j < resolveInfosForLauncherSize; j++) {
- ResolveInfo resolveInfo = resolveInfosForLauncher.get(j);
- if (componentStateMetrics.isSameComponent(resolveInfo.activityInfo)) {
- isLauncher = true;
- break;
- }
- }
reportComponentStateChanged(componentStateMetrics.mUid,
componentStateMetrics.mComponentOldState,
componentStateMetrics.mComponentNewState,
- isLauncher,
+ componentStateMetrics.isLauncherActivity(computer, userId),
componentStateMetrics.mIsForWholeApp,
componentStateMetrics.mCallingUid);
}
@@ -424,10 +441,4 @@
FrameworkStatsLog.write(FrameworkStatsLog.COMPONENT_STATE_CHANGED_REPORTED,
uid, componentOldState, componentNewState, isLauncher, isForWholeApp, callingUid);
}
-
- private static List<ResolveInfo> getHomeActivitiesResolveInfoAsUser(@NonNull Computer computer,
- @UserIdInt int userId) {
- return computer.queryIntentActivitiesInternal(computer.getHomeIntent(), /* resolvedType */
- null, /* flags */ 0, userId);
- }
}
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 483d308..95e5b84 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -156,7 +156,8 @@
UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
UserManager.DISALLOW_SIM_GLOBALLY,
UserManager.DISALLOW_ASSIST_CONTENT,
- UserManager.DISALLOW_THREAD_NETWORK
+ UserManager.DISALLOW_THREAD_NETWORK,
+ UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
});
public static final Set<String> DEPRECATED_USER_RESTRICTIONS = Sets.newArraySet(
@@ -208,7 +209,8 @@
UserManager.DISALLOW_CELLULAR_2G,
UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
- UserManager.DISALLOW_THREAD_NETWORK
+ UserManager.DISALLOW_THREAD_NETWORK,
+ UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
);
/**
@@ -254,7 +256,8 @@
UserManager.DISALLOW_CELLULAR_2G,
UserManager.DISALLOW_ULTRA_WIDEBAND_RADIO,
UserManager.DISALLOW_NEAR_FIELD_COMMUNICATION_RADIO,
- UserManager.DISALLOW_THREAD_NETWORK
+ UserManager.DISALLOW_THREAD_NETWORK,
+ UserManager.DISALLOW_CHANGE_NEAR_FIELD_COMMUNICATION_RADIO
);
/**
diff --git a/services/core/java/com/android/server/powerstats/Android.bp b/services/core/java/com/android/server/powerstats/Android.bp
new file mode 100644
index 0000000..7f3b091
--- /dev/null
+++ b/services/core/java/com/android/server/powerstats/Android.bp
@@ -0,0 +1,11 @@
+aconfig_declarations {
+ name: "powerstats_flags",
+ package: "com.android.server.powerstats",
+ container: "system",
+ srcs: ["*.aconfig"],
+}
+
+java_aconfig_library {
+ name: "powerstats_flags_lib",
+ aconfig_declarations: "powerstats_flags",
+}
diff --git a/services/core/java/com/android/server/powerstats/TimerTrigger.java b/services/core/java/com/android/server/powerstats/TimerTrigger.java
index f8a4135..817a40d 100644
--- a/services/core/java/com/android/server/powerstats/TimerTrigger.java
+++ b/services/core/java/com/android/server/powerstats/TimerTrigger.java
@@ -16,8 +16,10 @@
package com.android.server.powerstats;
+import android.app.AlarmManager;
import android.content.Context;
import android.os.Handler;
+import android.os.SystemClock;
import android.util.Slog;
/**
@@ -33,37 +35,53 @@
private static final long LOG_PERIOD_MS_HIGH_FREQUENCY = 2 * 60 * 1000; // 2 minutes
private final Handler mHandler;
+ private final AlarmManager mAlarmManager;
- private Runnable mLogDataLowFrequency = new Runnable() {
+ class PeriodicTimer implements Runnable, AlarmManager.OnAlarmListener {
+ private final String mName;
+ private final long mPeriodMs;
+ private final int mMsgType;
+
+ PeriodicTimer(String name, long periodMs, int msgType) {
+ mName = name;
+ mPeriodMs = periodMs;
+ mMsgType = msgType;
+ }
+
+ @Override
+ public void onAlarm() {
+ run();
+ }
+
@Override
public void run() {
- // Do not wake the device for these messages. Opportunistically log rail data every
- // LOG_PERIOD_MS_LOW_FREQUENCY.
- mHandler.postDelayed(mLogDataLowFrequency, LOG_PERIOD_MS_LOW_FREQUENCY);
- if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data low frequency");
- logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY);
+ if (Flags.alarmBasedPowerstatsLogging()) {
+ final long nextAlarmMs = SystemClock.elapsedRealtime() + mPeriodMs;
+ mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmMs,
+ AlarmManager.WINDOW_EXACT, 0, mName, this, mHandler, null);
+ } else {
+ mHandler.postDelayed(this, mPeriodMs);
+ }
+ if (DEBUG) Slog.d(TAG, "Received delayed message (" + mName + "). Logging rail data");
+ logPowerStatsData(mMsgType);
}
- };
-
- private Runnable mLogDataHighFrequency = new Runnable() {
- @Override
- public void run() {
- // Do not wake the device for these messages. Opportunistically log rail data every
- // LOG_PERIOD_MS_HIGH_FREQUENCY.
- mHandler.postDelayed(mLogDataHighFrequency, LOG_PERIOD_MS_HIGH_FREQUENCY);
- if (DEBUG) Slog.d(TAG, "Received delayed message. Log rail data high frequency");
- logPowerStatsData(PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY);
- }
- };
+ }
public TimerTrigger(Context context, PowerStatsLogger powerStatsLogger,
boolean triggerEnabled) {
super(context, powerStatsLogger);
mHandler = mContext.getMainThreadHandler();
+ mAlarmManager = mContext.getSystemService(AlarmManager.class);
if (triggerEnabled) {
- mLogDataLowFrequency.run();
- mLogDataHighFrequency.run();
+ final PeriodicTimer logDataLowFrequency = new PeriodicTimer("PowerStatsLowFreqLog",
+ LOG_PERIOD_MS_LOW_FREQUENCY,
+ PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_LOW_FREQUENCY);
+ final PeriodicTimer logDataHighFrequency = new PeriodicTimer("PowerStatsHighFreqLog",
+ LOG_PERIOD_MS_HIGH_FREQUENCY,
+ PowerStatsLogger.MSG_LOG_TO_DATA_STORAGE_HIGH_FREQUENCY);
+ logDataLowFrequency.run();
+ logDataHighFrequency.run();
}
}
}
diff --git a/services/core/java/com/android/server/powerstats/flags.aconfig b/services/core/java/com/android/server/powerstats/flags.aconfig
new file mode 100644
index 0000000..0a4a751
--- /dev/null
+++ b/services/core/java/com/android/server/powerstats/flags.aconfig
@@ -0,0 +1,13 @@
+
+package: "com.android.server.powerstats"
+container: "system"
+
+flag {
+ name: "alarm_based_powerstats_logging"
+ namespace: "backstage_power"
+ description: "Utilize new OomAdjuster implementation"
+ bug: "294598168"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 04db3e8..3138a9e 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -1870,6 +1870,11 @@
@Override
public boolean isInSignificantPlace() {
+ if (android.security.Flags.significantPlaces()) {
+ mSignificantPlaceServiceWatcher.runOnBinder(
+ binder -> ISignificantPlaceProvider.Stub.asInterface(binder)
+ .onSignificantPlaceCheck());
+ }
return mIsInSignificantPlace;
}