Add back the work-arounds for broken apps that assume JNI uses direct references.
Note that we'll need to add support for this to jni_compiler too.
Change-Id: I7e31ab4314ba913cde4629544addd0aad9a89b3b
diff --git a/src/scoped_jni_thread_state.h b/src/scoped_jni_thread_state.h
new file mode 100644
index 0000000..dd39cc3
--- /dev/null
+++ b/src/scoped_jni_thread_state.h
@@ -0,0 +1,55 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+// Author: enh@google.com (Elliott Hughes)
+
+#include "jni_internal.h"
+
+namespace art {
+
+// Entry/exit processing for all JNI calls.
+//
+// This performs the necessary thread state switching, lets us amortize the
+// cost of working out the current thread, and lets us check (and repair) apps
+// that are using a JNIEnv on the wrong thread.
+class ScopedJniThreadState {
+ public:
+ explicit ScopedJniThreadState(JNIEnv* env)
+ : env_(reinterpret_cast<JNIEnvExt*>(env)) {
+ self_ = ThreadForEnv(env);
+ self_->SetState(Thread::kRunnable);
+ }
+
+ ~ScopedJniThreadState() {
+ self_->SetState(Thread::kNative);
+ }
+
+ JNIEnvExt* Env() {
+ return env_;
+ }
+
+ Thread* Self() {
+ return self_;
+ }
+
+ JavaVMExt* Vm() {
+ return env_->vm;
+ }
+
+ private:
+ static Thread* ThreadForEnv(JNIEnv* env) {
+ JNIEnvExt* full_env(reinterpret_cast<JNIEnvExt*>(env));
+ Thread* env_self = full_env->self;
+ Thread* self = full_env->work_around_app_jni_bugs ? Thread::Current() : env_self;
+ if (self != env_self) {
+ LOG(ERROR) << "JNI ERROR: JNIEnv for " << *env_self
+ << " used on " << *self;
+ // TODO: dump stack
+ }
+ return self;
+ }
+
+ JNIEnvExt* env_;
+ Thread* self_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedJniThreadState);
+};
+
+} // namespace art