PeerConnection(java): replace ScopedLocalRef with ScopedLocalRefFrame and fix a local reference leak in OnMessage.
Hopefully the approach of pushing/popping frames will be easier to avoid messing up than remembering to annotate every single local reference with a ScopedLocalRef. BUG=2761 R=wu@webrtc.org Review URL: https://webrtc-codereview.appspot.com/6729004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5355 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
1794693ec8
commit
4177615e87
@ -376,22 +376,20 @@ class WeakRef {
|
|||||||
jobject const obj_;
|
jobject const obj_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Given a local ref, take ownership of it and delete the ref when this goes out
|
// Scope Java local references to the lifetime of this object. Use in all C++
|
||||||
// of scope.
|
// callbacks (i.e. entry points that don't originate in a Java callstack
|
||||||
template<class T> // T is jclass, jobject, jintArray, etc.
|
// through a "native" method call).
|
||||||
class ScopedLocalRef {
|
class ScopedLocalRefFrame {
|
||||||
public:
|
public:
|
||||||
ScopedLocalRef(JNIEnv* jni, T obj)
|
explicit ScopedLocalRefFrame(JNIEnv* jni) : jni_(jni) {
|
||||||
: jni_(jni), obj_(obj) {}
|
CHECK(!jni_->PushLocalFrame(0), "Failed to PushLocalFrame");
|
||||||
~ScopedLocalRef() {
|
|
||||||
jni_->DeleteLocalRef(obj_);
|
|
||||||
}
|
}
|
||||||
T operator*() const {
|
~ScopedLocalRefFrame() {
|
||||||
return obj_;
|
jni_->PopLocalFrame(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JNIEnv* jni_;
|
JNIEnv* jni_;
|
||||||
T obj_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scoped holder for global Java refs.
|
// Scoped holder for global Java refs.
|
||||||
@ -418,11 +416,10 @@ jobject JavaEnumFromIndex(
|
|||||||
jclass state_class = FindClass(jni, state_class_name.c_str());
|
jclass state_class = FindClass(jni, state_class_name.c_str());
|
||||||
jmethodID state_values_id = GetStaticMethodID(
|
jmethodID state_values_id = GetStaticMethodID(
|
||||||
jni, state_class, "values", ("()[L" + state_class_name + ";").c_str());
|
jni, state_class, "values", ("()[L" + state_class_name + ";").c_str());
|
||||||
ScopedLocalRef<jobjectArray> state_values(
|
jobjectArray state_values = static_cast<jobjectArray>(
|
||||||
jni,
|
jni->CallStaticObjectMethod(state_class, state_values_id));
|
||||||
(jobjectArray)jni->CallStaticObjectMethod(state_class, state_values_id));
|
|
||||||
CHECK_EXCEPTION(jni, "error during CallStaticObjectMethod");
|
CHECK_EXCEPTION(jni, "error during CallStaticObjectMethod");
|
||||||
jobject ret = jni->GetObjectArrayElement(*state_values, index);
|
jobject ret = jni->GetObjectArrayElement(state_values, index);
|
||||||
CHECK_EXCEPTION(jni, "error during GetObjectArrayElement");
|
CHECK_EXCEPTION(jni, "error during GetObjectArrayElement");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -500,20 +497,20 @@ class PCOJava : public PeerConnectionObserver {
|
|||||||
virtual ~PCOJava() {}
|
virtual ~PCOJava() {}
|
||||||
|
|
||||||
virtual void OnIceCandidate(const IceCandidateInterface* candidate) OVERRIDE {
|
virtual void OnIceCandidate(const IceCandidateInterface* candidate) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
std::string sdp;
|
std::string sdp;
|
||||||
CHECK(candidate->ToString(&sdp), "got so far: " << sdp);
|
CHECK(candidate->ToString(&sdp), "got so far: " << sdp);
|
||||||
jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate");
|
jclass candidate_class = FindClass(jni(), "org/webrtc/IceCandidate");
|
||||||
jmethodID ctor = GetMethodID(jni(), candidate_class,
|
jmethodID ctor = GetMethodID(jni(), candidate_class,
|
||||||
"<init>", "(Ljava/lang/String;ILjava/lang/String;)V");
|
"<init>", "(Ljava/lang/String;ILjava/lang/String;)V");
|
||||||
ScopedLocalRef<jstring> j_mid(
|
jstring j_mid = JavaStringFromStdString(jni(), candidate->sdp_mid());
|
||||||
jni(), JavaStringFromStdString(jni(), candidate->sdp_mid()));
|
jstring j_sdp = JavaStringFromStdString(jni(), sdp);
|
||||||
ScopedLocalRef<jstring> j_sdp(jni(), JavaStringFromStdString(jni(), sdp));
|
jobject j_candidate = jni()->NewObject(
|
||||||
ScopedLocalRef<jobject> j_candidate(jni(), jni()->NewObject(
|
candidate_class, ctor, j_mid, candidate->sdp_mline_index(), j_sdp);
|
||||||
candidate_class, ctor, *j_mid, candidate->sdp_mline_index(), *j_sdp));
|
|
||||||
CHECK_EXCEPTION(jni(), "error during NewObject");
|
CHECK_EXCEPTION(jni(), "error during NewObject");
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_,
|
jmethodID m = GetMethodID(jni(), *j_observer_class_,
|
||||||
"onIceCandidate", "(Lorg/webrtc/IceCandidate;)V");
|
"onIceCandidate", "(Lorg/webrtc/IceCandidate;)V");
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_candidate);
|
jni()->CallVoidMethod(*j_observer_global_, m, j_candidate);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -525,59 +522,63 @@ class PCOJava : public PeerConnectionObserver {
|
|||||||
|
|
||||||
virtual void OnSignalingChange(
|
virtual void OnSignalingChange(
|
||||||
PeerConnectionInterface::SignalingState new_state) OVERRIDE {
|
PeerConnectionInterface::SignalingState new_state) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jmethodID m = GetMethodID(
|
jmethodID m = GetMethodID(
|
||||||
jni(), *j_observer_class_, "onSignalingChange",
|
jni(), *j_observer_class_, "onSignalingChange",
|
||||||
"(Lorg/webrtc/PeerConnection$SignalingState;)V");
|
"(Lorg/webrtc/PeerConnection$SignalingState;)V");
|
||||||
ScopedLocalRef<jobject> new_state_enum(jni(), JavaEnumFromIndex(
|
jobject new_state_enum =
|
||||||
jni(), "PeerConnection$SignalingState", new_state));
|
JavaEnumFromIndex(jni(), "PeerConnection$SignalingState", new_state);
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *new_state_enum);
|
jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnIceConnectionChange(
|
virtual void OnIceConnectionChange(
|
||||||
PeerConnectionInterface::IceConnectionState new_state) OVERRIDE {
|
PeerConnectionInterface::IceConnectionState new_state) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jmethodID m = GetMethodID(
|
jmethodID m = GetMethodID(
|
||||||
jni(), *j_observer_class_, "onIceConnectionChange",
|
jni(), *j_observer_class_, "onIceConnectionChange",
|
||||||
"(Lorg/webrtc/PeerConnection$IceConnectionState;)V");
|
"(Lorg/webrtc/PeerConnection$IceConnectionState;)V");
|
||||||
ScopedLocalRef<jobject> new_state_enum(jni(), JavaEnumFromIndex(
|
jobject new_state_enum = JavaEnumFromIndex(
|
||||||
jni(), "PeerConnection$IceConnectionState", new_state));
|
jni(), "PeerConnection$IceConnectionState", new_state);
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *new_state_enum);
|
jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnIceGatheringChange(
|
virtual void OnIceGatheringChange(
|
||||||
PeerConnectionInterface::IceGatheringState new_state) OVERRIDE {
|
PeerConnectionInterface::IceGatheringState new_state) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jmethodID m = GetMethodID(
|
jmethodID m = GetMethodID(
|
||||||
jni(), *j_observer_class_, "onIceGatheringChange",
|
jni(), *j_observer_class_, "onIceGatheringChange",
|
||||||
"(Lorg/webrtc/PeerConnection$IceGatheringState;)V");
|
"(Lorg/webrtc/PeerConnection$IceGatheringState;)V");
|
||||||
ScopedLocalRef<jobject> new_state_enum(jni(), JavaEnumFromIndex(
|
jobject new_state_enum = JavaEnumFromIndex(
|
||||||
jni(), "PeerConnection$IceGatheringState", new_state));
|
jni(), "PeerConnection$IceGatheringState", new_state);
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *new_state_enum);
|
jni()->CallVoidMethod(*j_observer_global_, m, new_state_enum);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnAddStream(MediaStreamInterface* stream) OVERRIDE {
|
virtual void OnAddStream(MediaStreamInterface* stream) OVERRIDE {
|
||||||
ScopedLocalRef<jobject> j_stream(jni(), jni()->NewObject(
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
*j_media_stream_class_, j_media_stream_ctor_, (jlong)stream));
|
jobject j_stream = jni()->NewObject(
|
||||||
|
*j_media_stream_class_, j_media_stream_ctor_, (jlong)stream);
|
||||||
CHECK_EXCEPTION(jni(), "error during NewObject");
|
CHECK_EXCEPTION(jni(), "error during NewObject");
|
||||||
|
|
||||||
AudioTrackVector audio_tracks = stream->GetAudioTracks();
|
AudioTrackVector audio_tracks = stream->GetAudioTracks();
|
||||||
for (size_t i = 0; i < audio_tracks.size(); ++i) {
|
for (size_t i = 0; i < audio_tracks.size(); ++i) {
|
||||||
AudioTrackInterface* track = audio_tracks[i];
|
AudioTrackInterface* track = audio_tracks[i];
|
||||||
ScopedLocalRef<jstring> id(
|
jstring id = JavaStringFromStdString(jni(), track->id());
|
||||||
jni(), JavaStringFromStdString(jni(), track->id()));
|
jobject j_track = jni()->NewObject(
|
||||||
ScopedLocalRef<jobject> j_track(jni(), jni()->NewObject(
|
*j_audio_track_class_, j_audio_track_ctor_, (jlong)track, id);
|
||||||
*j_audio_track_class_, j_audio_track_ctor_, (jlong)track, *id));
|
|
||||||
CHECK_EXCEPTION(jni(), "error during NewObject");
|
CHECK_EXCEPTION(jni(), "error during NewObject");
|
||||||
jfieldID audio_tracks_id = GetFieldID(jni(),
|
jfieldID audio_tracks_id = GetFieldID(jni(),
|
||||||
*j_media_stream_class_,
|
*j_media_stream_class_,
|
||||||
"audioTracks",
|
"audioTracks",
|
||||||
"Ljava/util/LinkedList;");
|
"Ljava/util/LinkedList;");
|
||||||
ScopedLocalRef<jobject> audio_tracks(jni(), GetObjectField(
|
jobject audio_tracks = GetObjectField(jni(), j_stream, audio_tracks_id);
|
||||||
jni(), *j_stream, audio_tracks_id));
|
|
||||||
jmethodID add = GetMethodID(jni(),
|
jmethodID add = GetMethodID(jni(),
|
||||||
GetObjectClass(jni(), *audio_tracks), "add", "(Ljava/lang/Object;)Z");
|
GetObjectClass(jni(), audio_tracks),
|
||||||
jboolean added = jni()->CallBooleanMethod(*audio_tracks, add, *j_track);
|
"add",
|
||||||
|
"(Ljava/lang/Object;)Z");
|
||||||
|
jboolean added = jni()->CallBooleanMethod(audio_tracks, add, j_track);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallBooleanMethod");
|
CHECK_EXCEPTION(jni(), "error during CallBooleanMethod");
|
||||||
CHECK(added, "");
|
CHECK(added, "");
|
||||||
}
|
}
|
||||||
@ -585,33 +586,34 @@ class PCOJava : public PeerConnectionObserver {
|
|||||||
VideoTrackVector video_tracks = stream->GetVideoTracks();
|
VideoTrackVector video_tracks = stream->GetVideoTracks();
|
||||||
for (size_t i = 0; i < video_tracks.size(); ++i) {
|
for (size_t i = 0; i < video_tracks.size(); ++i) {
|
||||||
VideoTrackInterface* track = video_tracks[i];
|
VideoTrackInterface* track = video_tracks[i];
|
||||||
ScopedLocalRef<jstring> id(
|
jstring id = JavaStringFromStdString(jni(), track->id());
|
||||||
jni(), JavaStringFromStdString(jni(), track->id()));
|
jobject j_track = jni()->NewObject(
|
||||||
ScopedLocalRef<jobject> j_track(jni(), jni()->NewObject(
|
*j_video_track_class_, j_video_track_ctor_, (jlong)track, id);
|
||||||
*j_video_track_class_, j_video_track_ctor_, (jlong)track, *id));
|
|
||||||
CHECK_EXCEPTION(jni(), "error during NewObject");
|
CHECK_EXCEPTION(jni(), "error during NewObject");
|
||||||
jfieldID video_tracks_id = GetFieldID(jni(),
|
jfieldID video_tracks_id = GetFieldID(jni(),
|
||||||
*j_media_stream_class_,
|
*j_media_stream_class_,
|
||||||
"videoTracks",
|
"videoTracks",
|
||||||
"Ljava/util/LinkedList;");
|
"Ljava/util/LinkedList;");
|
||||||
ScopedLocalRef<jobject> video_tracks(jni(), GetObjectField(
|
jobject video_tracks = GetObjectField(jni(), j_stream, video_tracks_id);
|
||||||
jni(), *j_stream, video_tracks_id));
|
|
||||||
jmethodID add = GetMethodID(jni(),
|
jmethodID add = GetMethodID(jni(),
|
||||||
GetObjectClass(jni(), *video_tracks), "add", "(Ljava/lang/Object;)Z");
|
GetObjectClass(jni(), video_tracks),
|
||||||
jboolean added = jni()->CallBooleanMethod(*video_tracks, add, *j_track);
|
"add",
|
||||||
|
"(Ljava/lang/Object;)Z");
|
||||||
|
jboolean added = jni()->CallBooleanMethod(video_tracks, add, j_track);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallBooleanMethod");
|
CHECK_EXCEPTION(jni(), "error during CallBooleanMethod");
|
||||||
CHECK(added, "");
|
CHECK(added, "");
|
||||||
}
|
}
|
||||||
streams_[stream] = jni()->NewWeakGlobalRef(*j_stream);
|
streams_[stream] = jni()->NewWeakGlobalRef(j_stream);
|
||||||
CHECK_EXCEPTION(jni(), "error during NewWeakGlobalRef");
|
CHECK_EXCEPTION(jni(), "error during NewWeakGlobalRef");
|
||||||
|
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream",
|
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onAddStream",
|
||||||
"(Lorg/webrtc/MediaStream;)V");
|
"(Lorg/webrtc/MediaStream;)V");
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_stream);
|
jni()->CallVoidMethod(*j_observer_global_, m, j_stream);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnRemoveStream(MediaStreamInterface* stream) OVERRIDE {
|
virtual void OnRemoveStream(MediaStreamInterface* stream) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
NativeToJavaStreamsMap::iterator it = streams_.find(stream);
|
NativeToJavaStreamsMap::iterator it = streams_.find(stream);
|
||||||
CHECK(it != streams_.end(), "unexpected stream: " << std::hex << stream);
|
CHECK(it != streams_.end(), "unexpected stream: " << std::hex << stream);
|
||||||
|
|
||||||
@ -627,13 +629,14 @@ class PCOJava : public PeerConnectionObserver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnDataChannel(DataChannelInterface* channel) OVERRIDE {
|
virtual void OnDataChannel(DataChannelInterface* channel) OVERRIDE {
|
||||||
ScopedLocalRef<jobject> j_channel(jni(), jni()->NewObject(
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
*j_data_channel_class_, j_data_channel_ctor_, (jlong)channel));
|
jobject j_channel = jni()->NewObject(
|
||||||
|
*j_data_channel_class_, j_data_channel_ctor_, (jlong)channel);
|
||||||
CHECK_EXCEPTION(jni(), "error during NewObject");
|
CHECK_EXCEPTION(jni(), "error during NewObject");
|
||||||
|
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel",
|
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onDataChannel",
|
||||||
"(Lorg/webrtc/DataChannel;)V");
|
"(Lorg/webrtc/DataChannel;)V");
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_channel);
|
jni()->CallVoidMethod(*j_observer_global_, m, j_channel);
|
||||||
|
|
||||||
// Channel is now owned by Java object, and will be freed from
|
// Channel is now owned by Java object, and will be freed from
|
||||||
// DataChannel.dispose(). Important that this be done _after_ the
|
// DataChannel.dispose(). Important that this be done _after_ the
|
||||||
@ -738,17 +741,16 @@ static jobject JavaSdpFromNativeSdp(
|
|||||||
JNIEnv* jni, const SessionDescriptionInterface* desc) {
|
JNIEnv* jni, const SessionDescriptionInterface* desc) {
|
||||||
std::string sdp;
|
std::string sdp;
|
||||||
CHECK(desc->ToString(&sdp), "got so far: " << sdp);
|
CHECK(desc->ToString(&sdp), "got so far: " << sdp);
|
||||||
ScopedLocalRef<jstring> j_description(jni, JavaStringFromStdString(jni, sdp));
|
jstring j_description = JavaStringFromStdString(jni, sdp);
|
||||||
|
|
||||||
jclass j_type_class = FindClass(
|
jclass j_type_class = FindClass(
|
||||||
jni, "org/webrtc/SessionDescription$Type");
|
jni, "org/webrtc/SessionDescription$Type");
|
||||||
jmethodID j_type_from_canonical = GetStaticMethodID(
|
jmethodID j_type_from_canonical = GetStaticMethodID(
|
||||||
jni, j_type_class, "fromCanonicalForm",
|
jni, j_type_class, "fromCanonicalForm",
|
||||||
"(Ljava/lang/String;)Lorg/webrtc/SessionDescription$Type;");
|
"(Ljava/lang/String;)Lorg/webrtc/SessionDescription$Type;");
|
||||||
ScopedLocalRef<jstring> j_type_string(
|
jstring j_type_string = JavaStringFromStdString(jni, desc->type());
|
||||||
jni, JavaStringFromStdString(jni, desc->type()));
|
|
||||||
jobject j_type = jni->CallStaticObjectMethod(
|
jobject j_type = jni->CallStaticObjectMethod(
|
||||||
j_type_class, j_type_from_canonical, *j_type_string);
|
j_type_class, j_type_from_canonical, j_type_string);
|
||||||
CHECK_EXCEPTION(jni, "error during CallObjectMethod");
|
CHECK_EXCEPTION(jni, "error during CallObjectMethod");
|
||||||
|
|
||||||
jclass j_sdp_class = FindClass(jni, "org/webrtc/SessionDescription");
|
jclass j_sdp_class = FindClass(jni, "org/webrtc/SessionDescription");
|
||||||
@ -756,7 +758,7 @@ static jobject JavaSdpFromNativeSdp(
|
|||||||
jni, j_sdp_class, "<init>",
|
jni, j_sdp_class, "<init>",
|
||||||
"(Lorg/webrtc/SessionDescription$Type;Ljava/lang/String;)V");
|
"(Lorg/webrtc/SessionDescription$Type;Ljava/lang/String;)V");
|
||||||
jobject j_sdp = jni->NewObject(
|
jobject j_sdp = jni->NewObject(
|
||||||
j_sdp_class, j_sdp_ctor, j_type, *j_description);
|
j_sdp_class, j_sdp_ctor, j_type, j_description);
|
||||||
CHECK_EXCEPTION(jni, "error during NewObject");
|
CHECK_EXCEPTION(jni, "error during NewObject");
|
||||||
return j_sdp;
|
return j_sdp;
|
||||||
}
|
}
|
||||||
@ -775,6 +777,7 @@ class SdpObserverWrapper : public T {
|
|||||||
|
|
||||||
// Can't mark OVERRIDE because of templating.
|
// Can't mark OVERRIDE because of templating.
|
||||||
virtual void OnSuccess() {
|
virtual void OnSuccess() {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSetSuccess", "()V");
|
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onSetSuccess", "()V");
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m);
|
jni()->CallVoidMethod(*j_observer_global_, m);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
@ -782,11 +785,12 @@ class SdpObserverWrapper : public T {
|
|||||||
|
|
||||||
// Can't mark OVERRIDE because of templating.
|
// Can't mark OVERRIDE because of templating.
|
||||||
virtual void OnSuccess(SessionDescriptionInterface* desc) {
|
virtual void OnSuccess(SessionDescriptionInterface* desc) {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jmethodID m = GetMethodID(
|
jmethodID m = GetMethodID(
|
||||||
jni(), *j_observer_class_, "onCreateSuccess",
|
jni(), *j_observer_class_, "onCreateSuccess",
|
||||||
"(Lorg/webrtc/SessionDescription;)V");
|
"(Lorg/webrtc/SessionDescription;)V");
|
||||||
ScopedLocalRef<jobject> j_sdp(jni(), JavaSdpFromNativeSdp(jni(), desc));
|
jobject j_sdp = JavaSdpFromNativeSdp(jni(), desc);
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_sdp);
|
jni()->CallVoidMethod(*j_observer_global_, m, j_sdp);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,17 +800,16 @@ class SdpObserverWrapper : public T {
|
|||||||
void OnFailure(const std::string& op, const std::string& error) {
|
void OnFailure(const std::string& op, const std::string& error) {
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_, "on" + op + "Failure",
|
jmethodID m = GetMethodID(jni(), *j_observer_class_, "on" + op + "Failure",
|
||||||
"(Ljava/lang/String;)V");
|
"(Ljava/lang/String;)V");
|
||||||
ScopedLocalRef<jstring> j_error_string(
|
jstring j_error_string = JavaStringFromStdString(jni(), error);
|
||||||
jni(), JavaStringFromStdString(jni(), error));
|
jni()->CallVoidMethod(*j_observer_global_, m, j_error_string);
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_error_string);
|
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
JNIEnv* jni() {
|
JNIEnv* jni() {
|
||||||
return AttachCurrentThreadIfNeeded();
|
return AttachCurrentThreadIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
talk_base::scoped_ptr<ConstraintsWrapper> constraints_;
|
talk_base::scoped_ptr<ConstraintsWrapper> constraints_;
|
||||||
const ScopedGlobalRef<jobject> j_observer_global_;
|
const ScopedGlobalRef<jobject> j_observer_global_;
|
||||||
const ScopedGlobalRef<jclass> j_observer_class_;
|
const ScopedGlobalRef<jclass> j_observer_class_;
|
||||||
@ -820,6 +823,7 @@ class CreateSdpObserverWrapper
|
|||||||
: SdpObserverWrapper(jni, j_observer, constraints) {}
|
: SdpObserverWrapper(jni, j_observer, constraints) {}
|
||||||
|
|
||||||
virtual void OnFailure(const std::string& error) OVERRIDE {
|
virtual void OnFailure(const std::string& error) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
SdpObserverWrapper::OnFailure(std::string("Create"), error);
|
SdpObserverWrapper::OnFailure(std::string("Create"), error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -832,6 +836,7 @@ class SetSdpObserverWrapper
|
|||||||
: SdpObserverWrapper(jni, j_observer, constraints) {}
|
: SdpObserverWrapper(jni, j_observer, constraints) {}
|
||||||
|
|
||||||
virtual void OnFailure(const std::string& error) OVERRIDE {
|
virtual void OnFailure(const std::string& error) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
SdpObserverWrapper::OnFailure(std::string("Set"), error);
|
SdpObserverWrapper::OnFailure(std::string("Set"), error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -855,11 +860,13 @@ class DataChannelObserverWrapper : public DataChannelObserver {
|
|||||||
virtual ~DataChannelObserverWrapper() {}
|
virtual ~DataChannelObserverWrapper() {}
|
||||||
|
|
||||||
virtual void OnStateChange() OVERRIDE {
|
virtual void OnStateChange() OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jni()->CallVoidMethod(*j_observer_global_, j_on_state_change_mid_);
|
jni()->CallVoidMethod(*j_observer_global_, j_on_state_change_mid_);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void OnMessage(const DataBuffer& buffer) OVERRIDE {
|
virtual void OnMessage(const DataBuffer& buffer) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jobject byte_buffer =
|
jobject byte_buffer =
|
||||||
jni()->NewDirectByteBuffer(const_cast<char*>(buffer.data.data()),
|
jni()->NewDirectByteBuffer(const_cast<char*>(buffer.data.data()),
|
||||||
buffer.data.length());
|
buffer.data.length());
|
||||||
@ -904,11 +911,11 @@ class StatsObserverWrapper : public StatsObserver {
|
|||||||
virtual ~StatsObserverWrapper() {}
|
virtual ~StatsObserverWrapper() {}
|
||||||
|
|
||||||
virtual void OnComplete(const std::vector<StatsReport>& reports) OVERRIDE {
|
virtual void OnComplete(const std::vector<StatsReport>& reports) OVERRIDE {
|
||||||
ScopedLocalRef<jobjectArray> j_reports(jni(),
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
ReportsToJava(jni(), reports));
|
jobjectArray j_reports = ReportsToJava(jni(), reports);
|
||||||
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onComplete",
|
jmethodID m = GetMethodID(jni(), *j_observer_class_, "onComplete",
|
||||||
"([Lorg/webrtc/StatsReport;)V");
|
"([Lorg/webrtc/StatsReport;)V");
|
||||||
jni()->CallVoidMethod(*j_observer_global_, m, *j_reports);
|
jni()->CallVoidMethod(*j_observer_global_, m, j_reports);
|
||||||
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
CHECK_EXCEPTION(jni(), "error during CallVoidMethod");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -918,17 +925,18 @@ class StatsObserverWrapper : public StatsObserver {
|
|||||||
jobjectArray reports_array = jni->NewObjectArray(
|
jobjectArray reports_array = jni->NewObjectArray(
|
||||||
reports.size(), *j_stats_report_class_, NULL);
|
reports.size(), *j_stats_report_class_, NULL);
|
||||||
for (int i = 0; i < reports.size(); ++i) {
|
for (int i = 0; i < reports.size(); ++i) {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni);
|
||||||
const StatsReport& report = reports[i];
|
const StatsReport& report = reports[i];
|
||||||
ScopedLocalRef<jstring> j_id(
|
jstring j_id = JavaStringFromStdString(jni, report.id);
|
||||||
jni, JavaStringFromStdString(jni, report.id));
|
jstring j_type = JavaStringFromStdString(jni, report.type);
|
||||||
ScopedLocalRef<jstring> j_type(
|
jobjectArray j_values = ValuesToJava(jni, report.values);
|
||||||
jni, JavaStringFromStdString(jni, report.type));
|
jobject j_report = jni->NewObject(*j_stats_report_class_,
|
||||||
ScopedLocalRef<jobjectArray> j_values(
|
j_stats_report_ctor_,
|
||||||
jni, ValuesToJava(jni, report.values));
|
j_id,
|
||||||
ScopedLocalRef<jobject> j_report(jni, jni->NewObject(
|
j_type,
|
||||||
*j_stats_report_class_, j_stats_report_ctor_, *j_id, *j_type,
|
report.timestamp,
|
||||||
report.timestamp, *j_values));
|
j_values);
|
||||||
jni->SetObjectArrayElement(reports_array, i, *j_report);
|
jni->SetObjectArrayElement(reports_array, i, j_report);
|
||||||
}
|
}
|
||||||
return reports_array;
|
return reports_array;
|
||||||
}
|
}
|
||||||
@ -937,14 +945,13 @@ class StatsObserverWrapper : public StatsObserver {
|
|||||||
jobjectArray j_values = jni->NewObjectArray(
|
jobjectArray j_values = jni->NewObjectArray(
|
||||||
values.size(), *j_value_class_, NULL);
|
values.size(), *j_value_class_, NULL);
|
||||||
for (int i = 0; i < values.size(); ++i) {
|
for (int i = 0; i < values.size(); ++i) {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni);
|
||||||
const StatsReport::Value& value = values[i];
|
const StatsReport::Value& value = values[i];
|
||||||
ScopedLocalRef<jstring> j_name(
|
jstring j_name = JavaStringFromStdString(jni, value.name);
|
||||||
jni, JavaStringFromStdString(jni, value.name));
|
jstring j_value = JavaStringFromStdString(jni, value.value);
|
||||||
ScopedLocalRef<jstring> j_value(
|
jobject j_element_value =
|
||||||
jni, JavaStringFromStdString(jni, value.value));
|
jni->NewObject(*j_value_class_, j_value_ctor_, j_name, j_value);
|
||||||
ScopedLocalRef<jobject> j_element_value(jni, jni->NewObject(
|
jni->SetObjectArrayElement(j_values, i, j_element_value);
|
||||||
*j_value_class_, j_value_ctor_, *j_name, *j_value));
|
|
||||||
jni->SetObjectArrayElement(j_values, i, *j_element_value);
|
|
||||||
}
|
}
|
||||||
return j_values;
|
return j_values;
|
||||||
}
|
}
|
||||||
@ -974,11 +981,13 @@ class VideoRendererWrapper : public VideoRendererInterface {
|
|||||||
virtual ~VideoRendererWrapper() {}
|
virtual ~VideoRendererWrapper() {}
|
||||||
|
|
||||||
virtual void SetSize(int width, int height) OVERRIDE {
|
virtual void SetSize(int width, int height) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(AttachCurrentThreadIfNeeded());
|
||||||
const bool kNotReserved = false; // What does this param mean??
|
const bool kNotReserved = false; // What does this param mean??
|
||||||
renderer_->SetSize(width, height, kNotReserved);
|
renderer_->SetSize(width, height, kNotReserved);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
|
virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(AttachCurrentThreadIfNeeded());
|
||||||
renderer_->RenderFrame(frame);
|
renderer_->RenderFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1011,40 +1020,41 @@ class JavaVideoRendererWrapper : public VideoRendererInterface {
|
|||||||
virtual ~JavaVideoRendererWrapper() {}
|
virtual ~JavaVideoRendererWrapper() {}
|
||||||
|
|
||||||
virtual void SetSize(int width, int height) OVERRIDE {
|
virtual void SetSize(int width, int height) OVERRIDE {
|
||||||
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jni()->CallVoidMethod(*j_callbacks_, j_set_size_id_, width, height);
|
jni()->CallVoidMethod(*j_callbacks_, j_set_size_id_, width, height);
|
||||||
CHECK_EXCEPTION(jni(), "");
|
CHECK_EXCEPTION(jni(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
|
virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
|
||||||
ScopedLocalRef<jobject> j_frame(jni(), CricketToJavaFrame(frame));
|
ScopedLocalRefFrame local_ref_frame(jni());
|
||||||
jni()->CallVoidMethod(*j_callbacks_, j_render_frame_id_, *j_frame);
|
jobject j_frame = CricketToJavaFrame(frame);
|
||||||
|
jni()->CallVoidMethod(*j_callbacks_, j_render_frame_id_, j_frame);
|
||||||
CHECK_EXCEPTION(jni(), "");
|
CHECK_EXCEPTION(jni(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Return a VideoRenderer.I420Frame referring to the data in |frame|.
|
// Return a VideoRenderer.I420Frame referring to the data in |frame|.
|
||||||
jobject CricketToJavaFrame(const cricket::VideoFrame* frame) {
|
jobject CricketToJavaFrame(const cricket::VideoFrame* frame) {
|
||||||
ScopedLocalRef<jintArray> strides(jni(), jni()->NewIntArray(3));
|
jintArray strides = jni()->NewIntArray(3);
|
||||||
jint* strides_array = jni()->GetIntArrayElements(*strides, NULL);
|
jint* strides_array = jni()->GetIntArrayElements(strides, NULL);
|
||||||
strides_array[0] = frame->GetYPitch();
|
strides_array[0] = frame->GetYPitch();
|
||||||
strides_array[1] = frame->GetUPitch();
|
strides_array[1] = frame->GetUPitch();
|
||||||
strides_array[2] = frame->GetVPitch();
|
strides_array[2] = frame->GetVPitch();
|
||||||
jni()->ReleaseIntArrayElements(*strides, strides_array, 0);
|
jni()->ReleaseIntArrayElements(strides, strides_array, 0);
|
||||||
ScopedLocalRef<jobjectArray> planes(
|
jobjectArray planes = jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL);
|
||||||
jni(), jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL));
|
jobject y_buffer = jni()->NewDirectByteBuffer(
|
||||||
ScopedLocalRef<jobject> y_buffer(jni(), jni()->NewDirectByteBuffer(
|
|
||||||
const_cast<uint8*>(frame->GetYPlane()),
|
const_cast<uint8*>(frame->GetYPlane()),
|
||||||
frame->GetYPitch() * frame->GetHeight()));
|
frame->GetYPitch() * frame->GetHeight());
|
||||||
ScopedLocalRef<jobject> u_buffer(jni(), jni()->NewDirectByteBuffer(
|
jobject u_buffer = jni()->NewDirectByteBuffer(
|
||||||
const_cast<uint8*>(frame->GetUPlane()), frame->GetChromaSize()));
|
const_cast<uint8*>(frame->GetUPlane()), frame->GetChromaSize());
|
||||||
ScopedLocalRef<jobject> v_buffer(jni(), jni()->NewDirectByteBuffer(
|
jobject v_buffer = jni()->NewDirectByteBuffer(
|
||||||
const_cast<uint8*>(frame->GetVPlane()), frame->GetChromaSize()));
|
const_cast<uint8*>(frame->GetVPlane()), frame->GetChromaSize());
|
||||||
jni()->SetObjectArrayElement(*planes, 0, *y_buffer);
|
jni()->SetObjectArrayElement(planes, 0, y_buffer);
|
||||||
jni()->SetObjectArrayElement(*planes, 1, *u_buffer);
|
jni()->SetObjectArrayElement(planes, 1, u_buffer);
|
||||||
jni()->SetObjectArrayElement(*planes, 2, *v_buffer);
|
jni()->SetObjectArrayElement(planes, 2, v_buffer);
|
||||||
return jni()->NewObject(
|
return jni()->NewObject(
|
||||||
*j_frame_class_, j_frame_ctor_id_,
|
*j_frame_class_, j_frame_ctor_id_,
|
||||||
frame->GetWidth(), frame->GetHeight(), *strides, *planes);
|
frame->GetWidth(), frame->GetHeight(), strides, planes);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv* jni() {
|
JNIEnv* jni() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user