Add option to print peer connection factory Java stack traces.

R=wzh@webrtc.org

Review URL: https://codereview.webrtc.org/1395693002 .

Cr-Commit-Position: refs/heads/master@{#10204}
This commit is contained in:
Alex Glaznev
2015-10-07 14:50:13 -07:00
parent 91b348c702
commit 21622a1d19
3 changed files with 79 additions and 3 deletions

View File

@ -99,6 +99,7 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "org/webrtc/MediaSource$State"); LoadClass(jni, "org/webrtc/MediaSource$State");
LoadClass(jni, "org/webrtc/MediaStream"); LoadClass(jni, "org/webrtc/MediaStream");
LoadClass(jni, "org/webrtc/MediaStreamTrack$State"); LoadClass(jni, "org/webrtc/MediaStreamTrack$State");
LoadClass(jni, "org/webrtc/PeerConnectionFactory");
LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy"); LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy");
LoadClass(jni, "org/webrtc/PeerConnection$ContinualGatheringPolicy"); LoadClass(jni, "org/webrtc/PeerConnection$ContinualGatheringPolicy");
LoadClass(jni, "org/webrtc/PeerConnection$RtcpMuxPolicy"); LoadClass(jni, "org/webrtc/PeerConnection$RtcpMuxPolicy");

View File

