/*
 * Copyright (C) 2014 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.
 */

// A simple implementation of the native-bridge interface.

#include <dlfcn.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>

#include <jni.h>
#include <nativebridge/native_bridge.h>

#include "base/macros.h"

struct NativeBridgeMethod {
  const char* name;
  const char* signature;
  bool static_method;
  void* fnPtr;
  void* trampoline;
};

static NativeBridgeMethod* find_native_bridge_method(const char *name);
static const android::NativeBridgeRuntimeCallbacks* gNativeBridgeArtCallbacks;

static jint trampoline_JNI_OnLoad(JavaVM* vm, void* reserved) {
  JNIEnv* env = nullptr;
  using FnPtr_t = jint(*)(JavaVM*, void*);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("JNI_OnLoad")->fnPtr);

  vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
  if (env == nullptr) {
    return 0;
  }

  jclass klass = env->FindClass("Main");
  if (klass != nullptr) {
    int i, count1, count2;
    count1 = gNativeBridgeArtCallbacks->getNativeMethodCount(env, klass);
    std::unique_ptr<JNINativeMethod[]> methods(new JNINativeMethod[count1]);
    if (methods == nullptr) {
      return 0;
    }
    count2 = gNativeBridgeArtCallbacks->getNativeMethods(env, klass, methods.get(), count1);
    if (count1 == count2) {
      printf("Test ART callbacks: all JNI function number is %d.\n", count1);
    }

    for (i = 0; i < count1; i++) {
      NativeBridgeMethod* nb_method = find_native_bridge_method(methods[i].name);
      if (nb_method != nullptr) {
        jmethodID mid = nullptr;
        if (nb_method->static_method) {
          mid = env->GetStaticMethodID(klass, methods[i].name, nb_method->signature);
        } else {
          mid = env->GetMethodID(klass, methods[i].name, nb_method->signature);
        }
        if (mid != nullptr) {
          const char* shorty = gNativeBridgeArtCallbacks->getMethodShorty(env, mid);
          if (strcmp(shorty, methods[i].signature) == 0) {
            printf("    name:%s, signature:%s, shorty:%s.\n",
                   methods[i].name, nb_method->signature, shorty);
          }
        }
      }
    }
    methods.release();
  }

  printf("%s called!\n", __FUNCTION__);
  return fnPtr(vm, reserved);
}

