Chromium Code Reviews| Index: chrome/browser/android/seccomp_support_detector.cc |
| diff --git a/chrome/browser/android/seccomp_support_detector.cc b/chrome/browser/android/seccomp_support_detector.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2fe7aa244ac89abd544edb086c77aa2282fd4af0 |
| --- /dev/null |
| +++ b/chrome/browser/android/seccomp_support_detector.cc |
| @@ -0,0 +1,119 @@ |
| +// Copyright 2015 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 "chrome/browser/android/seccomp_support_detector.h" |
| + |
| +#include <sys/utsname.h> |
| + |
| +#include "base/message_loop/message_loop_proxy.h" |
| +#include "base/metrics/histogram_macros.h" |
| +#include "chrome/common/chrome_utility_messages.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/utility_process_host.h" |
| + |
| +using content::BrowserThread; |
| + |
| +enum AndroidSeccompStatus { |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
No enum class?
Robert Sesek
2015/03/18 21:41:35
It doesn't work well with the UMA_HISTOGRAM_ENUMER
|
| + kDetectionFailed, |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
The Chromium appendix to the style guide says to u
Robert Sesek
2015/03/18 21:41:36
Ah, yeah I was using the Google style. I'll follow
|
| + kNotSupported, |
| + kPrctlSupported, |
| + kSyscallSupported, |
| + kBothSupported, |
| + kLastStatus, |
| +}; |
| + |
| +void SeccompSupportDetector::StartDetection() { |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
//static?
Robert Sesek
2015/03/18 21:41:36
Done.
|
| + // This class owns itself. It is created here and the object is released |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
"It is created here" -> "An instance is created he
Robert Sesek
2015/03/18 21:41:35
Done.
|
| + // after seccomp suport is detected. |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
The lifetime of this refcounted class is a little
Robert Sesek
2015/03/18 21:41:35
I initially did as you suggested and let the Closu
|
| + SeccompSupportDetector* detector = new SeccompSupportDetector(); |
| + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| + base::Bind(&SeccompSupportDetector::DetectKernelVersion, detector)); |
| +} |
| + |
| +SeccompSupportDetector::SeccompSupportDetector() { |
| +} |
| + |
| +SeccompSupportDetector::~SeccompSupportDetector() { |
| +} |
| + |
| +void SeccompSupportDetector::DetectKernelVersion() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + |
| + // This method will report the kernel major and minor versions by |
| + // taking the lower 16 bits of each version number and combining |
| + // it into a 32-bit number. |
| + |
| + // Support known Android kernel versions, and leave room up to 3.50. |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
3.20 is actually 4.0
Robert Sesek
2015/03/18 21:41:35
Done.
|
| + const int kVersionRanges[] = { |
| + 0x00020006, |
| + 0x00030000, |
| + 0x00030003, |
| + 0x00030004, |
| + 0x00030008, |
| + 0x00030010, |
| + 0x00030014, |
| + 0x00030017, |
| + 0x00030018, |
| + 0x00030050, |
| + }; |
| + |
| + utsname uts; |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
nit: I prefer to use "struct X" for low-level C co
Robert Sesek
2015/03/18 21:41:35
Acknowledged.
|
| + if (uname(&uts) == 0) { |
| + int major, minor; |
| + if (sscanf(uts.release, "%d.%d", &major, &minor) == 2) { |
|
jln (very slow on Chromium)
2015/03/18 20:49:15
Ok to put all 2.6.X kernels in the same bucket?
F
Robert Sesek
2015/03/18 21:41:35
Yeah, I think so. I don't even know if Chrome runs
|
| + int version = ((major & 0xFFFF) << 16) | (minor & 0xFFFF); |
| + UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
| + "Android.KernelVersion", version, |
| + base::CustomHistogram::ArrayToCustomRanges( |
| + kVersionRanges, arraysize(kVersionRanges))); |
| + } |
| + } |
| + |
| + BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| + base::Bind(&SeccompSupportDetector::DetectSeccomp, this)); |
| +} |
| + |
| +void SeccompSupportDetector::DetectSeccomp() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + |
| + content::UtilityProcessHost* utility_process_host = |
| + content::UtilityProcessHost::Create( |
| + this, base::MessageLoopProxy::current()); |
| + utility_process_host->Send(new ChromeUtilityMsg_DetectSeccompSupport()); |
| +} |
| + |
| +void SeccompSupportDetector::OnProcessCrashed(int exit_code) { |
| + UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus", |
| + kDetectionFailed, |
| + kLastStatus); |
| + Release(); |
| +} |
| + |
| +bool SeccompSupportDetector::OnMessageReceived(const IPC::Message& message) { |
| + bool handled = false; |
| + IPC_BEGIN_MESSAGE_MAP(SeccompSupportDetector, message) |
| + IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_Result, |
| + OnDetectSeccompSupportResult) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + return handled; |
| +} |
| + |
| +void SeccompSupportDetector::OnDetectSeccompSupportResult( |
| + bool prctl_supported, bool syscall_supported) { |
| + |
| + AndroidSeccompStatus status = kNotSupported; |
| + if (prctl_supported && syscall_supported) |
| + status = kBothSupported; |
| + else if (prctl_supported) |
| + status = kPrctlSupported; |
| + else if (syscall_supported) |
| + status = kSyscallSupported; |
| + |
| + UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus", |
| + status, |
| + kLastStatus); |
| + |
| + Release(); |
| +} |