Merge "Allow compatibility-device-util-axt to be used with ExtendedMockito"
diff --git a/apps/CtsVerifier/res/layout/audio_headset_audio_activity.xml b/apps/CtsVerifier/res/layout/audio_headset_audio_activity.xml
index 24767d2..716b18f 100644
--- a/apps/CtsVerifier/res/layout/audio_headset_audio_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_headset_audio_activity.xml
@@ -123,7 +123,8 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/analog_headset_keycodes_label"/>
+ android:text="@string/analog_headset_keycodes_label"
+ android:id="@+id/headset_keycodes"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index b694e2f..704be2e 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -5419,6 +5419,16 @@
input jack and BT01 input plug to the USB interface output jack.
\nThe Virtual MIDI test does not require any MIDI interface hardware.
</string>
+ <string name="analog_headset_test_info_tv">This test tests the following functionality with respect to wired analog headsets.\n
+ 1. Correct audio playback.\n
+ 2. Plug intents.\n
+ \nTo execute test:\n
+ 1. Plug in an Android-compatible, analog headset. Verify connection/recognition.\n
+ 2. Play test tone and verify correct behavior.\n
+ \nTo run this test it is necessary to have an Android device with a 3.5mm analog headset jack and a compatible analog headset.\n
+ \n(see <a href="https://source.android.com/devices/accessories/headset/plug-headset-spec">3.5 mm Headset: Accessory Specification</a> and
+ <a href="https://source.android.com/compatibility/android-cdd#7_8_2_1_analog_audio_ports">Android CDD § 7.8.2.1. Analog Audio Ports</a>)
+ </string>
<string name="midiHasMIDILbl">Has MIDI Support</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
index 83b32de..307eb6f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AnalogHeadsetAudioActivity.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioDeviceCallback;
@@ -153,6 +154,14 @@
mHeadsetVolUpText = (TextView)findViewById(R.id.headset_keycode_volume_up);
mHeadsetVolDownText = (TextView)findViewById(R.id.headset_keycode_volume_down);
+ if (isTelevision()) {
+ mButtonsPromptTxt.setVisibility(View.GONE);
+ mHeadsetHookText.setVisibility(View.GONE);
+ mHeadsetVolUpText.setVisibility(View.GONE);
+ mHeadsetVolDownText.setVisibility(View.GONE);
+ ((TextView) findViewById(R.id.headset_keycodes)).setVisibility(View.GONE);
+ }
+
mResultsTxt = (TextView)findViewById(R.id.headset_results);
mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
@@ -168,7 +177,8 @@
showKeyMessagesState();
- setInfoResources(R.string.analog_headset_test, R.string.analog_headset_test_info, -1);
+ setInfoResources(R.string.analog_headset_test, isTelevision()
+ ? R.string.analog_headset_test_info_tv : R.string.analog_headset_test_info, -1);
setPassFailButtonClickListeners();
getPassButton().setEnabled(false);
@@ -182,11 +192,12 @@
mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass_noheadset));
return true;
} else {
- boolean pass = isReportLogOkToPass()
- && mPlugIntentReceived
- && mHeadsetDeviceInfo != null
- && mPlaybackSuccess
- && (mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown;
+ boolean pass = isReportLogOkToPass() &&
+ mPlugIntentReceived &&
+ mHeadsetDeviceInfo != null &&
+ mPlaybackSuccess &&
+ (isTelevision()
+ || ((mHasHeadsetHook || mHasPlayPause) && mHasVolUp && mHasVolDown));
if (pass) {
mResultsTxt.setText(getResources().getString(R.string.analog_headset_pass));
} else if (!isReportLogOkToPass()) {
@@ -488,4 +499,8 @@
}
return super.onKeyDown(keyCode, event);
}
+
+ private boolean isTelevision() {
+ return getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ }
}
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsMouseUtil.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsMouseUtil.java
index e53eb08..5cabd64 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsMouseUtil.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/CtsMouseUtil.java
@@ -126,8 +126,8 @@
@Override
public boolean matches(MotionEvent actual) {
return super.matches(actual)
- && ((int) actual.getX()) == mX
- && ((int) actual.getY()) == mY;
+ && Math.round(actual.getX()) == mX
+ && Math.round(actual.getY()) == mY;
}
@Override
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
index a9543c2..1611e13 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/UiAutomatorUtils.java
@@ -42,7 +42,13 @@
private static final String LOG_TAG = "UiAutomatorUtils";
/** Default swipe deadzone percentage. See {@link UiScrollable}. */
- private static final double DEFAULT_SWIPE_DEADZONE_PCT = 0.1;
+ private static final double DEFAULT_SWIPE_DEADZONE_PCT_TV = 0.1f;
+ private static final double DEFAULT_SWIPE_DEADZONE_PCT_ALL = 0.25f;
+ /**
+ * On Wear, some cts tests like CtsPermission3TestCases that run on
+ * low performance device. Keep 0.05 to have better matching.
+ */
+ private static final double DEFAULT_SWIPE_DEADZONE_PCT_WEAR = 0.05f;
/** Minimum view height accepted (before needing to scroll more). */
private static final float MIN_VIEW_HEIGHT_DP = 8;
@@ -78,6 +84,16 @@
ApplicationProvider.getApplicationContext().getResources().getDisplayMetrics()));
}
+ private static double getSwipeDeadZonePct() {
+ if (FeatureUtil.isTV()) {
+ return DEFAULT_SWIPE_DEADZONE_PCT_TV;
+ } else if (FeatureUtil.isWatch()) {
+ return DEFAULT_SWIPE_DEADZONE_PCT_WEAR;
+ } else {
+ return DEFAULT_SWIPE_DEADZONE_PCT_ALL;
+ }
+ }
+
public static UiObject2 waitFindObjectOrNull(BySelector selector, long timeoutMs)
throws UiObjectNotFoundException {
UiObject2 view = null;
@@ -101,8 +117,7 @@
}
if (view == null || view.getVisibleBounds().height() < minViewHeightPx) {
- final double deadZone = !(FeatureUtil.isWatch() || FeatureUtil.isTV())
- ? 0.25 : DEFAULT_SWIPE_DEADZONE_PCT;
+ final double deadZone = getSwipeDeadZonePct();
UiScrollable scrollable = new UiScrollable(new UiSelector().scrollable(true));
scrollable.setSwipeDeadZonePercentage(deadZone);
if (scrollable.exists()) {
diff --git a/libs/helpers/interfaces/Android.bp b/libs/helpers/interfaces/Android.bp
index 3cdb264..dcb38f5 100644
--- a/libs/helpers/interfaces/Android.bp
+++ b/libs/helpers/interfaces/Android.bp
@@ -23,7 +23,6 @@
static_libs: [
"cts-helpers-core",
- "ub-uiautomator",
],
sdk_version: "test_current",
diff --git a/tests/app/src/android/app/cts/DisplayTest.java b/tests/app/src/android/app/cts/DisplayTest.java
index f0669b9..a79a6b3 100644
--- a/tests/app/src/android/app/cts/DisplayTest.java
+++ b/tests/app/src/android/app/cts/DisplayTest.java
@@ -20,12 +20,17 @@
import static com.google.common.truth.Truth.assertWithMessage;
+import android.app.ActivityOptions;
import android.app.stubs.DisplayTestActivity;
import android.app.stubs.OrientationTestUtils;
+import android.content.Intent;
import android.graphics.Point;
import android.server.wm.SetRequestedOrientationRule;
+import android.util.Pair;
import android.view.Display;
+import androidx.test.platform.app.InstrumentationRegistry;
+
import com.android.compatibility.common.util.ApiTest;
import org.junit.Rule;
@@ -52,55 +57,62 @@
return;
}
- final DisplayTestActivity activity =
- mSetRequestedOrientationRule.launchActivityInFullscreen(DisplayTestActivity.class);
+ final Pair<Intent, ActivityOptions> launchArgs =
+ SetRequestedOrientationRule.buildFullScreenLaunchArgs(DisplayTestActivity.class);
- // Get a {@link Display} instance before rotation.
- final Display origDisplay = activity.getDisplay();
+ final DisplayTestActivity activity = (DisplayTestActivity) InstrumentationRegistry
+ .getInstrumentation()
+ .startActivitySync(launchArgs.first, launchArgs.second.toBundle());
+ try {
+ // Get a {@link Display} instance before rotation.
+ final Display origDisplay = activity.getDisplay();
- // Capture the originally reported width and heights
- final Point origSize = new Point();
- origDisplay.getRealSize(origSize);
+ // Capture the originally reported width and heights
+ final Point origSize = new Point();
+ origDisplay.getRealSize(origSize);
- // Change orientation
- activity.configurationChangeObserver.startObserving();
- OrientationTestUtils.switchOrientation(activity);
+ // Change orientation
+ activity.configurationChangeObserver.startObserving();
+ OrientationTestUtils.switchOrientation(activity);
- final boolean closeToSquareBounds =
- OrientationTestUtils.isCloseToSquareBounds(activity);
+ final boolean closeToSquareBounds =
+ OrientationTestUtils.isCloseToSquareBounds(activity);
- // Don't wait for the configuration to change if
- // the display is square. In many cases it won't.
- if (!closeToSquareBounds) {
- activity.configurationChangeObserver.await();
- }
+ // Don't wait for the configuration to change if
+ // the display is square. In many cases it won't.
+ if (!closeToSquareBounds) {
+ activity.configurationChangeObserver.await();
+ }
- final Point newOrigSize = new Point();
- origDisplay.getRealSize(newOrigSize);
+ final Point newOrigSize = new Point();
+ origDisplay.getRealSize(newOrigSize);
- // Get a {@link Display} instance after rotation.
- final Display updatedDisplay = activity.getDisplay();
- final Point updatedSize = new Point();
- updatedDisplay.getRealSize(updatedSize);
+ // Get a {@link Display} instance after rotation.
+ final Display updatedDisplay = activity.getDisplay();
+ final Point updatedSize = new Point();
+ updatedDisplay.getRealSize(updatedSize);
- // For square screens the following assertions do not make sense and will always
- // fail.
- if (!closeToSquareBounds) {
- // Ensure that the width and height of the original instance no longer are the
- // same.
- // Note that this will be false if the device width and height are identical.
- // Note there are cases where width and height may not all be updated, such as
- // on docked devices where the app is letterboxed. However, at least one
- // dimension needs to be updated.
+ // For square screens the following assertions do not make sense and will always
+ // fail.
+ if (!closeToSquareBounds) {
+ // Ensure that the width and height of the original instance no longer are the
+ // same.
+ // Note that this will be false if the device width and height are identical.
+ // Note there are cases where width and height may not all be updated, such as
+ // on docked devices where the app is letterboxed. However, at least one
+ // dimension needs to be updated.
+ assertWithMessage(
+ "size from original display instance should have changed")
+ .that(origSize).isNotEqualTo(newOrigSize);
+ }
+
+ // Ensure that the width and height of the original instance have been updated to
+ // match the values that would be found in a new instance.
assertWithMessage(
- "size from original display instance should have changed")
- .that(origSize).isNotEqualTo(newOrigSize);
+ "size from original display instance should match current")
+ .that(newOrigSize).isEqualTo(updatedSize);
+ } finally {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(activity::finish);
}
-
- // Ensure that the width and height of the original instance have been updated to
- // match the values that would be found in a new instance.
- assertWithMessage(
- "size from original display instance should match current")
- .that(newOrigSize).isEqualTo(updatedSize);
}
}
diff --git a/tests/app/src/android/app/cts/NotificationTemplateTest.kt b/tests/app/src/android/app/cts/NotificationTemplateTest.kt
index f7edaf7..cd1de26 100644
--- a/tests/app/src/android/app/cts/NotificationTemplateTest.kt
+++ b/tests/app/src/android/app/cts/NotificationTemplateTest.kt
@@ -36,7 +36,6 @@
import com.android.compatibility.common.util.CddTest
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
-import org.junit.Assume
class NotificationTemplateTest : NotificationTemplateTestBase() {
@@ -143,7 +142,10 @@
}
fun testWideIcon_inBigPicture_cappedTo16By9() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
+
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 100)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -161,7 +163,10 @@
}
fun testWideIcon_inBigPicture_canShowExact4By3() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
+
val picture = createBitmap(40, 30)
val icon = createBitmap(400, 300)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -179,7 +184,10 @@
}
fun testWideIcon_inBigPicture_neverNarrowerThanSquare() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
+
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 300)
val views = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -241,7 +249,10 @@
}
fun testBigPictureStyle_populatesExtrasCompatibly() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
+
val bitmap = createBitmap(40, 30)
val uri = Uri.parse("content://android.app.stubs.assets/picture_400_by_300.png")
val iconWithUri = Icon.createWithContentUri(uri)
@@ -276,7 +287,9 @@
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testBigPictureStyle_bigPictureUriIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val pictureUri = Uri.parse("content://android.app.stubs.assets/picture_400_by_300.png")
val pictureIcon = Icon.createWithContentUri(pictureUri)
@@ -296,7 +309,10 @@
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testPromoteBigPicture_withBigPictureUriIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
+
val pictureUri = Uri.parse("content://android.app.stubs.assets/picture_800_by_600.png")
val pictureIcon = Icon.createWithContentUri(pictureUri)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -316,7 +332,9 @@
}
fun testPromoteBigPicture_withoutLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -339,7 +357,9 @@
}
fun testPromoteBigPicture_withLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val icon = createBitmap(80, 65)
@@ -370,7 +390,9 @@
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testPromoteBigPicture_withBigLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val inputWidth = 400
@@ -405,7 +427,9 @@
@CddTest(requirement = "3.8.3.1/C-2-1")
fun testBigPicture_withBigLargeIcon_withContentUri() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val iconUri = Uri.parse("content://android.app.stubs.assets/picture_800_by_600.png")
val icon = Icon.createWithContentUri(iconUri)
@@ -808,10 +832,9 @@
*
* If the current platform does not support notification styles, skip this test without failure.
*/
- private fun skipIfPlatformDoesNotSupportNotificationStyles() {
- Assume.assumeFalse("Current platform does not support notification styles.",
- mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
- mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
+ private fun skipIfPlatformDoesNotSupportNotificationStyles(): Boolean {
+ return mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
}
companion object {
diff --git a/tests/framework/base/windowmanager/util/src/android/server/wm/SetRequestedOrientationRule.java b/tests/framework/base/windowmanager/util/src/android/server/wm/SetRequestedOrientationRule.java
index f882022..be64440 100644
--- a/tests/framework/base/windowmanager/util/src/android/server/wm/SetRequestedOrientationRule.java
+++ b/tests/framework/base/windowmanager/util/src/android/server/wm/SetRequestedOrientationRule.java
@@ -21,6 +21,7 @@
import android.app.WindowConfiguration;
import android.content.Intent;
import android.util.Log;
+import android.util.Pair;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -30,19 +31,12 @@
import org.junit.rules.ExternalResource;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
-import org.junit.runners.model.MultipleFailureException;
import org.junit.runners.model.Statement;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-
/**
* Rule for using setRequestedOrientation API in tests.
*/
public class SetRequestedOrientationRule implements TestRule {
- final Deque<AutoCloseable> mAutoCloseables = new ArrayDeque<>();
-
@Override
public Statement apply(Statement base,
Description description) {
@@ -51,44 +45,35 @@
public void evaluate() throws Throwable {
final DisableFixedToUserRotationRule mDisableFixedToUserRotationRule =
new DisableFixedToUserRotationRule();
+ mDisableFixedToUserRotationRule.before();
try {
- mDisableFixedToUserRotationRule.before();
- mAutoCloseables.push(mDisableFixedToUserRotationRule::after);
- mAutoCloseables.push(
- new IgnoreOrientationRequestSession(false /* don' ignore */));
- base.evaluate();
- } finally {
- final ArrayList<Throwable> throwables = new ArrayList<>();
- while (!mAutoCloseables.isEmpty()) {
- try {
- mAutoCloseables.pop().close();
- } catch (Throwable t) {
- throwables.add(t);
- }
+ try (IgnoreOrientationRequestSession session =
+ new IgnoreOrientationRequestSession(false /* don' ignore */)) {
+ base.evaluate();
}
- MultipleFailureException.assertEmpty(throwables);
+ } finally {
+ mDisableFixedToUserRotationRule.after();
}
}
};
}
/**
- * Launch an activity in fullscreen.
+ * Builds launch args to launch Activity in fullscreen windowing mode.
*
* Activities which request orientation need to be in fullscreen windowing mode.
- * The activity will be finished at the test end.
*/
- public <T extends Activity> T launchActivityInFullscreen(Class<T> klass) {
+ public static <T extends Activity> Pair<Intent, ActivityOptions> buildFullScreenLaunchArgs(
+ Class<T> klass) {
final Intent intent = new Intent(
InstrumentationRegistry.getInstrumentation().getTargetContext(),
klass);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN);
- final T activity = (T) InstrumentationRegistry.getInstrumentation().startActivitySync(
- intent, options.toBundle());
- mAutoCloseables.push(activity::finish);
- return activity;
+
+ return Pair.create(intent, options);
}
public static class DisableFixedToUserRotationRule extends ExternalResource {
diff --git a/tests/media/common/src/android/mediav2/common/cts/CodecEncoderTestBase.java b/tests/media/common/src/android/mediav2/common/cts/CodecEncoderTestBase.java
index daf4abb..cfff01c 100644
--- a/tests/media/common/src/android/mediav2/common/cts/CodecEncoderTestBase.java
+++ b/tests/media/common/src/android/mediav2/common/cts/CodecEncoderTestBase.java
@@ -16,21 +16,31 @@
package android.mediav2.common.cts;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;
+import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
+import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_FIRST;
+import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_LAST;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.annotation.NonNull;
import android.graphics.ImageFormat;
+import android.media.AudioFormat;
import android.media.Image;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
+import android.media.MediaMuxer;
import android.os.PersistableBundle;
import android.util.Log;
import com.android.compatibility.common.util.Preconditions;
+import org.junit.After;
import org.junit.Before;
import java.io.File;
@@ -38,19 +48,63 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
/**
* Wrapper class for trying and testing encoder components.
- * @deprecated This class is marked for future removal. Use {@link EncoderTestBase} instead.
- * {@link EncoderTestBase} offers same functionality as the current class. Besides that, it has
- * utility functions for muxing, offers better control over configuration params, utility
- * functions for better test labelling.
- * TODO (b/260533828) remove this once all encoders are update to use {@link EncoderConfigParams}
*/
-@Deprecated(forRemoval = true)
public class CodecEncoderTestBase extends CodecTestBase {
private static final String LOG_TAG = CodecEncoderTestBase.class.getSimpleName();
+ protected final EncoderConfigParams[] mEncCfgParams;
+
+ protected EncoderConfigParams mActiveEncCfg;
+ protected RawResource mActiveRawRes;
+ protected boolean mIsLoopBack;
+ protected int mLoopBackFrameLimit;
+
+ protected byte[] mInputData;
+ protected int mInputBufferReadOffset;
+ protected int mNumBytesSubmitted;
+ protected long mInputOffsetPts;
+
+ protected ArrayList<MediaCodec.BufferInfo> mInfoList = new ArrayList<>();
+
+ protected boolean mMuxOutput;
+ protected String mMuxedOutputFile;
+ protected MediaMuxer mMuxer;
+ protected int mTrackID = -1;
+
+ public CodecEncoderTestBase(String encoder, String mime, EncoderConfigParams[] encCfgParams,
+ String allTestParams) {
+ super(encoder, mime, allTestParams);
+ mEncCfgParams = encCfgParams;
+ }
+
+ private static final List<String> MEDIATYPE_LIST_FOR_TYPE_MP4 = new ArrayList<>(
+ Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
+ MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
+ MediaFormat.MIMETYPE_AUDIO_AAC));
+ static {
+ if (CodecTestBase.IS_AT_LEAST_U) {
+ MEDIATYPE_LIST_FOR_TYPE_MP4.add(MediaFormat.MIMETYPE_VIDEO_AV1);
+ }
+ }
+ private static final List<String> MEDIATYPE_LIST_FOR_TYPE_WEBM =
+ Arrays.asList(MediaFormat.MIMETYPE_VIDEO_VP8, MediaFormat.MIMETYPE_VIDEO_VP9,
+ MediaFormat.MIMETYPE_AUDIO_VORBIS, MediaFormat.MIMETYPE_AUDIO_OPUS);
+ private static final List<String> MEDIATYPE_LIST_FOR_TYPE_3GP =
+ Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
+ MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_AUDIO_AAC,
+ MediaFormat.MIMETYPE_AUDIO_AMR_NB, MediaFormat.MIMETYPE_AUDIO_AMR_WB);
+ private static final List<String> MEDIATYPE_LIST_FOR_TYPE_OGG =
+ Collections.singletonList(MediaFormat.MIMETYPE_AUDIO_OPUS);
+
+ public static final float ACCEPTABLE_WIRELESS_TX_QUALITY = 20.0f; // psnr in dB
+ public static final float ACCEPTABLE_AV_SYNC_ERROR = 22.0f; // duration in ms
+
/**
* Selects encoder input color format in byte buffer mode. As of now ndk tests support only
* 420p, 420sp. COLOR_FormatYUV420Flexible although can represent any form of yuv, it doesn't
@@ -72,50 +126,90 @@
return colorFormat;
}
- protected final int[] mBitrates;
- protected final int[] mEncParamList1;
- protected final int[] mEncParamList2;
-
- protected RawResource mActiveRawRes;
- protected byte[] mInputData;
- protected int mInputBufferReadOffset;
- protected int mNumBytesSubmitted;
- protected long mInputOffsetPts;
-
- protected ArrayList<MediaFormat> mFormats;
- protected ArrayList<MediaCodec.BufferInfo> mInfoList;
-
- protected int mWidth, mHeight;
- protected int mBytesPerSample;
- protected int mFrameRate;
- protected int mMaxBFrames;
- protected int mChannels;
- protected int mSampleRate;
- protected int mLoopBackFrameLimit;
- protected boolean mIsLoopBack;
-
- public CodecEncoderTestBase(String encoder, String mime, int[] bitrates, int[] encoderInfo1,
- int[] encoderInfo2, RawResource rawResource, String allTestParams) {
- super(encoder, mime, allTestParams);
- mBitrates = bitrates;
- mEncParamList1 = encoderInfo1;
- mEncParamList2 = encoderInfo2;
- mFormats = new ArrayList<>();
- mInfoList = new ArrayList<>();
- mWidth = 0;
- mHeight = 0;
- if (mime.equals(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
- mFrameRate = 12;
- } else if (mime.equals(MediaFormat.MIMETYPE_VIDEO_H263)) {
- mFrameRate = 12;
- } else {
- mFrameRate = 30;
+ public static void muxOutput(String filePath, int muxerFormat, MediaFormat format,
+ ByteBuffer buffer, ArrayList<MediaCodec.BufferInfo> infos) throws IOException {
+ MediaMuxer muxer = null;
+ try {
+ muxer = new MediaMuxer(filePath, muxerFormat);
+ int trackID = muxer.addTrack(format);
+ muxer.start();
+ for (MediaCodec.BufferInfo info : infos) {
+ muxer.writeSampleData(trackID, buffer, info);
+ }
+ muxer.stop();
+ } finally {
+ if (muxer != null) muxer.release();
}
- mMaxBFrames = 0;
- mChannels = 0;
- mSampleRate = 0;
- mActiveRawRes = rawResource;
- mBytesPerSample = mActiveRawRes.mBytesPerSample;
+ }
+
+ public static boolean isMediaTypeContainerPairValid(String mime, int format) {
+ boolean result = false;
+ if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) {
+ result = MEDIATYPE_LIST_FOR_TYPE_MP4.contains(mime) || mime.startsWith("application/");
+ } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM) {
+ result = MEDIATYPE_LIST_FOR_TYPE_WEBM.contains(mime);
+ } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP) {
+ result = MEDIATYPE_LIST_FOR_TYPE_3GP.contains(mime);
+ } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG) {
+ result = MEDIATYPE_LIST_FOR_TYPE_OGG.contains(mime);
+ }
+ return result;
+ }
+
+ public static int getMuxerFormatForMediaType(String mediaType) {
+ for (int muxFormat = MUXER_OUTPUT_FIRST; muxFormat <= MUXER_OUTPUT_LAST; muxFormat++) {
+ if (isMediaTypeContainerPairValid(mediaType, muxFormat)) {
+ return muxFormat;
+ }
+ }
+ fail("no configured muxer support for " + mediaType);
+ return MUXER_OUTPUT_LAST;
+ }
+
+ public static String getTempFilePath(String infix) throws IOException {
+ return File.createTempFile("tmp" + infix, ".bin").getAbsolutePath();
+ }
+
+ public static void validateEncodedPSNR(String inpMediaType, String inpFile,
+ String outMediaType, String outFile, boolean allowInpResize, boolean allowInpLoopBack,
+ double perFramePsnrThreshold)
+ throws IOException, InterruptedException {
+ CompareStreams cs = new CompareStreams(inpMediaType, inpFile, outMediaType, outFile,
+ allowInpResize, allowInpLoopBack);
+ validateEncodedPSNR(cs, perFramePsnrThreshold);
+ cs.cleanUp();
+ }
+
+ public static void validateEncodedPSNR(RawResource inp, String outMediaType, String outFile,
+ boolean allowInpResize, boolean allowInpLoopBack, double perFramePsnrThreshold)
+ throws IOException, InterruptedException {
+ CompareStreams cs = new CompareStreams(inp, outMediaType, outFile, allowInpResize,
+ allowInpLoopBack);
+ validateEncodedPSNR(cs, perFramePsnrThreshold);
+ cs.cleanUp();
+ }
+
+ public static void validateEncodedPSNR(@NonNull CompareStreams cs,
+ double perFramePsnrThreshold) throws IOException {
+ ArrayList<double[]> framesPSNR = cs.getFramesPSNR();
+ StringBuilder msg = new StringBuilder();
+ boolean isOk = true;
+ for (int j = 0; j < framesPSNR.size(); j++) {
+ double[] framePSNR = framesPSNR.get(j);
+ // https://www.itu.int/wftp3/av-arch/jctvc-site/2011_01_D_Daegu/JCTVC-D500.doc
+ // weighted psnr (6 * psnrY + psnrU + psnrV) / 8;
+ double weightPSNR = (6 * framePSNR[0] + framePSNR[1] + framePSNR[2]) / 8;
+ if (weightPSNR < perFramePsnrThreshold) {
+ msg.append(String.format(
+ "Frame %d - PSNR Y: %f, PSNR U: %f, PSNR V: %f, Weighted PSNR: %f < "
+ + "Threshold %f \n",
+ j, framePSNR[0], framePSNR[1], framePSNR[2], weightPSNR,
+ perFramePsnrThreshold));
+ isOk = false;
+ }
+ }
+ assertTrue("Encountered frames with PSNR less than configured threshold "
+ + perFramePsnrThreshold + "dB \n" + msg, isOk);
}
public static String bitRateModeToString(int mode) {
@@ -133,22 +227,96 @@
}
}
+ public static String rangeToString(int range) {
+ switch (range) {
+ case UNSPECIFIED:
+ return "unspecified";
+ case MediaFormat.COLOR_RANGE_FULL:
+ return "full";
+ case MediaFormat.COLOR_RANGE_LIMITED:
+ return "limited";
+ default:
+ return "unknown";
+ }
+ }
+
+ public static String colorStandardToString(int standard) {
+ switch (standard) {
+ case UNSPECIFIED:
+ return "unspecified";
+ case MediaFormat.COLOR_STANDARD_BT709:
+ return "bt709";
+ case MediaFormat.COLOR_STANDARD_BT601_PAL:
+ return "bt601pal";
+ case MediaFormat.COLOR_STANDARD_BT601_NTSC:
+ return "bt601ntsc";
+ case MediaFormat.COLOR_STANDARD_BT2020:
+ return "bt2020";
+ default:
+ return "unknown";
+ }
+ }
+
+ public static String colorTransferToString(int transfer) {
+ switch (transfer) {
+ case UNSPECIFIED:
+ return "unspecified";
+ case MediaFormat.COLOR_TRANSFER_LINEAR:
+ return "linear";
+ case MediaFormat.COLOR_TRANSFER_SDR_VIDEO:
+ return "sdr";
+ case MediaFormat.COLOR_TRANSFER_HLG:
+ return "hlg";
+ case MediaFormat.COLOR_TRANSFER_ST2084:
+ return "st2084";
+ default:
+ return "unknown";
+ }
+ }
+
+ public static String colorFormatToString(int colorFormat, int bitDepth) {
+ switch (colorFormat) {
+ case COLOR_FormatYUV420Flexible:
+ return "yuv420flexible";
+ case COLOR_FormatYUVP010:
+ return "yuvp010";
+ case COLOR_FormatSurface:
+ if (bitDepth == 8) {
+ return "surfacergb888";
+ } else if (bitDepth == 10) {
+ return "surfaceabgr2101010";
+ } else {
+ return "unknown";
+ }
+ default:
+ return "unknown";
+ }
+ }
+
+ public static String audioEncodingToString(int enc) {
+ switch (enc) {
+ case AudioFormat.ENCODING_INVALID:
+ return "invalid";
+ case AudioFormat.ENCODING_PCM_16BIT:
+ return "pcm16";
+ case AudioFormat.ENCODING_PCM_FLOAT:
+ return "pcmfloat";
+ default:
+ return "unknown";
+ }
+ }
+
@Before
public void setUpCodecEncoderTestBase() {
assertTrue("Testing a mime that is neither audio nor video is not supported \n"
+ mTestConfig, mIsAudio || mIsVideo);
}
- @Override
- protected void configureCodec(MediaFormat format, boolean isAsync,
- boolean signalEOSWithLastFrame, boolean isEncoder) {
- super.configureCodec(format, isAsync, signalEOSWithLastFrame, isEncoder);
- if (mIsAudio) {
- mSampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
- mChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
- } else {
- mWidth = format.getInteger(MediaFormat.KEY_WIDTH);
- mHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
+ @After
+ public void tearDown() {
+ if (mMuxer != null) {
+ mMuxer.release();
+ mMuxer = null;
}
}
@@ -158,6 +326,7 @@
mInputBufferReadOffset = 0;
mNumBytesSubmitted = 0;
mInputOffsetPts = 0;
+ mInfoList.clear();
}
protected void setUpSource(String inpPath) throws IOException {
@@ -175,7 +344,7 @@
format == ImageFormat.YUV_420_888 || format == ImageFormat.YCBCR_P010);
int bytesPerSample = (ImageFormat.getBitsPerPixel(format) * 2) / (8 * 3); // YUV420
assertEquals("Invalid bytes per sample \n" + mTestConfig + mTestEnv, bytesPerSample,
- mBytesPerSample);
+ mActiveRawRes.mBytesPerSample);
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
@@ -237,13 +406,13 @@
void fillByteBuffer(ByteBuffer inputBuffer) {
int offset = 0, frmOffset = mInputBufferReadOffset;
for (int plane = 0; plane < 3; plane++) {
- int width = mWidth;
- int height = mHeight;
+ int width = mActiveEncCfg.mWidth;
+ int height = mActiveEncCfg.mHeight;
int tileWidth = mActiveRawRes.mWidth;
int tileHeight = mActiveRawRes.mHeight;
if (plane != 0) {
- width = mWidth / 2;
- height = mHeight / 2;
+ width = mActiveEncCfg.mWidth / 2;
+ height = mActiveEncCfg.mHeight / 2;
tileWidth = mActiveRawRes.mWidth / 2;
tileHeight = mActiveRawRes.mHeight / 2;
}
@@ -253,14 +422,16 @@
for (int i = 0; i < width; i += tileWidth) {
int colsToCopy = Math.min(width - i, tileWidth);
inputBuffer.position(
- offset + (k + j) * width * mBytesPerSample + i * mBytesPerSample);
- inputBuffer.put(mInputData, frmOffset + j * tileWidth * mBytesPerSample,
- colsToCopy * mBytesPerSample);
+ offset + (k + j) * width * mActiveRawRes.mBytesPerSample
+ + i * mActiveRawRes.mBytesPerSample);
+ inputBuffer.put(mInputData,
+ frmOffset + j * tileWidth * mActiveRawRes.mBytesPerSample,
+ colsToCopy * mActiveRawRes.mBytesPerSample);
}
}
}
- offset += width * height * mBytesPerSample;
- frmOffset += tileWidth * tileHeight * mBytesPerSample;
+ offset += width * height * mActiveRawRes.mBytesPerSample;
+ frmOffset += tileWidth * tileHeight * mActiveRawRes.mBytesPerSample;
}
}
@@ -276,10 +447,11 @@
int flags = 0;
long pts = mInputOffsetPts;
if (mIsAudio) {
- pts += mNumBytesSubmitted * 1000000L / ((long) mBytesPerSample * mChannels
- * mSampleRate);
+ pts += mNumBytesSubmitted * 1000000L / ((long) mActiveRawRes.mBytesPerSample
+ * mActiveEncCfg.mChannelCount * mActiveEncCfg.mSampleRate);
size = Math.min(inputBuffer.capacity(), mInputData.length - mInputBufferReadOffset);
- assertEquals(0, size % ((long) mBytesPerSample * mChannels));
+ assertEquals(0, size % ((long) mActiveRawRes.mBytesPerSample
+ * mActiveEncCfg.mChannelCount));
inputBuffer.put(mInputData, mInputBufferReadOffset, size);
if (mSignalEOSWithLastFrame) {
if (mIsLoopBack ? (mInputCount + 1 >= mLoopBackFrameLimit) :
@@ -290,8 +462,9 @@
}
mInputBufferReadOffset += size;
} else {
- pts += mInputCount * 1000000L / mFrameRate;
- size = mBytesPerSample * mWidth * mHeight * 3 / 2;
+ pts += mInputCount * 1000000L / mActiveEncCfg.mFrameRate;
+ size = mActiveRawRes.mBytesPerSample * mActiveEncCfg.mWidth * mActiveEncCfg.mHeight
+ * 3 / 2;
int frmSize = mActiveRawRes.mBytesPerSample * mActiveRawRes.mWidth
* mActiveRawRes.mHeight * 3 / 2;
if (mInputBufferReadOffset + frmSize > mInputData.length) {
@@ -331,19 +504,26 @@
mSawOutputEOS = true;
}
if (info.size > 0) {
+ ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
if (mSaveToMem) {
MediaCodec.BufferInfo copy = new MediaCodec.BufferInfo();
copy.set(mOutputBuff.getOutStreamSize(), info.size, info.presentationTimeUs,
info.flags);
mInfoList.add(copy);
- ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
mOutputBuff.saveToMemory(buf, info);
}
if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
mOutputBuff.saveOutPTS(info.presentationTimeUs);
mOutputCount++;
}
+ if (mMuxer != null) {
+ if (mTrackID == -1) {
+ mTrackID = mMuxer.addTrack(mCodec.getOutputFormat());
+ mMuxer.start();
+ }
+ mMuxer.writeSampleData(mTrackID, buf, info);
+ }
}
mCodec.releaseOutputBuffer(bufferIndex, false);
}
@@ -351,10 +531,30 @@
@Override
protected void doWork(int frameLimit) throws IOException, InterruptedException {
mLoopBackFrameLimit = frameLimit;
+ if (mMuxOutput) {
+ int muxerFormat = getMuxerFormatForMediaType(mMime);
+ mMuxedOutputFile = getTempFilePath((mActiveEncCfg.mInputBitDepth == 10) ? "10bit" : "");
+ mMuxer = new MediaMuxer(mMuxedOutputFile, muxerFormat);
+ }
super.doWork(frameLimit);
}
@Override
+ public void waitForAllOutputs() throws InterruptedException {
+ super.waitForAllOutputs();
+ if (mMuxOutput) {
+ if (mTrackID != -1) {
+ mMuxer.stop();
+ mTrackID = -1;
+ }
+ if (mMuxer != null) {
+ mMuxer.release();
+ mMuxer = null;
+ }
+ }
+ }
+
+ @Override
protected PersistableBundle validateMetrics(String codec, MediaFormat format) {
PersistableBundle metrics = super.validateMetrics(codec, format);
assertEquals("error! metrics#MetricsConstants.MIME_TYPE is not as expected \n" + mTestConfig
@@ -364,74 +564,39 @@
return metrics;
}
- protected void setUpParams(int limit) {
- int count = 0;
- for (int bitrate : mBitrates) {
- if (mIsAudio) {
- for (int rate : mEncParamList1) {
- for (int channels : mEncParamList2) {
- MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, mMime);
- if (mMime.equals(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
- format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, bitrate);
- } else {
- format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
- }
- format.setInteger(MediaFormat.KEY_SAMPLE_RATE, rate);
- format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, channels);
- mFormats.add(format);
- count++;
- if (count >= limit) return;
- }
- }
- } else {
- assertEquals("Wrong number of height, width parameters \n" + mTestConfig + mTestEnv,
- mEncParamList1.length, mEncParamList2.length);
- for (int i = 0; i < mEncParamList1.length; i++) {
- MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, mMime);
- format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
- format.setInteger(MediaFormat.KEY_WIDTH, mEncParamList1[i]);
- format.setInteger(MediaFormat.KEY_HEIGHT, mEncParamList2[i]);
- format.setInteger(MediaFormat.KEY_FRAME_RATE, mFrameRate);
- format.setInteger(MediaFormat.KEY_MAX_B_FRAMES, mMaxBFrames);
- format.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 1.0f);
- format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
- MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
- mFormats.add(format);
- count++;
- if (count >= limit) return;
- }
- }
- }
- }
-
- public void encodeToMemory(String file, String encoder, int frameLimit, MediaFormat format,
- boolean saveToMem) throws IOException, InterruptedException {
+ public void encodeToMemory(String encoder, EncoderConfigParams cfg, RawResource res,
+ int frameLimit, boolean saveToMem, boolean muxOutput)
+ throws IOException, InterruptedException {
mSaveToMem = saveToMem;
+ mMuxOutput = muxOutput;
mOutputBuff = new OutputManager();
mInfoList.clear();
+ mActiveEncCfg = cfg;
+ mActiveRawRes = res;
mCodec = MediaCodec.createByCodecName(encoder);
- setUpSource(file);
- configureCodec(format, false, true, true);
+ setUpSource(mActiveRawRes.mFileName);
+ configureCodec(mActiveEncCfg.getFormat(), false, true, true);
mCodec.start();
doWork(frameLimit);
queueEOS();
waitForAllOutputs();
mCodec.stop();
mCodec.release();
+ mActiveRawRes = null;
+ mActiveEncCfg = null;
mSaveToMem = false;
+ mMuxOutput = false;
}
void validateTestState() {
super.validateTestState();
- if ((mIsAudio || (mIsVideo && mMaxBFrames == 0))
+ if ((mIsAudio || (mIsVideo && mActiveEncCfg.mMaxBFrames == 0))
&& !mOutputBuff.isPtsStrictlyIncreasing(mPrevOutputPts)) {
fail("Output timestamps are not strictly increasing \n" + mTestConfig + mTestEnv
+ mOutputBuff.getErrMsg());
}
if (mIsVideo) {
- if (!mOutputBuff.isOutPtsListIdenticalToInpPtsList((mMaxBFrames != 0))) {
+ if (!mOutputBuff.isOutPtsListIdenticalToInpPtsList((mActiveEncCfg.mMaxBFrames != 0))) {
fail("Input pts list and Output pts list are not identical \n" + mTestConfig
+ mTestEnv + mOutputBuff.getErrMsg());
}
diff --git a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
index e3acdea..08a958f 100644
--- a/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
+++ b/tests/media/common/src/android/mediav2/common/cts/CodecTestBase.java
@@ -108,6 +108,7 @@
//TODO(b/248315681) Remove codenameEquals() check once devices return correct version for U
public static final boolean IS_AT_LEAST_U = ApiLevelUtil.isAfter(Build.VERSION_CODES.TIRAMISU)
|| ApiLevelUtil.codenameEquals("UpsideDownCake");
+ public static final boolean IS_BEFORE_U = !IS_AT_LEAST_U;
public static final boolean FIRST_SDK_IS_AT_LEAST_T =
ApiLevelUtil.isFirstApiAtLeast(Build.VERSION_CODES.TIRAMISU);
public static final boolean VNDK_IS_AT_LEAST_T =
diff --git a/tests/media/common/src/android/mediav2/common/cts/EncoderTestBase.java b/tests/media/common/src/android/mediav2/common/cts/EncoderTestBase.java
deleted file mode 100644
index c629278..0000000
--- a/tests/media/common/src/android/mediav2/common/cts/EncoderTestBase.java
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright (C) 2022 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.mediav2.common.cts;
-
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;
-import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
-import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_FIRST;
-import static android.media.MediaMuxer.OutputFormat.MUXER_OUTPUT_LAST;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.graphics.ImageFormat;
-import android.media.AudioFormat;
-import android.media.Image;
-import android.media.MediaCodec;
-import android.media.MediaCodecInfo;
-import android.media.MediaFormat;
-import android.media.MediaMuxer;
-import android.os.PersistableBundle;
-import android.util.Log;
-
-import com.android.compatibility.common.util.Preconditions;
-
-import org.junit.After;
-import org.junit.Before;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Wrapper class for trying and testing encoder components.
- */
-public class EncoderTestBase extends CodecTestBase {
- private static final String LOG_TAG = EncoderTestBase.class.getSimpleName();
-
- protected final EncoderConfigParams[] mEncCfgParams;
-
- protected EncoderConfigParams mActiveEncCfg;
- protected RawResource mActiveRawRes;
- protected boolean mIsLoopBack;
- protected int mLoopBackFrameLimit;
-
- protected byte[] mInputData;
- protected int mInputBufferReadOffset;
- protected int mNumBytesSubmitted;
- protected long mInputOffsetPts;
-
- protected ArrayList<MediaCodec.BufferInfo> mInfoList = new ArrayList<>();
-
- protected boolean mMuxOutput;
- protected String mMuxedOutputFile;
- protected MediaMuxer mMuxer;
- protected int mTrackID = -1;
-
- public EncoderTestBase(String encoder, String mime, EncoderConfigParams[] encCfgParams,
- String allTestParams) {
- super(encoder, mime, allTestParams);
- mEncCfgParams = encCfgParams;
- }
-
- private static final List<String> MEDIATYPE_LIST_FOR_TYPE_MP4 = new ArrayList<>(
- Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
- MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_VIDEO_HEVC,
- MediaFormat.MIMETYPE_AUDIO_AAC));
- static {
- if (CodecTestBase.IS_AT_LEAST_U) {
- MEDIATYPE_LIST_FOR_TYPE_MP4.add(MediaFormat.MIMETYPE_VIDEO_AV1);
- }
- }
- private static final List<String> MEDIATYPE_LIST_FOR_TYPE_WEBM =
- Arrays.asList(MediaFormat.MIMETYPE_VIDEO_VP8, MediaFormat.MIMETYPE_VIDEO_VP9,
- MediaFormat.MIMETYPE_AUDIO_VORBIS, MediaFormat.MIMETYPE_AUDIO_OPUS);
- private static final List<String> MEDIATYPE_LIST_FOR_TYPE_3GP =
- Arrays.asList(MediaFormat.MIMETYPE_VIDEO_MPEG4, MediaFormat.MIMETYPE_VIDEO_H263,
- MediaFormat.MIMETYPE_VIDEO_AVC, MediaFormat.MIMETYPE_AUDIO_AAC,
- MediaFormat.MIMETYPE_AUDIO_AMR_NB, MediaFormat.MIMETYPE_AUDIO_AMR_WB);
- private static final List<String> MEDIATYPE_LIST_FOR_TYPE_OGG =
- Collections.singletonList(MediaFormat.MIMETYPE_AUDIO_OPUS);
-
- public static final float ACCEPTABLE_WIRELESS_TX_QUALITY = 20.0f; // psnr in dB
- public static final float ACCEPTABLE_AV_SYNC_ERROR = 22.0f; // duration in ms
-
- /**
- * Selects encoder input color format in byte buffer mode. As of now ndk tests support only
- * 420p, 420sp. COLOR_FormatYUV420Flexible although can represent any form of yuv, it doesn't
- * work in ndk due to lack of AMediaCodec_GetInputImage()
- */
- public static int findByteBufferColorFormat(String encoder, String mime) throws IOException {
- MediaCodec codec = MediaCodec.createByCodecName(encoder);
- MediaCodecInfo.CodecCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mime);
- int colorFormat = -1;
- for (int c : cap.colorFormats) {
- if (c == MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar
- || c == MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar) {
- Log.v(LOG_TAG, "selecting color format: " + c);
- colorFormat = c;
- break;
- }
- }
- codec.release();
- return colorFormat;
- }
-
- public static void muxOutput(String filePath, int muxerFormat, MediaFormat format,
- ByteBuffer buffer, ArrayList<MediaCodec.BufferInfo> infos) throws IOException {
- MediaMuxer muxer = null;
- try {
- muxer = new MediaMuxer(filePath, muxerFormat);
- int trackID = muxer.addTrack(format);
- muxer.start();
- for (MediaCodec.BufferInfo info : infos) {
- muxer.writeSampleData(trackID, buffer, info);
- }
- muxer.stop();
- } finally {
- if (muxer != null) muxer.release();
- }
- }
-
- public static boolean isMediaTypeContainerPairValid(String mime, int format) {
- boolean result = false;
- if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4) {
- result = MEDIATYPE_LIST_FOR_TYPE_MP4.contains(mime) || mime.startsWith("application/");
- } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM) {
- result = MEDIATYPE_LIST_FOR_TYPE_WEBM.contains(mime);
- } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP) {
- result = MEDIATYPE_LIST_FOR_TYPE_3GP.contains(mime);
- } else if (format == MediaMuxer.OutputFormat.MUXER_OUTPUT_OGG) {
- result = MEDIATYPE_LIST_FOR_TYPE_OGG.contains(mime);
- }
- return result;
- }
-
- public static int getMuxerFormatForMediaType(String mediaType) {
- for (int muxFormat = MUXER_OUTPUT_FIRST; muxFormat <= MUXER_OUTPUT_LAST; muxFormat++) {
- if (isMediaTypeContainerPairValid(mediaType, muxFormat)) {
- return muxFormat;
- }
- }
- fail("no configured muxer support for " + mediaType);
- return MUXER_OUTPUT_LAST;
- }
-
- public static String getTempFilePath(String infix) throws IOException {
- return File.createTempFile("tmp" + infix, ".bin").getAbsolutePath();
- }
-
- public static String bitRateModeToString(int mode) {
- switch (mode) {
- case MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR:
- return "cbr";
- case MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR:
- return "vbr";
- case MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CQ:
- return "cq";
- case MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_CBR_FD:
- return "cbrwithfd";
- default:
- return "unknown";
- }
- }
-
- public static String rangeToString(int range) {
- switch (range) {
- case UNSPECIFIED:
- return "unspecified";
- case MediaFormat.COLOR_RANGE_FULL:
- return "full";
- case MediaFormat.COLOR_RANGE_LIMITED:
- return "limited";
- default:
- return "unknown";
- }
- }
-
- public static String colorStandardToString(int standard) {
- switch (standard) {
- case UNSPECIFIED:
- return "unspecified";
- case MediaFormat.COLOR_STANDARD_BT709:
- return "bt709";
- case MediaFormat.COLOR_STANDARD_BT601_PAL:
- return "bt601pal";
- case MediaFormat.COLOR_STANDARD_BT601_NTSC:
- return "bt601ntsc";
- case MediaFormat.COLOR_STANDARD_BT2020:
- return "bt2020";
- default:
- return "unknown";
- }
- }
-
- public static String colorTransferToString(int transfer) {
- switch (transfer) {
- case UNSPECIFIED:
- return "unspecified";
- case MediaFormat.COLOR_TRANSFER_LINEAR:
- return "linear";
- case MediaFormat.COLOR_TRANSFER_SDR_VIDEO:
- return "sdr";
- case MediaFormat.COLOR_TRANSFER_HLG:
- return "hlg";
- case MediaFormat.COLOR_TRANSFER_ST2084:
- return "st2084";
- default:
- return "unknown";
- }
- }
-
- public static String colorFormatToString(int colorFormat, int bitDepth) {
- switch (colorFormat) {
- case COLOR_FormatYUV420Flexible:
- return "yuv420flexible";
- case COLOR_FormatYUVP010:
- return "yuvp010";
- case COLOR_FormatSurface:
- if (bitDepth == 8) {
- return "surfacergb888";
- } else if (bitDepth == 10) {
- return "surfaceabgr2101010";
- } else {
- return "unknown";
- }
- default:
- return "unknown";
- }
- }
-
- public static String audioEncodingToString(int enc) {
- switch (enc) {
- case AudioFormat.ENCODING_INVALID:
- return "invalid";
- case AudioFormat.ENCODING_PCM_16BIT:
- return "pcm16";
- case AudioFormat.ENCODING_PCM_FLOAT:
- return "pcmfloat";
- default:
- return "unknown";
- }
- }
-
- @Before
- public void setUpCodecEncoderTestBase() {
- assertTrue("Testing a mime that is neither audio nor video is not supported \n"
- + mTestConfig, mIsAudio || mIsVideo);
- }
-
- @After
- public void tearDown() {
- if (mMuxer != null) {
- mMuxer.release();
- mMuxer = null;
- }
- }
-
- @Override
- protected void resetContext(boolean isAsync, boolean signalEOSWithLastFrame) {
- super.resetContext(isAsync, signalEOSWithLastFrame);
- mInputBufferReadOffset = 0;
- mNumBytesSubmitted = 0;
- mInputOffsetPts = 0;
- mInfoList.clear();
- }
-
- protected void setUpSource(String inpPath) throws IOException {
- Preconditions.assertTestFileExists(inpPath);
- try (FileInputStream fInp = new FileInputStream(inpPath)) {
- int size = (int) new File(inpPath).length();
- mInputData = new byte[size];
- fInp.read(mInputData, 0, size);
- }
- }
-
- protected void fillImage(Image image) {
- int format = image.getFormat();
- assertTrue("unexpected image format \n" + mTestConfig + mTestEnv,
- format == ImageFormat.YUV_420_888 || format == ImageFormat.YCBCR_P010);
- int bytesPerSample = (ImageFormat.getBitsPerPixel(format) * 2) / (8 * 3); // YUV420
- assertEquals("Invalid bytes per sample \n" + mTestConfig + mTestEnv, bytesPerSample,
- mActiveRawRes.mBytesPerSample);
-
- int imageWidth = image.getWidth();
- int imageHeight = image.getHeight();
- Image.Plane[] planes = image.getPlanes();
- int offset = mInputBufferReadOffset;
- for (int i = 0; i < planes.length; ++i) {
- ByteBuffer buf = planes[i].getBuffer();
- int width = imageWidth;
- int height = imageHeight;
- int tileWidth = mActiveRawRes.mWidth;
- int tileHeight = mActiveRawRes.mHeight;
- int rowStride = planes[i].getRowStride();
- int pixelStride = planes[i].getPixelStride();
- if (i != 0) {
- width = imageWidth / 2;
- height = imageHeight / 2;
- tileWidth = mActiveRawRes.mWidth / 2;
- tileHeight = mActiveRawRes.mHeight / 2;
- }
- if (pixelStride == bytesPerSample) {
- if (width == rowStride && width == tileWidth && height == tileHeight) {
- buf.put(mInputData, offset, width * height * bytesPerSample);
- } else {
- for (int z = 0; z < height; z += tileHeight) {
- int rowsToCopy = Math.min(height - z, tileHeight);
- for (int y = 0; y < rowsToCopy; y++) {
- for (int x = 0; x < width; x += tileWidth) {
- int colsToCopy = Math.min(width - x, tileWidth);
- buf.position((z + y) * rowStride + x * bytesPerSample);
- buf.put(mInputData, offset + y * tileWidth * bytesPerSample,
- colsToCopy * bytesPerSample);
- }
- }
- }
- }
- } else {
- // do it pixel-by-pixel
- for (int z = 0; z < height; z += tileHeight) {
- int rowsToCopy = Math.min(height - z, tileHeight);
- for (int y = 0; y < rowsToCopy; y++) {
- int lineOffset = (z + y) * rowStride;
- for (int x = 0; x < width; x += tileWidth) {
- int colsToCopy = Math.min(width - x, tileWidth);
- for (int w = 0; w < colsToCopy; w++) {
- for (int bytePos = 0; bytePos < bytesPerSample; bytePos++) {
- buf.position(lineOffset + (x + w) * pixelStride + bytePos);
- buf.put(mInputData[offset + y * tileWidth * bytesPerSample
- + w * bytesPerSample + bytePos]);
- }
- }
- }
- }
- }
- }
- offset += tileWidth * tileHeight * bytesPerSample;
- }
- }
-
- void fillByteBuffer(ByteBuffer inputBuffer) {
- int offset = 0, frmOffset = mInputBufferReadOffset;
- for (int plane = 0; plane < 3; plane++) {
- int width = mActiveEncCfg.mWidth;
- int height = mActiveEncCfg.mHeight;
- int tileWidth = mActiveRawRes.mWidth;
- int tileHeight = mActiveRawRes.mHeight;
- if (plane != 0) {
- width = mActiveEncCfg.mWidth / 2;
- height = mActiveEncCfg.mHeight / 2;
- tileWidth = mActiveRawRes.mWidth / 2;
- tileHeight = mActiveRawRes.mHeight / 2;
- }
- for (int k = 0; k < height; k += tileHeight) {
- int rowsToCopy = Math.min(height - k, tileHeight);
- for (int j = 0; j < rowsToCopy; j++) {
- for (int i = 0; i < width; i += tileWidth) {
- int colsToCopy = Math.min(width - i, tileWidth);
- inputBuffer.position(
- offset + (k + j) * width * mActiveRawRes.mBytesPerSample
- + i * mActiveRawRes.mBytesPerSample);
- inputBuffer.put(mInputData,
- frmOffset + j * tileWidth * mActiveRawRes.mBytesPerSample,
- colsToCopy * mActiveRawRes.mBytesPerSample);
- }
- }
- }
- offset += width * height * mActiveRawRes.mBytesPerSample;
- frmOffset += tileWidth * tileHeight * mActiveRawRes.mBytesPerSample;
- }
- }
-
- protected void enqueueInput(int bufferIndex) {
- if (mIsLoopBack && mInputBufferReadOffset >= mInputData.length) {
- mInputBufferReadOffset = 0;
- }
- ByteBuffer inputBuffer = mCodec.getInputBuffer(bufferIndex);
- if (mInputBufferReadOffset >= mInputData.length) {
- enqueueEOS(bufferIndex);
- } else {
- int size;
- int flags = 0;
- long pts = mInputOffsetPts;
- if (mIsAudio) {
- pts += mNumBytesSubmitted * 1000000L / ((long) mActiveRawRes.mBytesPerSample
- * mActiveEncCfg.mChannelCount * mActiveEncCfg.mSampleRate);
- size = Math.min(inputBuffer.capacity(), mInputData.length - mInputBufferReadOffset);
- assertEquals(0, size % ((long) mActiveRawRes.mBytesPerSample
- * mActiveEncCfg.mChannelCount));
- inputBuffer.put(mInputData, mInputBufferReadOffset, size);
- if (mSignalEOSWithLastFrame) {
- if (mIsLoopBack ? (mInputCount + 1 >= mLoopBackFrameLimit) :
- (mInputBufferReadOffset + size >= mInputData.length)) {
- flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
- mSawInputEOS = true;
- }
- }
- mInputBufferReadOffset += size;
- } else {
- pts += mInputCount * 1000000L / mActiveEncCfg.mFrameRate;
- size = mActiveRawRes.mBytesPerSample * mActiveEncCfg.mWidth * mActiveEncCfg.mHeight
- * 3 / 2;
- int frmSize = mActiveRawRes.mBytesPerSample * mActiveRawRes.mWidth
- * mActiveRawRes.mHeight * 3 / 2;
- if (mInputBufferReadOffset + frmSize > mInputData.length) {
- fail("received partial frame to encode \n" + mTestConfig + mTestEnv);
- } else {
- Image img = mCodec.getInputImage(bufferIndex);
- assertNotNull("getInputImage() expected to return non-null for video \n"
- + mTestConfig + mTestEnv, img);
- fillImage(img);
- }
- if (mSignalEOSWithLastFrame) {
- if (mIsLoopBack ? (mInputCount + 1 >= mLoopBackFrameLimit) :
- (mInputBufferReadOffset + frmSize >= mInputData.length)) {
- flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
- mSawInputEOS = true;
- }
- }
- mInputBufferReadOffset += frmSize;
- }
- mNumBytesSubmitted += size;
- if (ENABLE_LOGS) {
- Log.v(LOG_TAG, "input: id: " + bufferIndex + " size: " + size + " pts: " + pts
- + " flags: " + flags);
- }
- mCodec.queueInputBuffer(bufferIndex, 0, size, pts, flags);
- mOutputBuff.saveInPTS(pts);
- mInputCount++;
- }
- }
-
- protected void dequeueOutput(int bufferIndex, MediaCodec.BufferInfo info) {
- if (ENABLE_LOGS) {
- Log.v(LOG_TAG, "output: id: " + bufferIndex + " flags: " + info.flags + " size: "
- + info.size + " timestamp: " + info.presentationTimeUs);
- }
- if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
- mSawOutputEOS = true;
- }
- if (info.size > 0) {
- ByteBuffer buf = mCodec.getOutputBuffer(bufferIndex);
- if (mSaveToMem) {
- MediaCodec.BufferInfo copy = new MediaCodec.BufferInfo();
- copy.set(mOutputBuff.getOutStreamSize(), info.size, info.presentationTimeUs,
- info.flags);
- mInfoList.add(copy);
-
- mOutputBuff.saveToMemory(buf, info);
- }
- if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
- mOutputBuff.saveOutPTS(info.presentationTimeUs);
- mOutputCount++;
- }
- if (mMuxer != null) {
- if (mTrackID == -1) {
- mTrackID = mMuxer.addTrack(mCodec.getOutputFormat());
- mMuxer.start();
- }
- mMuxer.writeSampleData(mTrackID, buf, info);
- }
- }
- mCodec.releaseOutputBuffer(bufferIndex, false);
- }
-
- @Override
- protected void doWork(int frameLimit) throws IOException, InterruptedException {
- mLoopBackFrameLimit = frameLimit;
- if (mMuxOutput) {
- int muxerFormat = getMuxerFormatForMediaType(mMime);
- mMuxedOutputFile = getTempFilePath((mActiveEncCfg.mInputBitDepth == 10) ? "10bit" : "");
- mMuxer = new MediaMuxer(mMuxedOutputFile, muxerFormat);
- }
- super.doWork(frameLimit);
- }
-
- @Override
- public void waitForAllOutputs() throws InterruptedException {
- super.waitForAllOutputs();
- if (mMuxOutput) {
- if (mTrackID != -1) {
- mMuxer.stop();
- mTrackID = -1;
- }
- if (mMuxer != null) {
- mMuxer.release();
- mMuxer = null;
- }
- }
- }
-
- @Override
- protected PersistableBundle validateMetrics(String codec, MediaFormat format) {
- PersistableBundle metrics = super.validateMetrics(codec, format);
- assertEquals("error! metrics#MetricsConstants.MIME_TYPE is not as expected \n" + mTestConfig
- + mTestEnv, metrics.getString(MediaCodec.MetricsConstants.MIME_TYPE), mMime);
- assertEquals("error! metrics#MetricsConstants.ENCODER is not as expected \n" + mTestConfig
- + mTestEnv, 1, metrics.getInt(MediaCodec.MetricsConstants.ENCODER));
- return metrics;
- }
-
- public void encodeToMemory(String encoder, EncoderConfigParams cfg, RawResource res,
- int frameLimit, boolean saveToMem, boolean muxOutput)
- throws IOException, InterruptedException {
- mSaveToMem = saveToMem;
- mMuxOutput = muxOutput;
- mOutputBuff = new OutputManager();
- mInfoList.clear();
- mActiveEncCfg = cfg;
- mActiveRawRes = res;
- mCodec = MediaCodec.createByCodecName(encoder);
- setUpSource(mActiveRawRes.mFileName);
- configureCodec(mActiveEncCfg.getFormat(), false, true, true);
- mCodec.start();
- doWork(frameLimit);
- queueEOS();
- waitForAllOutputs();
- mCodec.stop();
- mCodec.release();
- mActiveRawRes = null;
- mActiveEncCfg = null;
- mSaveToMem = false;
- mMuxOutput = false;
- }
-
- void validateTestState() {
- super.validateTestState();
- if ((mIsAudio || (mIsVideo && mActiveEncCfg.mMaxBFrames == 0))
- && !mOutputBuff.isPtsStrictlyIncreasing(mPrevOutputPts)) {
- fail("Output timestamps are not strictly increasing \n" + mTestConfig + mTestEnv
- + mOutputBuff.getErrMsg());
- }
- if (mIsVideo) {
- if (!mOutputBuff.isOutPtsListIdenticalToInpPtsList((mActiveEncCfg.mMaxBFrames != 0))) {
- fail("Input pts list and Output pts list are not identical \n" + mTestConfig
- + mTestEnv + mOutputBuff.getErrMsg());
- }
- }
- }
-}
diff --git a/tests/media/common/src/android/mediav2/common/cts/HDREncoderTestBase.java b/tests/media/common/src/android/mediav2/common/cts/HDREncoderTestBase.java
index f5d9186..14ef351 100644
--- a/tests/media/common/src/android/mediav2/common/cts/HDREncoderTestBase.java
+++ b/tests/media/common/src/android/mediav2/common/cts/HDREncoderTestBase.java
@@ -35,7 +35,7 @@
/**
* Wrapper class for testing HDR support in video encoder components
*/
-public class HDREncoderTestBase extends EncoderTestBase {
+public class HDREncoderTestBase extends CodecEncoderTestBase {
private static final String LOG_TAG = HDREncoderTestBase.class.getSimpleName();
private ByteBuffer mHdrStaticInfo;
diff --git a/tests/media/src/android/mediav2/cts/AudioEncoderTest.java b/tests/media/src/android/mediav2/cts/AudioEncoderTest.java
index 12b53d4..f4f1899 100644
--- a/tests/media/src/android/mediav2/cts/AudioEncoderTest.java
+++ b/tests/media/src/android/mediav2/cts/AudioEncoderTest.java
@@ -27,8 +27,8 @@
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.mediav2.common.cts.CodecDecoderTestBase;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.OutputManager;
import androidx.test.filters.LargeTest;
@@ -61,7 +61,7 @@
* </ul>
*/
@RunWith(Parameterized.class)
-public class AudioEncoderTest extends EncoderTestBase {
+public class AudioEncoderTest extends CodecEncoderTestBase {
public AudioEncoderTest(String encoder, String mediaType, EncoderConfigParams encCfgParams,
@SuppressWarnings("unused") String testLabel, String allTestParams) {
super(encoder, mediaType, new EncoderConfigParams[]{encCfgParams}, allTestParams);
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
index 22b762f..445642f 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderSurfaceTest.java
@@ -19,12 +19,13 @@
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
+import static android.mediav2.common.cts.CodecEncoderTestBase.ACCEPTABLE_WIRELESS_TX_QUALITY;
+import static android.mediav2.common.cts.CodecEncoderTestBase.colorFormatToString;
+import static android.mediav2.common.cts.CodecEncoderTestBase.getMuxerFormatForMediaType;
+import static android.mediav2.common.cts.CodecEncoderTestBase.getTempFilePath;
import static android.mediav2.common.cts.CodecTestBase.hasSupportForColorFormat;
import static android.mediav2.common.cts.CodecTestBase.isHardwareAcceleratedCodec;
import static android.mediav2.common.cts.CodecTestBase.isSoftwareCodec;
-import static android.mediav2.common.cts.EncoderTestBase.colorFormatToString;
-import static android.mediav2.common.cts.EncoderTestBase.getMuxerFormatForMediaType;
-import static android.mediav2.common.cts.EncoderTestBase.getTempFilePath;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -40,6 +41,7 @@
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.mediav2.common.cts.CodecAsyncHandler;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.CodecTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
import android.mediav2.common.cts.OutputManager;
@@ -686,8 +688,10 @@
public void testSimpleEncodeFromSurface() throws IOException, InterruptedException {
mDecoder = MediaCodec.createByCodecName(mDecoderName);
String tmpPath = null;
- boolean muxOutput = !mEncMediaType.equals(MediaFormat.MIMETYPE_VIDEO_AV1)
- || CodecTestBase.IS_AT_LEAST_U;
+ boolean muxOutput = true;
+ if (mEncMediaType.equals(MediaFormat.MIMETYPE_VIDEO_AV1) && CodecTestBase.IS_BEFORE_U) {
+ muxOutput = false;
+ }
{
mEncoder = MediaCodec.createByCodecName(mEncoderName);
/* TODO(b/149027258) */
@@ -790,6 +794,11 @@
}
mDecoder.release();
mExtractor.release();
+ // Skip stream validation as there is no reference for tone mapped input
+ if (muxOutput && !mTestToneMap) {
+ CodecEncoderTestBase.validateEncodedPSNR(mTestFileMediaType, mTestFile, mEncMediaType,
+ tmpPath, false, false, ACCEPTABLE_WIRELESS_TX_QUALITY);
+ }
if (muxOutput) new File(tmpPath).delete();
}
@@ -803,7 +812,7 @@
@ApiTest(apis = {"MediaCodecInfo.CodecCapabilities#COLOR_FormatSurface"})
@LargeTest
@Test(timeout = CodecTestBase.PER_TEST_TIMEOUT_LARGE_TEST_MS)
- public void testSimpleEncodeFromSurfaceNative() throws IOException {
+ public void testSimpleEncodeFromSurfaceNative() throws IOException, InterruptedException {
assumeFalse("tone mapping tests are skipped in native mode", mTestToneMap);
String tmpPath = null;
if (!mEncMediaType.equals(MediaFormat.MIMETYPE_VIDEO_AV1) || CodecTestBase.IS_AT_LEAST_U) {
@@ -816,6 +825,8 @@
EncoderConfigParams.TOKEN_SEPARATOR, mTestConfig);
assertTrue(mTestConfig.toString(), isPass);
if (tmpPath != null) {
+ CodecEncoderTestBase.validateEncodedPSNR(mTestFileMediaType, mTestFile, mEncMediaType,
+ tmpPath, false, false, ACCEPTABLE_WIRELESS_TX_QUALITY);
new File(tmpPath).delete();
}
}
diff --git a/tests/media/src/android/mediav2/cts/CodecEncoderTest.java b/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
index 843d305..cc86e76 100644
--- a/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
+++ b/tests/media/src/android/mediav2/cts/CodecEncoderTest.java
@@ -23,8 +23,8 @@
import android.media.MediaCodec;
import android.media.MediaFormat;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.OutputManager;
import android.os.Bundle;
import android.util.Log;
@@ -71,7 +71,7 @@
* The test runs mediacodec in synchronous and asynchronous mode.
*/
@RunWith(Parameterized.class)
-public class CodecEncoderTest extends EncoderTestBase {
+public class CodecEncoderTest extends CodecEncoderTestBase {
private static final String LOG_TAG = CodecEncoderTest.class.getSimpleName();
private static final ArrayList<String> ABR_MEDIATYPE_LIST = new ArrayList<>();
diff --git a/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java b/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java
index db0bf9e..df21ded 100644
--- a/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java
+++ b/tests/media/src/android/mediav2/cts/EncodeDecodeAccuracyTest.java
@@ -19,7 +19,7 @@
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_Format32bitABGR2101010;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
import static android.media.MediaCodecInfo.CodecCapabilities.COLOR_FormatYUVP010;
-import static android.mediav2.common.cts.EncoderTestBase.colorFormatToString;
+import static android.mediav2.common.cts.CodecEncoderTestBase.colorFormatToString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
index a07dc4d..a2f4b76 100644
--- a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
@@ -28,9 +28,9 @@
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.mediav2.common.cts.CodecDecoderTestBase;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.CodecTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.OutputManager;
import android.opengl.GLES20;
import android.os.Build;
@@ -73,7 +73,7 @@
* restricted to HLG/HDR profiles.
*/
@RunWith(Parameterized.class)
-public class EncoderColorAspectsTest extends EncoderTestBase {
+public class EncoderColorAspectsTest extends CodecEncoderTestBase {
private static final String LOG_TAG = EncoderColorAspectsTest.class.getSimpleName();
private Surface mInpSurface;
@@ -285,11 +285,6 @@
public void testColorAspects() throws IOException, InterruptedException {
Assume.assumeTrue("Test introduced with Android 11", sIsAtLeastR);
- if (mCodecName.equals("OMX.google.h264.encoder")) { // TODO(b/189883530)
- Log.d(LOG_TAG, "test skipped due to b/189883530");
- return;
- }
-
mActiveEncCfg = mEncCfgParams[0];
if (mActiveEncCfg.mInputBitDepth > 8) {
// Check if encoder is capable of supporting HDR profiles.
diff --git a/tests/media/src/android/mediav2/cts/EncoderInput.java b/tests/media/src/android/mediav2/cts/EncoderInput.java
index 2b7daa8..7b879b8 100644
--- a/tests/media/src/android/mediav2/cts/EncoderInput.java
+++ b/tests/media/src/android/mediav2/cts/EncoderInput.java
@@ -85,18 +85,4 @@
}
return null;
}
-
- /**
- * TODO (b/260533828) remove this once all encoders are update to use
- * @deprecated This function is marked for future removal. Use
- * {@link EncoderInput#getRawResource(EncoderConfigParams)} instead.
- */
- @Deprecated(forRemoval = true)
- public static RawResource getRawResource(String mediaType, boolean isHighBitDepth) {
- if (mediaType.startsWith("audio/")) {
- return isHighBitDepth ? INPUT_AUDIO_FILE_HBD : INPUT_AUDIO_FILE;
- } else {
- return isHighBitDepth ? INPUT_VIDEO_FILE_HBD : INPUT_VIDEO_FILE;
- }
- }
}
diff --git a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
index a5eb22c..c5c9a32 100644
--- a/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderProfileLevelTest.java
@@ -31,8 +31,8 @@
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.OutputManager;
import android.util.Log;
import android.util.Pair;
@@ -75,7 +75,7 @@
* handle certain profile and level configurations. This is verified as well.
*/
@RunWith(Parameterized.class)
-public class EncoderProfileLevelTest extends EncoderTestBase {
+public class EncoderProfileLevelTest extends CodecEncoderTestBase {
private static final String LOG_TAG = EncoderProfileLevelTest.class.getSimpleName();
private static final HashMap<String, Pair<int[], Integer>> PROFILE_LEVEL_CDD = new HashMap<>();
diff --git a/tests/media/src/android/mediav2/cts/MuxerTest.java b/tests/media/src/android/mediav2/cts/MuxerTest.java
index 938df1b..7804408 100644
--- a/tests/media/src/android/mediav2/cts/MuxerTest.java
+++ b/tests/media/src/android/mediav2/cts/MuxerTest.java
@@ -16,7 +16,7 @@
package android.mediav2.cts;
-import static android.mediav2.common.cts.EncoderTestBase.isMediaTypeContainerPairValid;
+import static android.mediav2.common.cts.CodecEncoderTestBase.isMediaTypeContainerPairValid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
diff --git a/tests/media/src/android/mediav2/cts/VideoEncoderTest.java b/tests/media/src/android/mediav2/cts/VideoEncoderTest.java
index 8a94a85..82cfae0 100644
--- a/tests/media/src/android/mediav2/cts/VideoEncoderTest.java
+++ b/tests/media/src/android/mediav2/cts/VideoEncoderTest.java
@@ -24,8 +24,9 @@
import static org.junit.Assert.assertTrue;
import android.media.MediaFormat;
+import android.mediav2.common.cts.CodecEncoderTestBase;
+import android.mediav2.common.cts.CodecTestBase;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.RawResource;
import androidx.test.filters.LargeTest;
@@ -55,7 +56,7 @@
* </ul>
*/
@RunWith(Parameterized.class)
-public class VideoEncoderTest extends EncoderTestBase {
+public class VideoEncoderTest extends CodecEncoderTestBase {
public VideoEncoderTest(String encoder, String mediaType, EncoderConfigParams encCfgParams,
@SuppressWarnings("unused") String testLabel, String allTestParams) {
super(encoder, mediaType, new EncoderConfigParams[]{encCfgParams}, allTestParams);
@@ -170,10 +171,19 @@
RawResource res = EncoderInput.getRawResource(mEncCfgParams[0]);
assertNotNull("no raw resource found for testing config : " + mActiveEncCfg + mTestConfig
+ mTestEnv, res);
- encodeToMemory(mCodecName, mEncCfgParams[0], res, Integer.MAX_VALUE, false, false);
+
+ boolean muxOutput = true;
+ if (mMime.equals(MediaFormat.MIMETYPE_VIDEO_AV1) && CodecTestBase.IS_BEFORE_U) {
+ muxOutput = false;
+ }
+ encodeToMemory(mCodecName, mEncCfgParams[0], res, Integer.MAX_VALUE, false, muxOutput);
// cleanup tmp files
- if (mMuxOutput) {
+ if (muxOutput) {
+ // validate output
+ validateEncodedPSNR(res, mMime, mMuxedOutputFile, true, mIsLoopBack,
+ ACCEPTABLE_WIRELESS_TX_QUALITY);
+
File tmp = new File(mMuxedOutputFile);
if (tmp.exists()) {
assertTrue("unable to delete tmp file" + mMuxedOutputFile, tmp.delete());
diff --git a/tests/tests/background/Android.bp b/tests/tests/background/Android.bp
index ad0efa0..03030212 100644
--- a/tests/tests/background/Android.bp
+++ b/tests/tests/background/Android.bp
@@ -25,7 +25,6 @@
"mockito-target-minus-junit4",
"compatibility-device-util-axt",
"ctstestrunner-axt",
- "ub-uiautomator",
],
libs: ["android.test.runner"],
srcs: ["src/**/*.java"],
diff --git a/tests/tests/contactsproviderwipe/Android.bp b/tests/tests/contactsproviderwipe/Android.bp
index 2a82727..62cf0c0 100644
--- a/tests/tests/contactsproviderwipe/Android.bp
+++ b/tests/tests/contactsproviderwipe/Android.bp
@@ -25,7 +25,6 @@
"mockito-target-minus-junit4",
"compatibility-device-util-axt",
"ctstestrunner-axt",
- "ub-uiautomator",
],
libs: [
"android.test.runner",
diff --git a/tests/tests/drm/TEST_MAPPING b/tests/tests/drm/TEST_MAPPING
index 437c95c..d2fb8f4 100644
--- a/tests/tests/drm/TEST_MAPPING
+++ b/tests/tests/drm/TEST_MAPPING
@@ -3,5 +3,16 @@
{
"name": "CtsDrmTestCases"
}
+ ],
+ "kernel-presubmit": [
+ {
+ "name": "CtsDrmTestCases",
+ "options": [
+ {
+ // TODO(b/244594813)
+ "exclude-filter": "android.drm.cts.DRMTest#testForwardLockAccess"
+ }
+ ]
+ }
]
}
diff --git a/tests/tests/hardware/Android.bp b/tests/tests/hardware/Android.bp
index ad603cc..9d337e4 100644
--- a/tests/tests/hardware/Android.bp
+++ b/tests/tests/hardware/Android.bp
@@ -65,7 +65,6 @@
"cts-wm-util",
"mockito-target-minus-junit4",
"platform-test-annotations",
- "ub-uiautomator",
"ctshardware-aidl-java",
],
jni_libs: [
diff --git a/tests/tests/hardware/src/android/hardware/input/cts/tests/UsbVoiceCommandTest.java b/tests/tests/hardware/src/android/hardware/input/cts/tests/UsbVoiceCommandTest.java
index a834b0d..2e13f30 100644
--- a/tests/tests/hardware/src/android/hardware/input/cts/tests/UsbVoiceCommandTest.java
+++ b/tests/tests/hardware/src/android/hardware/input/cts/tests/UsbVoiceCommandTest.java
@@ -31,7 +31,6 @@
import android.hardware.input.cts.InputAssistantActivity;
import android.server.wm.WindowManagerStateHelper;
import android.speech.RecognizerIntent;
-import android.support.test.uiautomator.UiDevice;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -50,8 +49,6 @@
public class UsbVoiceCommandTest extends InputHidTestCase {
private static final String TAG = "UsbVoiceCommandTest";
- private final UiDevice mUiDevice =
- UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
private final UiAutomation mUiAutomation =
InstrumentationRegistry.getInstrumentation().getUiAutomation();
private final PackageManager mPackageManager =
diff --git a/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java b/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java
index b712fdf..30e8477 100644
--- a/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/codec/src/android/media/codec/cts/EncodeDecodeTest.java
@@ -708,7 +708,7 @@
if (VERBOSE) Log.d(TAG, "decoder output format changed: " +
decoderOutputFormat);
} else if (decoderStatus < 0) {
- fail("unexpected result from deocder.dequeueOutputBuffer: " + decoderStatus);
+ fail("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
} else { // decoderStatus >= 0
if (!toSurface) {
ByteBuffer outputFrame = decoderOutputBuffers[decoderStatus];
@@ -863,7 +863,7 @@
if (VERBOSE) Log.d(TAG, "decoder output format changed: " +
decoderOutputFormat);
} else if (decoderStatus < 0) {
- fail("unexpected result from deocder.dequeueOutputBuffer: " + decoderStatus);
+ fail("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
} else { // decoderStatus >= 0
if (VERBOSE) Log.d(TAG, "surface decoder given buffer " + decoderStatus +
" (size=" + info.size + ")");
diff --git a/tests/tests/media/codec/src/android/media/codec/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/codec/src/android/media/codec/cts/EncodeVirtualDisplayTest.java
index 2baad3f..96f05c6 100755
--- a/tests/tests/media/codec/src/android/media/codec/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/codec/src/android/media/codec/cts/EncodeVirtualDisplayTest.java
@@ -359,7 +359,7 @@
if (VERBOSE) Log.d(TAG, "decoder output format changed: " +
decoderOutputFormat);
} else if (decoderStatus < 0) {
- fail("unexpected result from deocder.dequeueOutputBuffer: " + decoderStatus);
+ fail("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
} else { // decoderStatus >= 0
if (VERBOSE) Log.d(TAG, "surface decoder given buffer " + decoderStatus +
" (size=" + info.size + ")");
diff --git a/tests/tests/media/decoder/src/android/media/decoder/cts/ImageReaderDecoderTest.java b/tests/tests/media/decoder/src/android/media/decoder/cts/ImageReaderDecoderTest.java
index 48eaa42..9750f30 100644
--- a/tests/tests/media/decoder/src/android/media/decoder/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/decoder/src/android/media/decoder/cts/ImageReaderDecoderTest.java
@@ -507,7 +507,7 @@
if (VERBOSE) Log.v(TAG, "decoder output format changed: " + outFormat);
} else if (res < 0) {
// Should be decoding error.
- fail("unexpected result from deocder.dequeueOutputBuffer: " + res);
+ fail("unexpected result from decoder.dequeueOutputBuffer: " + res);
} else {
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawOutputEOS = true;
diff --git a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
index f879528..3c2ca72 100644
--- a/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/drmframework/src/android/media/drmframework/cts/MediaDrmClearkeyTest.java
@@ -20,6 +20,7 @@
import android.media.MediaDrm.KeyStatus;
import android.media.MediaDrm.MediaDrmStateException;
import android.media.MediaDrmException;
+import android.media.MediaDrmThrowable;
import android.media.MediaFormat;
import android.media.NotProvisionedException;
import android.media.ResourceBusyException;
@@ -51,6 +52,7 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import org.junit.Assert;
import java.nio.charset.Charset;
import java.util.ArrayList;
@@ -968,6 +970,10 @@
if (!Arrays.equals(deviceId, getByteArrayProperty(drm, DEVICEID_PROPERTY_KEY))) {
throw new Error("Failed to set byte array for key=" + DEVICEID_PROPERTY_KEY);
}
+
+ for (String k: new String[] {"oemError", "errorContext"}) {
+ testIntegerProperties(drm, k);
+ }
} finally {
stopDrm(drm);
}
@@ -1232,10 +1238,16 @@
MediaDrm drm = null;
boolean gotException = false;
+ final int OEM_ERROR = 123;
+ final int ERROR_CONTEXT = 456;
try {
drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
drm.setPropertyString("drmErrorTest", "resourceContention");
+ if (getClearkeyVersionInt(drm) >= 14) {
+ drm.setPropertyString("oemError", Integer.toString(OEM_ERROR));
+ drm.setPropertyString("errorContext", Integer.toString(ERROR_CONTEXT));
+ }
byte[] sessionId = drm.openSession();
try {
@@ -1248,6 +1260,13 @@
if(sIsAtLeastS && !e.isTransient()) {
throw new Error("Expected transient ERROR_RESOURCE_CONTENTION");
}
+ if (getClearkeyVersionInt(drm) >= 14) {
+ final MediaDrmThrowable mdt = e;
+ final int RESOURCE_CONTENTION_AIDL = 16;
+ assertEquals("Vendor Error mismatch", mdt.getVendorError(), RESOURCE_CONTENTION_AIDL);
+ assertEquals("OEM Error mismatch", mdt.getOemError(), OEM_ERROR);
+ assertEquals("Error context mismatch", mdt.getErrorContext(), ERROR_CONTEXT);
+ }
gotException = true;
}
} catch(Exception e) {
@@ -1643,8 +1662,6 @@
assertTrue("Expected ERROR_SESSION_NOT_OPENED value in info",
e.getDiagnosticInfo().contains(
String.valueOf(MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED)));
- assertEquals("No vendor error expected from Clearkey", 0, e.getVendorError());
- assertEquals("No OEM error expected from Clearkey", 0, e.getOemError());
} finally {
if (drm != null) {
drm.close();
@@ -1652,6 +1669,25 @@
}
}
+ private void testIntegerProperties(MediaDrm drm, String testKey)
+ throws ResourceBusyException, UnsupportedSchemeException, NotProvisionedException {
+ if (getClearkeyVersionInt(drm) < 14) {
+ return;
+ }
+ String testValue = "123456";
+ assertEquals("Default value not 0", drm.getPropertyString(testKey), "0");
+ Assert.assertThrows("Non-numeric must throw", Exception.class, () -> {
+ drm.setPropertyString(testKey, "xyz"); });
+ Assert.assertThrows("Non-integral must throw", Exception.class, () -> {
+ drm.setPropertyString(testKey, "3.141"); });
+ Assert.assertThrows("Out-of-range (MAX) must throw", Exception.class, () -> {
+ drm.setPropertyString(testKey, Long.toString(Long.MAX_VALUE)); });
+ Assert.assertThrows("Out-of-range (MIN) must throw", Exception.class, () -> {
+ drm.setPropertyString(testKey, Long.toString(Long.MIN_VALUE)); });
+ drm.setPropertyString(testKey, testValue);
+ assertEquals("Property didn't match", drm.getPropertyString(testKey), testValue);
+ }
+
private String getClearkeyVersion(MediaDrm drm) {
try {
return drm.getPropertyString("version");
@@ -1660,6 +1696,14 @@
}
}
+ private int getClearkeyVersionInt(MediaDrm drm) {
+ try {
+ return Integer.parseInt(drm.getPropertyString("version"));
+ } catch (Exception e) {
+ return Integer.MIN_VALUE;
+ }
+ }
+
private boolean cannotHandleGetPropertyByteArray(MediaDrm drm) {
boolean apiNotSupported = false;
byte[] bytes = new byte[0];
diff --git a/tests/tests/media/projection/OWNERS b/tests/tests/media/projection/OWNERS
new file mode 100644
index 0000000..d963c71
--- /dev/null
+++ b/tests/tests/media/projection/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 970984
+include platform/frameworks/base:/media/java/android/media/projection/OWNERS
+nmusgrave@google.com
diff --git a/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt b/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
index 3e121ec..6a1077c 100644
--- a/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
+++ b/tests/tests/notificationlegacy/notificationlegacy30/src/android/app/notification/legacy30/cts/NotificationTemplateApi30Test.kt
@@ -23,7 +23,6 @@
import android.widget.ImageView
import android.widget.TextView
import com.google.common.truth.Truth.assertThat
-import org.junit.Assume
class NotificationTemplateApi30Test : NotificationTemplateTestBase() {
@@ -58,7 +57,9 @@
}
fun testWideIcon_inBigPicture_isSquareForLegacyApps() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val icon = createBitmap(200, 100)
@@ -89,7 +90,9 @@
}
fun testPromoteBigPicture_withoutLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val builder = Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
@@ -114,7 +117,9 @@
}
fun testPromoteBigPicture_withLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val icon = createBitmap(80, 65)
@@ -143,7 +148,9 @@
}
fun testPromoteBigPicture_withBigLargeIcon() {
- skipIfPlatformDoesNotSupportNotificationStyles()
+ if (skipIfPlatformDoesNotSupportNotificationStyles()) {
+ return
+ }
val picture = createBitmap(40, 30)
val inputWidth = 400
@@ -292,10 +299,9 @@
*
* If the current platform does not support notification styles, skip this test without failure.
*/
- private fun skipIfPlatformDoesNotSupportNotificationStyles() {
- Assume.assumeFalse("Current platform does not support notification styles.",
- mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
- mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
+ private fun skipIfPlatformDoesNotSupportNotificationStyles(): Boolean {
+ return mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) ||
+ mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
}
companion object {
diff --git a/tests/tests/print/printTestUtilLib/Android.bp b/tests/tests/print/printTestUtilLib/Android.bp
index 9abb4ee..da85b79 100644
--- a/tests/tests/print/printTestUtilLib/Android.bp
+++ b/tests/tests/print/printTestUtilLib/Android.bp
@@ -24,7 +24,6 @@
static_libs: [
"mockito-target-minus-junit4",
"ctstestrunner-axt",
- "ub-uiautomator",
"compatibility-device-util-axt",
"androidx.test.rules",
"platformprotosnano",
diff --git a/tests/tests/resolverservice/OWNERS b/tests/tests/resolverservice/OWNERS
index 978b1b4..87f734b 100644
--- a/tests/tests/resolverservice/OWNERS
+++ b/tests/tests/resolverservice/OWNERS
@@ -1,4 +1,2 @@
-# Bug component: 24950
-kanlig@google.com
-patb@google.com
-chiuwinson@google.com
\ No newline at end of file
+# Bug component: 36137
+include platform/frameworks/base:/PACKAGE_MANAGER_OWNERS
\ No newline at end of file
diff --git a/tests/tests/slice/Android.bp b/tests/tests/slice/Android.bp
index 891a682..d3d75f8 100644
--- a/tests/tests/slice/Android.bp
+++ b/tests/tests/slice/Android.bp
@@ -34,7 +34,6 @@
"metrics-helper-lib",
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
- "ub-uiautomator",
],
compile_multilib: "both",
jni_libs: [
diff --git a/tests/tests/syncmanager/Android.bp b/tests/tests/syncmanager/Android.bp
index 2042319..b3d9216 100644
--- a/tests/tests/syncmanager/Android.bp
+++ b/tests/tests/syncmanager/Android.bp
@@ -26,7 +26,6 @@
"mockito-target-minus-junit4",
"compatibility-device-util-axt",
"ctstestrunner-axt",
- "ub-uiautomator",
],
libs: [
"android.test.runner",
diff --git a/tests/tests/syncmanager/apps/Android.bp b/tests/tests/syncmanager/apps/Android.bp
index cbcfe29..0cb4cb8 100644
--- a/tests/tests/syncmanager/apps/Android.bp
+++ b/tests/tests/syncmanager/apps/Android.bp
@@ -26,7 +26,6 @@
"androidx.legacy_legacy-support-v4",
"mockito-target-minus-junit4",
"compatibility-device-util-axt",
- "ub-uiautomator",
],
sdk_version: "test_current",
// tag this module as a cts test artifact
@@ -48,7 +47,6 @@
"androidx.legacy_legacy-support-v4",
"mockito-target-minus-junit4",
"compatibility-device-util-axt",
- "ub-uiautomator",
],
sdk_version: "test_current",
// tag this module as a cts test artifact
diff --git a/tests/tests/uiautomation/Android.bp b/tests/tests/uiautomation/Android.bp
index b4d80a8..b41d2fb 100644
--- a/tests/tests/uiautomation/Android.bp
+++ b/tests/tests/uiautomation/Android.bp
@@ -27,7 +27,6 @@
static_libs: [
"CtsAccessibilityCommon",
"ctstestrunner-axt",
- "ub-uiautomator",
],
libs: ["android.test.base"],
srcs: ["src/**/*.java"],
diff --git a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
index 68c4a77..20f7283 100644
--- a/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewUnbufferedTest.java
@@ -246,7 +246,7 @@
}
mReceivedEvents.add(new ReceivedEvent(event.getEventTime(), event.getAction(),
- (int) event.getX(), (int) event.getY(), event.getSource()));
+ Math.round(event.getX()), Math.round(event.getY()), event.getSource()));
// Always return true to make sure the event has been handled.
return true;
diff --git a/tests/videocodec/src/android/videocodec/cts/VideoEncoderValidationTestBase.java b/tests/videocodec/src/android/videocodec/cts/VideoEncoderValidationTestBase.java
index 044a311..676127c 100644
--- a/tests/videocodec/src/android/videocodec/cts/VideoEncoderValidationTestBase.java
+++ b/tests/videocodec/src/android/videocodec/cts/VideoEncoderValidationTestBase.java
@@ -27,9 +27,9 @@
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.mediav2.common.cts.BitStreamUtils;
+import android.mediav2.common.cts.CodecEncoderTestBase;
import android.mediav2.common.cts.DecodeStreamToYuv;
import android.mediav2.common.cts.EncoderConfigParams;
-import android.mediav2.common.cts.EncoderTestBase;
import android.mediav2.common.cts.RawResource;
import android.util.Log;
@@ -47,7 +47,7 @@
/**
* Wrapper class for handling and testing video encoder components.
*/
-public class VideoEncoderValidationTestBase extends EncoderTestBase {
+public class VideoEncoderValidationTestBase extends CodecEncoderTestBase {
private static final String LOG_TAG = VideoEncoderValidationTestBase.class.getSimpleName();
private static final String MEDIA_DIR = WorkDir.getMediaDirString();
diff --git a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
index a9c024f..1ccf352 100644
--- a/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
+++ b/tools/cts-tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/ValidateTestsAbi.java
@@ -103,6 +103,7 @@
BINARY_EXCEPTIONS.add("sepolicy-analyze");
BINARY_EXCEPTIONS.add("avbtool");
BINARY_EXCEPTIONS.add("img2simg");
+ BINARY_EXCEPTIONS.add("initrd_bootconfig");
BINARY_EXCEPTIONS.add("lpmake");
BINARY_EXCEPTIONS.add("lpunpack");
BINARY_EXCEPTIONS.add("mk_payload");