Skip to content

Commit

Permalink
Improve AudioCapabilities with AudioManager API in Android 13
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 604700601
(cherry picked from commit ccd603a)
  • Loading branch information
tianyif authored and SheenaChhabra committed Feb 8, 2024
1 parent bf8b874 commit 9f28e7d
Show file tree
Hide file tree
Showing 3 changed files with 347 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.CancellationException;
Expand Down Expand Up @@ -505,7 +506,7 @@ public static boolean isRunningOnEmulator() {

/**
* Tests two objects for {@link Object#equals(Object)} equality, handling the case where one or
* both may be null.
* both may be {@code null}.
*
* @param o1 The first object.
* @param o2 The second object.
Expand All @@ -516,6 +517,64 @@ public static boolean areEqual(@Nullable Object o1, @Nullable Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}

/**
* Tests two {@link SparseArray} instances for content equality, handling the case where one or
* both may be {@code null}.
*
* @see SparseArray#contentEquals(SparseArray)
* @param sparseArray1 The first {@link SparseArray} instance.
* @param sparseArray2 The second {@link SparseArray} instance.
* @return True if the two {@link SparseArray} instances are equal in contents.
*/
@UnstableApi
public static <T> boolean contentEquals(
@Nullable SparseArray<T> sparseArray1, @Nullable SparseArray<T> sparseArray2) {
if (sparseArray1 == null) {
return sparseArray2 == null;
} else if (sparseArray2 == null) {
return false;
}

if (Util.SDK_INT >= 31) {
return sparseArray1.contentEquals(sparseArray2);
}

int size = sparseArray1.size();
if (size != sparseArray2.size()) {
return false;
}

for (int index = 0; index < size; index++) {
int key = sparseArray1.keyAt(index);
if (!Objects.equals(sparseArray1.valueAt(index), sparseArray2.get(key))) {
return false;
}
}

return true;
}

/**
* Returns a hash code value for the contents of this {@link SparseArray}, combining the {@link
* Objects#hashCode(Object)} result of all its keys and values.
*
* @see SparseArray#contentHashCode()
* @param sparseArray The {@link SparseArray} instance.
* @return The hash code.
*/
@UnstableApi
public static <T> int contentHashCode(SparseArray<T> sparseArray) {
if (Util.SDK_INT >= 31) {
return sparseArray.contentHashCode();
}
int hash = 17;
for (int index = 0; index < sparseArray.size(); index++) {
hash = 31 * hash + sparseArray.keyAt(index);
hash = 31 * hash + Objects.hashCode(sparseArray.valueAt(index));
}
return hash;
}

/**
* Tests whether an {@code items} array contains an object equal to {@code item}, according to
* {@link Object#equals(Object)}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import static androidx.media3.common.util.Util.binarySearchCeil;
import static androidx.media3.common.util.Util.binarySearchFloor;
import static androidx.media3.common.util.Util.contentEquals;
import static androidx.media3.common.util.Util.contentHashCode;
import static androidx.media3.common.util.Util.escapeFileName;
import static androidx.media3.common.util.Util.getCodecsOfType;
import static androidx.media3.common.util.Util.getStringForTime;
Expand All @@ -42,6 +44,7 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.SparseArray;
import android.util.SparseLongArray;
import androidx.media3.common.C;
import androidx.test.ext.junit.runners.AndroidJUnit4;
Expand Down Expand Up @@ -1523,6 +1526,77 @@ public void getRoleFlagStrings() {
assertThat(roleFlags).containsExactly("describes-music", "easy-read");
}

@Test
public void contentEquals_twoNullSparseArrays_returnsTrue() {
assertThat(contentEquals(null, null)).isTrue();
}

@Test
public void contentEquals_oneNullSparseArrayAndOneNonNullSparseArray_returnsFalse() {
SparseArray<Integer> sparseArray = new SparseArray<>();
sparseArray.put(1, 2);

assertThat(contentEquals(sparseArray, null)).isFalse();
assertThat(contentEquals(null, sparseArray)).isFalse();
}

@Test
@Config(minSdk = 16) // Specifies the minimum SDK to enforce the test to run with all API levels.
public void contentEquals_sparseArraysWithEqualContent_returnsTrue() {
SparseArray<Integer> sparseArray1 = new SparseArray<>();
sparseArray1.put(1, 2);
sparseArray1.put(3, 4);
SparseArray<Integer> sparseArray2 = new SparseArray<>();
sparseArray2.put(3, 4);
sparseArray2.put(1, 2);

assertThat(contentEquals(sparseArray1, sparseArray2)).isTrue();
}

@Test
@Config(minSdk = 16) // Specifies the minimum SDK to enforce the test to run with all API levels.
public void contentEquals_sparseArraysWithDifferentContents_returnsFalse() {
SparseArray<Integer> sparseArray1 = new SparseArray<>();
sparseArray1.put(1, 2);
sparseArray1.put(3, 4);
SparseArray<Integer> sparseArray2 = new SparseArray<>();
sparseArray2.put(3, 4);
SparseArray<Integer> sparseArray3 = new SparseArray<>();
sparseArray3.put(1, 3);
sparseArray3.put(3, 4);

assertThat(contentEquals(sparseArray1, sparseArray2)).isFalse();
assertThat(contentEquals(sparseArray1, sparseArray3)).isFalse();
}

@Test
@Config(minSdk = 16) // Specifies the minimum SDK to enforce the test to run with all API levels.
public void contentHashCode_sparseArraysWithEqualContent_returnsEqualContentHashCode() {
SparseArray<Integer> sparseArray1 = new SparseArray<>();
sparseArray1.put(1, 2);
sparseArray1.put(3, 4);
SparseArray<Integer> sparseArray2 = new SparseArray<>();
sparseArray2.put(3, 4);
sparseArray2.put(1, 2);

assertThat(contentHashCode(sparseArray1)).isEqualTo(contentHashCode(sparseArray2));
}

@Test
@Config(minSdk = 16) // Specifies the minimum SDK to enforce the test to run with all API levels.
public void contentHashCode_sparseArraysWithDifferentContent_returnsDifferentContentHashCode() {
// In theory this is not guaranteed though, adding this test to ensure a sensible
// contentHashCode implementation.
SparseArray<Integer> sparseArray1 = new SparseArray<>();
sparseArray1.put(1, 2);
sparseArray1.put(3, 4);
SparseArray<Integer> sparseArray2 = new SparseArray<>();
sparseArray2.put(3, 2);
sparseArray2.put(1, 4);

assertThat(contentHashCode(sparseArray1)).isNotEqualTo(contentHashCode(sparseArray2));
}

private static void assertEscapeUnescapeFileName(String fileName, String escapedFileName) {
assertThat(escapeFileName(fileName)).isEqualTo(escapedFileName);
assertThat(unescapeFileName(escapedFileName)).isEqualTo(fileName);
Expand Down
Loading

0 comments on commit 9f28e7d

Please sign in to comment.