Chromium Code Reviews| 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 |