static void trampoline_Java_Main_testFindClassOnAttachedNativeThread(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testFindClassOnAttachedNativeThread")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testFindFieldOnAttachedNativeThreadNative(JNIEnv* env,
                                                                           jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testFindFieldOnAttachedNativeThreadNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
                                                                          jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testCallStaticVoidMethodOnSubClassNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static jobject trampoline_Java_Main_testGetMirandaMethodNative(JNIEnv* env, jclass klass) {
  using FnPtr_t = jobject(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testGetMirandaMethodNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testNewStringObject(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testNewStringObject")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testZeroLengthByteBuffers(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testZeroLengthByteBuffers")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static jbyte trampoline_Java_Main_byteMethod(JNIEnv* env, jclass klass, jbyte b1, jbyte b2,
                                             jbyte b3, jbyte b4, jbyte b5, jbyte b6,
                                             jbyte b7, jbyte b8, jbyte b9, jbyte b10) {
  using FnPtr_t = jbyte(*)(JNIEnv*, jclass, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte,
                           jbyte, jbyte);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("byteMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10);
}

static jshort trampoline_Java_Main_shortMethod(JNIEnv* env, jclass klass, jshort s1, jshort s2,
                                               jshort s3, jshort s4, jshort s5, jshort s6,
                                               jshort s7, jshort s8, jshort s9, jshort s10) {
  using FnPtr_t = jshort(*)(JNIEnv*, jclass, jshort, jshort, jshort, jshort, jshort, jshort, jshort,
                            jshort, jshort, jshort);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("shortMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
}

static jboolean trampoline_Java_Main_booleanMethod(JNIEnv* env, jclass klass, jboolean b1,
                                                   jboolean b2, jboolean b3, jboolean b4,
                                                   jboolean b5, jboolean b6, jboolean b7,
                                                   jboolean b8, jboolean b9, jboolean b10) {
  using FnPtr_t = jboolean(*)(JNIEnv*, jclass, jboolean, jboolean, jboolean, jboolean, jboolean,
                              jboolean, jboolean, jboolean, jboolean, jboolean);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("booleanMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10);
}

static jchar trampoline_Java_Main_charMethod(JNIEnv* env, jclass klass, jchar c1, jchar c2,
                                             jchar c3, jchar c4, jchar c5, jchar c6,
                                             jchar c7, jchar c8, jchar c9, jchar c10) {
  using FnPtr_t = jchar(*)(JNIEnv*, jclass, jchar, jchar, jchar, jchar, jchar, jchar, jchar, jchar,
                           jchar, jchar);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("charMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10);
}

// This code is adapted from 004-SignalTest and causes a segfault.
char *go_away_compiler = nullptr;

[[ noreturn ]] static void test_sigaction_handler(int sig ATTRIBUTE_UNUSED,
                                                  siginfo_t* info ATTRIBUTE_UNUSED,
                                                  void* context ATTRIBUTE_UNUSED) {
  printf("Should not reach the test sigaction handler.");
  abort();
}

static void raise_sigsegv() {
#if defined(__arm__) || defined(__i386__) || defined(__aarch64__)
  *go_away_compiler = 'a';
#elif defined(__x86_64__)
  // Cause a SEGV using an instruction known to be 2 bytes long to account for hardcoded jump
  // in the signal handler
  asm volatile("movl $0, %%eax;" "movb %%ah, (%%rax);" : : : "%eax");
#else
  // On other architectures we simulate SEGV.
  kill(getpid(), SIGSEGV);
#endif
}

static jint trampoline_Java_Main_testSignal(JNIEnv*, jclass) {
  // Install the sigaction handler above, which should *not* be reached as the native-bridge
  // handler should be called first. Note: we won't chain at all, if we ever get here, we'll die.
  struct sigaction tmp;
  sigemptyset(&tmp.sa_mask);
  tmp.sa_sigaction = test_sigaction_handler;
#if !defined(__APPLE__)
  tmp.sa_restorer = nullptr;
#endif

  // Test segv
  sigaction(SIGSEGV, &tmp, nullptr);
  raise_sigsegv();

  // Test sigill
  sigaction(SIGILL, &tmp, nullptr);
  kill(getpid(), SIGILL);

#if defined(__BIONIC__)
  // Do the same again, but with sigaction64.
  struct sigaction64 tmp2;
  sigemptyset64(&tmp2.sa_mask);
  tmp2.sa_sigaction = test_sigaction_handler;
#if defined(SA_RESTORER)
  tmp2.sa_restorer = nullptr;
#endif

  sigaction64(SIGSEGV, &tmp2, nullptr);
  sigaction64(SIGILL, &tmp2, nullptr);
#endif

  // Reraise SIGSEGV/SIGILL even on non-bionic, so that the expected output is
  // the same.
  raise_sigsegv();
  kill(getpid(), SIGILL);

  return 1234;
}

// Status of the tricky control path of testSignalHandlerNotReturn.
//
// "kNone" is the default status except testSignalHandlerNotReturn,
// others are used by testSignalHandlerNotReturn.
enum class TestStatus {
  kNone,
  kRaiseFirst,
  kHandleFirst,
  kRaiseSecond,
  kHandleSecond,
};

// State transition helper for testSignalHandlerNotReturn.
class SignalHandlerTestStatus {
 public:
  SignalHandlerTestStatus() : state_(TestStatus::kNone) {
  }

  TestStatus Get() {
    return state_;
  }

  void Reset() {
    Set(TestStatus::kNone);
  }

  void Set(TestStatus state) {
    switch (state) {
      case TestStatus::kNone:
        AssertState(TestStatus::kHandleSecond);
        break;

      case TestStatus::kRaiseFirst:
        AssertState(TestStatus::kNone);
        break;

      case TestStatus::kHandleFirst:
        AssertState(TestStatus::kRaiseFirst);
        break;

      case TestStatus::kRaiseSecond:
        AssertState(TestStatus::kHandleFirst);
        break;

      case TestStatus::kHandleSecond:
        AssertState(TestStatus::kRaiseSecond);
        break;

      default:
        printf("ERROR: unknown state\n");
        abort();
    }

    state_ = state;
  }

 private:
  TestStatus state_;

  void AssertState(TestStatus expected) {
    if (state_ != expected) {
      printf("ERROR: unexpected state, was %d, expected %d\n", state_, expected);
    }
  }
};

static SignalHandlerTestStatus gSignalTestStatus;
// The context is used to jump out from signal handler.
static sigjmp_buf gSignalTestJmpBuf;

// Test whether NativeBridge can receive future signal when its handler doesn't return.
//
// Control path:
//  1. Raise first SIGSEGV in test function.
//  2. Raise another SIGSEGV in NativeBridge's signal handler which is handling
//     the first SIGSEGV.
//  3. Expect that NativeBridge's signal handler invokes again. And jump back
//     to test function in when handling second SIGSEGV.
//  4. Exit test.
//
// NOTE: sigchain should be aware that "special signal handler" may not return.
//       Pay attention if this case fails.
static void trampoline_Java_Main_testSignalHandlerNotReturn(JNIEnv*, jclass) {
  if (gSignalTestStatus.Get() != TestStatus::kNone) {
    printf("ERROR: test already started?\n");
    return;
  }
  printf("start testSignalHandlerNotReturn\n");

  if (sigsetjmp(gSignalTestJmpBuf, 1) == 0) {
    gSignalTestStatus.Set(TestStatus::kRaiseFirst);
    printf("raising first SIGSEGV\n");
    raise_sigsegv();
  } else {
    // jump to here from signal handler when handling second SIGSEGV.
    if (gSignalTestStatus.Get() != TestStatus::kHandleSecond) {
      printf("ERROR: not jump from second SIGSEGV?\n");
      return;
    }
    gSignalTestStatus.Reset();
    printf("back to test from signal handler via siglongjmp(), and done!\n");
  }
}

// Signal handler for testSignalHandlerNotReturn.
// This handler won't return.
static bool NotReturnSignalHandler() {
  if (gSignalTestStatus.Get() == TestStatus::kRaiseFirst) {
    // handling first SIGSEGV
    gSignalTestStatus.Set(TestStatus::kHandleFirst);
    printf("handling first SIGSEGV, will raise another\n");
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGSEGV);
    printf("unblock SIGSEGV in handler\n");
    sigprocmask(SIG_UNBLOCK, &set, nullptr);
    gSignalTestStatus.Set(TestStatus::kRaiseSecond);
    printf("raising second SIGSEGV\n");
    raise_sigsegv();    // raise second SIGSEGV
  } else if (gSignalTestStatus.Get() == TestStatus::kRaiseSecond) {
    // handling second SIGSEGV
    gSignalTestStatus.Set(TestStatus::kHandleSecond);
    printf("handling second SIGSEGV, will jump back to test function\n");
    siglongjmp(gSignalTestJmpBuf, 1);
  }
  printf("ERROR: should not reach here!\n");
  return false;
}

NativeBridgeMethod gNativeBridgeMethods[] = {
  { "JNI_OnLoad", "", true, nullptr,
    reinterpret_cast<void*>(trampoline_JNI_OnLoad) },
  { "booleanMethod", "(ZZZZZZZZZZ)Z", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_booleanMethod) },
  { "byteMethod", "(BBBBBBBBBB)B", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_byteMethod) },
  { "charMethod", "(CCCCCCCCCC)C", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_charMethod) },
  { "shortMethod", "(SSSSSSSSSS)S", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_shortMethod) },
  { "testCallStaticVoidMethodOnSubClassNative", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testCallStaticVoidMethodOnSubClassNative) },
  { "testFindClassOnAttachedNativeThread", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testFindClassOnAttachedNativeThread) },
  { "testFindFieldOnAttachedNativeThreadNative", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testFindFieldOnAttachedNativeThreadNative) },
  { "testGetMirandaMethodNative", "()Ljava/lang/reflect/Method;", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testGetMirandaMethodNative) },
  { "testNewStringObject", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testNewStringObject) },
  { "testZeroLengthByteBuffers", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testZeroLengthByteBuffers) },
  { "testSignal", "()I", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testSignal) },
  { "testSignalHandlerNotReturn", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testSignalHandlerNotReturn) },
};

