| Index: webrtc/examples/unityplugin/classreferenceholder.cc
 | 
| diff --git a/webrtc/examples/unityplugin/classreferenceholder.cc b/webrtc/examples/unityplugin/classreferenceholder.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..88146997fe8cd1c459b62cf293fcce7367c2afdf
 | 
| --- /dev/null
 | 
| +++ b/webrtc/examples/unityplugin/classreferenceholder.cc
 | 
| @@ -0,0 +1,88 @@
 | 
| +/*
 | 
| + *  Copyright 2015 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.
 | 
| + */
 | 
| +#include "webrtc/examples/unityplugin/classreferenceholder.h"
 | 
| +
 | 
| +#include <utility>
 | 
| +
 | 
| +#include "webrtc/sdk/android/src/jni/jni_helpers.h"
 | 
| +
 | 
| +namespace unity_plugin {
 | 
| +
 | 
| +// ClassReferenceHolder holds global reference to Java classes in app/webrtc.
 | 
| +class ClassReferenceHolder {
 | 
| + public:
 | 
| +  explicit ClassReferenceHolder(JNIEnv* jni);
 | 
| +  ~ClassReferenceHolder();
 | 
| +
 | 
| +  void FreeReferences(JNIEnv* jni);
 | 
| +  jclass GetClass(const std::string& name);
 | 
| +
 | 
| +  void LoadClass(JNIEnv* jni, const std::string& name);
 | 
| +
 | 
| + private:
 | 
| +  std::map<std::string, jclass> classes_;
 | 
| +};
 | 
| +
 | 
| +// Allocated in LoadGlobalClassReferenceHolder(),
 | 
| +// freed in FreeGlobalClassReferenceHolder().
 | 
| +static ClassReferenceHolder* g_class_reference_holder = nullptr;
 | 
| +
 | 
| +void LoadGlobalClassReferenceHolder() {
 | 
| +  RTC_CHECK(g_class_reference_holder == nullptr);
 | 
| +  g_class_reference_holder = new ClassReferenceHolder(webrtc_jni::GetEnv());
 | 
| +}
 | 
| +
 | 
| +void FreeGlobalClassReferenceHolder() {
 | 
| +  g_class_reference_holder->FreeReferences(
 | 
| +      webrtc_jni::AttachCurrentThreadIfNeeded());
 | 
| +  delete g_class_reference_holder;
 | 
| +  g_class_reference_holder = nullptr;
 | 
| +}
 | 
| +
 | 
| +ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
 | 
| +  LoadClass(jni, "org/webrtc/UnityUtility");
 | 
| +}
 | 
| +
 | 
| +ClassReferenceHolder::~ClassReferenceHolder() {
 | 
| +  RTC_CHECK(classes_.empty()) << "Must call FreeReferences() before dtor!";
 | 
| +}
 | 
| +
 | 
| +void ClassReferenceHolder::FreeReferences(JNIEnv* jni) {
 | 
| +  for (std::map<std::string, jclass>::const_iterator it = classes_.begin();
 | 
| +       it != classes_.end(); ++it) {
 | 
| +    jni->DeleteGlobalRef(it->second);
 | 
| +  }
 | 
| +  classes_.clear();
 | 
| +}
 | 
| +
 | 
| +jclass ClassReferenceHolder::GetClass(const std::string& name) {
 | 
| +  std::map<std::string, jclass>::iterator it = classes_.find(name);
 | 
| +  RTC_CHECK(it != classes_.end()) << "Unexpected GetClass() call for: " << name;
 | 
| +  return it->second;
 | 
| +}
 | 
| +
 | 
| +void ClassReferenceHolder::LoadClass(JNIEnv* jni, const std::string& name) {
 | 
| +  jclass localRef = jni->FindClass(name.c_str());
 | 
| +  CHECK_EXCEPTION(jni) << "error during FindClass: " << name;
 | 
| +  RTC_CHECK(localRef) << name;
 | 
| +  jclass globalRef = reinterpret_cast<jclass>(jni->NewGlobalRef(localRef));
 | 
| +  CHECK_EXCEPTION(jni) << "error during NewGlobalRef: " << name;
 | 
| +  RTC_CHECK(globalRef) << name;
 | 
| +  bool inserted = classes_.insert(std::make_pair(name, globalRef)).second;
 | 
| +  RTC_CHECK(inserted) << "Duplicate class name: " << name;
 | 
| +}
 | 
| +
 | 
| +// Returns a global reference guaranteed to be valid for the lifetime of the
 | 
| +// process.
 | 
| +jclass FindClass(JNIEnv* jni, const char* name) {
 | 
| +  return g_class_reference_holder->GetClass(name);
 | 
| +}
 | 
| +
 | 
| +}  // namespace unity_plugin
 | 
| 
 |