130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni/* 230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Copyright (C) 2011 The Android Open Source Project 330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Licensed under the Apache License, Version 2.0 (the "License"); 530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * you may not use this file except in compliance with the License. 630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * You may obtain a copy of the License at 730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * http://www.apache.org/licenses/LICENSE-2.0 930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 1030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Unless required by applicable law or agreed to in writing, software 1130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * distributed under the License is distributed on an "AS IS" BASIS, 1230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * See the License for the specific language governing permissions and 1430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * limitations under the License. 1530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni */ 1630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <jni.h> 1830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <hash_map> 2030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include <string> 2130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 2230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "base/utilities.h" 23cfda0a38d6f394724e0cbd831ec9bc71d951fc74Marius Renn#include "core/value.h" 2430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala#ifndef ANDROID_FILTERFW_JNI_JNI_UTIL_H 26e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala#define ANDROID_FILTERFW_JNI_JNI_UTIL_H 2730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 2830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// We add this JNI_NULL macro to allow consistent code separation of Java and 2930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// C++ types. 3030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#define JNI_NULL NULL 3130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 3230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#if 0 3330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Pointer to current JavaVM. Do not use this directly. Instead use the funciton 3430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// GetCurrentJavaVM(). 3530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniextern JavaVM* g_current_java_vm_; 3630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 3730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Wrapper around a java object pointer, which includes the environment 3830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// pointer in which the object "lives". This is used for passing down Java 3930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// objects from the Java layer to C++. 4030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// While an instance of this class does not own the underlying java object, it 4130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// does hold a global reference to it, so that the Java garbage collector does 4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// not destroy it. It uses reference counting to determine when it can destroy 4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// the reference. 4430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// TODO: Add multi-thread support! 4530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniclass JavaObject { 4630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public: 4730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Creates a NULL JavaObject. 4830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni JavaObject(); 4930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Creates a wrapper around the given object in the given JNI environment. 5130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni JavaObject(jobject object, JNIEnv* env); 5230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Copy constructor. 5430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni JavaObject(const JavaObject& java_obj); 5530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Destructor. 5730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ~JavaObject(); 5830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Assignment operator. 6030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni JavaObject& operator=(const JavaObject& java_obj); 6130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 6230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Access to the object (non-const as JNI functions are non-const). 6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject object() const { 6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return object_; 6530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 6630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 6730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Resets this object to the NULL JavaObject. 6830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni void Reset(); 6930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 7030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private: 7130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Retain the instance, i.e. increase reference count. 7230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni void Retain(); 7330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 7430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Release the instance, i.e. decrease reference count. 7530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni void Release(); 7630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 7730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // The object pointer (not owned). 7830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject object_; 7930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 8030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // The reference count of this object 8130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int* ref_count_; 8230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}; 8330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#endif 8430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 8530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// ObjectPool template class. This class keeps track of C++ instances that are 8630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// coupled to Java objects. This is done by using an "id" field in the Java 8730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// object, which is then mapped to the correct instance here. It should not be 8830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// necessary to use this class directly. Instead, the convenience functions 8930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// below can be used. 9030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<class T> 9130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniclass ObjectPool { 9230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni public: 9330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create a new ObjectPool for a specific object type. Pass the path to the 9430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Java equivalent class of the C++ class, and the name of the java member 9530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // field that will store the object's ID. 96e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala static void Setup(const std::string& jclass_name, 97e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala const std::string& id_fld_name) { 9830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni instance_ = new ObjectPool<T>(jclass_name, id_fld_name); 9930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 10030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 10130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Return the shared instance to this type's pool. 10230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni static ObjectPool* Instance() { 10330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return instance_; 10430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 10530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 10630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Delete this type's pool. 10730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni static void TearDown() { 10830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni delete instance_; 10930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 11030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 11130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Register a new C++ object with the pool. This does not affect the Java 11230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // layer. Use WrapObject() instead to perform the necessary Java-side 11330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // assignments. Pass true to owns if the object pool owns the object. 11430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int RegisterObject(T* object, bool owns) { 11530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni const int id = next_id_; 11630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni objects_[id] = object; 11730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni owns_[id] = owns; 11830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ++next_id_; 11930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return id; 12030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 12130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 12230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Return the object in the pool with the specified ID. 12330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni T* ObjectWithID(int obj_id) const { 12430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni typename CObjMap::const_iterator iter = objects_.find(obj_id); 12530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return iter == objects_.end() ? NULL : iter->second; 12630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 12730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 12830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Get the ID of a Java object. This ID can be used to look-up the C++ 12930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // object. 13030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int GetObjectID(JNIEnv* env, jobject j_object) { 13130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jclass cls = env->GetObjectClass(j_object); 13230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I"); 13330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni const int result = env->GetIntField(j_object, id_field); 13430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni env->DeleteLocalRef(cls); 13530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return result; 13630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 13730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 13830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Take a C++ object and wrap it with a given Java object. This will 13930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // essentially set the ID member of the Java object to the ID of the C++ 14030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // object. Pass true to owns if the object pool owns the object. 14130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni bool WrapObject(T* c_object, JNIEnv* env, jobject j_object, bool owns) { 14230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni const int id = RegisterObject(c_object, owns); 14330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jclass cls = env->GetObjectClass(j_object); 14430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I"); 14530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni env->SetIntField(j_object, id_field, id); 14630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni env->DeleteLocalRef(cls); 14730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 14830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 14930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 15030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Remove the object with the given ID from this pool, and delete it. This 15130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // does not affect the Java layer. 15230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni bool DeleteObjectWithID(int obj_id) { 15330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni typename CObjMap::iterator iter = objects_.find(obj_id); 15430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni const bool found = iter != objects_.end(); 15530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (found) { 15630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (owns_[obj_id]) 15730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni delete iter->second; 15830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni objects_.erase(iter); 15930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 16030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return found; 16130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 16230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 16330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Instantiates a new java object for this class. The Java class must have 16430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // a default constructor for this to succeed. 16530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject CreateJavaObject(JNIEnv* env) { 16630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jclass cls = env->FindClass(jclass_name_.c_str()); 16730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jmethodID constructor = env->GetMethodID( 16830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni cls, 16930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni "<init>", 17030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni "(Landroid/filterfw/core/NativeAllocatorTag;)V"); 17130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject result = env->NewObject(cls, constructor, JNI_NULL); 17230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni env->DeleteLocalRef(cls); 17330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return result; 17430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 17530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 17630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int GetObjectCount() const { 17730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return objects_.size(); 17830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 17930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 180e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala const std::string& GetJavaClassName() const { 18130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return jclass_name_; 18230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 18330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 18430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni private: 185e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala explicit ObjectPool(const std::string& jclass_name, 186e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala const std::string& id_fld_name) 18730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni : jclass_name_(jclass_name), 18830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni id_field_name_(id_fld_name), 18930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni next_id_(0) { } 19030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 19130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni typedef std::hash_map<int, T*> CObjMap; 19230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni typedef std::hash_map<int, bool> FlagMap; 19330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni static ObjectPool* instance_; 194e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala std::string jclass_name_; 195e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala std::string id_field_name_; 19630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni int next_id_; 19730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni CObjMap objects_; 19830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni FlagMap owns_; 19930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni DISALLOW_COPY_AND_ASSIGN(ObjectPool); 20130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni}; 20230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<typename T> ObjectPool<T>* ObjectPool<T>::instance_ = NULL; 20430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convenience Functions /////////////////////////////////////////////////////// 20630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// This function "links" the C++ instance and the Java instance, so that they 20830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// can be mapped to one another. This must be called for every C++ instance 20930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// which is wrapped by a Java front-end interface. Pass true to owns, if the 21030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Java layer should own the object. 21130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<typename T> 21230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool WrapObjectInJava(T* c_object, JNIEnv* env, jobject j_object, bool owns) { 21330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ObjectPool<T>* pool = ObjectPool<T>::Instance(); 21430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return pool ? pool->WrapObject(c_object, env, j_object, owns) : false; 21530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 21630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 21730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Creates a new Java instance, which wraps the passed C++ instance. Returns 21830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// the wrapped object or JNI_NULL if there was an error. Pass true to owns, if 21930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// the Java layer should own the object. 22030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<typename T> 22130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijobject WrapNewObjectInJava(T* c_object, JNIEnv* env, bool owns) { 22230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ObjectPool<T>* pool = ObjectPool<T>::Instance(); 22330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (pool) { 22430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni jobject result = pool->CreateJavaObject(env); 22530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (WrapObjectInJava(c_object, env, result, owns)) 22630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return result; 22730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 22830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return JNI_NULL; 22930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 23030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 23130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Use ConvertFromJava to obtain a C++ instance given a Java object. This 23230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// instance must have been wrapped in Java using the WrapObjectInJava() 23330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// function. 23430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<typename T> 23530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniT* ConvertFromJava(JNIEnv* env, jobject j_object) { 23630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ObjectPool<T>* pool = ObjectPool<T>::Instance(); 23730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return pool && j_object 23830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ? pool->ObjectWithID(pool->GetObjectID(env, j_object)) 23930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni : NULL; 24030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 24130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 24230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Delete the native object given a Java instance. This should be called from 24330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// the Java object's finalizer. 24430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronitemplate<typename T> 24530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool DeleteNativeObject(JNIEnv* env, jobject j_object) { 24630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ObjectPool<T>* pool = ObjectPool<T>::Instance(); 24730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return pool && j_object 24830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ? pool->DeleteObjectWithID(pool->GetObjectID(env, j_object)) 24930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni : false; 25030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 25130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#if 0 25330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Get the current JNI VM, or NULL if there is no current VM 25430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniJavaVM* GetCurrentJavaVM(); 25530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Get the current JNI environment, or NULL if this is not a JNI thread 25730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniJNIEnv* GetCurrentJNIEnv(); 25830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#endif 25930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert C++ boolean to Java boolean. 26130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijboolean ToJBool(bool value); 26230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert Java boolean to C++ boolean. 26430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool ToCppBool(jboolean value); 26530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert Java String to C++ string. 267e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalajstring ToJString(JNIEnv* env, const std::string& value); 26830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert C++ string to Java String. 270e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalastd::string ToCppString(JNIEnv* env, jstring value); 27130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert Java object to a (C) Value object. 27330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniValue ToCValue(JNIEnv* env, jobject object); 27430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Convert a (C) Value object to a Java object. 27630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronijobject ToJObject(JNIEnv* env, const Value& value); 27730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Returns true, iff the passed object is an instance of the class specified 27930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// by its fully qualified class name. 280e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool IsJavaInstanceOf(JNIEnv* env, jobject object, 281e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala const std::string& class_name); 28230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 283e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala#endif // ANDROID_FILTERFW_JNI_JNI_UTIL_H 284