static NativeBridgeMethod* find_native_bridge_method(const char *name) {
  const char* pname = name;
  if (strncmp(name, "Java_Main_", 10) == 0) {
    pname += 10;
  }

  for (size_t i = 0; i < sizeof(gNativeBridgeMethods) / sizeof(gNativeBridgeMethods[0]); i++) {
    if (strcmp(pname, gNativeBridgeMethods[i].name) == 0) {
      return &gNativeBridgeMethods[i];
    }
  }
  return nullptr;
}

// NativeBridgeCallbacks implementations
extern "C" bool native_bridge_initialize(const android::NativeBridgeRuntimeCallbacks* art_cbs,
                                         const char* app_code_cache_dir,
                                         const char* isa ATTRIBUTE_UNUSED) {
  struct stat st;
  if (app_code_cache_dir != nullptr) {
    if (stat(app_code_cache_dir, &st) == 0) {
      if (!S_ISDIR(st.st_mode)) {
        printf("Code cache is not a directory.\n");
      }
    } else {
      perror("Error when stat-ing the code_cache:");
    }
  }

  if (art_cbs != nullptr) {
    gNativeBridgeArtCallbacks = art_cbs;
    printf("Native bridge initialized.\n");
  }
  return true;
}

extern "C" void* native_bridge_loadLibrary(const char* libpath, int flag) {
  if (strstr(libpath, "libinvalid.so") != nullptr) {
    printf("Was to load 'libinvalid.so', force fail.\n");
    return nullptr;
  }
  size_t len = strlen(libpath);
  char* tmp = new char[len + 10];
  strncpy(tmp, libpath, len);
  tmp[len - 3] = '2';
  tmp[len - 2] = '.';
  tmp[len - 1] = 's';
  tmp[len] = 'o';
  tmp[len + 1] = 0;
  void* handle = dlopen(tmp, flag);
  delete[] tmp;

  if (handle == nullptr) {
    printf("Handle = nullptr!\n");
    printf("Was looking for %s.\n", libpath);
    printf("Error = %s.\n", dlerror());
    char cwd[1024] = {'\0'};
    if (getcwd(cwd, sizeof(cwd)) != nullptr) {
      printf("Current working dir: %s\n", cwd);
    }
  }
  return handle;
}

