| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <fcntl.h> | 5 #include <fcntl.h> |
| 6 #include <unistd.h> | 6 #include <unistd.h> |
| 7 | 7 |
| 8 #include "chromeos/dbus/debug_daemon_client.h" | 8 #include "chromeos/dbus/debug_daemon_client.h" |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/chromeos/chromeos_version.h" | 12 #include "base/chromeos/chromeos_version.h" |
| 13 #include "base/eintr_wrapper.h" | 13 #include "base/eintr_wrapper.h" |
| 14 #include "base/memory/ref_counted_memory.h" | 14 #include "base/memory/ref_counted_memory.h" |
| 15 #include "base/platform_file.h" | 15 #include "base/platform_file.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "base/threading/worker_pool.h" |
| 17 #include "dbus/bus.h" | 18 #include "dbus/bus.h" |
| 18 #include "dbus/message.h" | 19 #include "dbus/message.h" |
| 19 #include "dbus/object_path.h" | 20 #include "dbus/object_path.h" |
| 20 #include "dbus/object_proxy.h" | 21 #include "dbus/object_proxy.h" |
| 21 #include "net/base/file_stream.h" | 22 #include "net/base/file_stream.h" |
| 22 #include "net/base/io_buffer.h" | 23 #include "net/base/io_buffer.h" |
| 23 #include "net/base/net_errors.h" | 24 #include "net/base/net_errors.h" |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | 25 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 25 | 26 |
| 26 namespace { | 27 namespace { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 debugdaemon_proxy_ = bus->GetObjectProxy( | 146 debugdaemon_proxy_ = bus->GetObjectProxy( |
| 146 debugd::kDebugdServiceName, | 147 debugd::kDebugdServiceName, |
| 147 dbus::ObjectPath(debugd::kDebugdServicePath)); | 148 dbus::ObjectPath(debugd::kDebugdServicePath)); |
| 148 } | 149 } |
| 149 | 150 |
| 150 virtual ~DebugDaemonClientImpl() {} | 151 virtual ~DebugDaemonClientImpl() {} |
| 151 | 152 |
| 152 // DebugDaemonClient override. | 153 // DebugDaemonClient override. |
| 153 virtual void GetDebugLogs(base::PlatformFile file, | 154 virtual void GetDebugLogs(base::PlatformFile file, |
| 154 const GetDebugLogsCallback& callback) OVERRIDE { | 155 const GetDebugLogsCallback& callback) OVERRIDE { |
| 155 dbus::MethodCall method_call( | |
| 156 debugd::kDebugdInterface, | |
| 157 debugd::kGetDebugLogs); | |
| 158 dbus::MessageWriter writer(&method_call); | |
| 159 dbus::FileDescriptor fd(file); // explicit temp for C++ 98 | |
| 160 writer.AppendFileDescriptor(fd); | |
| 161 | 156 |
| 162 debugdaemon_proxy_->CallMethod( | 157 dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file); |
| 163 &method_call, | 158 // Punt descriptor validity check to a worker thread; on return we'll |
| 164 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | 159 // issue the D-Bus request to stop tracing and collect results. |
| 165 base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs, | 160 base::WorkerPool::PostTaskAndReply( |
| 161 FROM_HERE, |
| 162 base::Bind(&DebugDaemonClientImpl::CheckValidity, |
| 163 file_descriptor), |
| 164 base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs, |
| 166 weak_ptr_factory_.GetWeakPtr(), | 165 weak_ptr_factory_.GetWeakPtr(), |
| 167 callback)); | 166 base::Owned(file_descriptor), |
| 167 callback), |
| 168 false); |
| 168 } | 169 } |
| 169 | 170 |
| 170 virtual void SetDebugMode(const std::string& subsystem, | 171 virtual void SetDebugMode(const std::string& subsystem, |
| 171 const SetDebugModeCallback& callback) OVERRIDE { | 172 const SetDebugModeCallback& callback) OVERRIDE { |
| 172 dbus::MethodCall method_call(debugd::kDebugdInterface, | 173 dbus::MethodCall method_call(debugd::kDebugdInterface, |
| 173 debugd::kSetDebugMode); | 174 debugd::kSetDebugMode); |
| 174 dbus::MessageWriter writer(&method_call); | 175 dbus::MessageWriter writer(&method_call); |
| 175 writer.AppendString(subsystem); | 176 writer.AppendString(subsystem); |
| 176 debugdaemon_proxy_->CallMethod( | 177 debugdaemon_proxy_->CallMethod( |
| 177 &method_call, | 178 &method_call, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 int write_fd = -1; | 210 int write_fd = -1; |
| 210 if (!pipe_reader_->StartIO()) { | 211 if (!pipe_reader_->StartIO()) { |
| 211 LOG(ERROR) << "Cannot create pipe reader"; | 212 LOG(ERROR) << "Cannot create pipe reader"; |
| 212 // NB: continue anyway to shutdown tracing; toss trace data | 213 // NB: continue anyway to shutdown tracing; toss trace data |
| 213 write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY)); | 214 write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY)); |
| 214 // TODO(sleffler) if this fails AppendFileDescriptor will abort | 215 // TODO(sleffler) if this fails AppendFileDescriptor will abort |
| 215 } else { | 216 } else { |
| 216 write_fd = pipe_reader_->GetWriteFD(); | 217 write_fd = pipe_reader_->GetWriteFD(); |
| 217 } | 218 } |
| 218 | 219 |
| 219 callback_ = callback; | 220 dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd); |
| 220 | 221 // Punt descriptor validity check to a worker thread; on return we'll |
| 221 // Issue the dbus request to stop system tracing | 222 // issue the D-Bus request to stop tracing and collect results. |
| 222 dbus::MethodCall method_call( | 223 base::WorkerPool::PostTaskAndReply( |
| 223 debugd::kDebugdInterface, | 224 FROM_HERE, |
| 224 debugd::kSystraceStop); | 225 base::Bind(&DebugDaemonClientImpl::CheckValidity, |
| 225 dbus::MessageWriter writer(&method_call); | 226 file_descriptor), |
| 226 dbus::FileDescriptor temp(write_fd); // NB: explicit temp for C++98 | 227 base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem, |
| 227 writer.AppendFileDescriptor(temp); | 228 weak_ptr_factory_.GetWeakPtr(), |
| 228 | 229 base::Owned(file_descriptor), |
| 229 DVLOG(1) << "Requesting a systrace stop"; | 230 callback), |
| 230 debugdaemon_proxy_->CallMethod( | 231 false); |
| 231 &method_call, | |
| 232 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 233 base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing, | |
| 234 weak_ptr_factory_.GetWeakPtr())); | |
| 235 | |
| 236 pipe_reader_->CloseWriteFD(); // close our copy of fd after send | |
| 237 | 232 |
| 238 return true; | 233 return true; |
| 239 } | 234 } |
| 240 | 235 |
| 241 private: | 236 private: |
| 237 // Called to check descriptor validity on a thread where i/o is permitted. |
| 238 static void CheckValidity(dbus::FileDescriptor* file_descriptor) { |
| 239 file_descriptor->CheckValidity(); |
| 240 } |
| 241 |
| 242 // Called when a CheckValidity response is received. |
| 243 void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor, |
| 244 const GetDebugLogsCallback& callback) { |
| 245 // Issue the dbus request to get debug logs. |
| 246 dbus::MethodCall method_call( |
| 247 debugd::kDebugdInterface, |
| 248 debugd::kGetDebugLogs); |
| 249 dbus::MessageWriter writer(&method_call); |
| 250 writer.AppendFileDescriptor(*file_descriptor); |
| 251 |
| 252 debugdaemon_proxy_->CallMethod( |
| 253 &method_call, |
| 254 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 255 base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs, |
| 256 weak_ptr_factory_.GetWeakPtr(), |
| 257 callback)); |
| 258 } |
| 259 |
| 242 // Called when a response for GetDebugLogs() is received. | 260 // Called when a response for GetDebugLogs() is received. |
| 243 void OnGetDebugLogs(const GetDebugLogsCallback& callback, | 261 void OnGetDebugLogs(const GetDebugLogsCallback& callback, |
| 244 dbus::Response* response) { | 262 dbus::Response* response) { |
| 245 if (!response) { | 263 if (!response) { |
| 246 LOG(ERROR) << "Failed to get debug logs"; | 264 LOG(ERROR) << "Failed to get debug logs"; |
| 247 callback.Run(false); | 265 callback.Run(false); |
| 248 return; | 266 return; |
| 249 } | 267 } |
| 250 callback.Run(true); | 268 callback.Run(true); |
| 251 } | 269 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 262 } | 280 } |
| 263 | 281 |
| 264 // Called when a response for StartSystemTracing() is received. | 282 // Called when a response for StartSystemTracing() is received. |
| 265 void OnStartSystemTracing(dbus::Response* response) { | 283 void OnStartSystemTracing(dbus::Response* response) { |
| 266 if (!response) { | 284 if (!response) { |
| 267 LOG(ERROR) << "Failed to request systrace start"; | 285 LOG(ERROR) << "Failed to request systrace start"; |
| 268 return; | 286 return; |
| 269 } | 287 } |
| 270 } | 288 } |
| 271 | 289 |
| 290 // Called when a CheckValidity response is received. |
| 291 void OnCheckValidityRequestStopSystem( |
| 292 dbus::FileDescriptor* file_descriptor, |
| 293 const StopSystemTracingCallback& callback) { |
| 294 // Issue the dbus request to stop system tracing |
| 295 dbus::MethodCall method_call( |
| 296 debugd::kDebugdInterface, |
| 297 debugd::kSystraceStop); |
| 298 dbus::MessageWriter writer(&method_call); |
| 299 writer.AppendFileDescriptor(*file_descriptor); |
| 300 |
| 301 callback_ = callback; |
| 302 |
| 303 DVLOG(1) << "Requesting a systrace stop"; |
| 304 debugdaemon_proxy_->CallMethod( |
| 305 &method_call, |
| 306 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| 307 base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing, |
| 308 weak_ptr_factory_.GetWeakPtr())); |
| 309 |
| 310 pipe_reader_->CloseWriteFD(); // close our copy of fd after send |
| 311 } |
| 312 |
| 272 // Called when a response for RequestStopSystemTracing() is received. | 313 // Called when a response for RequestStopSystemTracing() is received. |
| 273 void OnRequestStopSystemTracing(dbus::Response* response) { | 314 void OnRequestStopSystemTracing(dbus::Response* response) { |
| 274 if (!response) { | 315 if (!response) { |
| 275 LOG(ERROR) << "Failed to request systrace stop"; | 316 LOG(ERROR) << "Failed to request systrace stop"; |
| 276 pipe_reader_->OnDataReady(-1); // terminate data stream | 317 pipe_reader_->OnDataReady(-1); // terminate data stream |
| 277 } | 318 } |
| 278 // NB: requester is signaled when i/o completes | 319 // NB: requester is signaled when i/o completes |
| 279 } | 320 } |
| 280 | 321 |
| 281 // Called when pipe i/o completes; pass data on and delete the instance. | 322 // Called when pipe i/o completes; pass data on and delete the instance. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 // static | 369 // static |
| 329 DebugDaemonClient* DebugDaemonClient::Create(DBusClientImplementationType type, | 370 DebugDaemonClient* DebugDaemonClient::Create(DBusClientImplementationType type, |
| 330 dbus::Bus* bus) { | 371 dbus::Bus* bus) { |
| 331 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | 372 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) |
| 332 return new DebugDaemonClientImpl(bus); | 373 return new DebugDaemonClientImpl(bus); |
| 333 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | 374 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); |
| 334 return new DebugDaemonClientStubImpl(); | 375 return new DebugDaemonClientStubImpl(); |
| 335 } | 376 } |
| 336 | 377 |
| 337 } // namespace chromeos | 378 } // namespace chromeos |
| OLD | NEW |