diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-04-03 01:05:53 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-04-03 01:05:53 +0000 |
commit | ce88ef7d100a1f495f943da189cc6933cf64ed55 (patch) | |
tree | b8f09ce07ce711d0d3ad77107d3e84f5b1fbb15c | |
parent | 676168fe65a4dc72ea1b47a9cd90365a705b89ad (diff) | |
parent | 24cce7d21e6f8cfc400a13d6e99aad464b51c20b (diff) | |
download | cts-android13-mainline-resolv-release.tar.gz |
Snap for 9867914 from 24cce7d21e6f8cfc400a13d6e99aad464b51c20b to mainline-resolv-releaseaml_res_331820000android13-mainline-resolv-release
Change-Id: Ibbcfa87d02d0297ea477bc74529015299292f184
17 files changed, 367 insertions, 2189 deletions
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java index 7cc15765747..d79668dc6f3 100644 --- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java +++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java @@ -947,6 +947,7 @@ public class JobThrottlingTest { assumeFalse("not testable in automotive device", mAutomotiveDevice); assumeFalse("not testable in leanback device", mLeanbackOnly); + assumeTrue(BatteryUtils.hasBattery()); assumeTrue(mNetworkingHelper.hasWifiFeature()); mNetworkingHelper.ensureSavedWifiNetwork(); diff --git a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java index ee74c656271..d812c338a6a 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/CloudPhotoPickerTest.java @@ -18,6 +18,7 @@ package android.photopicker.cts; import static android.photopicker.cts.PhotoPickerCloudUtils.addImage; import static android.photopicker.cts.PhotoPickerCloudUtils.containsExcept; +import static android.photopicker.cts.PhotoPickerCloudUtils.enableCloudMediaAndSetAllowedCloudProviders; import static android.photopicker.cts.PhotoPickerCloudUtils.extractMediaIds; import static android.photopicker.cts.PickerProviderMediaGenerator.MediaGenerator; import static android.photopicker.cts.PickerProviderMediaGenerator.setCloudProvider; @@ -91,6 +92,9 @@ public class CloudPhotoPickerTest extends PhotoPickerBaseTest { mCloudPrimaryMediaGenerator.setMediaCollectionId(COLLECTION_1); mCloudSecondaryMediaGenerator.setMediaCollectionId(COLLECTION_1); + // This is a self-instrumentation test, so both "target" package name and "own" package name + // should be the same (android.photopicker.cts). + enableCloudMediaAndSetAllowedCloudProviders(sTargetPackageName); setCloudProvider(mContext, null); } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBannersTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBannersTest.java index da295d0074e..cf65e3967dc 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBannersTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerBannersTest.java @@ -16,6 +16,10 @@ package android.photopicker.cts; +import static android.photopicker.cts.PhotoPickerCloudUtils.disableCloudMediaAndClearAllowedCloudProviders; +import static android.photopicker.cts.PhotoPickerCloudUtils.enableCloudMediaAndSetAllowedCloudProviders; +import static android.photopicker.cts.PhotoPickerCloudUtils.getAllowedProvidersDeviceConfig; +import static android.photopicker.cts.PhotoPickerCloudUtils.isCloudMediaEnabled; import static android.photopicker.cts.PickerProviderMediaGenerator.setCloudProvider; import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImage; import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; @@ -52,22 +56,30 @@ import org.junit.Test; @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) public class PhotoPickerBannersTest extends PhotoPickerBaseTest { + private static boolean sCloudMediaPreviouslyEnabled; private static String sPreviouslyAllowedCloudProviders; private Uri mLocalMediaFileUri; @BeforeClass public static void setUpBeforeClass() { - // Store the current allowed cloud providers for reset at the end of tests. - sPreviouslyAllowedCloudProviders = PhotoPickerCloudUtils.getAllowedProvidersDeviceConfig(); + // Store the current CMP configs, so that we can reset them at the end of the test. + sCloudMediaPreviouslyEnabled = isCloudMediaEnabled(); + if (sCloudMediaPreviouslyEnabled) { + sPreviouslyAllowedCloudProviders = getAllowedProvidersDeviceConfig(); + } // Override the allowed cloud providers config to enable the banners. - PhotoPickerCloudUtils.setAllowedProvidersDeviceConfig(sTargetPackageName); + enableCloudMediaAndSetAllowedCloudProviders(sTargetPackageName); } @AfterClass public static void tearDownClass() { - // Reset the allowed cloud providers device config. - PhotoPickerCloudUtils.setAllowedProvidersDeviceConfig(sPreviouslyAllowedCloudProviders); + // Reset CloudMedia configs. + if (sCloudMediaPreviouslyEnabled) { + enableCloudMediaAndSetAllowedCloudProviders(sPreviouslyAllowedCloudProviders); + } else { + disableCloudMediaAndClearAllowedCloudProviders(); + } } @Before diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java index 59b552cdddf..891917d3cc6 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerCloudUtils.java @@ -45,7 +45,8 @@ import java.util.List; public class PhotoPickerCloudUtils { private static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot"; - private static final String ALLOWED_CLOUD_PROVIDERS_KEY = "allowed_cloud_providers"; + private static final String KEY_ALLOWED_CLOUD_PROVIDERS = "allowed_cloud_providers"; + private static final String KEY_CLOUD_MEDIA_FEATURE_ENABLED = "cloud_media_feature_enabled"; public static List<String> extractMediaIds(ClipData clipData, int minCount) { final int count = clipData.getItemCount(); @@ -109,40 +110,64 @@ public class PhotoPickerCloudUtils { assertThat(mediaIds).containsNoneIn(Collections.singletonList(notContained)); } + public static boolean isCloudMediaEnabled() { + return Boolean.parseBoolean(readDeviceConfigProp(KEY_CLOUD_MEDIA_FEATURE_ENABLED)); + } + @Nullable static String getAllowedProvidersDeviceConfig() { + return readDeviceConfigProp(KEY_ALLOWED_CLOUD_PROVIDERS); + } + + static void enableCloudMediaAndSetAllowedCloudProviders(@NonNull String allowedPackagesJoined) { + writeDeviceConfigProp(KEY_ALLOWED_CLOUD_PROVIDERS, allowedPackagesJoined); + assertWithMessage("Failed to update the allowed cloud providers device config") + .that(getAllowedProvidersDeviceConfig()) + .isEqualTo(allowedPackagesJoined); + + writeDeviceConfigProp(KEY_CLOUD_MEDIA_FEATURE_ENABLED, true); + } + + + static void disableCloudMediaAndClearAllowedCloudProviders() { + writeDeviceConfigProp(KEY_CLOUD_MEDIA_FEATURE_ENABLED, false); + + deleteDeviceConfigProp(KEY_ALLOWED_CLOUD_PROVIDERS); + assertWithMessage("Failed to delete the allowed cloud providers device config") + .that(getAllowedProvidersDeviceConfig()) + .isNull(); + } + + @NonNull + private static UiAutomation getUiAutomation() { + return InstrumentationRegistry.getInstrumentation().getUiAutomation(); + } + + @Nullable + private static String readDeviceConfigProp(@NonNull String name) { getUiAutomation().adoptShellPermissionIdentity(READ_DEVICE_CONFIG); try { - return DeviceConfig.getProperty(NAMESPACE_STORAGE_NATIVE_BOOT, - ALLOWED_CLOUD_PROVIDERS_KEY); + return DeviceConfig.getProperty(NAMESPACE_STORAGE_NATIVE_BOOT, name); } finally { getUiAutomation().dropShellPermissionIdentity(); } } - static void setAllowedProvidersDeviceConfig(@Nullable String allowedCloudProviders) { + private static void writeDeviceConfigProp(@NonNull String name, boolean value) { + writeDeviceConfigProp(name, Boolean.toString(value)); + } + + private static void writeDeviceConfigProp(@NonNull String name, @NonNull String value) { getUiAutomation().adoptShellPermissionIdentity(WRITE_DEVICE_CONFIG); try { - if (allowedCloudProviders == null) { - DeviceConfig.deleteProperty(NAMESPACE_STORAGE_NATIVE_BOOT, - ALLOWED_CLOUD_PROVIDERS_KEY); - assertWithMessage("Failed to delete the allowed cloud providers device config") - .that(getAllowedProvidersDeviceConfig()) - .isNull(); - } else { - DeviceConfig.setProperty(NAMESPACE_STORAGE_NATIVE_BOOT, ALLOWED_CLOUD_PROVIDERS_KEY, - allowedCloudProviders, /* makeDefault */ false); - assertWithMessage("Failed to update the allowed cloud providers device config") - .that(getAllowedProvidersDeviceConfig()) - .isEqualTo(allowedCloudProviders); - } + DeviceConfig.setProperty(NAMESPACE_STORAGE_NATIVE_BOOT, name, value, + /* makeDefault*/ false); } finally { getUiAutomation().dropShellPermissionIdentity(); } } - @NonNull - private static UiAutomation getUiAutomation() { - return InstrumentationRegistry.getInstrumentation().getUiAutomation(); + private static void deleteDeviceConfigProp(@NonNull String name) { + DeviceConfig.deleteProperty(NAMESPACE_STORAGE_NATIVE_BOOT, name); } } diff --git a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java index d8cc456fe32..70e050212db 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/PhotoPickerSettingsTest.java @@ -16,6 +16,10 @@ package android.photopicker.cts; +import static android.photopicker.cts.PhotoPickerCloudUtils.disableCloudMediaAndClearAllowedCloudProviders; +import static android.photopicker.cts.PhotoPickerCloudUtils.enableCloudMediaAndSetAllowedCloudProviders; +import static android.photopicker.cts.PhotoPickerCloudUtils.getAllowedProvidersDeviceConfig; +import static android.photopicker.cts.PhotoPickerCloudUtils.isCloudMediaEnabled; import static android.photopicker.cts.util.PhotoPickerUiUtils.isPhotoPickerVisible; import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsActionBarIsVisible; import static android.photopicker.cts.util.PhotoPickerUiUtils.verifySettingsActivityIsVisible; @@ -45,22 +49,30 @@ import org.junit.Test; @SdkSuppress(minSdkVersion = Build.VERSION_CODES.S) public class PhotoPickerSettingsTest extends PhotoPickerBaseTest { + private static boolean sCloudMediaPreviouslyEnabled; private static String sPreviouslyAllowedCloudProviders; @BeforeClass public static void setUpBeforeClass() { - // Store current allowed cloud providers for reset at the end of tests. - sPreviouslyAllowedCloudProviders = PhotoPickerCloudUtils.getAllowedProvidersDeviceConfig(); + // Store the current CMP configs, so that we can reset them at the end of the test. + sCloudMediaPreviouslyEnabled = isCloudMediaEnabled(); + if (sCloudMediaPreviouslyEnabled) { + sPreviouslyAllowedCloudProviders = getAllowedProvidersDeviceConfig(); + } // Enable Settings menu item in PhotoPickerActivity's overflow menu. - PhotoPickerCloudUtils.setAllowedProvidersDeviceConfig( + PhotoPickerCloudUtils.enableCloudMediaAndSetAllowedCloudProviders( /* allowedCloudProviders */ "not_empty"); } @AfterClass public static void tearDownClass() { - // Reset allowed cloud providers device config. - PhotoPickerCloudUtils.setAllowedProvidersDeviceConfig(sPreviouslyAllowedCloudProviders); + // Reset CloudMedia configs. + if (sCloudMediaPreviouslyEnabled) { + enableCloudMediaAndSetAllowedCloudProviders(sPreviouslyAllowedCloudProviders); + } else { + disableCloudMediaAndClearAllowedCloudProviders(); + } } @Test diff --git a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java index 0c19f5c51dc..382be794d84 100644 --- a/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java +++ b/tests/PhotoPicker/src/android/photopicker/cts/RemoteVideoPreviewTest.java @@ -16,6 +16,7 @@ package android.photopicker.cts; +import static android.photopicker.cts.PhotoPickerCloudUtils.enableCloudMediaAndSetAllowedCloudProviders; import static android.photopicker.cts.PickerProviderMediaGenerator.setCloudProvider; import static android.photopicker.cts.PickerProviderMediaGenerator.syncCloudProvider; import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia; @@ -93,6 +94,10 @@ public class RemoteVideoPreviewTest extends PhotoPickerBaseTest { mCloudPrimaryMediaGenerator.resetAll(); mCloudPrimaryMediaGenerator.setMediaCollectionId(COLLECTION_1); + // This is a self-instrumentation test, so both "target" package name and "own" package name + // should be the same (android.photopicker.cts). + enableCloudMediaAndSetAllowedCloudProviders(sTargetPackageName); + setCloudProvider(mContext, CloudProviderPrimary.AUTHORITY); assertThat(MediaStore.isCurrentCloudMediaProviderAuthority(mContext.getContentResolver(), CloudProviderPrimary.AUTHORITY)).isTrue(); diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java index 28bb02ebba7..6090cdce8b1 100644 --- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java +++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java @@ -59,12 +59,14 @@ import android.media.Image; import android.media.Image.Plane; import android.media.ImageReader; import android.media.ImageWriter; +import android.os.Build; import android.os.SystemClock; import android.os.ConditionVariable; import android.util.Log; import android.util.Size; import android.view.Surface; +import com.android.compatibility.common.util.PropertyUtil; import com.android.ex.camera2.blocking.BlockingSessionCallback; import org.junit.Test; @@ -1454,7 +1456,9 @@ public class ImageReaderTest extends Camera2AndroidTestCase { if (mStaticInfo.isCapabilitySupported( CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) { StaticMetadata staticInfo = mStaticInfo; - if (mStaticInfo.isLogicalMultiCamera() + boolean supportActivePhysicalIdConsistency = + PropertyUtil.getFirstApiLevel() >= Build.VERSION_CODES.S; + if (mStaticInfo.isLogicalMultiCamera() && supportActivePhysicalIdConsistency && mStaticInfo.isActivePhysicalCameraIdSupported()) { String activePhysicalId = result.get(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java index e7d6650fa90..c5b520d6a02 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiDisplayPolicyTests.java @@ -565,7 +565,7 @@ public class MultiDisplayPolicyTests extends MultiDisplayTestBase { mWmState.assertFocusedActivity("Top activity must be the latest launched one", VIRTUAL_DISPLAY_ACTIVITY); - launchActivityOnDisplay(TEST_ACTIVITY, newDisplay.mId); + launchActivityOnDisplay(TEST_ACTIVITY, WINDOWING_MODE_FULLSCREEN, newDisplay.mId); waitAndAssertActivityStateOnDisplay(TEST_ACTIVITY, STATE_RESUMED, newDisplay.mId, "Activity launched on secondary display must be resumed"); diff --git a/tests/framework/base/windowmanager/src/android/server/wm/MultiWindowTests.java b/tests/framework/base/windowmanager/src/android/server/wm/MultiWindowTests.java index e6e1e81acaf..06ca39f12dc 100644 --- a/tests/framework/base/windowmanager/src/android/server/wm/MultiWindowTests.java +++ b/tests/framework/base/windowmanager/src/android/server/wm/MultiWindowTests.java @@ -457,21 +457,24 @@ public class MultiWindowTests extends ActivityManagerTestBase { mAm.getLockTaskModeState() != LOCK_TASK_MODE_NONE); // Verify specifying non-fullscreen windowing mode will fail. - boolean exceptionThrown = false; - try { - runWithShellPermission(() -> { - final WindowContainerTransaction wct = new WindowContainerTransaction() - .setWindowingMode( - mTaskOrganizer.getTaskInfo(task.mTaskId).getToken(), - WINDOWING_MODE_MULTI_WINDOW); - mTaskOrganizer.applyTransaction(wct); - }); - } catch (UnsupportedOperationException e) { - exceptionThrown = true; - } - assertTrue("Not allowed to specify windowing mode while in locked task mode.", - exceptionThrown); + runWithShellPermission(() -> { + final WindowContainerTransaction wct = new WindowContainerTransaction() + .setWindowingMode( + mTaskOrganizer.getTaskInfo(task.mTaskId).getToken(), + WINDOWING_MODE_MULTI_WINDOW); + mTaskOrganizer.applyTransaction(wct); + }); + } catch (UnsupportedOperationException e) { + // Non-fullscreen windowing mode change can cause an exception. } finally { + // The default behavior in T is to throw an exception, but this has changed in U+ to + // ensure Core won't crash with some timing issues. Thus, in T, we allow both throwing + // and not throwing an exception in this case, but at least the windowing mode change + // must be rejected. + mWmState.computeState(TEST_ACTIVITY); + assertEquals(WINDOWING_MODE_FULLSCREEN, + mWmState.getWindowState(TEST_ACTIVITY).getWindowingMode()); + runWithShellPermission(() -> { mAtm.stopSystemLockTaskMode(); }); diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java index bf2e941bfa5..56dd1b0f561 100644 --- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java +++ b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java @@ -16,13 +16,11 @@ package android.keystore.cts; -import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -39,13 +37,6 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; -import com.android.bedstead.nene.annotations.Nullable; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; @@ -72,7 +63,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; @@ -88,6 +78,11 @@ import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.security.auth.x500.X500Principal; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + @RunWith(AndroidJUnit4.class) public class AndroidKeyStoreTest { private static final String TAG = AndroidKeyStoreTest.class.getSimpleName(); @@ -828,12 +823,6 @@ public class AndroidKeyStoreTest { expectedAliases.length, count); } - private void deleteEntryIfNotNull(@Nullable String alias) throws Exception { - if (alias != null) { - mKeyStore.deleteEntry(alias); - } - } - @Test public void testKeyStore_Aliases_Unencrypted_Success() throws Exception { mKeyStore.load(null, null); @@ -2172,9 +2161,8 @@ public class AndroidKeyStoreTest { PrivateKey privateKey3 = generatePrivateKey("RSA", FAKE_RSA_KEY_1); final int MAX_NUMBER_OF_KEYS = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_rsa_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_rsa_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2187,12 +2175,11 @@ public class AndroidKeyStoreTest { new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, - new PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), - protectionParams); + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, + new PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}), protectionParams); @@ -2219,9 +2206,7 @@ public class AndroidKeyStoreTest { sig.update(message); assertTrue(sig.verify(signature)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2250,9 +2235,8 @@ public class AndroidKeyStoreTest { PrivateKey privateKey3 = generatePrivateKey("EC", FAKE_EC_KEY_1); final int MAX_NUMBER_OF_KEYS = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_ec_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_ec_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2264,12 +2248,12 @@ public class AndroidKeyStoreTest { new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.PrivateKeyEntry(privateKey3, new Certificate[] {cert3}), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}), protectionParams); @@ -2296,9 +2280,7 @@ public class AndroidKeyStoreTest { sig.update(message); assertTrue(sig.verify(signature)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2325,9 +2307,8 @@ public class AndroidKeyStoreTest { HexEncoding.decode("33333333333333333333777777777777"), "AES"); final int MAX_NUMBER_OF_KEYS = 10000; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_aes_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_aes_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2338,11 +2319,11 @@ public class AndroidKeyStoreTest { .build(); mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.SecretKeyEntry(key3), protectionParams); ++keyCount; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams); SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null); SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null); @@ -2364,9 +2345,7 @@ public class AndroidKeyStoreTest { cipher.init(Cipher.DECRYPT_MODE, key2, cipherParams); assertArrayEquals(plaintext, cipher.doFinal(ciphertext)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2395,9 +2374,8 @@ public class AndroidKeyStoreTest { HexEncoding.decode("33333333333333333333777777777777"), "HmacSHA256"); final int MAX_NUMBER_OF_KEYS = 10000; - final StringBuilder aliasPrefix = new StringBuilder("test_large_number_of_hmac_keys_"); + final String ALIAS_PREFIX = "test_large_number_of_hmac_keys_"; int keyCount = 0; - String entryName2 = null; mKeyStore.load(null); try { @@ -2406,11 +2384,11 @@ public class AndroidKeyStoreTest { .build(); mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams); - keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, aliasPrefix, + keyCount = importKeyManyTimes(MAX_NUMBER_OF_KEYS, ALIAS_PREFIX, new KeyStore.SecretKeyEntry(key3), protectionParams); keyCount++; - entryName2 = "test" + keyCount; + String entryName2 = "test" + keyCount; mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams); SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null); SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null); @@ -2430,9 +2408,7 @@ public class AndroidKeyStoreTest { "59b57e77e4e2cb36b5c7b84af198ac004327bc549de6931a1b5505372dd8c957"), mac.doFinal(message)); } finally { - mKeyStore.deleteEntry(entryName1); - deleteEntryIfNotNull(entryName2); - deleteManyTestKeys(keyCount, aliasPrefix); + deleteManyTestKeys(keyCount, ALIAS_PREFIX); } } @@ -2630,8 +2606,8 @@ public class AndroidKeyStoreTest { * * This method is time-bounded */ - private int importKeyManyTimes(int numberOfKeys, StringBuilder aliasPrefix, Entry keyEntry, - KeyProtection protectionParams, boolean isTimeBound) + private int importKeyManyTimes(int numberOfKeys, String aliasPrefix, Entry keyEntry, + KeyProtection protectionParams) throws InterruptedException { TimeBox timeBox = new TimeBox(mMaxImportDuration); AtomicInteger keyCounter = new AtomicInteger(0); @@ -2640,7 +2616,7 @@ public class AndroidKeyStoreTest { threads.add(new Thread(() -> { // Import key lots of times, under different aliases. Do this until we either run // out of time or we import the key numberOfKeys times. - while (!isTimeBound || !timeBox.isOutOfTime()) { + while (!timeBox.isOutOfTime()) { int count = keyCounter.incrementAndGet(); if (count > numberOfKeys) { // The loop is inherently racy, as multiple threads are simultaneously @@ -2653,7 +2629,7 @@ public class AndroidKeyStoreTest { if ((count % 1000) == 0) { Log.i(TAG, "Imported " + count + " keys"); } - String entryAlias = aliasPrefix.toString() + count; + String entryAlias = aliasPrefix + count; try { mKeyStore.setEntry(entryAlias, keyEntry, protectionParams); } catch (Throwable e) { @@ -2670,7 +2646,7 @@ public class AndroidKeyStoreTest { threads.get(i).join(); } Log.i(TAG, "Imported " + keyCounter.get() + " keys in " + timeBox.elapsed()); - if (keyCounter.get() != numberOfKeys && keyCounter.get() < MIN_SUPPORTED_KEY_COUNT) { + if (keyCounter.get() < MIN_SUPPORTED_KEY_COUNT) { fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in " + timeBox.elapsed() + ". Imported: " + keyCounter.get() + " keys"); } @@ -2678,22 +2654,11 @@ public class AndroidKeyStoreTest { return keyCounter.get(); } - private int importKeyManyTimes(int numberOfKeys, StringBuilder aliasPrefix, Entry keyEntry, - KeyProtection protectionParams) throws InterruptedException { - return importKeyManyTimes(numberOfKeys, aliasPrefix, keyEntry, protectionParams, true); - } - - private int importKeyManyTimesWithoutTimeLimit(int numberOfKeys, StringBuilder aliasPrefix, - Entry keyEntry, - KeyProtection protectionParams) throws InterruptedException { - return importKeyManyTimes(numberOfKeys, aliasPrefix, keyEntry, protectionParams, false); - } - /** * Delete <code>numberOfKeys</code> keys that follow the pattern "[aliasPrefix][keyCounter]". * This is done across multiple threads to both increase throughput as well as stress keystore. */ - private void deleteManyTestKeys(int numberOfKeys, StringBuilder aliasPrefix) + private void deleteManyTestKeys(int numberOfKeys, String aliasPrefix) throws InterruptedException { // Clean up Keystore without using KeyStore.aliases() which can't handle this many // entries. @@ -2708,9 +2673,8 @@ public class AndroidKeyStoreTest { if ((key > 0) && ((key % 1000) == 0)) { Log.i(TAG, "Deleted " + key + " keys"); } - String entryAlias = aliasPrefix.toString() + key; try { - mKeyStore.deleteEntry(entryAlias); + mKeyStore.deleteEntry("test" + key); } catch (Exception e) { fail("Unexpected exception in key cleanup: " + e); } @@ -2726,114 +2690,4 @@ public class AndroidKeyStoreTest { } Log.i(TAG, "Deleted " + numberOfKeys + " keys"); } - - private Set<String> createLargeNumberOfKeyStoreEntryAliases(int numberOfKeys, - StringBuilder aliasPrefix) - throws Exception { - Certificate cert = generateCertificate(FAKE_RSA_USER_1); - PrivateKey privateKey = generatePrivateKey("RSA", FAKE_RSA_KEY_1); - - mKeyStore.load(null); - KeyProtection protectionParams = new KeyProtection.Builder( - KeyProperties.PURPOSE_SIGN) - .setDigests(KeyProperties.DIGEST_SHA256) - .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1) - .build(); - - int keyCount = importKeyManyTimesWithoutTimeLimit(numberOfKeys, aliasPrefix, - new PrivateKeyEntry(privateKey, new Certificate[]{cert}), protectionParams); - - // Construct expected aliases list. - final Set<String> expectedAliases = new HashSet<>(keyCount); - for (int count = 1; count <= keyCount; count++) { - String entryAlias = aliasPrefix.toString() + count; - expectedAliases.add(entryAlias); - } - - return expectedAliases; - } - - private void importLargeNumberOfKeysValidateAliases(int numberOfKeys, StringBuilder aliasPrefix) - throws Exception { - Set<String> importedKeyAliases = createLargeNumberOfKeyStoreEntryAliases(numberOfKeys, - aliasPrefix); - assertThat(importedKeyAliases.size()).isEqualTo(numberOfKeys); - - try { - // b/222287335 Currently, limiting Keystore `listEntries` API to return subset of the - // Keystore entries to avoid running out of binder buffer space. - // To verify that all the imported key aliases are present in Keystore, get the list of - // aliases from Keystore, delete the matched aliases from Keystore and imported list of - // key aliases, continue this till all the imported key aliases are matched. - while (!importedKeyAliases.isEmpty()) { - // List the keystore entries aliases until all the imported key aliases are matched. - Set<String> aliases = new HashSet<String>(Collections.list(mKeyStore.aliases())); - - // Try to match the aliases with imported key aliases. - // Cleanup matching aliases from Keystore and imported key aliases list. - for (String alias: aliases) { - if (importedKeyAliases.contains(alias)) { - mKeyStore.deleteEntry(alias); - importedKeyAliases.remove(alias); - } - } - } - assertTrue("Failed to match imported keystore entries.", - importedKeyAliases.isEmpty()); - } finally { - if (!importedKeyAliases.isEmpty()) { - Log.i(TAG, "Final cleanup of imported keys"); - for (String alias: importedKeyAliases) { - mKeyStore.deleteEntry(alias); - } - } - } - assertTrue(importedKeyAliases.isEmpty()); - } - - /** - * Create long alias prefix of length 6000 characters. - */ - private StringBuilder createLongAliasPrefix() { - char[] prefixChar = new char[6000]; - Arrays.fill(prefixChar, 'T'); - StringBuilder prefixAlias = new StringBuilder(); - prefixAlias.append(prefixChar); - - return prefixAlias; - } - - /** - * Create large number of Keystore entries with long aliases and try to list aliases of all the - * entries in the keystore. - */ - @Test - public void testKeyStore_LargeNumberOfLongAliases() throws Exception { - final int maxNumberOfKeys = 100; - - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, createLongAliasPrefix()); - } - - /** - * Create limited number of Keystore entries with long aliases and try to list aliases of all - * the entries in the keystore. Test should successfully list all the Keystore entries aliases. - */ - @Test - public void testKeyStore_LimitedNumberOfLongAliasesSuccess() throws Exception { - final int maxNumberOfKeys = 10; - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, createLongAliasPrefix()); - } - - /** - * Create large number of Keystore entries with short length aliases and try to list aliases of - * all the entries in the keystore. Test should successfully list all the Keystore entries - * aliases. - */ - @Test - public void testKeyStore_LargeNumberShortAliasesSuccess() throws Exception { - final int maxNumberOfKeys = 2500; - final StringBuilder aliasPrefix = new StringBuilder("test_short_key_alias_"); - - importLargeNumberOfKeysValidateAliases(maxNumberOfKeys, aliasPrefix); - } } diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java deleted file mode 100644 index af5f908cf97..00000000000 --- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java +++ /dev/null @@ -1,1966 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.media.cts; - -import static org.junit.Assert.assertNotEquals; - -import static android.media.AudioManager.ADJUST_LOWER; -import static android.media.AudioManager.ADJUST_RAISE; -import static android.media.AudioManager.ADJUST_SAME; -import static android.media.AudioManager.MODE_IN_CALL; -import static android.media.AudioManager.MODE_IN_COMMUNICATION; -import static android.media.AudioManager.MODE_NORMAL; -import static android.media.AudioManager.MODE_RINGTONE; -import static android.media.AudioManager.RINGER_MODE_NORMAL; -import static android.media.AudioManager.RINGER_MODE_SILENT; -import static android.media.AudioManager.RINGER_MODE_VIBRATE; -import static android.media.AudioManager.STREAM_ACCESSIBILITY; -import static android.media.AudioManager.STREAM_ALARM; -import static android.media.AudioManager.STREAM_DTMF; -import static android.media.AudioManager.STREAM_MUSIC; -import static android.media.AudioManager.STREAM_NOTIFICATION; -import static android.media.AudioManager.STREAM_RING; -import static android.media.AudioManager.STREAM_SYSTEM; -import static android.media.AudioManager.STREAM_VOICE_CALL; -import static android.media.AudioManager.USE_DEFAULT_STREAM_TYPE; -import static android.media.AudioManager.VIBRATE_SETTING_OFF; -import static android.media.AudioManager.VIBRATE_SETTING_ON; -import static android.media.AudioManager.VIBRATE_SETTING_ONLY_SILENT; -import static android.media.AudioManager.VIBRATE_TYPE_NOTIFICATION; -import static android.media.AudioManager.VIBRATE_TYPE_RINGER; -import static android.provider.Settings.System.SOUND_EFFECTS_ENABLED; - -import android.Manifest; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.media.AudioAttributes; -import android.media.AudioDeviceAttributes; -import android.media.AudioDeviceInfo; -import android.media.AudioFormat; -import android.media.AudioManager; -import android.media.AudioProfile; -import android.media.AudioDescriptor; -import android.media.MediaPlayer; -import android.media.MediaRecorder; -import android.media.MicrophoneInfo; -import android.media.audiopolicy.AudioProductStrategy; -import android.os.Build; -import android.os.SystemClock; -import android.os.Vibrator; -import android.platform.test.annotations.AppModeFull; -import android.provider.Settings; -import android.provider.Settings.System; -import android.test.InstrumentationTestCase; -import android.text.TextUtils; -import android.util.Log; -import android.view.SoundEffectConstants; - -import androidx.test.InstrumentationRegistry; - -import com.android.compatibility.common.util.ApiLevelUtil; -import com.android.compatibility.common.util.CddTest; -import com.android.compatibility.common.util.MediaUtils; -import com.android.compatibility.common.util.SettingsStateKeeperRule; -import com.android.internal.annotations.GuardedBy; - -import org.junit.ClassRule; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.Executors; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -@NonMediaMainlineTest -public class AudioManagerTest extends InstrumentationTestCase { - private final static String TAG = "AudioManagerTest"; - - private final static long ASYNC_TIMING_TOLERANCE_MS = 50; - private final static long POLL_TIME_VOLUME_ADJUST = 200; - private final static long POLL_TIME_UPDATE_INTERRUPTION_FILTER = 5000; - private final static int MP3_TO_PLAY = R.raw.testmp3; // ~ 5 second mp3 - private final static long POLL_TIME_PLAY_MUSIC = 2000; - private final static long TIME_TO_PLAY = 2000; - private final static String APPOPS_OP_STR = "android:write_settings"; - private final static Set<Integer> ALL_KNOWN_ENCAPSULATION_TYPES = new HashSet<>() {{ - add(AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937); - }}; - private final static Set<Integer> ALL_ENCAPSULATION_TYPES = new HashSet<>() {{ - add(AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE); - add(AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937); - }}; - private final static HashSet<Integer> ALL_AUDIO_STANDARDS = new HashSet<>() {{ - add(AudioDescriptor.STANDARD_NONE); - add(AudioDescriptor.STANDARD_EDID); - }}; - private AudioManager mAudioManager; - private NotificationManager mNm; - private boolean mHasVibrator; - private boolean mUseFixedVolume; - private boolean mIsTelevision; - private boolean mIsSingleVolume; - private boolean mSkipRingerTests; - // From N onwards, ringer mode adjustments that toggle DND are not allowed unless - // package has DND access. Many tests in this package toggle DND access in order - // to get device out of the DND state for the test to proceed correctly. - // But DND access is disabled completely on low ram devices, - // so completely skip those tests here. - // These tests are migrated to CTS verifier tests to ensure test coverage. - private Context mContext; - private int mOriginalRingerMode; - private Map<Integer, Integer> mOriginalStreamVolumes = new HashMap<>(); - private NotificationManager.Policy mOriginalNotificationPolicy; - private int mOriginalZen; - private boolean mDoNotCheckUnmute; - private boolean mAppsBypassingDnd; - - @ClassRule - public static final SettingsStateKeeperRule mSurroundSoundFormatsSettingsKeeper = - new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), - Settings.Global.ENCODED_SURROUND_OUTPUT_ENABLED_FORMATS); - - @ClassRule - public static final SettingsStateKeeperRule mSurroundSoundModeSettingsKeeper = - new SettingsStateKeeperRule(InstrumentationRegistry.getTargetContext(), - Settings.Global.ENCODED_SURROUND_OUTPUT); - - @Override - protected void setUp() throws Exception { - super.setUp(); - mContext = getInstrumentation().getContext(); - Utils.enableAppOps(mContext.getPackageName(), APPOPS_OP_STR, getInstrumentation()); - mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE); - mNm = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - mAppsBypassingDnd = NotificationManager.getService().areChannelsBypassingDnd(); - mHasVibrator = (vibrator != null) && vibrator.hasVibrator(); - mUseFixedVolume = mContext.getResources().getBoolean( - Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android")); - PackageManager packageManager = mContext.getPackageManager(); - mIsTelevision = packageManager != null - && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) - || packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)); - mIsSingleVolume = mContext.getResources().getBoolean( - Resources.getSystem().getIdentifier("config_single_volume", "bool", "android")); - mSkipRingerTests = mUseFixedVolume || mIsTelevision || mIsSingleVolume; - - // Store the original volumes that that they can be recovered in tearDown(). - final int[] streamTypes = { - STREAM_VOICE_CALL, - STREAM_SYSTEM, - STREAM_RING, - STREAM_MUSIC, - STREAM_ALARM, - STREAM_NOTIFICATION, - STREAM_DTMF, - STREAM_ACCESSIBILITY, - }; - mOriginalRingerMode = mAudioManager.getRingerMode(); - for (int streamType : streamTypes) { - mOriginalStreamVolumes.put(streamType, mAudioManager.getStreamVolume(streamType)); - } - - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mOriginalNotificationPolicy = mNm.getNotificationPolicy(); - mOriginalZen = mNm.getCurrentInterruptionFilter(); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - } - - // Check original microphone mute/unmute status - mDoNotCheckUnmute = false; - if (mAudioManager.isMicrophoneMute()) { - mAudioManager.setMicrophoneMute(false); - if (mAudioManager.isMicrophoneMute()) { - Log.w(TAG, "Mic seems muted by hardware! Please unmute and rerrun the test."); - mDoNotCheckUnmute = true; - } - } - } - - @Override - protected void tearDown() throws Exception { - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mNm.setNotificationPolicy(mOriginalNotificationPolicy); - setInterruptionFilter(mOriginalZen); - - // Recover the volume and the ringer mode that the test may have overwritten. - for (Map.Entry<Integer, Integer> e : mOriginalStreamVolumes.entrySet()) { - mAudioManager.setStreamVolume(e.getKey(), e.getValue(), - AudioManager.FLAG_ALLOW_RINGER_MODES); - } - mAudioManager.setRingerMode(mOriginalRingerMode); - } finally { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - } - } - - @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") - public void testMicrophoneMute() throws Exception { - mAudioManager.setMicrophoneMute(true); - assertTrue(mAudioManager.isMicrophoneMute()); - mAudioManager.setMicrophoneMute(false); - assertFalse(mAudioManager.isMicrophoneMute() && !mDoNotCheckUnmute); - } - - @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") - public void testMicrophoneMuteIntent() throws Exception { - if (!mDoNotCheckUnmute) { - final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver( - AudioManager.ACTION_MICROPHONE_MUTE_CHANGED); - final boolean initialMicMute = mAudioManager.isMicrophoneMute(); - try { - mContext.registerReceiver(receiver, - new IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED)); - // change the mic mute state - mAudioManager.setMicrophoneMute(!initialMicMute); - // verify a change was reported - final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/); - assertTrue("ACTION_MICROPHONE_MUTE_CHANGED wasn't fired", intentFired); - // verify the mic mute state is expected - final boolean newMicMute = mAudioManager.isMicrophoneMute(); - assertTrue("new mic mute state not as expected (" + !initialMicMute + ")", - (newMicMute == !initialMicMute)); - } finally { - mContext.unregisterReceiver(receiver); - mAudioManager.setMicrophoneMute(initialMicMute); - } - } - } - - @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") - public void testSpeakerphoneIntent() throws Exception { - if (!hasBuiltinSpeaker()) { - return; - } - final MyBlockingIntentReceiver receiver = new MyBlockingIntentReceiver( - AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED); - final boolean initialSpeakerphoneState = mAudioManager.isSpeakerphoneOn(); - try { - mContext.registerReceiver(receiver, - new IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED)); - // change the speakerphone state - mAudioManager.setSpeakerphoneOn(!initialSpeakerphoneState); - // verify a change was reported - final boolean intentFired = receiver.waitForExpectedAction(500/*ms*/); - assertTrue("ACTION_SPEAKERPHONE_STATE_CHANGED wasn't fired", intentFired); - // verify the speakerphon state is expected - final boolean newSpeakerphoneState = mAudioManager.isSpeakerphoneOn(); - assertTrue("new mic mute state not as expected (" - + !initialSpeakerphoneState + ")", - newSpeakerphoneState == !initialSpeakerphoneState); - } finally { - mContext.unregisterReceiver(receiver); - mAudioManager.setSpeakerphoneOn(initialSpeakerphoneState); - } - } - - private boolean hasBuiltinSpeaker() { - AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); - for (AudioDeviceInfo device : devices) { - final int type = device.getType(); - if (type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER - || type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER_SAFE) { - return true; - } - } - return false; - } - - private static final class MyBlockingIntentReceiver extends BroadcastReceiver { - private final SafeWaitObject mLock = new SafeWaitObject(); - // the action for the intent to check - private final String mAction; - @GuardedBy("mLock") - private boolean mIntentReceived = false; - - MyBlockingIntentReceiver(String action) { - mAction = action; - } - - @Override - public void onReceive(Context context, Intent intent) { - if (!TextUtils.equals(intent.getAction(), mAction)) { - // move along, this is not the action we're looking for - return; - } - synchronized (mLock) { - mIntentReceived = true; - mLock.safeNotify(); - } - } - - public boolean waitForExpectedAction(long timeOutMs) { - synchronized (mLock) { - try { - mLock.safeWait(timeOutMs); - } catch (InterruptedException e) { } - return mIntentReceived; - } - } - } - - public void testSoundEffects() throws Exception { - Settings.System.putInt(mContext.getContentResolver(), SOUND_EFFECTS_ENABLED, 1); - - // should hear sound after loadSoundEffects() called. - mAudioManager.loadSoundEffects(); - Thread.sleep(TIME_TO_PLAY); - float volume = 0.5f; // volume should be between 0.f to 1.f (or -1). - mAudioManager.playSoundEffect(SoundEffectConstants.CLICK); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); - - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT, volume); - - // won't hear sound after unloadSoundEffects() called(); - mAudioManager.unloadSoundEffects(); - mAudioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT); - - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_UP, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_DOWN, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_LEFT, volume); - mAudioManager.playSoundEffect(AudioManager.FX_FOCUS_NAVIGATION_RIGHT, volume); - } - - public void testCheckingZenModeBlockDoesNotRequireNotificationPolicyAccess() throws Exception { - try { - // set zen mode to priority only, so playSoundEffect will check notification policy - Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), - true); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - Settings.System.putInt(mContext.getContentResolver(), SOUND_EFFECTS_ENABLED, 1); - - // take away write-notification policy access from the package - Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), - false); - - // playSoundEffect should NOT throw a security exception; all apps have read-access - mAudioManager.playSoundEffect(SoundEffectConstants.CLICK); - } finally { - Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), - true); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), - false); - } - } - - public void testMusicActive() throws Exception { - if (mAudioManager.isMusicActive()) { - return; - } - MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY); - assertNotNull(mp); - mp.setAudioStreamType(STREAM_MUSIC); - mp.start(); - assertMusicActive(true); - mp.stop(); - mp.release(); - assertMusicActive(false); - } - - @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") - public void testAccessMode() throws Exception { - mAudioManager.setMode(MODE_RINGTONE); - assertEquals(MODE_RINGTONE, mAudioManager.getMode()); - mAudioManager.setMode(MODE_IN_COMMUNICATION); - assertEquals(MODE_IN_COMMUNICATION, mAudioManager.getMode()); - mAudioManager.setMode(MODE_NORMAL); - assertEquals(MODE_NORMAL, mAudioManager.getMode()); - } - - public void testSetSurroundFormatEnabled() throws Exception { - getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( - Manifest.permission.WRITE_SETTINGS); - - int audioFormat = AudioFormat.ENCODING_DTS; - - mAudioManager.setSurroundFormatEnabled(audioFormat, true /*enabled*/); - assertTrue(mAudioManager.isSurroundFormatEnabled(audioFormat)); - - mAudioManager.setSurroundFormatEnabled(audioFormat, false /*enabled*/); - assertFalse(mAudioManager.isSurroundFormatEnabled(audioFormat)); - - getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); - } - - public void testSetEncodedSurroundMode() throws Exception { - getInstrumentation().getUiAutomation().adoptShellPermissionIdentity( - Manifest.permission.WRITE_SETTINGS); - - int expectedSurroundFormatsMode = Settings.Global.ENCODED_SURROUND_OUTPUT_MANUAL; - mAudioManager.setEncodedSurroundMode(expectedSurroundFormatsMode); - assertEquals(expectedSurroundFormatsMode, mAudioManager.getEncodedSurroundMode()); - - expectedSurroundFormatsMode = Settings.Global.ENCODED_SURROUND_OUTPUT_NEVER; - mAudioManager.setEncodedSurroundMode(expectedSurroundFormatsMode); - assertEquals(expectedSurroundFormatsMode, mAudioManager.getEncodedSurroundMode()); - - getInstrumentation().getUiAutomation().dropShellPermissionIdentity(); - } - - @SuppressWarnings("deprecation") - @AppModeFull(reason = "Instant apps cannot hold android.permission.MODIFY_AUDIO_SETTINGS") - public void testRouting() throws Exception { - // setBluetoothA2dpOn is a no-op, and getRouting should always return -1 - boolean oldA2DP = mAudioManager.isBluetoothA2dpOn(); - mAudioManager.setBluetoothA2dpOn(true); - assertEquals(oldA2DP , mAudioManager.isBluetoothA2dpOn()); - mAudioManager.setBluetoothA2dpOn(false); - assertEquals(oldA2DP , mAudioManager.isBluetoothA2dpOn()); - - assertEquals(-1, mAudioManager.getRouting(MODE_RINGTONE)); - assertEquals(-1, mAudioManager.getRouting(MODE_NORMAL)); - assertEquals(-1, mAudioManager.getRouting(MODE_IN_CALL)); - assertEquals(-1, mAudioManager.getRouting(MODE_IN_COMMUNICATION)); - - mAudioManager.setBluetoothScoOn(true); - assertTrueCheckTimeout(mAudioManager, p -> p.isBluetoothScoOn(), - DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned false"); - - mAudioManager.setBluetoothScoOn(false); - assertTrueCheckTimeout(mAudioManager, p -> !p.isBluetoothScoOn(), - DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isBluetoothScoOn returned true"); - - mAudioManager.setSpeakerphoneOn(true); - assertTrueCheckTimeout(mAudioManager, p -> p.isSpeakerphoneOn(), - DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned false"); - - mAudioManager.setSpeakerphoneOn(false); - assertTrueCheckTimeout(mAudioManager, p -> !p.isSpeakerphoneOn(), - DEFAULT_ASYNC_CALL_TIMEOUT_MS, "isSpeakerPhoneOn() returned true"); - } - - public void testVibrateNotification() throws Exception { - if (mUseFixedVolume || !mHasVibrator) { - return; - } - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - // VIBRATE_SETTING_ON - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - // VIBRATE_SETTING_OFF - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF); - assertEquals(VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - // VIBRATE_SETTING_ONLY_SILENT - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION)); - - // VIBRATE_TYPE_NOTIFICATION - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF); - assertEquals(VIBRATE_SETTING_OFF, mAudioManager - .getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION)); - } - - public void testVibrateRinger() throws Exception { - if (mUseFixedVolume || !mHasVibrator) { - return; - } - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - // VIBRATE_TYPE_RINGER - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - // VIBRATE_SETTING_OFF - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF); - assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will - // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to - // disable the vibration for incoming calls only. - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - // VIBRATE_SETTING_ONLY_SILENT - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - assertEquals(mHasVibrator, mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER)); - - // VIBRATE_TYPE_NOTIFICATION - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ON : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF); - assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT); - assertEquals(mHasVibrator ? VIBRATE_SETTING_ONLY_SILENT : VIBRATE_SETTING_OFF, - mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER)); - } - - public void testAccessRingMode() throws Exception { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - // AudioService#setRingerMode() has: - // if (isTelevision) return; - if (mSkipRingerTests) { - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - } else { - assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); - } - - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - if (mSkipRingerTests) { - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - } else { - assertEquals(mHasVibrator ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT, - mAudioManager.getRingerMode()); - } - } - - public void testSetRingerModePolicyAccess() throws Exception { - if (mSkipRingerTests) { - return; - } - // Apps without policy access cannot change silent -> normal or silent -> vibrate. - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - assertEquals(RINGER_MODE_SILENT, mAudioManager.getRingerMode()); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - - try { - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - fail("Apps without notification policy access cannot change ringer mode"); - } catch (SecurityException e) { - } - - try { - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - fail("Apps without notification policy access cannot change ringer mode"); - } catch (SecurityException e) { - } - - // Apps without policy access cannot change normal -> silent. - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - - try { - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - fail("Apps without notification policy access cannot change ringer mode"); - } catch (SecurityException e) { - } - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - - if (mHasVibrator) { - // Apps without policy access cannot change vibrate -> silent. - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - - try { - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - fail("Apps without notification policy access cannot change ringer mode"); - } catch (SecurityException e) { - } - - // Apps without policy access can change vibrate -> normal and vice versa. - assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - assertEquals(RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - mAudioManager.setRingerMode(RINGER_MODE_VIBRATE); - assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode()); - } - } - - public void testVolume() throws Exception { - if (MediaUtils.check(mIsTelevision, "No volume test due to fixed/full vol devices")) - return; - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - int volume, volumeDelta; - int[] streams = {STREAM_ALARM, - STREAM_MUSIC, - STREAM_VOICE_CALL, - STREAM_RING}; - - mAudioManager.adjustVolume(ADJUST_RAISE, 0); - // adjusting volume is asynchronous, wait before other volume checks - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - mAudioManager.adjustSuggestedStreamVolume( - ADJUST_LOWER, USE_DEFAULT_STREAM_TYPE, 0); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC); - - for (int stream : streams) { - if (mIsSingleVolume && stream != STREAM_MUSIC) { - continue; - } - - // set ringer mode to back normal to not interfere with volume tests - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - - int maxVolume = mAudioManager.getStreamMaxVolume(stream); - int minVolume = mAudioManager.getStreamMinVolume(stream); - - // validate min - assertTrue(String.format("minVolume(%d) must be >= 0", minVolume), minVolume >= 0); - assertTrue(String.format("minVolume(%d) must be < maxVolume(%d)", minVolume, - maxVolume), - minVolume < maxVolume); - - final int minNonZeroVolume = Math.max(minVolume, 1); - mAudioManager.setStreamVolume(stream, minNonZeroVolume, 0); - if (mUseFixedVolume) { - assertEquals(maxVolume, mAudioManager.getStreamVolume(stream)); - continue; - } - assertEquals(String.format("stream=%d", stream), - minNonZeroVolume, mAudioManager.getStreamVolume(stream)); - - if (stream == STREAM_MUSIC && mAudioManager.isWiredHeadsetOn()) { - // due to new regulations, music sent over a wired headset may be volume limited - // until the user explicitly increases the limit, so we can't rely on being able - // to set the volume to getStreamMaxVolume(). Instead, determine the current limit - // by increasing the volume until it won't go any higher, then use that volume as - // the maximum for the purposes of this test - int curvol = 0; - int prevvol = 0; - do { - prevvol = curvol; - mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); - curvol = mAudioManager.getStreamVolume(stream); - } while (curvol != prevvol); - maxVolume = maxMusicVolume = curvol; - } - mAudioManager.setStreamVolume(stream, maxVolume, 0); - mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); - assertEquals(maxVolume, mAudioManager.getStreamVolume(stream)); - - volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); - mAudioManager.adjustSuggestedStreamVolume(ADJUST_LOWER, stream, 0); - assertStreamVolumeEquals(stream, maxVolume - volumeDelta, - "Vol ADJUST_LOWER suggested stream:" + stream + " maxVol:" + maxVolume); - - // volume lower - mAudioManager.setStreamVolume(stream, maxVolume, 0); - volume = mAudioManager.getStreamVolume(stream); - while (volume > minVolume) { - volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); - mAudioManager.adjustStreamVolume(stream, ADJUST_LOWER, 0); - assertStreamVolumeEquals(stream, Math.max(0, volume - volumeDelta), - "Vol ADJUST_LOWER on stream:" + stream + " vol:" + volume - + " minVol:" + minVolume + " volDelta:" + volumeDelta); - volume = mAudioManager.getStreamVolume(stream); - } - - mAudioManager.adjustStreamVolume(stream, ADJUST_SAME, 0); - - // volume raise - mAudioManager.setStreamVolume(stream, minNonZeroVolume, 0); - volume = mAudioManager.getStreamVolume(stream); - while (volume < maxVolume) { - volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(stream)); - mAudioManager.adjustStreamVolume(stream, ADJUST_RAISE, 0); - assertStreamVolumeEquals(stream, Math.min(volume + volumeDelta, maxVolume), - "Vol ADJUST_RAISE on stream:" + stream + " vol:" + volume - + " maxVol:" + maxVolume + " volDelta:" + volumeDelta); - volume = mAudioManager.getStreamVolume(stream); - } - - // volume same - mAudioManager.setStreamVolume(stream, maxVolume, 0); - mAudioManager.adjustStreamVolume(stream, ADJUST_SAME, 0); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - assertEquals("Vol ADJUST_RAISE onADJUST_SAME stream:" + stream, - maxVolume, mAudioManager.getStreamVolume(stream)); - - mAudioManager.setStreamVolume(stream, maxVolume, 0); - } - - if (mUseFixedVolume) { - return; - } - - // adjust volume - mAudioManager.adjustVolume(ADJUST_RAISE, 0); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - - boolean isMusicPlayingBeforeTest = false; - if (mAudioManager.isMusicActive()) { - isMusicPlayingBeforeTest = true; - } - - MediaPlayer mp = MediaPlayer.create(mContext, MP3_TO_PLAY); - assertNotNull(mp); - mp.setAudioStreamType(STREAM_MUSIC); - mp.setLooping(true); - mp.start(); - assertMusicActive(true); - - // adjust volume as ADJUST_SAME - mAudioManager.adjustVolume(ADJUST_SAME, 0); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - assertStreamVolumeEquals(STREAM_MUSIC, maxMusicVolume); - - // adjust volume as ADJUST_RAISE - mAudioManager.setStreamVolume(STREAM_MUSIC, 0, 0); - volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); - mAudioManager.adjustVolume(ADJUST_RAISE, 0); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - assertStreamVolumeEquals(STREAM_MUSIC, Math.min(volumeDelta, maxMusicVolume)); - - // adjust volume as ADJUST_LOWER - mAudioManager.setStreamVolume(STREAM_MUSIC, maxMusicVolume, 0); - maxMusicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); - mAudioManager.adjustVolume(ADJUST_LOWER, 0); - assertStreamVolumeEquals(STREAM_MUSIC, Math.max(0, maxMusicVolume - volumeDelta)); - - mp.stop(); - mp.release(); - if (!isMusicPlayingBeforeTest) { - assertMusicActive(false); - } - } - - public void testAccessibilityVolume() throws Exception { - if (mUseFixedVolume) { - Log.i("AudioManagerTest", "testAccessibilityVolume() skipped: fixed volume"); - return; - } - final int maxA11yVol = mAudioManager.getStreamMaxVolume(STREAM_ACCESSIBILITY); - assertTrue("Max a11yVol not strictly positive", maxA11yVol > 0); - int originalVol = mAudioManager.getStreamVolume(STREAM_ACCESSIBILITY); - - // changing STREAM_ACCESSIBILITY is subject to permission, shouldn't be able to change it - // test setStreamVolume - final int testSetVol; - if (originalVol != maxA11yVol) { - testSetVol = maxA11yVol; - } else { - testSetVol = maxA11yVol - 1; - } - mAudioManager.setStreamVolume(STREAM_ACCESSIBILITY, testSetVol, 0); - assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, - "Should not be able to change A11y vol"); - - // test adjustStreamVolume - // LOWER - if (originalVol > 0) { - mAudioManager.adjustStreamVolume(STREAM_ACCESSIBILITY, ADJUST_LOWER, 0); - assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, - "Should not be able to change A11y vol"); - } - // RAISE - if (originalVol < maxA11yVol) { - mAudioManager.adjustStreamVolume(STREAM_ACCESSIBILITY, ADJUST_RAISE, 0); - assertStreamVolumeEquals(STREAM_ACCESSIBILITY, originalVol, - "Should not be able to change A11y vol"); - } - } - - public void testSetVoiceCallVolumeToZeroPermission() { - // Verify that only apps with MODIFY_PHONE_STATE can set VOICE_CALL_STREAM to 0 - mAudioManager.setStreamVolume(STREAM_VOICE_CALL, 0, 0); - assertTrue("MODIFY_PHONE_STATE is required in order to set voice call volume to 0", - mAudioManager.getStreamVolume(STREAM_VOICE_CALL) != 0); - } - - public void testMuteFixedVolume() throws Exception { - int[] streams = { - STREAM_VOICE_CALL, - STREAM_MUSIC, - STREAM_RING, - STREAM_ALARM, - STREAM_NOTIFICATION, - STREAM_SYSTEM}; - if (mUseFixedVolume) { - for (int stream : streams) { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); - assertFalse("Muting should not affect a fixed volume device.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); - assertFalse("Toggling mute should not affect a fixed volume device.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.setStreamMute(stream, true); - assertFalse("Muting should not affect a fixed volume device.", - mAudioManager.isStreamMute(stream)); - } - } - } - - public void testMuteDndAffectedStreams() throws Exception { - if (mSkipRingerTests) { - return; - } - int[] streams = { STREAM_RING }; - // Mute streams - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - // Verify streams cannot be unmuted without policy access. - for (int stream : streams) { - try { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_UNMUTE, 0); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_SILENT, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - - try { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, - 0); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_SILENT, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - - try { - mAudioManager.setStreamMute(stream, false); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_SILENT, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - } - - // This ensures we're out of vibrate or silent modes. - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - for (int stream : streams) { - // ensure each stream is on and turned up. - mAudioManager.setStreamVolume(stream, - mAudioManager.getStreamMaxVolume(stream), - 0); - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - try { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - try { - mAudioManager.adjustStreamVolume( - stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - - try { - mAudioManager.setStreamMute(stream, true); - assertEquals("Apps without Notification policy access can't change ringer mode", - RINGER_MODE_NORMAL, mAudioManager.getRingerMode()); - } catch (SecurityException e) { - } - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - testStreamMuting(stream); - } - } - - public void testMuteDndUnaffectedStreams() throws Exception { - if (mSkipRingerTests) { - return; - } - int[] streams = { - STREAM_VOICE_CALL, - STREAM_MUSIC, - STREAM_ALARM - }; - - int muteAffectedStreams = System.getInt(mContext.getContentResolver(), - System.MUTE_STREAMS_AFFECTED, - // same defaults as in AudioService. Should be kept in sync. - (1 << STREAM_MUSIC) | - (1 << STREAM_RING) | - (1 << STREAM_NOTIFICATION) | - (1 << STREAM_SYSTEM) | - (1 << STREAM_VOICE_CALL)); - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - // This ensures we're out of vibrate or silent modes. - mAudioManager.setRingerMode(RINGER_MODE_NORMAL); - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), false); - for (int stream : streams) { - // ensure each stream is on and turned up. - mAudioManager.setStreamVolume(stream, - mAudioManager.getStreamMaxVolume(stream), - 0); - if (((1 << stream) & muteAffectedStreams) == 0) { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); - assertFalse("Stream " + stream + " should not be affected by mute.", - mAudioManager.isStreamMute(stream)); - mAudioManager.setStreamMute(stream, true); - assertFalse("Stream " + stream + " should not be affected by mute.", - mAudioManager.isStreamMute(stream)); - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, - 0); - assertFalse("Stream " + stream + " should not be affected by mute.", - mAudioManager.isStreamMute(stream)); - continue; - } - testStreamMuting(stream); - } - } - - private void testStreamMuting(int stream) { - // Voice call requires MODIFY_PHONE_STATE, so we should not be able to mute - if (stream == STREAM_VOICE_CALL) { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); - assertFalse("Muting voice call stream (" + stream + ") should require " - + "MODIFY_PHONE_STATE.", mAudioManager.isStreamMute(stream)); - } else { - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0); - assertTrue("Muting stream " + stream + " failed.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_UNMUTE, 0); - assertFalse("Unmuting stream " + stream + " failed.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); - assertTrue("Toggling mute on stream " + stream + " failed.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.adjustStreamVolume(stream, AudioManager.ADJUST_TOGGLE_MUTE, 0); - assertFalse("Toggling mute on stream " + stream + " failed.", - mAudioManager.isStreamMute(stream)); - - mAudioManager.setStreamMute(stream, true); - assertTrue("Muting stream " + stream + " using setStreamMute failed", - mAudioManager.isStreamMute(stream)); - - // mute it three more times to verify the ref counting is gone. - mAudioManager.setStreamMute(stream, true); - mAudioManager.setStreamMute(stream, true); - mAudioManager.setStreamMute(stream, true); - - mAudioManager.setStreamMute(stream, false); - assertFalse("Unmuting stream " + stream + " using setStreamMute failed.", - mAudioManager.isStreamMute(stream)); - } - } - - public void testSetInvalidRingerMode() { - int ringerMode = mAudioManager.getRingerMode(); - mAudioManager.setRingerMode(-1337); - assertEquals(ringerMode, mAudioManager.getRingerMode()); - - mAudioManager.setRingerMode(-3007); - assertEquals(ringerMode, mAudioManager.getRingerMode()); - } - - public void testAdjustVolumeInTotalSilenceMode() throws Exception { - if (mSkipRingerTests) { - return; - } - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - mAudioManager.adjustStreamVolume( - STREAM_MUSIC, ADJUST_RAISE, 0); - assertStreamVolumeEquals(STREAM_MUSIC, musicVolume); - - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testAdjustVolumeInAlarmsOnlyMode() throws Exception { - if (mSkipRingerTests) { - return; - } - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - mAudioManager.adjustStreamVolume( - STREAM_MUSIC, ADJUST_RAISE, 0); - int volumeDelta = - getVolumeDelta(mAudioManager.getStreamVolume(STREAM_MUSIC)); - assertStreamVolumeEquals(STREAM_MUSIC, musicVolume + volumeDelta); - - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testSetStreamVolumeInTotalSilenceMode() throws Exception { - if (mSkipRingerTests) { - return; - } - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_NONE); - // delay for streams interruption filter to get into correct state - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - - // cannot adjust music, can adjust ringer since it could exit DND - int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - mAudioManager.setStreamVolume(STREAM_MUSIC, 7, 0); - assertStreamVolumeEquals(STREAM_MUSIC, musicVolume); - mAudioManager.setStreamVolume(STREAM_RING, 7, 0); - assertStreamVolumeEquals(STREAM_RING, 7); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testSetStreamVolumeInAlarmsOnlyMode() throws Exception { - if (mSkipRingerTests) { - return; - } - try { - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALARMS); - // delay for streams to get into correct volume states - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - - // can still adjust music and ring volume - mAudioManager.setStreamVolume(STREAM_MUSIC, 3, 0); - assertStreamVolumeEquals(STREAM_MUSIC, 3); - mAudioManager.setStreamVolume(STREAM_RING, 7, 0); - assertStreamVolumeEquals(STREAM_RING, 7); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testSetStreamVolumeInPriorityOnlyMode() throws Exception { - if (mSkipRingerTests) { - return; - } - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - - try { - // turn off zen, set stream volumes to check for later - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - - final int testRingerVol = getTestRingerVol(); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - int alarmVolume = mAudioManager.getStreamVolume(STREAM_ALARM); - - // disallow all sounds in priority only, turn on priority only DND, try to change volume - mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0 , 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - // delay for streams to get into correct volume states - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - mAudioManager.setStreamVolume(STREAM_MUSIC, 3, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 5, 0); - mAudioManager.setStreamVolume(STREAM_RING, testRingerVol, 0); - - // Turn off zen and make sure stream levels are still the same prior to zen - // aside from ringer since ringer can exit dnd - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); // delay for streams to get into correct states - assertEquals(musicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC)); - assertEquals(alarmVolume, mAudioManager.getStreamVolume(STREAM_ALARM)); - assertEquals(testRingerVol, mAudioManager.getStreamVolume(STREAM_RING)); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testAdjustVolumeInPriorityOnly() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // turn off zen, set stream volumes to check for later - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - int ringVolume = mAudioManager.getStreamVolume(STREAM_RING); - int musicVolume = mAudioManager.getStreamVolume(STREAM_MUSIC); - int alarmVolume = mAudioManager.getStreamVolume(STREAM_ALARM); - - // disallow all sounds in priority only, turn on priority only DND, try to change volume - mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - // delay for streams to get into correct mute states - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); - mAudioManager.adjustStreamVolume( - STREAM_RING, ADJUST_RAISE, 0); - mAudioManager.adjustStreamVolume( - STREAM_MUSIC, ADJUST_RAISE, 0); - mAudioManager.adjustStreamVolume( - STREAM_ALARM, ADJUST_RAISE, 0); - - // Turn off zen and make sure stream levels are still the same prior to zen - // aside from ringer since ringer can exit dnd - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - Thread.sleep(ASYNC_TIMING_TOLERANCE_MS); // delay for streams to get into correct states - assertEquals(musicVolume, mAudioManager.getStreamVolume(STREAM_MUSIC)); - assertEquals(alarmVolume, mAudioManager.getStreamVolume(STREAM_ALARM)); - - int volumeDelta = - getVolumeDelta(mAudioManager.getStreamVolume(STREAM_RING)); - assertEquals(ringVolume + volumeDelta, - mAudioManager.getStreamVolume(STREAM_RING)); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlyMuteAll() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // disallow all sounds in priority only, turn on priority only DND - mNm.setNotificationPolicy(new NotificationManager.Policy(0, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - - // if channels cannot bypass DND, the Ringer stream should be muted, else it - // shouldn't be muted - assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, - "Ringer stream should be muted if channels cannot bypassDnd"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlyMediaAllowed() throws Exception { - if (mSkipRingerTests) { - return; - } - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // allow only media in priority only - mNm.setNotificationPolicy(new NotificationManager.Policy( - NotificationManager.Policy.PRIORITY_CATEGORY_MEDIA, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, false, - "Music (media) stream should not be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - - // if channels cannot bypass DND, the Ringer stream should be muted, else it - // shouldn't be muted - assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, - "Ringer stream should be muted if channels cannot bypassDnd"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlySystemAllowed() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // allow only system in priority only - mNm.setNotificationPolicy(new NotificationManager.Policy( - NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, false, - "System stream should not be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - assertStreamMuted(STREAM_RING, false, - "Ringer stream should not be muted"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlySystemDisallowedWithRingerMuted() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test, but then mute ringer - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 0, 0); - mAudioManager.setRingerMode(RINGER_MODE_SILENT); - - // allow only system in priority only - mNm.setNotificationPolicy(new NotificationManager.Policy( - NotificationManager.Policy.PRIORITY_CATEGORY_SYSTEM, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - assertStreamMuted(STREAM_RING, true, - "Ringer stream should be muted"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlyAlarmsAllowed() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // allow only alarms in priority only - mNm.setNotificationPolicy(new NotificationManager.Policy( - NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, false, - "Alarm stream should not be muted"); - - // if channels cannot bypass DND, the Ringer stream should be muted, else it - // shouldn't be muted - assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, - "Ringer stream should be muted if channels cannot bypassDnd"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlyRingerAllowed() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // allow only reminders in priority only - mNm.setNotificationPolicy(new NotificationManager.Policy( - NotificationManager.Policy.PRIORITY_CATEGORY_REMINDERS, 0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - assertStreamMuted(STREAM_RING, false, - "Ringer stream should not be muted"); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - } - } - - public void testPriorityOnlyChannelsCanBypassDnd() throws Exception { - if (mSkipRingerTests) { - return; - } - - Utils.toggleNotificationPolicyAccess( - mContext.getPackageName(), getInstrumentation(), true); - - final String NOTIFICATION_CHANNEL_ID = "test_id_" + SystemClock.uptimeMillis(); - NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "TEST", - NotificationManager.IMPORTANCE_DEFAULT); - try { - // ensure volume is not muted/0 to start test - mAudioManager.setStreamVolume(STREAM_MUSIC, 1, 0); - mAudioManager.setStreamVolume(STREAM_ALARM, 1, 0); - mAudioManager.setStreamVolume(STREAM_SYSTEM, 1, 0); - mAudioManager.setStreamVolume(STREAM_RING, 1, 0); - - // create a channel that can bypass dnd - channel.setBypassDnd(true); - mNm.createNotificationChannel(channel); - - // allow nothing - mNm.setNotificationPolicy(new NotificationManager.Policy(0,0, 0)); - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_PRIORITY); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - assertStreamMuted(STREAM_RING, false, - "Ringer stream should not be muted." - + " areChannelsBypassing=" - + NotificationManager.getService().areChannelsBypassingDnd()); - - // delete the channel that can bypass dnd - mNm.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); - - assertStreamMuted(STREAM_MUSIC, true, - "Music (media) stream should be muted"); - assertStreamMuted(STREAM_SYSTEM, true, - "System stream should be muted"); - assertStreamMuted(STREAM_ALARM, true, - "Alarm stream should be muted"); - // if channels cannot bypass DND, the Ringer stream should be muted, else it - // shouldn't be muted - assertStreamMuted(STREAM_RING, !mAppsBypassingDnd, - "Ringer stream should be muted if apps are bypassing dnd" - + " areChannelsBypassing=" - + NotificationManager.getService().areChannelsBypassingDnd()); - } finally { - setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL); - mNm.deleteNotificationChannel(NOTIFICATION_CHANNEL_ID); - Utils.toggleNotificationPolicyAccess(mContext.getPackageName(), getInstrumentation(), - false); - } - } - - public void testAdjustVolumeWithIllegalDirection() throws Exception { - // Call the method with illegal direction. System should not reboot. - mAudioManager.adjustVolume(37, 0); - } - - private final int[] PUBLIC_STREAM_TYPES = { STREAM_VOICE_CALL, - STREAM_SYSTEM, STREAM_RING, STREAM_MUSIC, - STREAM_ALARM, STREAM_NOTIFICATION, - STREAM_DTMF, STREAM_ACCESSIBILITY }; - - public void testGetStreamVolumeDbWithIllegalArguments() throws Exception { - Exception ex = null; - // invalid stream type - try { - float gain = mAudioManager.getStreamVolumeDb(-100 /*streamType*/, 0, - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); - } catch (Exception e) { - ex = e; // expected - } - assertNotNull("No exception was thrown for an invalid stream type", ex); - assertEquals("Wrong exception thrown for invalid stream type", - ex.getClass(), IllegalArgumentException.class); - - // invalid volume index - ex = null; - try { - float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, -101 /*volume*/, - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); - } catch (Exception e) { - ex = e; // expected - } - assertNotNull("No exception was thrown for an invalid volume index", ex); - assertEquals("Wrong exception thrown for invalid volume index", - ex.getClass(), IllegalArgumentException.class); - - // invalid out of range volume index - ex = null; - try { - final int maxVol = mAudioManager.getStreamMaxVolume(STREAM_MUSIC); - float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, maxVol + 1, - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); - } catch (Exception e) { - ex = e; // expected - } - assertNotNull("No exception was thrown for an invalid out of range volume index", ex); - assertEquals("Wrong exception thrown for invalid out of range volume index", - ex.getClass(), IllegalArgumentException.class); - - // invalid device type - ex = null; - try { - float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, 0, - -102 /*deviceType*/); - } catch (Exception e) { - ex = e; // expected - } - assertNotNull("No exception was thrown for an invalid device type", ex); - assertEquals("Wrong exception thrown for invalid device type", - ex.getClass(), IllegalArgumentException.class); - - // invalid input device type - ex = null; - try { - float gain = mAudioManager.getStreamVolumeDb(STREAM_MUSIC, 0, - AudioDeviceInfo.TYPE_BUILTIN_MIC); - } catch (Exception e) { - ex = e; // expected - } - assertNotNull("No exception was thrown for an invalid input device type", ex); - assertEquals("Wrong exception thrown for invalid input device type", - ex.getClass(), IllegalArgumentException.class); - } - - public void testGetStreamVolumeDb() throws Exception { - for (int streamType : PUBLIC_STREAM_TYPES) { - // verify mininum index is strictly inferior to maximum index - final int minIndex = mAudioManager.getStreamMinVolume(streamType); - final int maxIndex = mAudioManager.getStreamMaxVolume(streamType); - assertTrue("Min vol index (" + minIndex + ") for stream " + streamType + " not inferior" - + " to max vol index (" + maxIndex + ")", minIndex <= maxIndex); - float prevGain = Float.NEGATIVE_INFINITY; - // verify gain increases with the volume indices - for (int idx = minIndex ; idx <= maxIndex ; idx++) { - float gain = mAudioManager.getStreamVolumeDb(streamType, idx, - AudioDeviceInfo.TYPE_BUILTIN_SPEAKER); - assertTrue("Non-monotonically increasing gain at index " + idx + " for stream" - + streamType, prevGain <= gain); - prevGain = gain; - } - } - } - - public void testAdjustSuggestedStreamVolumeWithIllegalArguments() throws Exception { - // Call the method with illegal direction. System should not reboot. - mAudioManager.adjustSuggestedStreamVolume(37, STREAM_MUSIC, 0); - - // Call the method with illegal stream. System should not reboot. - mAudioManager.adjustSuggestedStreamVolume(ADJUST_RAISE, 66747, 0); - } - - @CddTest(requirement="5.4.1/C-1-4") - public void testGetMicrophones() throws Exception { - if (!mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_MICROPHONE)) { - return; - } - List<MicrophoneInfo> microphones = mAudioManager.getMicrophones(); - assertTrue(microphones.size() > 0); - for (int i = 0; i < microphones.size(); i++) { - MicrophoneInfo microphone = microphones.get(i); - Log.i(TAG, "deviceId:" + microphone.getDescription()); - Log.i(TAG, "portId:" + microphone.getId()); - Log.i(TAG, "type:" + microphone.getType()); - Log.i(TAG, "address:" + microphone.getAddress()); - Log.i(TAG, "deviceLocation:" + microphone.getLocation()); - Log.i(TAG, "deviceGroup:" + microphone.getGroup() - + " index:" + microphone.getIndexInTheGroup()); - MicrophoneInfo.Coordinate3F position = microphone.getPosition(); - Log.i(TAG, "position:" + position.x + " " + position.y + " " + position.z); - MicrophoneInfo.Coordinate3F orientation = microphone.getOrientation(); - Log.i(TAG, "orientation:" + orientation.x + " " - + orientation.y + " " + orientation.z); - Log.i(TAG, "frequencyResponse:" + microphone.getFrequencyResponse()); - Log.i(TAG, "channelMapping:" + microphone.getChannelMapping()); - Log.i(TAG, "sensitivity:" + microphone.getSensitivity()); - Log.i(TAG, "max spl:" + microphone.getMaxSpl()); - Log.i(TAG, "min spl:" + microphone.getMinSpl()); - Log.i(TAG, "directionality:" + microphone.getDirectionality()); - Log.i(TAG, "--------------"); - } - } - - public void testIsHapticPlaybackSupported() { - // Calling the API to make sure it doesn't crash. - Log.i(TAG, "isHapticPlaybackSupported: " + AudioManager.isHapticPlaybackSupported()); - } - - public void testGetAudioHwSyncForSession() { - // AudioManager.getAudioHwSyncForSession is not supported before S - if (ApiLevelUtil.isAtMost(Build.VERSION_CODES.R)) { - Log.i(TAG, "testGetAudioHwSyncForSession skipped, release: " + Build.VERSION.SDK_INT); - return; - } - try { - int sessionId = mAudioManager.generateAudioSessionId(); - assertNotEquals("testGetAudioHwSyncForSession cannot get audio session ID", - AudioManager.ERROR, sessionId); - int hwSyncId = mAudioManager.getAudioHwSyncForSession(sessionId); - Log.i(TAG, "getAudioHwSyncForSession: " + hwSyncId); - } catch (UnsupportedOperationException e) { - Log.i(TAG, "getAudioHwSyncForSession not supported"); - } catch (Exception e) { - fail("Unexpected exception thrown by getAudioHwSyncForSession: " + e); - } - } - - private void setInterruptionFilter(int filter) { - mNm.setInterruptionFilter(filter); - final long startPoll = SystemClock.uptimeMillis(); - int currentFilter = -1; - while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_UPDATE_INTERRUPTION_FILTER) { - currentFilter = mNm.getCurrentInterruptionFilter(); - if (currentFilter == filter) { - return; - } - } - Log.e(TAG, "interruption filter unsuccessfully set. wanted=" + filter - + " actual=" + currentFilter); - } - - private int getVolumeDelta(int volume) { - return 1; - } - - private int getTestRingerVol() { - final int currentRingVol = mAudioManager.getStreamVolume(STREAM_RING); - final int maxRingVol = mAudioManager.getStreamMaxVolume(STREAM_RING); - if (currentRingVol != maxRingVol) { - return maxRingVol; - } else { - return maxRingVol - 1; - } - } - - public void testAllowedCapturePolicy() throws Exception { - final int policy = mAudioManager.getAllowedCapturePolicy(); - assertEquals("Wrong default capture policy", AudioAttributes.ALLOW_CAPTURE_BY_ALL, policy); - - for (int setPolicy : new int[] { AudioAttributes.ALLOW_CAPTURE_BY_NONE, - AudioAttributes.ALLOW_CAPTURE_BY_SYSTEM, - AudioAttributes.ALLOW_CAPTURE_BY_ALL}) { - mAudioManager.setAllowedCapturePolicy(setPolicy); - final int getPolicy = mAudioManager.getAllowedCapturePolicy(); - assertEquals("Allowed capture policy doesn't match", setPolicy, getPolicy); - } - } - - public void testIsHdmiSystemAudidoSupported() { - // just make sure the call works - boolean isSupported = mAudioManager.isHdmiSystemAudioSupported(); - Log.d(TAG, "isHdmiSystemAudioSupported() = " + isSupported); - } - - public void testIsBluetoothScoAvailableOffCall() { - // just make sure the call works - boolean isSupported = mAudioManager.isBluetoothScoAvailableOffCall(); - Log.d(TAG, "isBluetoothScoAvailableOffCall() = " + isSupported); - } - - public void testStartStopBluetoothSco() { - mAudioManager.startBluetoothSco(); - mAudioManager.stopBluetoothSco(); - } - - public void testStartStopBluetoothScoVirtualCall() { - mAudioManager.startBluetoothScoVirtualCall(); - mAudioManager.stopBluetoothSco(); - } - - public void testGetAdditionalOutputDeviceDelay() { - AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL); - for (AudioDeviceInfo device : devices) { - long delay = mAudioManager.getAdditionalOutputDeviceDelay(device); - assertTrue("getAdditionalOutputDeviceDelay() = " + delay +" (should be >= 0)", - delay >= 0); - delay = mAudioManager.getMaxAdditionalOutputDeviceDelay(device); - assertTrue("getMaxAdditionalOutputDeviceDelay() = " + delay +" (should be >= 0)", - delay >= 0); - } - } - - static class MyPrevDevForStrategyListener implements - AudioManager.OnPreferredDevicesForStrategyChangedListener { - @Override - public void onPreferredDevicesForStrategyChanged(AudioProductStrategy strategy, - List<AudioDeviceAttributes> devices) { - fail("onPreferredDevicesForStrategyChanged must not be called"); - } - } - - public void testPreferredDevicesForStrategy() { - // setPreferredDeviceForStrategy - AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); - if (devices.length <= 0) { - Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no output device"); - return; - } - final AudioDeviceAttributes ada = new AudioDeviceAttributes(devices[0]); - - final AudioAttributes mediaAttr = new AudioAttributes.Builder().setUsage( - AudioAttributes.USAGE_MEDIA).build(); - final List<AudioProductStrategy> strategies = - AudioProductStrategy.getAudioProductStrategies(); - AudioProductStrategy strategyForMedia = null; - for (AudioProductStrategy strategy : strategies) { - if (strategy.supportsAudioAttributes(mediaAttr)) { - strategyForMedia = strategy; - break; - } - } - if (strategyForMedia == null) { - Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no strategy for media"); - return; - } - - try { - mAudioManager.setPreferredDeviceForStrategy(strategyForMedia, ada); - fail("setPreferredDeviceForStrategy must fail due to no permission"); - } catch (SecurityException e) { - } - try { - mAudioManager.getPreferredDeviceForStrategy(strategyForMedia); - fail("getPreferredDeviceForStrategy must fail due to no permission"); - } catch (SecurityException e) { - } - final List<AudioDeviceAttributes> adas = new ArrayList<>(); - adas.add(ada); - try { - mAudioManager.setPreferredDevicesForStrategy(strategyForMedia, adas); - fail("setPreferredDevicesForStrategy must fail due to no permission"); - } catch (SecurityException e) { - } - try { - mAudioManager.getPreferredDevicesForStrategy(strategyForMedia); - fail("getPreferredDevicesForStrategy must fail due to no permission"); - } catch (SecurityException e) { - } - MyPrevDevForStrategyListener listener = new MyPrevDevForStrategyListener(); - try { - mAudioManager.addOnPreferredDevicesForStrategyChangedListener( - Executors.newSingleThreadExecutor(), listener); - fail("addOnPreferredDevicesForStrategyChangedListener must fail due to no permission"); - } catch (SecurityException e) { - } - // There is not listener added at server side. Nothing to remove. - mAudioManager.removeOnPreferredDevicesForStrategyChangedListener(listener); - } - - static class MyPrevDevicesForCapturePresetChangedListener implements - AudioManager.OnPreferredDevicesForCapturePresetChangedListener { - @Override - public void onPreferredDevicesForCapturePresetChanged( - int capturePreset, List<AudioDeviceAttributes> devices) { - fail("onPreferredDevicesForCapturePresetChanged must not be called"); - } - } - - public void testPreferredDeviceForCapturePreset() { - AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS); - if (devices.length <= 0) { - Log.i(TAG, "Skip testPreferredDevicesForStrategy as there is no input device"); - return; - } - final AudioDeviceAttributes ada = new AudioDeviceAttributes(devices[0]); - - try { - mAudioManager.setPreferredDeviceForCapturePreset(MediaRecorder.AudioSource.MIC, ada); - fail("setPreferredDeviceForCapturePreset must fail due to no permission"); - } catch (SecurityException e) { - } - try { - mAudioManager.getPreferredDevicesForCapturePreset(MediaRecorder.AudioSource.MIC); - fail("getPreferredDevicesForCapturePreset must fail due to no permission"); - } catch (SecurityException e) { - } - try { - mAudioManager.clearPreferredDevicesForCapturePreset(MediaRecorder.AudioSource.MIC); - fail("clearPreferredDevicesForCapturePreset must fail due to no permission"); - } catch (SecurityException e) { - } - MyPrevDevicesForCapturePresetChangedListener listener = - new MyPrevDevicesForCapturePresetChangedListener(); - try { - mAudioManager.addOnPreferredDevicesForCapturePresetChangedListener( - Executors.newSingleThreadExecutor(), listener); - fail("addOnPreferredDevicesForCapturePresetChangedListener must fail" - + "due to no permission"); - } catch (SecurityException e) { - } - // There is not listener added at server side. Nothing to remove. - mAudioManager.removeOnPreferredDevicesForCapturePresetChangedListener(listener); - } - - public void testGetDevices() { - AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL); - for (AudioDeviceInfo device : devices) { - HashSet<Integer> formats = IntStream.of(device.getEncodings()).boxed() - .collect(Collectors.toCollection(HashSet::new)); - HashSet<Integer> channelMasks = IntStream.of(device.getChannelMasks()).boxed() - .collect(Collectors.toCollection(HashSet::new)); - HashSet<Integer> channelIndexMasks = IntStream.of(device.getChannelIndexMasks()).boxed() - .collect(Collectors.toCollection(HashSet::new)); - HashSet<Integer> sampleRates = IntStream.of(device.getSampleRates()).boxed() - .collect(Collectors.toCollection(HashSet::new)); - HashSet<Integer> formatsFromProfile = new HashSet<>(); - HashSet<Integer> channelMasksFromProfile = new HashSet<>(); - HashSet<Integer> channelIndexMasksFromProfile = new HashSet<>(); - HashSet<Integer> sampleRatesFromProfile = new HashSet<>(); - for (AudioProfile profile : device.getAudioProfiles()) { - formatsFromProfile.add(profile.getFormat()); - channelMasksFromProfile.addAll(Arrays.stream(profile.getChannelMasks()).boxed() - .collect(Collectors.toList())); - channelIndexMasksFromProfile.addAll(Arrays.stream(profile.getChannelIndexMasks()) - .boxed().collect(Collectors.toList())); - sampleRatesFromProfile.addAll(Arrays.stream(profile.getSampleRates()).boxed() - .collect(Collectors.toList())); - assertTrue(ALL_ENCAPSULATION_TYPES.contains(profile.getEncapsulationType())); - } - for (AudioDescriptor descriptor : device.getAudioDescriptors()) { - assertNotEquals(AudioDescriptor.STANDARD_NONE, descriptor.getStandard()); - assertNotNull(descriptor.getDescriptor()); - assertTrue( - ALL_KNOWN_ENCAPSULATION_TYPES.contains(descriptor.getEncapsulationType())); - } - assertEquals(formats, formatsFromProfile); - assertEquals(channelMasks, channelMasksFromProfile); - assertEquals(channelIndexMasks, channelIndexMasksFromProfile); - assertEquals(sampleRates, sampleRatesFromProfile); - } - } - - private void assertStreamVolumeEquals(int stream, int expectedVolume) throws Exception { - assertStreamVolumeEquals(stream, expectedVolume, - "Unexpected stream volume for stream=" + stream); - } - - // volume adjustments are asynchronous, we poll the volume in case the volume state hasn't - // been adjusted yet - private void assertStreamVolumeEquals(int stream, int expectedVolume, String msg) - throws Exception { - final long startPoll = SystemClock.uptimeMillis(); - int actualVolume = mAudioManager.getStreamVolume(stream); - while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_VOLUME_ADJUST - && expectedVolume != actualVolume) { - actualVolume = mAudioManager.getStreamVolume(stream); - } - assertEquals(msg, expectedVolume, actualVolume); - } - - // volume adjustments are asynchronous, we poll the volume in case the mute state hasn't - // changed yet - private void assertStreamMuted(int stream, boolean expectedMuteState, String msg) - throws Exception{ - final long startPoll = SystemClock.uptimeMillis(); - boolean actualMuteState = mAudioManager.isStreamMute(stream); - while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_VOLUME_ADJUST - && expectedMuteState != actualMuteState) { - actualMuteState = mAudioManager.isStreamMute(stream); - } - assertEquals(msg, expectedMuteState, actualMuteState); - } - - private void assertMusicActive(boolean expectedIsMusicActive) throws Exception { - final long startPoll = SystemClock.uptimeMillis(); - boolean actualIsMusicActive = mAudioManager.isMusicActive(); - while (SystemClock.uptimeMillis() - startPoll < POLL_TIME_PLAY_MUSIC - && expectedIsMusicActive != actualIsMusicActive) { - actualIsMusicActive = mAudioManager.isMusicActive(); - } - assertEquals(actualIsMusicActive, actualIsMusicActive); - } - - private static final long REPEATED_CHECK_POLL_PERIOD_MS = 100; // 100ms - private static final long DEFAULT_ASYNC_CALL_TIMEOUT_MS = 5 * REPEATED_CHECK_POLL_PERIOD_MS; - - /** - * Makes multiple attempts over a given timeout period to test the predicate on an AudioManager - * instance. Test success is evaluated against a true predicate result. - * @param am the AudioManager instance to use for the test - * @param predicate the test to run either until it returns true, or until the timeout expires - * @param timeoutMs the maximum time allowed for the test to pass - * @param errorString the string to be displayed in case of failure - * @throws Exception - */ - private void assertTrueCheckTimeout(AudioManager am, Predicate<AudioManager> predicate, - long timeoutMs, String errorString) throws Exception { - long checkStart = SystemClock.uptimeMillis(); - boolean result = false; - while (SystemClock.uptimeMillis() - checkStart < timeoutMs) { - result = predicate.test(am); - if (result) { - break; - } - Thread.sleep(REPEATED_CHECK_POLL_PERIOD_MS); - } - assertTrue(errorString, result); - } - - // getParameters() & setParameters() are deprecated, so don't test - - // setAdditionalOutputDeviceDelay(), getAudioVolumeGroups(), getVolumeIndexForAttributes() - // getMinVolumeIndexForAttributes(), getMaxVolumeIndexForAttributes() & - // setVolumeIndexForAttributes() require privledged permission MODIFY_AUDIO_ROUTING - // and thus cannot be tested here. -} diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml index 5487fb43bde..4e43d570881 100644 --- a/tests/tests/security/AndroidManifest.xml +++ b/tests/tests/security/AndroidManifest.xml @@ -238,6 +238,9 @@ android:resource="@xml/syncadapter" /> </service> + <activity android:name="android.security.cts.CVE_2023_20953.PocActivity" + android:exported="true" /> + <activity android:name="android.security.cts.CVE_2021_0642.PocActivity" android:exported="true"> <intent-filter> diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java b/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java new file mode 100644 index 00000000000..8c1863cffd7 --- /dev/null +++ b/tests/tests/security/src/android/security/cts/CVE_2023_20953/CVE_2023_20953.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts.CVE_2023_20953; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assume.assumeNoException; +import static org.junit.Assume.assumeTrue; + +import android.app.Instrumentation; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.platform.test.annotations.AsbSecurityTest; +import android.support.test.uiautomator.By; +import android.support.test.uiautomator.BySelector; +import android.support.test.uiautomator.UiDevice; +import android.support.test.uiautomator.UiObject2; +import android.support.test.uiautomator.Until; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.sts.common.SystemUtil; +import com.android.sts.common.util.StsExtraBusinessLogicTestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.regex.Pattern; + +@RunWith(AndroidJUnit4.class) +public class CVE_2023_20953 extends StsExtraBusinessLogicTestCase { + + @AsbSecurityTest(cveBugId = 251778420) + @Test + public void testCliboardIfUserSetupNotComplete() { + try { + Instrumentation instrumentation = getInstrumentation(); + Context context = instrumentation.getContext(); + UiDevice device = UiDevice.getInstance(instrumentation); + + // Change the setting 'user_setup_complete' to 0. + try (AutoCloseable withSettingCloseable = + SystemUtil.withSetting(instrumentation, "secure", "user_setup_complete", "0")) { + // Launch the PocActivity which shows a basic view to edit some text. + final String pkgName = context.getPackageName(); + Intent intent = new Intent(); + intent.setClassName(pkgName, pkgName + ".CVE_2023_20953.PocActivity"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + // Look for UI with text "CVE-2023-20955" and select it. Doing so will show some + // clipboard options such as 'copy', 'select all', 'cut'. + final String uiNotFoundMsg = "UI not found with selector %s"; + BySelector selector = By.text("CVE-2023-20955"); + final long timeoutMs = 5000; + boolean uiFound = device.wait(Until.findObject(selector), timeoutMs) != null; + assumeTrue(String.format(uiNotFoundMsg, selector), uiFound); + UiObject2 object = device.findObject(selector); + device.drag(object.getVisibleBounds().left, object.getVisibleCenter().y, + object.getVisibleBounds().right, object.getVisibleCenter().y, 1); + + // Click on 'Copy' option. + selector = By.desc(Pattern.compile(".*copy.*", Pattern.CASE_INSENSITIVE)); + uiFound = device.wait(Until.findObject(selector), timeoutMs) != null; + assumeTrue(String.format(uiNotFoundMsg, selector), uiFound); + device.findObject(selector).click(); + + // Retrieve System UI package name dynamically. + String systemUiPkgName = "com.android.systemui"; + intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG); + PackageManager pm = context.getPackageManager(); + ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_SYSTEM_ONLY); + if (info != null && info.activityInfo != null + && info.activityInfo.packageName != null) { + systemUiPkgName = info.activityInfo.packageName; + } + + // On vulnerable device, user whose setup is not yet complete will be able to share + // the copied text, in which case test fails, else it passes. + // Look for UI with resource = com.android.systemui:id/share_chip, if found test + // will fail. + final String shareBtnResName = "%s:id/share_chip"; + selector = By.res(String.format(shareBtnResName, systemUiPkgName)); + assertFalse("Vulnerable to b/251778420 !!", + device.wait(Until.hasObject(selector), timeoutMs)); + } + } catch (Exception e) { + assumeNoException(e); + } + } +} diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java b/tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java new file mode 100644 index 00000000000..5ef6ceba4f2 --- /dev/null +++ b/tests/tests/security/src/android/security/cts/CVE_2023_20953/PocActivity.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts.CVE_2023_20953; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.EditText; + +public class PocActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + try { + super.onCreate(savedInstanceState); + EditText editText = new EditText(this); + editText.setText("CVE-2023-20955"); + setContentView(editText); + } catch (Exception e) { + // ignore + } + } +} diff --git a/tests/tests/security/src/android/security/cts/CVE_2023_20959.java b/tests/tests/security/src/android/security/cts/CVE_2023_20959.java new file mode 100644 index 00000000000..00c0e6dabd1 --- /dev/null +++ b/tests/tests/security/src/android/security/cts/CVE_2023_20959.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.security.cts; + +import static org.junit.Assert.assertNull; +import static org.junit.Assume.assumeNoException; + +import android.app.Instrumentation; +import android.app.UiAutomation; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.os.UserHandle; +import android.platform.test.annotations.AsbSecurityTest; +import android.provider.Settings; + +import androidx.test.runner.AndroidJUnit4; + +import com.android.sts.common.util.StsExtraBusinessLogicTestCase; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class CVE_2023_20959 extends StsExtraBusinessLogicTestCase { + + @AsbSecurityTest(cveBugId = 249057848) + @Test + public void testPocCVE_2023_20959() { + UiAutomation uiAutomation = null; + try { + String settingsPackageName = "com.android.settings"; + Instrumentation instrumentation = getInstrumentation(); + PackageManager packageManager = instrumentation.getTargetContext().getPackageManager(); + uiAutomation = instrumentation.getUiAutomation(); + uiAutomation.adoptShellPermissionIdentity( + android.Manifest.permission.INTERACT_ACROSS_USERS); + ResolveInfo info = + packageManager.resolveActivityAsUser(new Intent(Settings.ACTION_SETTINGS), + PackageManager.MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM); + if (info != null && info.activityInfo != null) { + settingsPackageName = info.activityInfo.packageName; + } + assertNull(new Intent() + .setComponent(new ComponentName(settingsPackageName, + settingsPackageName + ".users.AddSupervisedUserActivity")) + .resolveActivityInfo(packageManager, PackageManager.MATCH_SYSTEM_ONLY)); + } catch (Exception e) { + assumeNoException(e); + } finally { + try { + uiAutomation.dropShellPermissionIdentity(); + } catch (Exception e) { + // Ignore exceptions as the test has finished + } + } + } +} diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml index ba1205e5306..f58fe04bd1b 100644 --- a/tests/tests/view/AndroidManifest.xml +++ b/tests/tests/view/AndroidManifest.xml @@ -214,7 +214,7 @@ android:label="PixelCopyViewProducerDialogActivity" android:screenOrientation="portrait" android:rotationAnimation="jumpcut" - android:theme="@android:style/Theme.Material.Dialog.NoActionBar" + android:theme="@style/PixelCopyViewProducerDialogActivityTheme" android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize"/> <activity android:name="android.view.cts.FocusFinderCtsActivity" diff --git a/tests/tests/view/res/values/styles.xml b/tests/tests/view/res/values/styles.xml index bb513bfc73a..34df7cce0df 100644 --- a/tests/tests/view/res/values/styles.xml +++ b/tests/tests/view/res/values/styles.xml @@ -184,6 +184,10 @@ <item name="android:windowAnimationStyle">@null</item> </style> + <style name="PixelCopyViewProducerDialogActivityTheme" parent="@android:style/Theme.Material.Dialog.NoActionBar"> + <item name="android:windowLayoutInDisplayCutoutMode">default</item> + </style> + <style name="ViewAttributeTestTheme" parent="@android:Theme.Material"/> <style name="ExplicitStyle1" parent="@style/ParentOfExplicitStyle1"> |