extern "C" void* native_bridge_getTrampoline(void* handle, const char* name, const char* shorty,
                                             uint32_t len ATTRIBUTE_UNUSED) {
  printf("Getting trampoline for %s with shorty %s.\n", name, shorty);

  // The name here is actually the JNI name, so we can directly do the lookup.
  void* sym = dlsym(handle, name);
  NativeBridgeMethod* method = find_native_bridge_method(name);
  if (method == nullptr)
    return nullptr;
  method->fnPtr = sym;

  return method->trampoline;
}

extern "C" bool native_bridge_isSupported(const char* libpath) {
  printf("Checking for support.\n");

  if (libpath == nullptr) {
    return false;
  }
  // We don't want to hijack javacore. So we should get libarttest...
  return strcmp(libpath, "libjavacore.so") != 0;
}

namespace android {

// Environment values required by the apps running with native bridge.
struct NativeBridgeRuntimeValues {
  const char* os_arch;
  const char* cpu_abi;
  const char* cpu_abi2;
  const char* *supported_abis;
  int32_t abi_count;
};

}  // namespace android

const char* supported_abis[] = {
    "supported1", "supported2", "supported3"
};

const struct android::NativeBridgeRuntimeValues nb_env {
    .os_arch = "os.arch",
    .cpu_abi = "cpu_abi",
    .cpu_abi2 = "cpu_abi2",
    .supported_abis = supported_abis,
    .abi_count = 3
};

extern "C" const struct android::NativeBridgeRuntimeValues* native_bridge_getAppEnv(
    const char* abi) {
  printf("Checking for getEnvValues.\n");

  if (abi == nullptr) {
    return nullptr;
  }

  return &nb_env;
}

// v2 parts.

extern "C" bool native_bridge_isCompatibleWith(uint32_t bridge_version ATTRIBUTE_UNUSED) {
  return true;
}

#if defined(__i386__) || defined(__x86_64__)
#if defined(__APPLE__)
#define ucontext __darwin_ucontext

#if defined(__x86_64__)
// 64 bit mac build.
#define CTX_EIP uc_mcontext->__ss.__rip
#else
// 32 bit mac build.
#define CTX_EIP uc_mcontext->__ss.__eip
#endif

#elif defined(__x86_64__)
// 64 bit linux build.
#define CTX_EIP uc_mcontext.gregs[REG_RIP]
#else
// 32 bit linux build.
#define CTX_EIP uc_mcontext.gregs[REG_EIP]
#endif
#endif

