/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nativehelper/JniInvocation.h"

#include <string>

#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

#define LOG_TAG "JniInvocation"
#include <log/log.h>

#if defined(__ANDROID__)
#include <sys/system_properties.h>
#elif defined(_WIN32)
#include <android-base/errors.h>
#endif

#include "JniConstants.h"

namespace {

template <typename T>
void UNUSED(const T&) {}

bool IsDebuggable() {
#ifdef __ANDROID__
  char debuggable[PROP_VALUE_MAX] = {0};
  __system_property_get("ro.debuggable", debuggable);
  return strcmp(debuggable, "1") == 0;
#else
  return false;
#endif
}

int GetLibrarySystemProperty(char* buffer) {
#ifdef __ANDROID__
  return __system_property_get("persist.sys.dalvik.vm.lib.2", buffer);
#else
  UNUSED(buffer);
  return 0;
#endif
}

#ifdef _WIN32
#define FUNC_POINTER FARPROC
#else
#define FUNC_POINTER void*
#endif

void* OpenLibrary(const char* filename) {
#ifdef _WIN32
  return LoadLibrary(filename);
#else
  // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.
  // This is due to the fact that it is possible that some threads might have yet to finish
  // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is
  // unloaded.
  const int kDlopenFlags = RTLD_NOW | RTLD_NODELETE;
  return dlopen(filename, kDlopenFlags);
#endif
}

int CloseLibrary(void* handle) {
#ifdef _WIN32
  return FreeLibrary(static_cast<HMODULE>(handle));
#else
  return dlclose(handle);
#endif
}

FUNC_POINTER GetSymbol(void* handle, const char* symbol) {
#ifdef _WIN32
  return GetProcAddress(static_cast<HMODULE>(handle), symbol);
#else
  return dlsym(handle, symbol);
#endif
}

std::string GetError() {
#ifdef _WIN32
  return android::base::SystemErrorCodeToString(GetLastError());
#else
  return std::string(dlerror());
#endif
}

}  // namespace

struct JniInvocationImpl final {
 public:
  JniInvocationImpl();
  ~JniInvocationImpl();

  bool Init(const char* library);

  static const char* GetLibrary(const char* library,
                                char* buffer,
                                bool (*is_debuggable)() = IsDebuggable,
                                int (*get_library_system_property)(char* buffer) = GetLibrarySystemProperty);

  static JniInvocationImpl& GetJniInvocation();

  jint JNI_GetDefaultJavaVMInitArgs(void* vmargs);
  jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args);
  jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count);

 private:
  JniInvocationImpl(const JniInvocationImpl&) = delete;
  JniInvocationImpl& operator=(const JniInvocationImpl&) = delete;

  bool FindSymbol(FUNC_POINTER* pointer, const char* symbol);

  static JniInvocationImpl* jni_invocation_;

  // Handle to library opened with dlopen(). Library exports
  // JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM, JNI_GetCreatedJavaVMs.
  void* handle_;
  jint (*JNI_GetDefaultJavaVMInitArgs_)(void*);
  jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*);
  jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*);

  friend class JNIInvocation_Debuggable_Test;
  friend class JNIInvocation_NonDebuggable_Test;
};

// Check JniInvocationImpl size is same as fields, e.g. no vtable present.
static_assert(sizeof(JniInvocationImpl) == 4 * sizeof(uintptr_t));

JniInvocationImpl* JniInvocationImpl::jni_invocation_ = NULL;

JniInvocationImpl::JniInvocationImpl() :
    handle_(NULL),
    JNI_GetDefaultJavaVMInitArgs_(NULL),
    JNI_CreateJavaVM_(NULL),
    JNI_GetCreatedJavaVMs_(NULL) {
  LOG_ALWAYS_FATAL_IF(jni_invocation_ != NULL, "JniInvocation instance already initialized");
  jni_invocation_ = this;
}

JniInvocationImpl::~JniInvocationImpl() {
  jni_invocation_ = NULL;
  if (handle_ != NULL) {
    CloseLibrary(handle_);
  }
}

static const char* kLibraryFallback = "libart.so";

