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