Home | History | Annotate | Download | only in jni
      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