OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "remoting/host/mouse_shape_pump.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/location.h" |
| 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/timer/timer.h" |
| 11 #include "remoting/proto/control.pb.h" |
| 12 #include "remoting/protocol/cursor_shape_stub.h" |
| 13 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 14 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h" |
| 15 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" |
| 16 |
| 17 namespace remoting { |
| 18 |
| 19 // Poll mouse shape 10 times a second. |
| 20 static const int kCursorCaptureIntervalMs = 100; |
| 21 |
| 22 class MouseShapePump::Core : public webrtc::MouseCursorMonitor::Callback { |
| 23 public: |
| 24 Core(base::WeakPtr<MouseShapePump> proxy, |
| 25 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
| 26 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
| 27 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor); |
| 28 ~Core(); |
| 29 |
| 30 void Start(); |
| 31 void Capture(); |
| 32 |
| 33 private: |
| 34 // webrtc::MouseCursorMonitor::Callback implementation. |
| 35 void OnMouseCursor(webrtc::MouseCursor* mouse_cursor) override; |
| 36 void OnMouseCursorPosition(webrtc::MouseCursorMonitor::CursorState state, |
| 37 const webrtc::DesktopVector& position) override; |
| 38 |
| 39 base::WeakPtr<MouseShapePump> proxy_; |
| 40 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_; |
| 41 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_; |
| 42 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor_; |
| 43 |
| 44 base::Timer capture_timer_; |
| 45 |
| 46 DISALLOW_COPY_AND_ASSIGN(Core); |
| 47 }; |
| 48 |
| 49 MouseShapePump::Core::Core( |
| 50 base::WeakPtr<MouseShapePump> proxy, |
| 51 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
| 52 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
| 53 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor) |
| 54 : proxy_(proxy), |
| 55 network_task_runner_(network_task_runner), |
| 56 capture_task_runner_(capture_task_runner), |
| 57 mouse_cursor_monitor_(mouse_cursor_monitor.Pass()), |
| 58 capture_timer_(true, true) { |
| 59 } |
| 60 |
| 61 MouseShapePump::Core::~Core() { |
| 62 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 63 } |
| 64 |
| 65 void MouseShapePump::Core::Start() { |
| 66 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 67 |
| 68 mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY); |
| 69 |
| 70 capture_timer_.Start( |
| 71 FROM_HERE, base::TimeDelta::FromMilliseconds(kCursorCaptureIntervalMs), |
| 72 base::Bind(&MouseShapePump::Core::Capture, base::Unretained(this))); |
| 73 } |
| 74 |
| 75 void MouseShapePump::Core::Capture() { |
| 76 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 77 |
| 78 mouse_cursor_monitor_->Capture(); |
| 79 } |
| 80 |
| 81 void MouseShapePump::Core::OnMouseCursor(webrtc::MouseCursor* cursor) { |
| 82 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 83 |
| 84 scoped_ptr<webrtc::MouseCursor> owned_cursor(cursor); |
| 85 |
| 86 scoped_ptr<protocol::CursorShapeInfo> cursor_proto( |
| 87 new protocol::CursorShapeInfo()); |
| 88 cursor_proto->set_width(cursor->image()->size().width()); |
| 89 cursor_proto->set_height(cursor->image()->size().height()); |
| 90 cursor_proto->set_hotspot_x(cursor->hotspot().x()); |
| 91 cursor_proto->set_hotspot_y(cursor->hotspot().y()); |
| 92 |
| 93 cursor_proto->set_data(std::string()); |
| 94 uint8_t* current_row = cursor->image()->data(); |
| 95 for (int y = 0; y < cursor->image()->size().height(); ++y) { |
| 96 cursor_proto->mutable_data()->append( |
| 97 current_row, |
| 98 current_row + cursor->image()->size().width() * |
| 99 webrtc::DesktopFrame::kBytesPerPixel); |
| 100 current_row += cursor->image()->stride(); |
| 101 } |
| 102 |
| 103 network_task_runner_->PostTask( |
| 104 FROM_HERE, base::Bind(&MouseShapePump::OnCursorShape, proxy_, |
| 105 base::Passed(&cursor_proto))); |
| 106 } |
| 107 |
| 108 void MouseShapePump::Core::OnMouseCursorPosition( |
| 109 webrtc::MouseCursorMonitor::CursorState state, |
| 110 const webrtc::DesktopVector& position) { |
| 111 // We're not subscribing to mouse position changes. |
| 112 NOTREACHED(); |
| 113 } |
| 114 |
| 115 MouseShapePump::MouseShapePump( |
| 116 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
| 117 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
| 118 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor, |
| 119 protocol::CursorShapeStub* cursor_shape_stub) |
| 120 : network_task_runner_(network_task_runner), |
| 121 capture_task_runner_(capture_task_runner), |
| 122 cursor_shape_stub_(cursor_shape_stub), |
| 123 weak_factory_(this) { |
| 124 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 125 |
| 126 core_.reset(new Core(weak_factory_.GetWeakPtr(), network_task_runner, |
| 127 capture_task_runner, mouse_cursor_monitor.Pass())); |
| 128 capture_task_runner_->PostTask( |
| 129 FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()))); |
| 130 } |
| 131 |
| 132 MouseShapePump::~MouseShapePump() { |
| 133 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 134 |
| 135 capture_task_runner_->DeleteSoon(FROM_HERE, core_.release()); |
| 136 } |
| 137 |
| 138 void MouseShapePump::OnCursorShape( |
| 139 scoped_ptr<protocol::CursorShapeInfo> cursor) { |
| 140 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 141 |
| 142 cursor_shape_stub_->SetCursorShape(*cursor); |
| 143 } |
| 144 |
| 145 } // namespace remoting |
OLD | NEW |