Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / debug_daemon_client.cc
index 25a55e3..8a8804f 100644 (file)
 #include "base/platform_file.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_util.h"
+#include "base/task_runner_util.h"
 #include "base/threading/worker_pool.h"
+#include "chromeos/dbus/pipe_reader.h"
 #include "dbus/bus.h"
 #include "dbus/message.h"
 #include "dbus/object_path.h"
 #include "dbus/object_proxy.h"
-#include "net/base/file_stream.h"
-#include "net/base/io_buffer.h"
-#include "net/base/net_errors.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
 
 namespace {
@@ -35,107 +34,6 @@ void EmptyStopSystemTracingCallbackBody(
   const scoped_refptr<base::RefCountedString>& unused_result) {
 }
 
-// Simple class to encapsulate collecting data from a pipe into a
-// string.  To use, instantiate the class, start i/o, and then delete
-// the instance on callback.  The data should be retrieved before
-// delete and extracted or copied.
-//
-// TODO(sleffler) move data collection to a sub-class so this
-// can be reused to process data as it is received
-class PipeReader {
- public:
-  typedef base::Callback<void(void)>IOCompleteCallback;
-
-  explicit PipeReader(IOCompleteCallback callback)
-      : io_buffer_(new net::IOBufferWithSize(4096)),
-        callback_(callback),
-        weak_ptr_factory_(this) {
-    pipe_fd_[0] = pipe_fd_[1] = -1;
-  }
-
-  virtual ~PipeReader() {
-    // Don't close pipe_fd_[0] as it's closed by data_stream_.
-    if (pipe_fd_[1] != -1)
-      if (IGNORE_EINTR(close(pipe_fd_[1])) < 0)
-        PLOG(ERROR) << "close[1]";
-  }
-
-  // Returns descriptor for the writeable side of the pipe.
-  int GetWriteFD() { return pipe_fd_[1]; }
-
-  // Closes writeable descriptor; normally used in parent process after fork.
-  void CloseWriteFD() {
-    if (pipe_fd_[1] != -1) {
-      if (IGNORE_EINTR(close(pipe_fd_[1])) < 0)
-        PLOG(ERROR) << "close";
-      pipe_fd_[1] = -1;
-    }
-  }
-
-  // Returns collected data.
-  std::string* data() { return &data_; }
-
-  // Starts data collection.  Returns true if stream was setup correctly.
-  // On success data will automatically be accumulated into a string that
-  // can be retrieved with PipeReader::data().  To shutdown collection delete
-  // the instance and/or use PipeReader::OnDataReady(-1).
-  bool StartIO() {
-    // Use a pipe to collect data
-    const int status = HANDLE_EINTR(pipe(pipe_fd_));
-    if (status < 0) {
-      PLOG(ERROR) << "pipe";
-      return false;
-    }
-    base::PlatformFile data_file_ = pipe_fd_[0];  // read side
-    data_stream_.reset(new net::FileStream(data_file_,
-        base::PLATFORM_FILE_READ | base::PLATFORM_FILE_ASYNC,
-        NULL));
-
-    // Post an initial async read to setup data collection
-    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
-        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
-    if (rv != net::ERR_IO_PENDING) {
-      LOG(ERROR) << "Unable to post initial read";
-      return false;
-    }
-    return true;
-  }
-
-  // Called when pipe data are available.  Can also be used to shutdown
-  // data collection by passing -1 for |byte_count|.
-  void OnDataReady(int byte_count) {
-    DVLOG(1) << "OnDataReady byte_count " << byte_count;
-    if (byte_count <= 0) {
-      callback_.Run();  // signal creator to take data and delete us
-      return;
-    }
-    data_.append(io_buffer_->data(), byte_count);
-
-    // Post another read
-    int rv = data_stream_->Read(io_buffer_.get(), io_buffer_->size(),
-        base::Bind(&PipeReader::OnDataReady, weak_ptr_factory_.GetWeakPtr()));
-    if (rv != net::ERR_IO_PENDING) {
-      LOG(ERROR) << "Unable to post another read";
-      // TODO(sleffler) do something more intelligent?
-    }
-  }
-
- private:
-  friend class base::RefCounted<PipeReader>;
-
-  int pipe_fd_[2];
-  scoped_ptr<net::FileStream> data_stream_;
-  scoped_refptr<net::IOBufferWithSize> io_buffer_;
-  std::string data_;
-  IOCompleteCallback callback_;
-
-  // Note: This should remain the last member so it'll be destroyed and
-  // invalidate its weak pointers before any other members are destroyed.
-  base::WeakPtrFactory<PipeReader> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PipeReader);
-};
-
 }  // namespace
 
 namespace chromeos {
@@ -156,8 +54,8 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
     // issue the D-Bus request to stop tracing and collect results.
     base::WorkerPool::PostTaskAndReply(
         FROM_HERE,
-        base::Bind(&DebugDaemonClientImpl::CheckValidity,
-                   file_descriptor),
+        base::Bind(&dbus::FileDescriptor::CheckValidity,
+                   base::Unretained(file_descriptor)),
         base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
                    weak_ptr_factory_.GetWeakPtr(),
                    base::Owned(file_descriptor),
@@ -313,7 +211,7 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
     debugdaemon_proxy_->CallMethod(
         &method_call,
         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::Bind(&DebugDaemonClientImpl::OnStartSystemTracing,
+        base::Bind(&DebugDaemonClientImpl::OnStartMethod,
                    weak_ptr_factory_.GetWeakPtr()));
   }
 
@@ -324,32 +222,27 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
       return false;
     }
 
-    pipe_reader_.reset(new PipeReader(
+    scoped_refptr<base::TaskRunner> task_runner =
+        base::WorkerPool::GetTaskRunner(true /* task_is_slow */);
+
+    pipe_reader_.reset(new PipeReaderForString(
+        task_runner,
         base::Bind(&DebugDaemonClientImpl::OnIOComplete,
                    weak_ptr_factory_.GetWeakPtr())));
-    int write_fd = -1;
-    if (!pipe_reader_->StartIO()) {
-      LOG(ERROR) << "Cannot create pipe reader";
-      // NB: continue anyway to shutdown tracing; toss trace data
-      write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
-      // TODO(sleffler) if this fails AppendFileDescriptor will abort
-    } else {
-      write_fd = pipe_reader_->GetWriteFD();
-    }
 
-    dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
-    // Punt descriptor validity check to a worker thread; on return we'll
+    base::File pipe_write_end = pipe_reader_->StartIO();
+    // Create dbus::FileDescriptor on the worker thread; on return we'll
     // issue the D-Bus request to stop tracing and collect results.
-    base::WorkerPool::PostTaskAndReply(
+    base::PostTaskAndReplyWithResult(
+        task_runner,
         FROM_HERE,
-        base::Bind(&DebugDaemonClientImpl::CheckValidity,
-                   file_descriptor),
-        base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
-                   weak_ptr_factory_.GetWeakPtr(),
-                   base::Owned(file_descriptor),
-                   callback),
-        false);
-
+        base::Bind(
+            &DebugDaemonClientImpl::CreateFileDescriptorToStopSystemTracing,
+            base::Passed(&pipe_write_end)),
+        base::Bind(
+            &DebugDaemonClientImpl::OnCreateFileDescriptorRequestStopSystem,
+            weak_ptr_factory_.GetWeakPtr(),
+            callback));
     return true;
   }
 
@@ -400,6 +293,16 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
                    callback));
   }
 
