Fix emulator build error
[platform/framework/web/chromium-efl.git] / base / android / java_exception_reporter.cc
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/android/java_exception_reporter.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/base_jni/JavaExceptionReporter_jni.h"
11 #include "base/debug/dump_without_crashing.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/lazy_instance.h"
15
16 using base::android::JavaParamRef;
17 using base::android::JavaRef;
18
19 namespace base {
20 namespace android {
21
22 namespace {
23
24 void (*g_java_exception_callback)(const char*);
25
26 using JavaExceptionFilter =
27     base::RepeatingCallback<bool(const JavaRef<jthrowable>&)>;
28
29 LazyInstance<JavaExceptionFilter>::Leaky g_java_exception_filter =
30     LAZY_INSTANCE_INITIALIZER;
31
32 }  // namespace
33
34 void InitJavaExceptionReporter() {
35   JNIEnv* env = base::android::AttachCurrentThread();
36   // Since JavaExceptionReporter#installHandler will chain through to the
37   // default handler, the default handler should cause a crash as if it's a
38   // normal java exception. Prefer to crash the browser process in java rather
39   // than native since for webview, the embedding app may have installed its
40   // own JavaExceptionReporter handler and would expect it to be called.
41   constexpr bool crash_after_report = false;
42   SetJavaExceptionFilter(
43       base::BindRepeating([](const JavaRef<jthrowable>&) { return true; }));
44   Java_JavaExceptionReporter_installHandler(env, crash_after_report);
45 }
46
47 void InitJavaExceptionReporterForChildProcess() {
48   JNIEnv* env = base::android::AttachCurrentThread();
49   constexpr bool crash_after_report = true;
50   SetJavaExceptionFilter(
51       base::BindRepeating([](const JavaRef<jthrowable>&) { return true; }));
52   Java_JavaExceptionReporter_installHandler(env, crash_after_report);
53 }
54
55 void SetJavaExceptionFilter(JavaExceptionFilter java_exception_filter) {
56   g_java_exception_filter.Get() = std::move(java_exception_filter);
57 }
58
59 void SetJavaExceptionCallback(void (*callback)(const char*)) {
60   DCHECK(!g_java_exception_callback);
61   g_java_exception_callback = callback;
62 }
63
64 void SetJavaException(const char* exception) {
65   // No need to print exception because they are already logged via
66   // env->ExceptionDescribe() within jni_android.cc.
67   if (g_java_exception_callback) {
68     g_java_exception_callback(exception);
69   }
70 }
71
72 void JNI_JavaExceptionReporter_ReportJavaException(
73     JNIEnv* env,
74     jboolean crash_after_report,
75     const JavaParamRef<jthrowable>& e) {
76   std::string exception_info = base::android::GetJavaExceptionInfo(env, e);
77   bool should_report_exception = g_java_exception_filter.Get().Run(e);
78   if (should_report_exception) {
79     SetJavaException(exception_info.c_str());
80   }
81   if (crash_after_report) {
82     LOG(ERROR) << exception_info;
83     LOG(FATAL) << "Uncaught exception";
84   }
85   if (should_report_exception) {
86     base::debug::DumpWithoutCrashing();
87     SetJavaException(nullptr);
88   }
89 }
90
91 void JNI_JavaExceptionReporter_ReportJavaStackTrace(
92     JNIEnv* env,
93     const JavaParamRef<jstring>& stack_trace) {
94   SetJavaException(ConvertJavaStringToUTF8(stack_trace).c_str());
95   base::debug::DumpWithoutCrashing();
96   SetJavaException(nullptr);
97 }
98
99 }  // namespace android
100 }  // namespace base