Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / media / capture / desktop_capture_device.cc
index bcd0dbb..446e9e2 100644 (file)
@@ -7,10 +7,14 @@
 #include "base/bind.h"
 #include "base/location.h"
 #include "base/logging.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram.h"
 #include "base/sequenced_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/sequenced_worker_pool.h"
+#include "base/threading/thread.h"
+#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/desktop_media_id.h"
 #include "media/base/video_util.h"
@@ -50,7 +54,9 @@ class DesktopCaptureDevice::Core
       public webrtc::DesktopCapturer::Callback {
  public:
   Core(scoped_refptr<base::SequencedTaskRunner> task_runner,
-       scoped_ptr<webrtc::DesktopCapturer> capturer);
+       scoped_ptr<base::Thread> thread,
+       scoped_ptr<webrtc::DesktopCapturer> capturer,
+       DesktopMediaID::Type type);
 
   // Implementation of VideoCaptureDevice methods.
   void AllocateAndStart(const media::VideoCaptureParams& params,
@@ -93,6 +99,9 @@ class DesktopCaptureDevice::Core
   // Task runner used for capturing operations.
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
+  // The thread on which the capturer is running.
+  scoped_ptr<base::Thread> thread_;
+
   // The underlying DesktopCapturer instance used to capture frames.
   scoped_ptr<webrtc::DesktopCapturer> desktop_capturer_;
 
@@ -125,16 +134,27 @@ class DesktopCaptureDevice::Core
   // True when waiting for |desktop_capturer_| to capture current frame.
   bool capture_in_progress_;
 
+  // The type of the capturer.
+  DesktopMediaID::Type capturer_type_;
+
   DISALLOW_COPY_AND_ASSIGN(Core);
 };
 
 DesktopCaptureDevice::Core::Core(
     scoped_refptr<base::SequencedTaskRunner> task_runner,
-    scoped_ptr<webrtc::DesktopCapturer> capturer)
+    scoped_ptr<base::Thread> thread,
+    scoped_ptr<webrtc::DesktopCapturer> capturer,
+    DesktopMediaID::Type type)
     : task_runner_(task_runner),
+      thread_(thread.Pass()),
       desktop_capturer_(capturer.Pass()),
       capture_task_posted_(false),
-      capture_in_progress_(false) {}
+      capture_in_progress_(false),
+      capturer_type_(type) {
+  DCHECK(!task_runner_.get() || !thread_.get());
+  if (thread_.get())
+    task_runner_ = thread_->message_loop_proxy();
+}
 
 DesktopCaptureDevice::Core::~Core() {
 }