@ -1075,8 +1075,11 @@ class OwnedFactoryAndThreads {
PeerConnectionFactoryInterface* factory() { return factory_; } PeerConnectionFactoryInterface* factory() { return factory_; }
WebRtcVideoEncoderFactory* encoder_factory() { return encoder_factory_; } WebRtcVideoEncoderFactory* encoder_factory() { return encoder_factory_; }
WebRtcVideoDecoderFactory* decoder_factory() { return decoder_factory_; } WebRtcVideoDecoderFactory* decoder_factory() { return decoder_factory_; }
void InvokeJavaCallbacksOnFactoryThreads();
private: private:
void JavaCallbackOnFactoryThreads();
const scoped_ptr<Thread> worker_thread_; const scoped_ptr<Thread> worker_thread_;
const scoped_ptr<Thread> signaling_thread_; const scoped_ptr<Thread> signaling_thread_;
WebRtcVideoEncoderFactory* encoder_factory_; WebRtcVideoEncoderFactory* encoder_factory_;
@ -1084,6 +1087,34 @@ class OwnedFactoryAndThreads {
PeerConnectionFactoryInterface* factory_; // Const after ctor except dtor. PeerConnectionFactoryInterface* factory_; // Const after ctor except dtor.
}; };
void OwnedFactoryAndThreads::JavaCallbackOnFactoryThreads() {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);
jclass j_factory_class = FindClass(jni, "org/webrtc/PeerConnectionFactory");
jmethodID m = nullptr;
if (Thread::Current() == worker_thread_) {
LOG(LS_INFO) << "Worker thread JavaCallback";
m = GetStaticMethodID(jni, j_factory_class, "onWorkerThreadReady", "()V");
}
if (Thread::Current() == signaling_thread_) {
LOG(LS_INFO) << "Signaling thread JavaCallback";
m = GetStaticMethodID(
jni, j_factory_class, "onSignalingThreadReady", "()V");
}
if (m != nullptr) {
jni->CallStaticVoidMethod(j_factory_class, m);
CHECK_EXCEPTION(jni) << "error during JavaCallback::CallStaticVoidMethod";
}
}
void OwnedFactoryAndThreads::InvokeJavaCallbacksOnFactoryThreads() {
LOG(LS_INFO) << "InvokeJavaCallbacksOnFactoryThreads.";
worker_thread_->Invoke<void>(
Bind(&OwnedFactoryAndThreads::JavaCallbackOnFactoryThreads, this));
signaling_thread_->Invoke<void>(
Bind(&OwnedFactoryAndThreads::JavaCallbackOnFactoryThreads, this));
}
JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnectionFactory)( JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnectionFactory)(
JNIEnv* jni, jclass) { JNIEnv* jni, jclass) {
// talk/ assumes pretty widely that the current Thread is ThreadManager'd, but // talk/ assumes pretty widely that the current Thread is ThreadManager'd, but
@ -1119,10 +1150,11 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnectionFactory)(
worker_thread, signaling_thread, worker_thread, signaling_thread,
encoder_factory, decoder_factory, encoder_factory, decoder_factory,
factory.release()); factory.release());
owned_factory->InvokeJavaCallbacksOnFactoryThreads();
return jlongFromPointer(owned_factory); return jlongFromPointer(owned_factory);
} }
JOW(void, PeerConnectionFactory_freeFactory)(JNIEnv*, jclass, jlong j_p) { JOW(void, PeerConnectionFactory_nativeFreeFactory)(JNIEnv*, jclass, jlong j_p) {
delete reinterpret_cast<OwnedFactoryAndThreads*>(j_p); delete reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
if (field_trials_init_string) { if (field_trials_init_string) {
webrtc::field_trial::InitFieldTrialsFromString(NULL); webrtc::field_trial::InitFieldTrialsFromString(NULL);
@ -1136,6 +1168,13 @@ static PeerConnectionFactoryInterface* factoryFromJava(jlong j_p) {
return reinterpret_cast<OwnedFactoryAndThreads*>(j_p)->factory(); return reinterpret_cast<OwnedFactoryAndThreads*>(j_p)->factory();
} }
JOW(void, PeerConnectionFactory_nativeThreadsCallbacks)(
JNIEnv*, jclass, jlong j_p) {
OwnedFactoryAndThreads *factory =
reinterpret_cast<OwnedFactoryAndThreads*>(j_p);
factory->InvokeJavaCallbacksOnFactoryThreads();
}
JOW(jlong, PeerConnectionFactory_nativeCreateLocalMediaStream)( JOW(jlong, PeerConnectionFactory_nativeCreateLocalMediaStream)(
JNIEnv* jni, jclass, jlong native_factory, jstring label) { JNIEnv* jni, jclass, jlong native_factory, jstring label) {
rtc::scoped_refptr<PeerConnectionFactoryInterface> factory( rtc::scoped_refptr<PeerConnectionFactoryInterface> factory(

View File

@ -39,7 +39,10 @@ public class PeerConnectionFactory {
System.loadLibrary("jingle_peerconnection_so"); System.loadLibrary("jingle_peerconnection_so");
} }
private static final String TAG = "PeerConnectionFactory";
private final long nativeFactory; private final long nativeFactory;
private static Thread workerThread;
private static Thread signalingThread;
public static class Options { public static class Options {
// Keep in sync with webrtc/base/network.h! // Keep in sync with webrtc/base/network.h!
@ -136,7 +139,38 @@ public class PeerConnectionFactory {
} }
public void dispose() { public void dispose() {
freeFactory(nativeFactory); nativeFreeFactory(nativeFactory);
signalingThread = null;
workerThread = null;
}
public void threadsCallbacks() {
nativeThreadsCallbacks(nativeFactory);
}
public static void printStackTraces() {
if (workerThread != null) {
Logging.d(TAG, "Worker thread stacks trace:");
for (StackTraceElement stackTrace : workerThread.getStackTrace()) {
Logging.d(TAG, stackTrace.toString());
}
}
if (signalingThread != null) {
Logging.d(TAG, "Signaling thread stacks trace:");
for (StackTraceElement stackTrace : signalingThread.getStackTrace()) {
Logging.d(TAG, stackTrace.toString());
}
}
}
private static void onWorkerThreadReady() {
workerThread = Thread.currentThread();
Logging.d(TAG, "onWorkerThreadReady");
}
private static void onSignalingThreadReady() {
signalingThread = Thread.currentThread();
Logging.d(TAG, "onSignalingThreadReady");
} }
private static native long nativeCreatePeerConnectionFactory(); private static native long nativeCreatePeerConnectionFactory();
@ -169,5 +203,7 @@ public class PeerConnectionFactory {
private static native void nativeSetVideoHwAccelerationOptions( private static native void nativeSetVideoHwAccelerationOptions(
long nativeFactory, Object renderEGLContext); long nativeFactory, Object renderEGLContext);
private static native void freeFactory(long nativeFactory); private static native void nativeThreadsCallbacks(long nativeFactory);
private static native void nativeFreeFactory(long nativeFactory);
} }