GN + Android: extract android_standalone_library rule.
[chromium-blink-merge.git] / remoting / host / chromeos / mouse_cursor_monitor_aura.cc
blobad48f141bc0cc040193096016d546607ba7618c3
1 // Copyright 2014 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.
5 #include "remoting/host/chromeos/mouse_cursor_monitor_aura.h"
7 #include "ash/shell.h"
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/location.h"
11 #include "remoting/host/chromeos/skia_bitmap_desktop_frame.h"
12 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
13 #include "ui/aura/env.h"
14 #include "ui/aura/window.h"
15 #include "ui/aura/window_tree_host.h"
16 #include "ui/base/cursor/cursors_aura.h"
18 namespace remoting {
20 MouseCursorMonitorAura::MouseCursorMonitorAura()
21 : callback_(nullptr),
22 mode_(SHAPE_AND_POSITION) {
25 void MouseCursorMonitorAura::Init(Callback* callback, Mode mode) {
26 DCHECK(!callback_);
27 DCHECK(callback);
29 callback_ = callback;
30 mode_ = mode;
33 void MouseCursorMonitorAura::Capture() {
34 // Check if the cursor is different.
35 gfx::NativeCursor cursor =
36 ash::Shell::GetPrimaryRootWindow()->GetHost()->last_cursor();
38 if (cursor != last_cursor_) {
39 NotifyCursorChanged(cursor);
42 // Check if we need to update the location.
43 if (mode_ == SHAPE_AND_POSITION) {
44 gfx::Point position = aura::Env::GetInstance()->last_mouse_location();
45 if (position != last_mouse_location_) {
46 last_mouse_location_ = position;
47 callback_->OnMouseCursorPosition(
48 INSIDE, webrtc::DesktopVector(position.x(), position.y()));
53 void MouseCursorMonitorAura::NotifyCursorChanged(const ui::Cursor& cursor) {
54 scoped_ptr<SkBitmap> cursor_bitmap(new SkBitmap());
55 gfx::Point cursor_hotspot;
56 if (!ui::GetCursorBitmap(cursor, cursor_bitmap.get(), &cursor_hotspot)) {
57 LOG(ERROR) << "Failed to load bitmap for cursor type:"
58 << cursor.native_type();
59 return;
62 last_cursor_ = cursor;
64 // There is a bug (crbug.com/436993) in aura::GetCursorBitmap() such that it
65 // it would return a scale-factor-100 bitmap with a scale-factor-200 hotspot.
66 // This causes the hotspot to go out of range. As a result, we would need to
67 // manually downscale the hotspot.
68 float scale_factor = cursor.device_scale_factor();
69 cursor_hotspot.SetPoint(cursor_hotspot.x() / scale_factor,
70 cursor_hotspot.y() / scale_factor);
72 if (cursor_hotspot.x() >= cursor_bitmap->width() ||
73 cursor_hotspot.y() >= cursor_bitmap->height()) {
74 LOG(WARNING) << "Cursor hotspot is out of bounds for type: "
75 << cursor.native_type() << ". Setting to (0,0) instead";
76 cursor_hotspot.SetPoint(0, 0);
79 scoped_ptr<webrtc::DesktopFrame> image(
80 SkiaBitmapDesktopFrame::Create(cursor_bitmap.Pass()));
81 scoped_ptr<webrtc::MouseCursor> cursor_shape(new webrtc::MouseCursor(
82 image.release(),
83 webrtc::DesktopVector(cursor_hotspot.x(), cursor_hotspot.y())));
85 callback_->OnMouseCursor(cursor_shape.release());
88 } // namespace remoting