Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: content/browser/tracing/arc_tracing_agent.cc

Issue 2400163003: arc: enable Android tracing in verified-boot mode (Closed)
Patch Set: Address comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/tracing/arc_tracing_agent.h" 5 #include "content/browser/tracing/arc_tracing_agent.h"
6 6
7 #include <string.h>
8 #include <sys/socket.h>
9
10 #include <memory>
7 #include <string> 11 #include <string>
12 #include <utility>
13 #include <vector>
8 14
9 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/bind_helpers.h"
17 #include "base/files/file.h"
18 #include "base/files/file_descriptor_watcher_posix.h"
10 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/memory/ptr_util.h"
11 #include "base/memory/singleton.h" 21 #include "base/memory/singleton.h"
12 #include "base/threading/thread_checker.h" 22 #include "base/memory/weak_ptr.h"
23 #include "base/posix/unix_domain_socket_linux.h"
24 #include "base/threading/sequenced_task_runner_handle.h"
13 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
26 #include "base/time/time.h"
27 #include "cc/base/ring_buffer.h"
28 #include "content/public/browser/browser_thread.h"
14 29
15 namespace content { 30 namespace content {
16 31
17 namespace { 32 namespace {
18 33
34 constexpr size_t kArcTraceMessageLength = 1024 + 512;
oystein (OOO til 10th of July) 2017/04/07 18:31:40 Can you document why this particular value was cho
Earl Ou 2017/04/08 14:48:17 Done.
19 constexpr char kArcTracingAgentName[] = "arc"; 35 constexpr char kArcTracingAgentName[] = "arc";
20 constexpr char kArcTraceLabel[] = "ArcTraceEvents"; 36 constexpr char kArcTraceLabel[] = "ArcTraceEvents";
21 37
22 void OnStopTracing(bool success) { 38 // Number of events for the ring buffer.
23 DLOG_IF(WARNING, !success) << "Failed to stop ARC tracing."; 39 constexpr size_t kTraceEventBufferSize = 64000;
24 } 40
41 class ArcTracingReader {
oystein (OOO til 10th of July) 2017/04/07 18:31:40 It's not immediately obvious to me why this was fa
Earl Ou 2017/04/08 14:48:17 Done.
42 public:
43 using StopTracingCallback =
44 base::Callback<void(const scoped_refptr<base::RefCountedString>&)>;
45
46 ArcTracingReader() : weak_ptr_factory_(this) {}
47
48 void StartTracing(base::ScopedFD read_fd) {
49 DCHECK_CURRENTLY_ON(BrowserThread::IO);
50 read_fd_ = std::move(read_fd);
51 fd_watcher_ = base::FileDescriptorWatcher::WatchReadable(
52 read_fd_.get(), base::Bind(&ArcTracingReader::OnTraceDataAvailable,
53 base::Unretained(this)));
Luis Héctor Chávez 2017/04/07 16:17:46 nit: s/base::Unretained(this)/GetWeakPtr())/
dcheng 2017/04/07 17:58:28 I'm OK with unretained as long as it's explained w
Earl Ou 2017/04/08 14:48:17 Yes, I think we should use |Unretained| here to av
54 }
55
56 void OnTraceDataAvailable() {
57 DCHECK_CURRENTLY_ON(BrowserThread::IO);
58
59 char buf[kArcTraceMessageLength + 1];
60 std::vector<base::ScopedFD> unused_fds;
61 ssize_t n = base::UnixDomainSocket::RecvMsg(
62 read_fd_.get(), buf, kArcTraceMessageLength, &unused_fds);
63 // When EOF, return and do nothing. The clean up is done in StopTracing.
64 if (n == 0)
65 return;
66
67 if (n < 0) {
68 PLOG(WARNING) << "Unexpected error while reading trace from client.";
dcheng 2017/04/07 17:58:28 DPLOG?
Earl Ou 2017/04/08 14:48:17 Done.
69 // Do nothing here as StopTracing will do the clean up and the existing
70 // trace logs will be returned.
71 return;
72 }
73
74 if (n > static_cast<ssize_t>(kArcTraceMessageLength)) {
75 LOG(WARNING) << "Unexpected data size when reading trace from client.";
dcheng 2017/04/07 17:58:28 DLOG?
Earl Ou 2017/04/08 14:48:17 Done.
76 return;
77 }
78 buf[n] = 0;
79 ring_buffer_.SaveToBuffer(buf);
Luis Héctor Chávez 2017/04/07 16:17:46 nit: you can still avoid the +1 above: ring_buffe
Earl Ou 2017/04/08 14:48:17 Done.
80 }
81
82 void StopTracing(const StopTracingCallback& callback) {
83 DCHECK_CURRENTLY_ON(BrowserThread::IO);
84 // Stop fd_watcher_.
oystein (OOO til 10th of July) 2017/04/07 18:31:41 nit: Not really a helpful comment, as it just stat
Earl Ou 2017/04/08 14:48:17 Done.
85 fd_watcher_.reset();
86 read_fd_.reset();
87
88 bool append_comma = false;
89 std::string data;
90 for (auto it = ring_buffer_.Begin(); it; ++it) {
91 if (append_comma)
92 data.append(",");
oystein (OOO til 10th of July) 2017/04/07 18:31:41 nit: maybe: if (append_comma) data.append(",");
Earl Ou 2017/04/08 14:48:17 Done.
93 data.append(**it);
94 append_comma = true;
dcheng 2017/04/07 17:58:28 Nit: move inside the if at 91
Earl Ou 2017/04/08 14:48:17 Done.
95 }
96 ring_buffer_.Clear();
97
98 BrowserThread::PostTask(
99 BrowserThread::IO, FROM_HERE,
100 base::Bind(callback, base::RefCountedString::TakeString(&data)));
101 }
102
103 base::WeakPtr<ArcTracingReader> GetWeakPtr() {
104 return weak_ptr_factory_.GetWeakPtr();
105 }
106
107 private:
108 base::ScopedFD read_fd_;
109 std::unique_ptr<base::FileDescriptorWatcher::Controller> fd_watcher_;
110 cc::RingBuffer<std::string, kTraceEventBufferSize> ring_buffer_;
111 // NOTE: Weak pointers must be invalidated before all other member variables
112 // so it must be the last member.
113 base::WeakPtrFactory<ArcTracingReader> weak_ptr_factory_;
114
115 DISALLOW_COPY_AND_ASSIGN(ArcTracingReader);
116 };
25 117
26 class ArcTracingAgentImpl : public ArcTracingAgent { 118 class ArcTracingAgentImpl : public ArcTracingAgent {
27 public: 119 public:
28 // base::trace_event::TracingAgent overrides: 120 // base::trace_event::TracingAgent overrides:
29 std::string GetTracingAgentName() override { return kArcTracingAgentName; } 121 std::string GetTracingAgentName() override { return kArcTracingAgentName; }
30 122
31 std::string GetTraceEventLabel() override { return kArcTraceLabel; } 123 std::string GetTraceEventLabel() override { return kArcTraceLabel; }
32 124
33 void StartAgentTracing(const base::trace_event::TraceConfig& trace_config, 125 void StartAgentTracing(const base::trace_event::TraceConfig& trace_config,
34 const StartAgentTracingCallback& callback) override { 126 const StartAgentTracingCallback& callback) override {
35 DCHECK(thread_checker_.CalledOnValidThread()); 127 DCHECK_CURRENTLY_ON(BrowserThread::UI);
128
36 // delegate_ may be nullptr if ARC is not enabled on the system. In such 129 // delegate_ may be nullptr if ARC is not enabled on the system. In such
37 // case, simply do nothing. 130 // case, simply do nothing.
38 if (!delegate_) { 131 bool success = delegate_ != nullptr;
oystein (OOO til 10th of July) 2017/04/07 18:31:40 nit: (delegate_ != nullptr) for readability.
Earl Ou 2017/04/08 14:48:17 Done.
132
133 base::ScopedFD write_fd, read_fd;
134 success = success && CreateSocketPair(&read_fd, &write_fd);
135
136 if (!success) {
39 // Use PostTask as the convention of TracingAgent. The caller expects 137 // Use PostTask as the convention of TracingAgent. The caller expects
40 // callback to be called after this function returns. 138 // callback to be called after this function returns.
41 base::ThreadTaskRunnerHandle::Get()->PostTask( 139 base::ThreadTaskRunnerHandle::Get()->PostTask(
42 FROM_HERE, base::Bind(callback, GetTracingAgentName(), false)); 140 FROM_HERE, base::Bind(callback, GetTracingAgentName(), false));
43 return; 141 return;
44 } 142 }
45 143
46 delegate_->StartTracing(trace_config, 144 BrowserThread::PostTask(
145 BrowserThread::IO, FROM_HERE,
146 base::Bind(&ArcTracingReader::StartTracing, reader_->GetWeakPtr(),
147 base::Passed(&read_fd)));
148
149 delegate_->StartTracing(trace_config, std::move(write_fd),
47 base::Bind(callback, GetTracingAgentName())); 150 base::Bind(callback, GetTracingAgentName()));
48 } 151 }
49 152
50 void StopAgentTracing(const StopAgentTracingCallback& callback) override { 153 void StopAgentTracing(const StopAgentTracingCallback& callback) override {
51 DCHECK(thread_checker_.CalledOnValidThread()); 154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
52 if (delegate_)
53 delegate_->StopTracing(base::Bind(OnStopTracing));
54 155
55 // Trace data is collect via systrace (debugd) in dev-mode. Simply 156 if (is_stopping_) {
56 // return empty data here. 157 DLOG(WARNING) << "Already working on stopping ArcTracingAgent.";
57 std::string no_data; 158 return;
58 base::ThreadTaskRunnerHandle::Get()->PostTask( 159 }
59 FROM_HERE, 160 is_stopping_ = true;
60 base::Bind(callback, GetTracingAgentName(), GetTraceEventLabel(), 161 if (delegate_) {
61 base::RefCountedString::TakeString(&no_data))); 162 delegate_->StopTracing(
163 base::Bind(&ArcTracingAgentImpl::OnArcTracingStopped,
164 weak_ptr_factory_.GetWeakPtr(), callback));
165 }
62 } 166 }
63 167
64 // ArcTracingAgent overrides: 168 // ArcTracingAgent overrides:
65 void SetDelegate(Delegate* delegate) override { 169 void SetDelegate(Delegate* delegate) override {
66 DCHECK(thread_checker_.CalledOnValidThread()); 170 DCHECK_CURRENTLY_ON(BrowserThread::UI);
67 delegate_ = delegate; 171 delegate_ = delegate;
68 } 172 }
69 173
70 static ArcTracingAgentImpl* GetInstance() { 174 static ArcTracingAgentImpl* GetInstance() {
71 return base::Singleton<ArcTracingAgentImpl>::get(); 175 return base::Singleton<ArcTracingAgentImpl>::get();
72 } 176 }
73 177
74 private: 178 private:
75 // This allows constructor and destructor to be private and usable only 179 // This allows constructor and destructor to be private and usable only
76 // by the Singleton class. 180 // by the Singleton class.
77 friend struct base::DefaultSingletonTraits<ArcTracingAgentImpl>; 181 friend struct base::DefaultSingletonTraits<ArcTracingAgentImpl>;
78 182
79 ArcTracingAgentImpl() = default; 183 ArcTracingAgentImpl()
184 : reader_(base::MakeUnique<ArcTracingReader>()),
185 weak_ptr_factory_(this) {}
186
80 ~ArcTracingAgentImpl() override = default; 187 ~ArcTracingAgentImpl() override = default;
81 188
189 void OnArcTracingStopped(const StopAgentTracingCallback& callback,
190 bool success) {
191 DCHECK_CURRENTLY_ON(BrowserThread::UI);
192 if (!success) {
193 DLOG(WARNING) << "Failed to stop ARC tracing.";
194 callback.Run(GetTracingAgentName(), GetTraceEventLabel(),
195 new base::RefCountedString);
Luis Héctor Chávez 2017/04/07 16:17:46 nit: new base::RefCountedString() (see https://ww
Earl Ou 2017/04/08 14:48:17 Done.
196 is_stopping_ = false;
197 return;
198 }
199 BrowserThread::PostTask(
200 BrowserThread::IO, FROM_HERE,
201 base::Bind(&ArcTracingReader::StopTracing, reader_->GetWeakPtr(),
202 base::Bind(&ArcTracingAgentImpl::OnTracingReaderStopped,
203 weak_ptr_factory_.GetWeakPtr(), callback)));
204 }
205
206 void OnTracingReaderStopped(
207 const StopAgentTracingCallback& callback,
208 const scoped_refptr<base::RefCountedString>& data) {
209 DCHECK_CURRENTLY_ON(BrowserThread::UI);
210 callback.Run(GetTracingAgentName(), GetTraceEventLabel(), data);
211 is_stopping_ = false;
212 }
213
82 Delegate* delegate_ = nullptr; // Owned by ArcServiceLauncher. 214 Delegate* delegate_ = nullptr; // Owned by ArcServiceLauncher.
83 base::ThreadChecker thread_checker_; 215 std::unique_ptr<ArcTracingReader> reader_;
oystein (OOO til 10th of July) 2017/04/07 18:31:41 Why is this a unique_ptr rather than just an inlin
Earl Ou 2017/04/08 14:48:17 Done.
216 bool is_stopping_ = false;
217 // NOTE: Weak pointers must be invalidated before all other member variables
218 // so it must be the last member.
219 base::WeakPtrFactory<ArcTracingAgentImpl> weak_ptr_factory_;
84 220
85 DISALLOW_COPY_AND_ASSIGN(ArcTracingAgentImpl); 221 DISALLOW_COPY_AND_ASSIGN(ArcTracingAgentImpl);
86 }; 222 };
87 223
88 } // namespace 224 } // namespace
89 225
90 // static 226 // static
91 ArcTracingAgent* ArcTracingAgent::GetInstance() { 227 ArcTracingAgent* ArcTracingAgent::GetInstance() {
92 return ArcTracingAgentImpl::GetInstance(); 228 return ArcTracingAgentImpl::GetInstance();
93 } 229 }
94 230
95 ArcTracingAgent::ArcTracingAgent() = default; 231 ArcTracingAgent::ArcTracingAgent() = default;
96 ArcTracingAgent::~ArcTracingAgent() = default; 232 ArcTracingAgent::~ArcTracingAgent() = default;
97 233
98 ArcTracingAgent::Delegate::~Delegate() = default; 234 ArcTracingAgent::Delegate::~Delegate() = default;
99 235
100 } // namespace content 236 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/tracing/arc_tracing_agent.h ('k') | content/browser/tracing/tracing_controller_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698