const char* JniInvocationImpl::GetLibrary(const char* library,
                                          char* buffer,
                                          bool (*is_debuggable)(),
                                          int (*get_library_system_property)(char* buffer)) {
#ifdef __ANDROID__
  const char* default_library;

  if (!is_debuggable()) {
    // Not a debuggable build.
    // Do not allow arbitrary library. Ignore the library parameter. This
    // will also ignore the default library, but initialize to fallback
    // for cleanliness.
    library = kLibraryFallback;
    default_library = kLibraryFallback;
  } else {
    // Debuggable build.
    // Accept the library parameter. For the case it is NULL, load the default
    // library from the system property.
    if (buffer != NULL) {
      if (get_library_system_property(buffer) > 0) {
        default_library = buffer;
      } else {
        default_library = kLibraryFallback;
      }
    } else {
      // No buffer given, just use default fallback.
      default_library = kLibraryFallback;
    }
  }
#else
  UNUSED(buffer);
  UNUSED(is_debuggable);
  UNUSED(get_library_system_property);
  const char* default_library = kLibraryFallback;
#endif
  if (library == NULL) {
    library = default_library;
  }

  return library;
}

bool JniInvocationImpl::Init(const char* library) {
#ifdef __ANDROID__
  char buffer[PROP_VALUE_MAX];
#else
  char* buffer = NULL;
#endif
  library = GetLibrary(library, buffer);
  handle_ = OpenLibrary(library);
  if (handle_ == NULL) {
    if (strcmp(library, kLibraryFallback) == 0) {
      // Nothing else to try.
      ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
      return false;
    }
    // Note that this is enough to get something like the zygote
    // running, we can't property_set here to fix this for the future
    // because we are root and not the system user. See
    // RuntimeInit.commonInit for where we fix up the property to
    // avoid future fallbacks. http://b/11463182
    ALOGW("Falling back from %s to %s after dlopen error: %s",
          library, kLibraryFallback, GetError().c_str());
    library = kLibraryFallback;
    handle_ = OpenLibrary(library);
    if (handle_ == NULL) {
      ALOGE("Failed to dlopen %s: %s", library, GetError().c_str());
      return false;
    }
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_GetDefaultJavaVMInitArgs_),
                  "JNI_GetDefaultJavaVMInitArgs")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_CreateJavaVM_),
                  "JNI_CreateJavaVM")) {
    return false;
  }
  if (!FindSymbol(reinterpret_cast<FUNC_POINTER*>(&JNI_GetCreatedJavaVMs_),
                  "JNI_GetCreatedJavaVMs")) {
    return false;
  }
  return true;
}

jint JniInvocationImpl::JNI_GetDefaultJavaVMInitArgs(void* vmargs) {
  return JNI_GetDefaultJavaVMInitArgs_(vmargs);
}

jint JniInvocationImpl::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}

jint JniInvocationImpl::JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
  return JNI_GetCreatedJavaVMs_(vms, size, vm_count);
}

bool JniInvocationImpl::FindSymbol(FUNC_POINTER* pointer, const char* symbol) {
  *pointer = GetSymbol(handle_, symbol);
  if (*pointer == NULL) {
    ALOGE("Failed to find symbol %s: %s\n", symbol, GetError().c_str());
    CloseLibrary(handle_);
    handle_ = NULL;
    return false;
  }
  return true;
}

JniInvocationImpl& JniInvocationImpl::GetJniInvocation() {
  LOG_ALWAYS_FATAL_IF(jni_invocation_ == NULL,
                      "Failed to create JniInvocation instance before using JNI invocation API");
  return *jni_invocation_;
}

jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {
  return JniInvocationImpl::GetJniInvocation().JNI_GetDefaultJavaVMInitArgs(vm_args);
}

jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  // Ensure any cached heap objects from previous VM instances are
  // invalidated. There is no notification here that a VM is destroyed. These
  // cached objects limit us to one VM instance per process.
  JniConstants::Uninitialize();
  return JniInvocationImpl::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}

jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count) {
  return JniInvocationImpl::GetJniInvocation().JNI_GetCreatedJavaVMs(vms, size, vm_count);
}

const char* JniInvocation::GetLibrary(const char* library,
                                      char* buffer,
                                      bool (*is_debuggable)(),
                                      int (*get_library_system_property)(char* buffer)) {
  return JniInvocationImpl::GetLibrary(library, buffer, is_debuggable, get_library_system_property);
}

JniInvocationImpl* JniInvocationCreate() {
  return new JniInvocationImpl();
}

void JniInvocationDestroy(JniInvocationImpl* instance) {
  delete instance;
}

int JniInvocationInit(JniInvocationImpl* instance, const char* library) {
  return instance->Init(library) ? 1 : 0;
}

const char* JniInvocationGetLibrary(const char* library, char* buffer) {
  return JniInvocationImpl::GetLibrary(library, buffer);
}
