xref: /aosp_15_r20/external/cronet/base/android/jni_android_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/android/jni_android.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker #include <string>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/android/java_exception_reporter.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/at_exit.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/base_unittest_support_jni/JniAndroidTestUtils_jni.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
20*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker using ::testing::Eq;
23*6777b538SAndroid Build Coastguard Worker using ::testing::Optional;
24*6777b538SAndroid Build Coastguard Worker using ::testing::StartsWith;
25*6777b538SAndroid Build Coastguard Worker 
26*6777b538SAndroid Build Coastguard Worker namespace base {
27*6777b538SAndroid Build Coastguard Worker namespace android {
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker namespace {
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker class JniAndroidExceptionTestContext final {
32*6777b538SAndroid Build Coastguard Worker  public:
JniAndroidExceptionTestContext()33*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext() {
34*6777b538SAndroid Build Coastguard Worker     CHECK(instance == nullptr);
35*6777b538SAndroid Build Coastguard Worker     instance = this;
36*6777b538SAndroid Build Coastguard Worker     SetJavaExceptionCallback(CapturingExceptionCallback);
37*6777b538SAndroid Build Coastguard Worker     g_log_fatal_callback_for_testing = CapturingLogFatalCallback;
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker 
~JniAndroidExceptionTestContext()40*6777b538SAndroid Build Coastguard Worker   ~JniAndroidExceptionTestContext() {
41*6777b538SAndroid Build Coastguard Worker     g_log_fatal_callback_for_testing = nullptr;
42*6777b538SAndroid Build Coastguard Worker     SetJavaExceptionCallback(prev_exception_callback_);
43*6777b538SAndroid Build Coastguard Worker     env->ExceptionClear();
44*6777b538SAndroid Build Coastguard Worker     Java_JniAndroidTestUtils_restoreGlobalExceptionHandler(env);
45*6777b538SAndroid Build Coastguard Worker     instance = nullptr;
46*6777b538SAndroid Build Coastguard Worker   }
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker  private:
CapturingLogFatalCallback(const char * message)49*6777b538SAndroid Build Coastguard Worker   static void CapturingLogFatalCallback(const char* message) {
50*6777b538SAndroid Build Coastguard Worker     auto* self = instance;
51*6777b538SAndroid Build Coastguard Worker     CHECK(self);
52*6777b538SAndroid Build Coastguard Worker     // Capture only the first one (can be called multiple times due to
53*6777b538SAndroid Build Coastguard Worker     // LOG(FATAL) not terminating).
54*6777b538SAndroid Build Coastguard Worker     if (!self->assertion_message) {
55*6777b538SAndroid Build Coastguard Worker       self->assertion_message = message;
56*6777b538SAndroid Build Coastguard Worker     }
57*6777b538SAndroid Build Coastguard Worker   }
58*6777b538SAndroid Build Coastguard Worker 
CapturingExceptionCallback(const char * message)59*6777b538SAndroid Build Coastguard Worker   static void CapturingExceptionCallback(const char* message) {
60*6777b538SAndroid Build Coastguard Worker     auto* self = instance;
61*6777b538SAndroid Build Coastguard Worker     CHECK(self);
62*6777b538SAndroid Build Coastguard Worker     if (self->throw_in_exception_callback) {
63*6777b538SAndroid Build Coastguard Worker       self->throw_in_exception_callback = false;
64*6777b538SAndroid Build Coastguard Worker       Java_JniAndroidTestUtils_throwRuntimeException(self->env);
65*6777b538SAndroid Build Coastguard Worker     } else if (self->throw_oom_in_exception_callback) {
66*6777b538SAndroid Build Coastguard Worker       self->throw_oom_in_exception_callback = false;
67*6777b538SAndroid Build Coastguard Worker       Java_JniAndroidTestUtils_throwOutOfMemoryError(self->env);
68*6777b538SAndroid Build Coastguard Worker     } else {
69*6777b538SAndroid Build Coastguard Worker       self->last_java_exception = message;
70*6777b538SAndroid Build Coastguard Worker     }
71*6777b538SAndroid Build Coastguard Worker   }
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   static JniAndroidExceptionTestContext* instance;
74*6777b538SAndroid Build Coastguard Worker   const JavaExceptionCallback prev_exception_callback_ =
75*6777b538SAndroid Build Coastguard Worker       GetJavaExceptionCallback();
76*6777b538SAndroid Build Coastguard Worker 
77*6777b538SAndroid Build Coastguard Worker  public:
78*6777b538SAndroid Build Coastguard Worker   const raw_ptr<JNIEnv> env = base::android::AttachCurrentThread();
79*6777b538SAndroid Build Coastguard Worker   bool throw_in_exception_callback = false;
80*6777b538SAndroid Build Coastguard Worker   bool throw_oom_in_exception_callback = false;
81*6777b538SAndroid Build Coastguard Worker   std::optional<std::string> assertion_message;
82*6777b538SAndroid Build Coastguard Worker   std::optional<std::string> last_java_exception;
83*6777b538SAndroid Build Coastguard Worker };
84*6777b538SAndroid Build Coastguard Worker 
85*6777b538SAndroid Build Coastguard Worker JniAndroidExceptionTestContext* JniAndroidExceptionTestContext::instance =
86*6777b538SAndroid Build Coastguard Worker     nullptr;
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker std::atomic<jmethodID> g_atomic_id(nullptr);
LazyMethodIDCall(JNIEnv * env,jclass clazz,int p)89*6777b538SAndroid Build Coastguard Worker int LazyMethodIDCall(JNIEnv* env, jclass clazz, int p) {
90*6777b538SAndroid Build Coastguard Worker   jmethodID id = base::android::MethodID::LazyGet<
91*6777b538SAndroid Build Coastguard Worker       base::android::MethodID::TYPE_STATIC>(
92*6777b538SAndroid Build Coastguard Worker       env, clazz,
93*6777b538SAndroid Build Coastguard Worker       "abs",
94*6777b538SAndroid Build Coastguard Worker       "(I)I",
95*6777b538SAndroid Build Coastguard Worker       &g_atomic_id);
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   return env->CallStaticIntMethod(clazz, id, p);
98*6777b538SAndroid Build Coastguard Worker }
99*6777b538SAndroid Build Coastguard Worker 
MethodIDCall(JNIEnv * env,jclass clazz,jmethodID id,int p)100*6777b538SAndroid Build Coastguard Worker int MethodIDCall(JNIEnv* env, jclass clazz, jmethodID id, int p) {
101*6777b538SAndroid Build Coastguard Worker   return env->CallStaticIntMethod(clazz, id, p);
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker }  // namespace
105*6777b538SAndroid Build Coastguard Worker 
TEST(JNIAndroidMicrobenchmark,MethodId)106*6777b538SAndroid Build Coastguard Worker TEST(JNIAndroidMicrobenchmark, MethodId) {
107*6777b538SAndroid Build Coastguard Worker   JNIEnv* env = AttachCurrentThread();
108*6777b538SAndroid Build Coastguard Worker   ScopedJavaLocalRef<jclass> clazz(GetClass(env, "java/lang/Math"));
109*6777b538SAndroid Build Coastguard Worker   base::Time start_lazy = base::Time::Now();
110*6777b538SAndroid Build Coastguard Worker   int o = 0;
111*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 1024; ++i)
112*6777b538SAndroid Build Coastguard Worker     o += LazyMethodIDCall(env, clazz.obj(), i);
113*6777b538SAndroid Build Coastguard Worker   base::Time end_lazy = base::Time::Now();
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   jmethodID id = g_atomic_id;
116*6777b538SAndroid Build Coastguard Worker   base::Time start = base::Time::Now();
117*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i < 1024; ++i)
118*6777b538SAndroid Build Coastguard Worker     o += MethodIDCall(env, clazz.obj(), id, i);
119*6777b538SAndroid Build Coastguard Worker   base::Time end = base::Time::Now();
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   // On a Galaxy Nexus, results were in the range of:
122*6777b538SAndroid Build Coastguard Worker   // JNI LazyMethodIDCall (us) 1984
123*6777b538SAndroid Build Coastguard Worker   // JNI MethodIDCall (us) 1861
124*6777b538SAndroid Build Coastguard Worker   LOG(ERROR) << "JNI LazyMethodIDCall (us) " <<
125*6777b538SAndroid Build Coastguard Worker       base::TimeDelta(end_lazy - start_lazy).InMicroseconds();
126*6777b538SAndroid Build Coastguard Worker   LOG(ERROR) << "JNI MethodIDCall (us) " <<
127*6777b538SAndroid Build Coastguard Worker       base::TimeDelta(end - start).InMicroseconds();
128*6777b538SAndroid Build Coastguard Worker   LOG(ERROR) << "JNI " << o;
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidTest,GetJavaStackTraceIfPresent_Normal)131*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidTest, GetJavaStackTraceIfPresent_Normal) {
132*6777b538SAndroid Build Coastguard Worker   // The main thread should always have Java frames in it.
133*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(GetJavaStackTraceIfPresent(), StartsWith("\tat"));
134*6777b538SAndroid Build Coastguard Worker }
135*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidTest,GetJavaStackTraceIfPresent_NoEnv)136*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidTest, GetJavaStackTraceIfPresent_NoEnv) {
137*6777b538SAndroid Build Coastguard Worker   class HelperThread : public Thread {
138*6777b538SAndroid Build Coastguard Worker    public:
139*6777b538SAndroid Build Coastguard Worker     HelperThread()
140*6777b538SAndroid Build Coastguard Worker         : Thread("TestThread"), java_stack_1_("X"), java_stack_2_("X") {}
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker     void Init() override {
143*6777b538SAndroid Build Coastguard Worker       // Test without a JNIEnv.
144*6777b538SAndroid Build Coastguard Worker       java_stack_1_ = GetJavaStackTraceIfPresent();
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker       // Test with a JNIEnv but no Java frames.
147*6777b538SAndroid Build Coastguard Worker       AttachCurrentThread();
148*6777b538SAndroid Build Coastguard Worker       java_stack_2_ = GetJavaStackTraceIfPresent();
149*6777b538SAndroid Build Coastguard Worker     }
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker     std::string java_stack_1_;
152*6777b538SAndroid Build Coastguard Worker     std::string java_stack_2_;
153*6777b538SAndroid Build Coastguard Worker   };
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker   HelperThread t;
156*6777b538SAndroid Build Coastguard Worker   t.StartAndWaitForTesting();
157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(t.java_stack_1_, "");
158*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(t.java_stack_2_, "");
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidTest,GetJavaStackTraceIfPresent_PendingException)161*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidTest, GetJavaStackTraceIfPresent_PendingException) {
162*6777b538SAndroid Build Coastguard Worker   JNIEnv* env = base::android::AttachCurrentThread();
163*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeExceptionUnchecked(env);
164*6777b538SAndroid Build Coastguard Worker   std::string result = GetJavaStackTraceIfPresent();
165*6777b538SAndroid Build Coastguard Worker   env->ExceptionClear();
166*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, kUnableToGetStackTraceMessage);
167*6777b538SAndroid Build Coastguard Worker }
168*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidTest,GetJavaStackTraceIfPresent_OutOfMemoryError)169*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidTest, GetJavaStackTraceIfPresent_OutOfMemoryError) {
170*6777b538SAndroid Build Coastguard Worker   JNIEnv* env = base::android::AttachCurrentThread();
171*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setSimulateOomInSanitizedStacktrace(env, true);
172*6777b538SAndroid Build Coastguard Worker   std::string result = GetJavaStackTraceIfPresent();
173*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setSimulateOomInSanitizedStacktrace(env, false);
174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(result, "");
175*6777b538SAndroid Build Coastguard Worker }
176*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInNative)177*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInNative) {
178*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
179*6777b538SAndroid Build Coastguard Worker   test::ScopedFeatureList feature_list;
180*6777b538SAndroid Build Coastguard Worker   feature_list.InitFromCommandLine("", "HandleJniExceptionsInJava");
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   // Do not call setGlobalExceptionHandlerAsNoOp().
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
185*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
186*6777b538SAndroid Build Coastguard Worker               Optional(StartsWith("java.lang.RuntimeException")));
187*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message, Optional(Eq(kUncaughtExceptionMessage)));
188*6777b538SAndroid Build Coastguard Worker }
189*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_NoOpHandler)190*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_NoOpHandler) {
191*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
192*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerAsNoOp(ctx.env);
193*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
196*6777b538SAndroid Build Coastguard Worker               Optional(StartsWith("java.lang.RuntimeException")));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message,
198*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kUncaughtExceptionHandlerFailedMessage)));
199*6777b538SAndroid Build Coastguard Worker }
200*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_ThrowingHandler)201*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_ThrowingHandler) {
202*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
203*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerToThrow(ctx.env);
204*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
207*6777b538SAndroid Build Coastguard Worker               Optional(StartsWith("java.lang.IllegalStateException")));
208*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message,
209*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kUncaughtExceptionHandlerFailedMessage)));
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_OomThrowingHandler)212*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_OomThrowingHandler) {
213*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
214*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerToThrowOom(ctx.env);
215*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   // Should still report the original exception when the global exception
218*6777b538SAndroid Build Coastguard Worker   // handler throws an OutOfMemoryError.
219*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
220*6777b538SAndroid Build Coastguard Worker               Optional(StartsWith("java.lang.RuntimeException")));
221*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message,
222*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kUncaughtExceptionHandlerFailedMessage)));
223*6777b538SAndroid Build Coastguard Worker }
224*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_OomInGetJavaExceptionInfo)225*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_OomInGetJavaExceptionInfo) {
226*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
227*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerToThrowOom(ctx.env);
228*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setSimulateOomInSanitizedStacktrace(ctx.env, true);
229*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
230*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setSimulateOomInSanitizedStacktrace(ctx.env, false);
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
233*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kOomInGetJavaExceptionInfoMessage)));
234*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message,
235*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kUncaughtExceptionHandlerFailedMessage)));
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_Reentrant)238*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_Reentrant) {
239*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
240*6777b538SAndroid Build Coastguard Worker   // Use the SetJavaException() callback to trigger re-entrancy.
241*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerToThrow(ctx.env);
242*6777b538SAndroid Build Coastguard Worker   ctx.throw_in_exception_callback = true;
243*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception, Optional(Eq(kReetrantExceptionMessage)));
246*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message, Optional(Eq(kReetrantExceptionMessage)));
247*6777b538SAndroid Build Coastguard Worker }
248*6777b538SAndroid Build Coastguard Worker 
TEST(JniAndroidExceptionTest,HandleExceptionInJava_ReentrantOom)249*6777b538SAndroid Build Coastguard Worker TEST(JniAndroidExceptionTest, HandleExceptionInJava_ReentrantOom) {
250*6777b538SAndroid Build Coastguard Worker   JniAndroidExceptionTestContext ctx;
251*6777b538SAndroid Build Coastguard Worker   // Use the SetJavaException() callback to trigger re-entrancy.
252*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_setGlobalExceptionHandlerToThrow(ctx.env);
253*6777b538SAndroid Build Coastguard Worker   ctx.throw_oom_in_exception_callback = true;
254*6777b538SAndroid Build Coastguard Worker   Java_JniAndroidTestUtils_throwRuntimeException(ctx.env);
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.last_java_exception,
257*6777b538SAndroid Build Coastguard Worker               Optional(Eq(kReetrantOutOfMemoryMessage)));
258*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(ctx.assertion_message, Optional(Eq(kReetrantOutOfMemoryMessage)));
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker }  // namespace android
262*6777b538SAndroid Build Coastguard Worker }  // namespace base
263