1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/android/java/jni_helper.h"
7 #include "base/android/jni_android.h"
8 #include "base/at_exit.h"
9 #include "base/logging.h"
10 #include "testing/gtest/include/gtest/gtest.h"
16 const char kJavaLangObject
[] = "java/lang/Object";
17 const char kGetClass
[] = "getClass";
18 const char kToString
[] = "toString";
19 const char kReturningJavaLangClass
[] = "()Ljava/lang/Class;";
20 const char kReturningJavaLangString
[] = "()Ljava/lang/String;";
22 const char* g_last_method
;
23 const char* g_last_jni_signature
;
24 jmethodID g_last_method_id
;
26 const JNINativeInterface
* g_previous_functions
;
28 jmethodID
GetMethodIDWrapper(JNIEnv
* env
, jclass clazz
, const char* method
,
29 const char* jni_signature
) {
30 g_last_method
= method
;
31 g_last_jni_signature
= jni_signature
;
32 g_last_method_id
= g_previous_functions
->GetMethodID(env
, clazz
, method
,
34 return g_last_method_id
;
39 class JNIAndroidTest
: public testing::Test
{
41 void SetUp() override
{
42 JNIEnv
* env
= base::android::AttachCurrentThread();
43 g_previous_functions
= env
->functions
;
44 hooked_functions
= *g_previous_functions
;
45 env
->functions
= &hooked_functions
;
46 hooked_functions
.GetMethodID
= &GetMethodIDWrapper
;
49 void TearDown() override
{
50 JNIEnv
* env
= base::android::AttachCurrentThread();
51 env
->functions
= g_previous_functions
;
57 g_last_jni_signature
= 0;
58 g_last_method_id
= NULL
;
60 // Needed to cleanup the cached method map in the implementation between
61 // runs (e.g. if using --gtest_repeat)
62 base::ShadowingAtExitManager exit_manager
;
63 // From JellyBean release, the instance of this struct provided in JNIEnv is
64 // read-only, so we deep copy it to allow individual functions to be hooked.
65 JNINativeInterface hooked_functions
;
68 TEST_F(JNIAndroidTest
, GetMethodIDFromClassNameCaching
) {
69 JNIEnv
* env
= base::android::AttachCurrentThread();
72 jmethodID id1
= GetMethodIDFromClassName(env
, kJavaLangObject
, kGetClass
,
73 kReturningJavaLangClass
);
74 EXPECT_STREQ(kGetClass
, g_last_method
);
75 EXPECT_STREQ(kReturningJavaLangClass
, g_last_jni_signature
);
76 EXPECT_EQ(g_last_method_id
, id1
);
79 jmethodID id2
= GetMethodIDFromClassName(env
, kJavaLangObject
, kGetClass
,
80 kReturningJavaLangClass
);
81 EXPECT_STREQ(0, g_last_method
);
82 EXPECT_STREQ(0, g_last_jni_signature
);
83 EXPECT_EQ(NULL
, g_last_method_id
);
87 jmethodID id3
= GetMethodIDFromClassName(env
, kJavaLangObject
, kToString
,
88 kReturningJavaLangString
);
89 EXPECT_STREQ(kToString
, g_last_method
);
90 EXPECT_STREQ(kReturningJavaLangString
, g_last_jni_signature
);
91 EXPECT_EQ(g_last_method_id
, id3
);
94 } // namespace content