165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/* 265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2011 The Android Open Source Project 365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License"); 565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License. 665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at 765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * http://www.apache.org/licenses/LICENSE-2.0 965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * 1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software 1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS, 1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and 1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License. 1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */ 1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <jni.h> 1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <hash_map> 2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <string> 2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "base/utilities.h" 2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include "core/value.h" 2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifndef ANDROID_FILTERFW_JNI_JNI_UTIL_H 2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define ANDROID_FILTERFW_JNI_JNI_UTIL_H 2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// We add this JNI_NULL macro to allow consistent code separation of Java and 2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// C++ types. 3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define JNI_NULL NULL 3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#if 0 3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Pointer to current JavaVM. Do not use this directly. Instead use the funciton 3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// GetCurrentJavaVM(). 3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennextern JavaVM* g_current_java_vm_; 3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Wrapper around a java object pointer, which includes the environment 3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// pointer in which the object "lives". This is used for passing down Java 3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// objects from the Java layer to C++. 4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// While an instance of this class does not own the underlying java object, it 4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// does hold a global reference to it, so that the Java garbage collector does 4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// not destroy it. It uses reference counting to determine when it can destroy 4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// the reference. 4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// TODO: Add multi-thread support! 4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass JavaObject { 4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public: 4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Creates a NULL JavaObject. 4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JavaObject(); 4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Creates a wrapper around the given object in the given JNI environment. 5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JavaObject(jobject object, JNIEnv* env); 5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Copy constructor. 5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JavaObject(const JavaObject& java_obj); 5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Destructor. 5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ~JavaObject(); 5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Assignment operator. 6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn JavaObject& operator=(const JavaObject& java_obj); 6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Access to the object (non-const as JNI functions are non-const). 6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject object() const { 6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return object_; 6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Resets this object to the NULL JavaObject. 6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn void Reset(); 6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private: 7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Retain the instance, i.e. increase reference count. 7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn void Retain(); 7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Release the instance, i.e. decrease reference count. 7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn void Release(); 7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // The object pointer (not owned). 7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject object_; 7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // The reference count of this object 8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int* ref_count_; 8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}; 8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif 8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// ObjectPool template class. This class keeps track of C++ instances that are 8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// coupled to Java objects. This is done by using an "id" field in the Java 8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// object, which is then mapped to the correct instance here. It should not be 8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// necessary to use this class directly. Instead, the convenience functions 8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// below can be used. 9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<class T> 9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennclass ObjectPool { 9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn public: 9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Create a new ObjectPool for a specific object type. Pass the path to the 9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Java equivalent class of the C++ class, and the name of the java member 9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // field that will store the object's ID. 9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static void Setup(const std::string& jclass_name, 9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const std::string& id_fld_name) { 9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn instance_ = new ObjectPool<T>(jclass_name, id_fld_name); 9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Return the shared instance to this type's pool. 10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static ObjectPool* Instance() { 10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return instance_; 10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Delete this type's pool. 10765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static void TearDown() { 10865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete instance_; 10965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 11065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 11165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Register a new C++ object with the pool. This does not affect the Java 11265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // layer. Use WrapObject() instead to perform the necessary Java-side 11365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // assignments. Pass true to owns if the object pool owns the object. 11465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int RegisterObject(T* object, bool owns) { 11565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const int id = next_id_; 11665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn objects_[id] = object; 11765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn owns_[id] = owns; 11865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ++next_id_; 11965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return id; 12065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Return the object in the pool with the specified ID. 12365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn T* ObjectWithID(int obj_id) const { 12465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn typename CObjMap::const_iterator iter = objects_.find(obj_id); 12565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return iter == objects_.end() ? NULL : iter->second; 12665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 12765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 12865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Get the ID of a Java object. This ID can be used to look-up the C++ 12965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // object. 13065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int GetObjectID(JNIEnv* env, jobject j_object) { 13165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass cls = env->GetObjectClass(j_object); 13265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I"); 13365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const int result = env->GetIntField(j_object, id_field); 13465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->DeleteLocalRef(cls); 13565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 13665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 13765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 13865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Take a C++ object and wrap it with a given Java object. This will 13965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // essentially set the ID member of the Java object to the ID of the C++ 14065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // object. Pass true to owns if the object pool owns the object. 14165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool WrapObject(T* c_object, JNIEnv* env, jobject j_object, bool owns) { 14265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const int id = RegisterObject(c_object, owns); 14365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass cls = env->GetObjectClass(j_object); 14465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I"); 14565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->SetIntField(j_object, id_field, id); 14665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->DeleteLocalRef(cls); 14765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return true; 14865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 14965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 15065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Remove the object with the given ID from this pool, and delete it. This 15165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // does not affect the Java layer. 15265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn bool DeleteObjectWithID(int obj_id) { 15365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn typename CObjMap::iterator iter = objects_.find(obj_id); 15465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const bool found = iter != objects_.end(); 15565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (found) { 15665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (owns_[obj_id]) 15765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn delete iter->second; 15865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn objects_.erase(iter); 15965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return found; 16165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 16265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 16365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // Instantiates a new java object for this class. The Java class must have 16465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn // a default constructor for this to succeed. 16565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject CreateJavaObject(JNIEnv* env) { 16665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jclass cls = env->FindClass(jclass_name_.c_str()); 16765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jmethodID constructor = env->GetMethodID( 16865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn cls, 16965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "<init>", 17065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn "(Landroid/filterfw/core/NativeAllocatorTag;)V"); 17165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject result = env->NewObject(cls, constructor, JNI_NULL); 17265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn env->DeleteLocalRef(cls); 17365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 17465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 17665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int GetObjectCount() const { 17765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return objects_.size(); 17865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 17965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const std::string& GetJavaClassName() const { 18165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return jclass_name_; 18265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 18365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 18465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn private: 18565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn explicit ObjectPool(const std::string& jclass_name, 18665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const std::string& id_fld_name) 18765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : jclass_name_(jclass_name), 18865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn id_field_name_(id_fld_name), 18965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn next_id_(0) { } 19065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 19165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn typedef std::hash_map<int, T*> CObjMap; 19265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn typedef std::hash_map<int, bool> FlagMap; 19365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn static ObjectPool* instance_; 19465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn std::string jclass_name_; 19565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn std::string id_field_name_; 19665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn int next_id_; 19765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn CObjMap objects_; 19865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn FlagMap owns_; 19965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn DISALLOW_COPY_AND_ASSIGN(ObjectPool); 20165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn}; 20265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T> ObjectPool<T>* ObjectPool<T>::instance_ = NULL; 20465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convenience Functions /////////////////////////////////////////////////////// 20665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 20765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// This function "links" the C++ instance and the Java instance, so that they 20865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// can be mapped to one another. This must be called for every C++ instance 20965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// which is wrapped by a Java front-end interface. Pass true to owns, if the 21065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Java layer should own the object. 21165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T> 21265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool WrapObjectInJava(T* c_object, JNIEnv* env, jobject j_object, bool owns) { 21365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ObjectPool<T>* pool = ObjectPool<T>::Instance(); 21465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return pool ? pool->WrapObject(c_object, env, j_object, owns) : false; 21565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 21665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 21765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Creates a new Java instance, which wraps the passed C++ instance. Returns 21865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// the wrapped object or JNI_NULL if there was an error. Pass true to owns, if 21965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// the Java layer should own the object. 22065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T> 22165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjobject WrapNewObjectInJava(T* c_object, JNIEnv* env, bool owns) { 22265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ObjectPool<T>* pool = ObjectPool<T>::Instance(); 22365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (pool) { 22465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn jobject result = pool->CreateJavaObject(env); 22565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn if (WrapObjectInJava(c_object, env, result, owns)) 22665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return result; 22765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn } 22865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return JNI_NULL; 22965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 23065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 23165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Use ConvertFromJava to obtain a C++ instance given a Java object. This 23265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// instance must have been wrapped in Java using the WrapObjectInJava() 23365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// function. 23465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T> 23565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennT* ConvertFromJava(JNIEnv* env, jobject j_object) { 23665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ObjectPool<T>* pool = ObjectPool<T>::Instance(); 23765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return pool && j_object 23865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ? pool->ObjectWithID(pool->GetObjectID(env, j_object)) 23965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : NULL; 24065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 24165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 24265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Delete the native object given a Java instance. This should be called from 24365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// the Java object's finalizer. 24465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renntemplate<typename T> 24565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool DeleteNativeObject(JNIEnv* env, jobject j_object) { 24665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ObjectPool<T>* pool = ObjectPool<T>::Instance(); 24765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn return pool && j_object 24865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn ? pool->DeleteObjectWithID(pool->GetObjectID(env, j_object)) 24965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn : false; 25065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn} 25165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#if 0 25365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Get the current JNI VM, or NULL if there is no current VM 25465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennJavaVM* GetCurrentJavaVM(); 25565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 25665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Get the current JNI environment, or NULL if this is not a JNI thread 25765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennJNIEnv* GetCurrentJNIEnv(); 25865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif 25965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert C++ boolean to Java boolean. 26165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjboolean ToJBool(bool value); 26265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert Java boolean to C++ boolean. 26465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool ToCppBool(jboolean value); 26565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert Java String to C++ string. 26765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjstring ToJString(JNIEnv* env, const std::string& value); 26865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 26965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert C++ string to Java String. 27065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennstd::string ToCppString(JNIEnv* env, jstring value); 27165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert Java object to a (C) Value object. 27365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius RennValue ToCValue(JNIEnv* env, jobject object); 27465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Convert a (C) Value object to a Java object. 27665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennjobject ToJObject(JNIEnv* env, const Value& value); 27765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 27865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// Returns true, iff the passed object is an instance of the class specified 27965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn// by its fully qualified class name. 28065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennbool IsJavaInstanceOf(JNIEnv* env, jobject object, 28165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn const std::string& class_name); 28265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn 28365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#endif // ANDROID_FILTERFW_JNI_JNI_UTIL_H 284