@@ -172,6 +192,18 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted(
   DCHECK(task_runner_->RunsTasksOnCurrentThread());
   DCHECK(capture_in_progress_);
 
+  static bool first_call = true;
+  if (first_call) {
+    first_call = false;
+    if (capturer_type_ == DesktopMediaID::TYPE_SCREEN) {
+      IncrementDesktopCaptureCounter(frame ? FIRST_SCREEN_CAPTURE_SUCCEEDED
+                                           : FIRST_SCREEN_CAPTURE_FAILED);
+    } else {
+      IncrementDesktopCaptureCounter(frame ? FIRST_WINDOW_CAPTURE_SUCCEEDED
+                                           : FIRST_WINDOW_CAPTURE_FAILED);
+    }
+  }
+
   capture_in_progress_ = false;
 
   if (!frame) {
@@ -184,6 +216,13 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted(
   if (!client_)
     return;
 
+  base::TimeDelta capture_time(
+      base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
+  UMA_HISTOGRAM_TIMES(
+      capturer_type_ == DesktopMediaID::TYPE_SCREEN ? kUmaScreenCaptureTime
+                                                    : kUmaWindowCaptureTime,
+      capture_time);
+
   scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
 
   // Handle initial frame size and size changes.
@@ -368,11 +407,7 @@ void DesktopCaptureDevice::Core::DoSetNotificationWindowId(
 // static
 scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
     const DesktopMediaID& source) {
-  scoped_refptr<base::SequencedWorkerPool> blocking_pool =
-      BrowserThread::GetBlockingPool();
-  scoped_refptr<base::SequencedTaskRunner> task_runner =
-      blocking_pool->GetSequencedTaskRunner(
-          blocking_pool->GetSequenceToken());
+  scoped_ptr<base::Thread> ui_thread;
 
   webrtc::DesktopCaptureOptions options =
       webrtc::DesktopCaptureOptions::CreateDefault();
@@ -384,11 +419,28 @@ scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
   switch (source.type) {
     case DesktopMediaID::TYPE_SCREEN: {
       scoped_ptr<webrtc::ScreenCapturer> screen_capturer;
+
+#if defined(OS_WIN)
+      bool magnification_allowed =
+          base::FieldTrialList::FindFullName("ScreenCaptureUseMagnification") ==
+          "Enabled";
+
+      if (magnification_allowed) {
+        // The magnification capturer requires running on a dedicated UI thread.
+        ui_thread.reset(new base::Thread("screenCaptureUIThread"));
+        base::Thread::Options thread_options(base::MessageLoop::TYPE_UI, 0);
+        ui_thread->StartWithOptions(thread_options);
+
+        options.set_allow_use_magnification_api(true);
+      }
+#endif
+
       screen_capturer.reset(webrtc::ScreenCapturer::Create(options));
       if (screen_capturer && screen_capturer->SelectScreen(source.id)) {
         capturer.reset(new webrtc::DesktopAndCursorComposer(
             screen_capturer.release(),
             webrtc::MouseCursorMonitor::CreateForScreen(options, source.id)));
+        IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED);
       }
       break;
     }
@@ -401,6 +453,7 @@ scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
         capturer.reset(new webrtc::DesktopAndCursorComposer(
             window_capturer.release(),
             webrtc::MouseCursorMonitor::CreateForWindow(options, source.id)));
+        IncrementDesktopCaptureCounter(WINDOW_CATPTURER_CREATED);
       }
       break;
     }
@@ -411,17 +464,21 @@ scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
   }
 
   scoped_ptr<media::VideoCaptureDevice> result;
-  if (capturer)
-    result.reset(new DesktopCaptureDevice(task_runner, capturer.Pass()));
+  if (capturer) {
+    scoped_refptr<base::SequencedTaskRunner> task_runner;
+    if (!ui_thread.get()) {
+      scoped_refptr<base::SequencedWorkerPool> blocking_pool =
+          BrowserThread::GetBlockingPool();
+      task_runner = blocking_pool->GetSequencedTaskRunner(
+          blocking_pool->GetSequenceToken());
+    }
+    result.reset(new DesktopCaptureDevice(
+        task_runner, ui_thread.Pass(), capturer.Pass(), source.type));
+  }
 
   return result.Pass();
 }
 
-DesktopCaptureDevice::DesktopCaptureDevice(
-    scoped_refptr<base::SequencedTaskRunner> task_runner,
-    scoped_ptr<webrtc::DesktopCapturer> capturer)
-    : core_(new Core(task_runner, capturer.Pass())) {}
-
 DesktopCaptureDevice::~DesktopCaptureDevice() {
   StopAndDeAllocate();
 }
@@ -441,4 +498,12 @@ void DesktopCaptureDevice::SetNotificationWindowId(
   core_->SetNotificationWindowId(window_id);
 }
 
+DesktopCaptureDevice::DesktopCaptureDevice(
+    scoped_refptr<base::SequencedTaskRunner> task_runner,
+    scoped_ptr<base::Thread> thread,
+    scoped_ptr<webrtc::DesktopCapturer> capturer,
+    DesktopMediaID::Type type)
+    : core_(new Core(task_runner, thread.Pass(), capturer.Pass(), type)) {
+}
+
 }  // namespace content