15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_ANDROID_SCOPED_JAVA_REF_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_ANDROID_SCOPED_JAVA_REF_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <jni.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace android {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Creates a new local reference frame, in which at least a given number of
18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// local references can be created. Note that local references already created
19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// in previous local frames are still valid in the current local frame.
20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass BASE_EXPORT ScopedJavaLocalFrame {
21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public:
22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  explicit ScopedJavaLocalFrame(JNIEnv* env);
23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ScopedJavaLocalFrame(JNIEnv* env, int capacity);
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ~ScopedJavaLocalFrame();
25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private:
27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // This class is only good for use on the thread it was created on so
28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // it's safe to cache the non-threadsafe JNIEnv* inside this object.
29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  JNIEnv* env_;
30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
31c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ScopedJavaLocalFrame);
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch};
33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forward declare the generic java reference template class.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> class JavaRef;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Template specialization of JavaRef, which acts as the base class for all
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// other JavaRef<> template types. This allows you to e.g. pass
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ScopedJavaLocalRef<jstring> into a function taking const JavaRef<jobject>&
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT JavaRef<jobject> {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jobject obj() const { return obj_; }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_null() const { return obj_ == NULL; }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes a NULL reference.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaRef();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes ownership of the |obj| reference passed; requires it to be a local
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reference type.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaRef(JNIEnv* env, jobject obj);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~JavaRef();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following are implementation detail convenience methods, for
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // use by the sub-classes.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* SetNewLocalRef(JNIEnv* env, jobject obj);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetNewGlobalRef(JNIEnv* env, jobject obj);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetLocalRef(JNIEnv* env);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResetGlobalRef();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jobject ReleaseInternal();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jobject obj_;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(JavaRef);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for allowing functions to accept a reference without having to mandate
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whether it is a local or global type.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class JavaRef : public JavaRef<jobject> {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T obj() const { return static_cast<T>(JavaRef<jobject>::obj()); }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaRef() {}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~JavaRef() {}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaRef(JNIEnv* env, T obj) : JavaRef<jobject>(env, obj) {}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(JavaRef);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds a local reference to a Java object. The local reference is scoped
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the lifetime of this object.
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Instances of this class may hold onto any JNIEnv passed into it until
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destroyed. Therefore, since a JNIEnv is only suitable for use on a single
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread, objects of this class must be created, used, and destroyed, on a
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// single thread.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Therefore, this class should only be used as a stack-based object and from a
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// single thread. If you wish to have the reference outlive the current
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// callstack (e.g. as a class member) or you wish to pass it across threads,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// use a ScopedJavaGlobalRef instead.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedJavaLocalRef : public JavaRef<T> {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef() : env_(NULL) {}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-explicit copy constructor, to allow ScopedJavaLocalRef to be returned
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by value as this is the normal usage pattern.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef(const ScopedJavaLocalRef<T>& other)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : env_(other.env_) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->SetNewLocalRef(env_, other.obj());
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScopedJavaLocalRef(const U& other)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : env_(NULL) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(other);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Assumes that |obj| is a local reference to a Java object and takes
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership  of this local reference.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(env, obj), env_(env) {}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedJavaLocalRef() {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overloaded assignment operator defined for consistency with the implicit
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // copy constructor.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator=(const ScopedJavaLocalRef<T>& other) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(other);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->ResetLocalRef(env_);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(const ScopedJavaLocalRef<U>& other) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can copy over env_ here as |other| instance must be from the same
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // thread as |this| local ref. (See class comment for multi-threading
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // limitations, and alternatives).
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(other.env_, other.obj());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(const U& other) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If |env_| was not yet set (is still NULL) it will be attached to the
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // current thread in SetNewLocalRef().
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(env_, other.obj());
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(JNIEnv* env, U obj) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    implicit_cast<T>(obj);  // Ensure U is assignable to T
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    env_ = this->SetNewLocalRef(env, obj);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Releases the local reference to the caller. The caller *must* delete the
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // local reference when it is done with it.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T Release() {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<T>(this->ReleaseInternal());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This class is only good for use on the thread it was created on so
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it's safe to cache the non-threadsafe JNIEnv* inside this object.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* env_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Holds a global reference to a Java object. The global reference is scoped
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the lifetime of this object. This class does not hold onto any JNIEnv*
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passed to it, hence it is safe to use across threads (within the constraints
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// imposed by the underlying Java object that it references).
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T>
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedJavaGlobalRef : public JavaRef<T> {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaGlobalRef() {}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScopedJavaGlobalRef(const ScopedJavaGlobalRef<T>& other) {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(other);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ScopedJavaGlobalRef(const U& other) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(other);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedJavaGlobalRef() {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset() {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->ResetGlobalRef();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(const U& other) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->Reset(NULL, other.obj());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template<typename U>
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(JNIEnv* env, U obj) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    implicit_cast<T>(obj);  // Ensure U is assignable to T
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->SetNewGlobalRef(env, obj);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Releases the global reference to the caller. The caller *must* delete the
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // global reference when it is done with it.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T Release() {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<T>(this->ReleaseInternal());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace android
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_ANDROID_SCOPED_JAVA_REF_H_
216