Index: chromecast/crash/android/crash_handler.cc |
diff --git a/chromecast/crash/android/crash_handler.cc b/chromecast/crash/android/crash_handler.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..07b9de1fb16bbec831ab561abd15caa91bab0338 |
--- /dev/null |
+++ b/chromecast/crash/android/crash_handler.cc |
@@ -0,0 +1,140 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chromecast/crash/android/crash_handler.h" |
+ |
+#include <jni.h> |
+#include <string> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/jni_string.h" |
+#include "base/files/file_path.h" |
+#include "base/lazy_instance.h" |
Lei Zhang
2014/10/06 22:44:25
nit: not used
gunsch
2014/10/09 00:20:55
Done.
|
+#include "base/logging.h" |
+#include "breakpad/src/client/linux/handler/exception_handler.h" |
+#include "breakpad/src/client/linux/handler/minidump_descriptor.h" |
+#include "chromecast/common/version.h" |
+#include "chromecast/crash/android/cast_crash_reporter_client_android.h" |
+#include "components/crash/app/breakpad_linux.h" |
+#include "components/crash/app/crash_reporter_client.h" |
+#include "content/public/common/content_switches.h" |
+#include "jni/CastCrashHandler_jni.h" |
+ |
+namespace { |
+ |
+chromecast::CrashHandler* g_crash_handler = NULL; |
+ |
+// ExceptionHandler requires a HandlerCallback as a function pointer. This |
+// function exists to proxy into the global CrashHandler instance. |
+bool HandleCrash(const void*, size_t, void*) { |
Lei Zhang
2014/10/06 22:44:25
nit: you can write in the parameter names but comm
gunsch
2014/10/09 00:20:55
Done.
|
+ DCHECK(g_crash_handler); |
+ if (g_crash_handler->CanUploadCrashDump()) { |
+ g_crash_handler->AttemptUploadCrashDump(); |
+ } else { |
+ g_crash_handler->RemoveCrashDumps(); |
+ } |
+ |
+ // Let the exception continue to propagate up to the system. |
+ return false; |
+} |
+ |
+} // namespace |
+ |
+namespace chromecast { |
+ |
+CrashHandler::CrashHandler(const std::string& process_type, |
+ const base::FilePath& log_file_path) |
+ : log_file_path_(log_file_path), |
+ crash_reporter_client_(new CastCrashReporterClientAndroid) { |
+ CHECK(crash_reporter_client_->GetCrashDumpLocation(&crash_dump_path_)); |
Lei Zhang
2014/10/06 22:44:25
Do you have to CHECK() here?
gunsch
2014/10/09 00:20:55
I'll change it to a LOG(ERROR) --- but I don't nec
|
+ SetCrashReporterClient(crash_reporter_client_.get()); |
+ |
+ if (process_type != switches::kZygoteProcess) { |
+ if (process_type.empty()) { |
+ // ExceptionHandlers are called on crash in reverse order of |
+ // instantiation. This ExceptionHandler will attempt to upload crashes |
+ // and the log file written out by the main process. |
+ |
+ // Dummy MinidumpDescriptor just to start up another ExceptionHandler. |
+ google_breakpad::MinidumpDescriptor dummy(crash_dump_path_.value()); |
+ crash_uploader_.reset(new google_breakpad::ExceptionHandler( |
+ dummy, NULL, NULL, NULL, true, -1)); |
+ crash_uploader_->set_crash_handler(&::HandleCrash); |
+ |
+ breakpad::InitCrashReporter(process_type); |
+ } else { |
+ breakpad::InitNonBrowserCrashReporterForAndroid(process_type); |
+ } |
+ } |
+ |
+ UploadCrashDumpsAsync(); |
+} |
+ |
+// static |
+void CrashHandler::Initialize(const std::string& process_type, |
+ const base::FilePath& log_file_path) { |
+ DCHECK(!g_crash_handler); |
+ g_crash_handler = new CrashHandler(process_type, log_file_path); |
+} |
+ |
+// static |
+bool CrashHandler::GetCrashDumpLocation(base::FilePath* crash_dir) { |
+ DCHECK(g_crash_handler); |
+ return g_crash_handler->crash_reporter_client_-> |
+ GetCrashDumpLocation(crash_dir); |
+} |
+ |
+CrashHandler::~CrashHandler() { |
+ DCHECK(g_crash_handler); |
+ g_crash_handler = NULL; |
+} |
+ |
+bool CrashHandler::CanUploadCrashDump() { |
+ DCHECK(crash_reporter_client_); |
+ return crash_reporter_client_->GetCollectStatsConsent(); |
+} |
+ |
+void CrashHandler::AttemptUploadCrashDump() { |
+ LOG(INFO) << "Attempting to upload current process crash"; |
Lei Zhang
2014/10/06 22:44:25
No LOG(INFO) please. Use VLOG() if you want to kee
gunsch
2014/10/09 00:20:55
Done (this isn't terribly important), but in gener
|
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ // Crash dump location |
+ base::android::ScopedJavaLocalRef<jstring> crash_dump_path_java = |
+ base::android::ConvertUTF8ToJavaString(env, |
+ crash_dump_path_.value()); |
+ // Current log file location |
+ base::android::ScopedJavaLocalRef<jstring> log_file_path_java = |
+ base::android::ConvertUTF8ToJavaString(env, log_file_path_.value()); |
+ Java_CastCrashHandler_uploadCurrentProcessDumpSync( |
+ env, |
+ crash_dump_path_java.obj(), |
+ log_file_path_java.obj(), |
+ CAST_IS_DEBUG_BUILD); |
+} |
+ |
+void CrashHandler::UploadCrashDumpsAsync() { |
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ base::android::ScopedJavaLocalRef<jstring> crash_dump_path_java = |
+ base::android::ConvertUTF8ToJavaString(env, |
+ crash_dump_path_.value()); |
+ Java_CastCrashHandler_uploadCrashDumpsAsync(env, |
+ crash_dump_path_java.obj(), |
+ CAST_IS_DEBUG_BUILD); |
+} |
+ |
+void CrashHandler::RemoveCrashDumps() { |
+ LOG(INFO) << "Removing crash dumps instead of uploading"; |
Lei Zhang
2014/10/06 22:44:25
ditto
gunsch
2014/10/09 00:20:55
Done.
|
+ JNIEnv* env = base::android::AttachCurrentThread(); |
+ base::android::ScopedJavaLocalRef<jstring> crash_dump_path_java = |
+ base::android::ConvertUTF8ToJavaString(env, |
+ crash_dump_path_.value()); |
+ Java_CastCrashHandler_removeCrashDumpsSync( |
+ env, crash_dump_path_java.obj(), CAST_IS_DEBUG_BUILD); |
+} |
+ |
+// static |
+bool CrashHandler::RegisterCastCrashJni(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+} // namespace chromecast |