[Android] Add RtcError class and use it in RtpTransceiver.setCodecPreferences

This CL modifies RtpTransceiver.setCodecPreferences to return RtcError
instead of void, making it easier to handle errors when setting
codec preferences. To achieve this, new RtcException and RtcError
classes are introduced to represent errors in WebRTC,
mimicking api/rtc_error.h in C++.

Bug: webrtc:42225493
Change-Id: I0f4c6e56f8f2af3353915a41084f6b7b46d793d4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352900
Reviewed-by: Zoé Lepaul <xalep@webrtc.org>
Commit-Queue: Zoé Lepaul <xalep@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42476}
This commit is contained in:
Byoungchan Lee 2024-06-13 21:55:41 +09:00 committed by WebRTC LUCI CQ
parent 6724f1b573
commit b244727265
6 changed files with 124 additions and 10 deletions

View File

@ -164,6 +164,8 @@ if (is_android) {
"src/java/org/webrtc/JniCommon.java",
"src/java/org/webrtc/JniHelper.java",
"src/java/org/webrtc/RefCountDelegate.java",
"src/java/org/webrtc/RtcError.java",
"src/java/org/webrtc/RtcException.java",
"src/java/org/webrtc/WebRtcClassLoader.java",
]
@ -765,7 +767,9 @@ if (current_os == "linux" || is_android) {
deps = [
":base_jni",
":generated_external_classes_jni",
":generated_external_classes_jni",
":generated_peerconnection_jni",
":generated_rtcerror_jni",
":logging_jni",
":native_api_jni",
":native_api_stacktrace",
@ -1389,6 +1393,12 @@ if (current_os == "linux" || is_android) {
jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
}
generate_jni("generated_rtcerror_jni") {
sources = [ "src/java/org/webrtc/RtcError.java" ]
namespace = "webrtc::jni"
jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
}
generate_jni("generated_peerconnection_jni") {
sources = [
"api/org/webrtc/AddIceObserver.java",

View File

@ -215,9 +215,9 @@ public class RtpTransceiver {
nativeStopInternal(nativeRtpTransceiver);
}
public void setCodecPreferences(List<RtpCapabilities.CodecCapability> codecs) {
public RtcError setCodecPreferences(List<RtpCapabilities.CodecCapability> codecs) {
checkRtpTransceiverExists();
nativeSetCodecPreferences(nativeRtpTransceiver, codecs);
return nativeSetCodecPreferences(nativeRtpTransceiver, codecs);
}
/**
@ -268,6 +268,6 @@ public class RtpTransceiver {
private static native void nativeStopStandard(long rtpTransceiver);
private static native boolean nativeSetDirection(
long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection);
private static native void nativeSetCodecPreferences(
private static native RtcError nativeSetCodecPreferences(
long rtpTransceiver, List<RtpCapabilities.CodecCapability> codecs);
}

View File

@ -158,7 +158,8 @@ public class RtpCapabilitiesTest {
assertNotNull(targetCodec);
transceiver.setCodecPreferences(Arrays.asList(targetCodec));
RtcError result = transceiver.setCodecPreferences(Arrays.asList(targetCodec));
assertTrue(result.isSuccess());
SdpObserverLatch sdpLatch = new SdpObserverLatch();
pc.createOffer(sdpLatch, new MediaConstraints());
@ -183,6 +184,18 @@ public class RtpCapabilitiesTest {
String expected =
"a=rtpmap:" + targetPayload + " " + targetCodec.name + "/" + targetCodec.getClockRate();
assertEquals(expected, rtpMap);
// Set an invalid codec preference and check that an error is returned.
RtpCapabilities audioCapabilities =
factory.getRtpSenderCapabilities(MediaStreamTrack.MediaType.MEDIA_TYPE_AUDIO);
assertNotNull(audioCapabilities);
RtpCapabilities.CodecCapability audioCodec = audioCapabilities.getCodecs().get(0);
result = transceiver.setCodecPreferences(Arrays.asList(audioCodec));
assertTrue(result.isError());
Throwable resultException = result.error();
assertTrue(resultException instanceof RtcException);
assertTrue(resultException.getMessage().startsWith("Invalid codec preferences:"));
}
private List<String> getMediaDescriptions(String[] sdpDescriptionLines) {

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2024 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* RtcError class is used to handle errors obtainable from WebRTC operations.
*/
public class RtcError {
private final RtcException error;
private RtcError(RtcException error) {
this.error = error;
}
/** Creates a RtcError with success */
@CalledByNative
public static RtcError success() {
return new RtcError(null);
}
/** Creates a RtcError with an error */
@CalledByNative
public static RtcError error(@NonNull String error) {
return new RtcError(new RtcException(error));
}
public boolean isSuccess() {
return error == null;
}
public boolean isError() {
return error != null;
}
/**
* Retrieve the error from the WebRTC operation.
* If the operation was successful, this will return null.
*/
@Nullable
public RtcException error() {
return error;
}
/** Throws the error if it is not null. */
public void throwError() {
if (error != null) {
throw error;
}
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.webrtc;
/**
* RtcException represents exceptions that are specific to the WebRTC library. Refer to the file
* api/rtc_error.h for more information.
*/
public class RtcException extends RuntimeException {
public RtcException(String message) {
super(message);
}
}

View File

@ -13,6 +13,7 @@
#include <string>
#include "sdk/android/generated_peerconnection_jni/RtpTransceiver_jni.h"
#include "sdk/android/generated_rtcerror_jni/RtcError_jni.h"
#include "sdk/android/native_api/jni/java_types.h"
#include "sdk/android/src/jni/jni_helpers.h"
#include "sdk/android/src/jni/pc/media_stream_track.h"
@ -140,15 +141,22 @@ ScopedJavaLocalRef<jobject> JNI_RtpTransceiver_CurrentDirection(
: nullptr;
}
void JNI_RtpTransceiver_SetCodecPreferences(
ScopedJavaLocalRef<jobject> JNI_RtpTransceiver_SetCodecPreferences(
JNIEnv* jni,
jlong j_rtp_transceiver_pointer,
const JavaParamRef<jobject>& j_codecs) {
std::vector<RtpCodecCapability> codecs =
JavaListToNativeVector<RtpCodecCapability, jobject>(
jni, j_codecs, &JavaToNativeRtpCodecCapability);
reinterpret_cast<RtpTransceiverInterface*>(j_rtp_transceiver_pointer)
->SetCodecPreferences(codecs);
std::vector<RtpCodecCapability> codecs;
if (j_codecs) {
codecs = JavaListToNativeVector<RtpCodecCapability, jobject>(
jni, j_codecs, &JavaToNativeRtpCodecCapability);
}
RTCError error =
reinterpret_cast<RtpTransceiverInterface*>(j_rtp_transceiver_pointer)
->SetCodecPreferences(codecs);
if (!error.ok()) {
return Java_RtcError_error(jni, NativeToJavaString(jni, error.message()));
}
return Java_RtcError_success(jni);
}
void JNI_RtpTransceiver_StopInternal(JNIEnv* jni,