+  virtual void UploadCrashes() OVERRIDE {
+    dbus::MethodCall method_call(debugd::kDebugdInterface,
+                                 debugd::kUploadCrashes);
+    debugdaemon_proxy_->CallMethod(
+        &method_call,
+        dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+        base::Bind(&DebugDaemonClientImpl::OnStartMethod,
+                   weak_ptr_factory_.GetWeakPtr()));
+  }
+
  protected:
   virtual void Init(dbus::Bus* bus) OVERRIDE {
     debugdaemon_proxy_ =
@@ -408,11 +311,6 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
   }
 
  private:
-  // Called to check descriptor validity on a thread where i/o is permitted.
-  static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
-    file_descriptor->CheckValidity();
-  }
-
   // Called when a CheckValidity response is received.
   void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
                                    const GetDebugLogsCallback& callback) {
@@ -553,18 +451,36 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
     return OnGetAllLogs(callback, response);
   }
 
-  // Called when a response for StartSystemTracing() is received.
-  void OnStartSystemTracing(dbus::Response* response) {
+  // Called when a response for a simple start is received.
+  void OnStartMethod(dbus::Response* response) {
     if (!response) {
-      LOG(ERROR) << "Failed to request systrace start";
+      LOG(ERROR) << "Failed to request start";
       return;
     }
   }
 
+  // Creates dbus::FileDescriptor from base::File.
+  static scoped_ptr<dbus::FileDescriptor>
+  CreateFileDescriptorToStopSystemTracing(base::File pipe_write_end) {
+    if (!pipe_write_end.IsValid()) {
+      LOG(ERROR) << "Cannot create pipe reader";
+      // NB: continue anyway to shutdown tracing; toss trace data
+      pipe_write_end.Initialize(base::FilePath(FILE_PATH_LITERAL("/dev/null")),
+                                base::File::FLAG_OPEN | base::File::FLAG_WRITE);
+      // TODO(sleffler) if this fails AppendFileDescriptor will abort
+    }
+    scoped_ptr<dbus::FileDescriptor> file_descriptor(new dbus::FileDescriptor);
+    file_descriptor->PutValue(pipe_write_end.TakePlatformFile());
+    file_descriptor->CheckValidity();
+    return file_descriptor.Pass();
+  }
+
   // Called when a CheckValidity response is received.
-  void OnCheckValidityRequestStopSystem(
-      dbus::FileDescriptor* file_descriptor,
-      const StopSystemTracingCallback& callback) {
+  void OnCreateFileDescriptorRequestStopSystem(
+      const StopSystemTracingCallback& callback,
+      scoped_ptr<dbus::FileDescriptor> file_descriptor) {
+    DCHECK(file_descriptor);
+
     // Issue the dbus request to stop system tracing
     dbus::MethodCall method_call(
         debugd::kDebugdInterface,
@@ -580,8 +496,6 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
         dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
         base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
                    weak_ptr_factory_.GetWeakPtr()));
-
-    pipe_reader_->CloseWriteFD();  // close our copy of fd after send
   }
 
   // Called when a response for RequestStopSystemTracing() is received.
@@ -606,12 +520,14 @@ class DebugDaemonClientImpl : public DebugDaemonClient {
 
   // Called when pipe i/o completes; pass data on and delete the instance.
   void OnIOComplete() {
-    callback_.Run(base::RefCountedString::TakeString(pipe_reader_->data()));
+    std::string pipe_data;
+    pipe_reader_->GetData(&pipe_data);
+    callback_.Run(base::RefCountedString::TakeString(&pipe_data));
     pipe_reader_.reset();
   }
 
   dbus::ObjectProxy* debugdaemon_proxy_;
-  scoped_ptr<PipeReader> pipe_reader_;
+  scoped_ptr<PipeReaderForString> pipe_reader_;
   StopSystemTracingCallback callback_;
   base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;