1 /* 2 * libjingle 3 * Copyright 2015 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 */ 28 #include "talk/app/webrtc/java/jni/classreferenceholder.h" 29 30 #include "talk/app/webrtc/java/jni/jni_helpers.h" 31 32 namespace webrtc_jni { 33 34 // ClassReferenceHolder holds global reference to Java classes in app/webrtc. 35 class ClassReferenceHolder { 36 public: 37 explicit ClassReferenceHolder(JNIEnv* jni); 38 ~ClassReferenceHolder(); 39 40 void FreeReferences(JNIEnv* jni); 41 jclass GetClass(const std::string& name); 42 43 private: 44 void LoadClass(JNIEnv* jni, const std::string& name); 45 46 std::map<std::string, jclass> classes_; 47 }; 48 49 // Allocated in LoadGlobalClassReferenceHolder(), 50 // freed in FreeGlobalClassReferenceHolder(). 51 static ClassReferenceHolder* g_class_reference_holder = nullptr; 52 53 void LoadGlobalClassReferenceHolder() { 54 RTC_CHECK(g_class_reference_holder == nullptr); 55 g_class_reference_holder = new ClassReferenceHolder(GetEnv()); 56 } 57 58 void FreeGlobalClassReferenceHolder() { 59 g_class_reference_holder->FreeReferences(AttachCurrentThreadIfNeeded()); 60 delete g_class_reference_holder; 61 g_class_reference_holder = nullptr; 62 } 63 64 ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) { 65 LoadClass(jni, "java/nio/ByteBuffer"); 66 LoadClass(jni, "java/util/ArrayList"); 67 LoadClass(jni, "org/webrtc/AudioTrack"); 68 LoadClass(jni, "org/webrtc/DataChannel"); 69 LoadClass(jni, "org/webrtc/DataChannel$Buffer"); 70 LoadClass(jni, "org/webrtc/DataChannel$Init"); 71 LoadClass(jni, "org/webrtc/DataChannel$State"); 72 LoadClass(jni, "org/webrtc/IceCandidate"); 73 #if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD) 74 LoadClass(jni, "android/graphics/SurfaceTexture"); 75 LoadClass(jni, "org/webrtc/CameraEnumerator"); 76 LoadClass(jni, "org/webrtc/Camera2Enumerator"); 77 LoadClass(jni, "org/webrtc/CameraEnumerationAndroid"); 78 LoadClass(jni, "org/webrtc/VideoCapturerAndroid"); 79 LoadClass(jni, "org/webrtc/VideoCapturerAndroid$NativeObserver"); 80 LoadClass(jni, "org/webrtc/EglBase"); 81 LoadClass(jni, "org/webrtc/EglBase$Context"); 82 LoadClass(jni, "org/webrtc/EglBase14$Context"); 83 LoadClass(jni, "org/webrtc/NetworkMonitor"); 84 LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder"); 85 LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$OutputBufferInfo"); 86 LoadClass(jni, "org/webrtc/MediaCodecVideoEncoder$VideoCodecType"); 87 LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder"); 88 LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedTextureBuffer"); 89 LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$DecodedOutputBuffer"); 90 LoadClass(jni, "org/webrtc/MediaCodecVideoDecoder$VideoCodecType"); 91 LoadClass(jni, "org/webrtc/SurfaceTextureHelper"); 92 #endif 93 LoadClass(jni, "org/webrtc/MediaSource$State"); 94 LoadClass(jni, "org/webrtc/MediaStream"); 95 LoadClass(jni, "org/webrtc/MediaStreamTrack$State"); 96 LoadClass(jni, "org/webrtc/PeerConnectionFactory"); 97 LoadClass(jni, "org/webrtc/PeerConnection$BundlePolicy"); 98 LoadClass(jni, "org/webrtc/PeerConnection$ContinualGatheringPolicy"); 99 LoadClass(jni, "org/webrtc/PeerConnection$RtcpMuxPolicy"); 100 LoadClass(jni, "org/webrtc/PeerConnection$IceConnectionState"); 101 LoadClass(jni, "org/webrtc/PeerConnection$IceGatheringState"); 102 LoadClass(jni, "org/webrtc/PeerConnection$IceTransportsType"); 103 LoadClass(jni, "org/webrtc/PeerConnection$TcpCandidatePolicy"); 104 LoadClass(jni, "org/webrtc/PeerConnection$KeyType"); 105 LoadClass(jni, "org/webrtc/PeerConnection$SignalingState"); 106 LoadClass(jni, "org/webrtc/RtpReceiver"); 107 LoadClass(jni, "org/webrtc/RtpSender"); 108 LoadClass(jni, "org/webrtc/SessionDescription"); 109 LoadClass(jni, "org/webrtc/SessionDescription$Type"); 110 LoadClass(jni, "org/webrtc/StatsReport"); 111 LoadClass(jni, "org/webrtc/StatsReport$Value"); 112 LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame"); 113 LoadClass(jni, "org/webrtc/VideoCapturer"); 114 LoadClass(jni, "org/webrtc/VideoTrack"); 115 } 116 117 ClassReferenceHolder::~ClassReferenceHolder() { 118 RTC_CHECK(classes_.empty()) << "Must call FreeReferences() before dtor!"; 119 } 120 121 void ClassReferenceHolder::FreeReferences(JNIEnv* jni) { 122 for (std::map<std::string, jclass>::const_iterator it = classes_.begin(); 123 it != classes_.end(); ++it) { 124 jni->DeleteGlobalRef(it->second); 125 } 126 classes_.clear(); 127 } 128 129 jclass ClassReferenceHolder::GetClass(const std::string& name) { 130 std::map<std::string, jclass>::iterator it = classes_.find(name); 131 RTC_CHECK(it != classes_.end()) << "Unexpected GetClass() call for: " << name; 132 return it->second; 133 } 134 135 void ClassReferenceHolder::LoadClass(JNIEnv* jni, const std::string& name) { 136 jclass localRef = jni->FindClass(name.c_str()); 137 CHECK_EXCEPTION(jni) << "error during FindClass: " << name; 138 RTC_CHECK(localRef) << name; 139 jclass globalRef = reinterpret_cast<jclass>(jni->NewGlobalRef(localRef)); 140 CHECK_EXCEPTION(jni) << "error during NewGlobalRef: " << name; 141 RTC_CHECK(globalRef) << name; 142 bool inserted = classes_.insert(std::make_pair(name, globalRef)).second; 143 RTC_CHECK(inserted) << "Duplicate class name: " << name; 144 } 145 146 // Returns a global reference guaranteed to be valid for the lifetime of the 147 // process. 148 jclass FindClass(JNIEnv* jni, const char* name) { 149 return g_class_reference_holder->GetClass(name); 150 } 151 152 } // namespace webrtc_jni 153