static bool StandardSignalHandler(int sig, siginfo_t* info ATTRIBUTE_UNUSED,
                                     void* context) {
  if (sig == SIGSEGV) {
#if defined(__arm__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
    mc->arm_pc += 2;          // Skip instruction causing segv & sigill.
#elif defined(__aarch64__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
    mc->pc += 4;          // Skip instruction causing segv & sigill.
#elif defined(__i386__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    uc->CTX_EIP += 3;
#elif defined(__x86_64__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    uc->CTX_EIP += 2;
#else
    UNUSED(context);
#endif
  }

  // We handled this...
  return true;
}

// A placeholder special handler, continueing after the faulting location. This code comes from
// 004-SignalTest.
static bool nb_signalhandler(int sig, siginfo_t* info, void* context) {
  printf("NB signal handler with signal %d.\n", sig);

  if (gSignalTestStatus.Get() == TestStatus::kNone) {
    return StandardSignalHandler(sig, info, context);
  } else if (sig == SIGSEGV) {
    return NotReturnSignalHandler();
  } else {
    printf("ERROR: should not reach here!\n");
    return false;
  }
}

static ::android::NativeBridgeSignalHandlerFn native_bridge_getSignalHandler(int signal) {
  // Test segv for already claimed signal, and sigill for not claimed signal
  if ((signal == SIGSEGV) || (signal == SIGILL)) {
    return &nb_signalhandler;
  }
  return nullptr;
}

extern "C" int native_bridge_unloadLibrary(void* handle ATTRIBUTE_UNUSED) {
  printf("dlclose() in native bridge.\n");
  return 0;
}

extern "C" const char* native_bridge_getError() {
  printf("getError() in native bridge.\n");
  return "";
}

extern "C" bool native_bridge_isPathSupported(const char* library_path ATTRIBUTE_UNUSED) {
  printf("Checking for path support in native bridge.\n");
  return false;
}

extern "C" bool native_bridge_initAnonymousNamespace(const char* public_ns_sonames ATTRIBUTE_UNUSED,
                                                     const char* anon_ns_library_path ATTRIBUTE_UNUSED) {
  printf("Initializing anonymous namespace in native bridge.\n");
  return false;
}

extern "C" android::native_bridge_namespace_t*
native_bridge_createNamespace(const char* name ATTRIBUTE_UNUSED,
                              const char* ld_library_path ATTRIBUTE_UNUSED,
                              const char* default_library_path ATTRIBUTE_UNUSED,
                              uint64_t type ATTRIBUTE_UNUSED,
                              const char* permitted_when_isolated_path ATTRIBUTE_UNUSED,
                              android::native_bridge_namespace_t* parent_ns ATTRIBUTE_UNUSED) {
  printf("Creating namespace in native bridge.\n");
  return nullptr;
}

extern "C" bool native_bridge_linkNamespaces(android::native_bridge_namespace_t* from ATTRIBUTE_UNUSED,
                                             android::native_bridge_namespace_t* to ATTRIBUTE_UNUSED,
                                             const char* shared_libs_sonames ATTRIBUTE_UNUSED) {
  printf("Linking namespaces in native bridge.\n");
  return false;
}

extern "C" void* native_bridge_loadLibraryExt(const char* libpath ATTRIBUTE_UNUSED,
                                               int flag ATTRIBUTE_UNUSED,
                                               android::native_bridge_namespace_t* ns ATTRIBUTE_UNUSED) {
    printf("Loading library with Extension in native bridge.\n");
    return nullptr;
}

// "NativeBridgeItf" is effectively an API (it is the name of the symbol that will be loaded
// by the native bridge library).
android::NativeBridgeCallbacks NativeBridgeItf {
  // v1
  .version = 3,
  .initialize = &native_bridge_initialize,
  .loadLibrary = &native_bridge_loadLibrary,
  .getTrampoline = &native_bridge_getTrampoline,
  .isSupported = &native_bridge_isSupported,
  .getAppEnv = &native_bridge_getAppEnv,
  // v2
  .isCompatibleWith = &native_bridge_isCompatibleWith,
  .getSignalHandler = &native_bridge_getSignalHandler,
  // v3
  .unloadLibrary = &native_bridge_unloadLibrary,
  .getError = &native_bridge_getError,
  .isPathSupported = &native_bridge_isPathSupported,
  .initAnonymousNamespace = &native_bridge_initAnonymousNamespace,
  .createNamespace = &native_bridge_createNamespace,
  .linkNamespaces = &native_bridge_linkNamespaces,
  .loadLibraryExt = &native_bridge_loadLibraryExt
};
