Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / media / video / capture / linux / video_capture_device_chromeos.cc
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.
4
5 #include "media/video/capture/linux/video_capture_device_chromeos.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "ui/gfx/display.h"
11 #include "ui/gfx/display_observer.h"
12 #include "ui/gfx/screen.h"
13
14 namespace media {
15
16 // This is a delegate class used to transfer Display change events from the UI
17 // thread to the media thread.
18 class VideoCaptureDeviceChromeOS::ScreenObserverDelegate
19     : public gfx::DisplayObserver,
20       public base::RefCountedThreadSafe<ScreenObserverDelegate> {
21  public:
22   ScreenObserverDelegate(
23       VideoCaptureDeviceChromeOS* capture_device,
24       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
25       : capture_device_(capture_device),
26         ui_task_runner_(ui_task_runner),
27         capture_task_runner_(base::MessageLoopProxy::current()) {
28     ui_task_runner_->PostTask(
29         FROM_HERE,
30         base::Bind(&ScreenObserverDelegate::AddObserverOnUIThread, this));
31   }
32
33   void RemoveObserver() {
34     DCHECK(capture_task_runner_->BelongsToCurrentThread());
35     capture_device_ = NULL;
36     ui_task_runner_->PostTask(
37         FROM_HERE,
38         base::Bind(&ScreenObserverDelegate::RemoveObserverOnUIThread, this));
39   }
40
41  private:
42   friend class base::RefCountedThreadSafe<ScreenObserverDelegate>;
43
44   virtual ~ScreenObserverDelegate() {
45     DCHECK(!capture_device_);
46   }
47
48   virtual void OnDisplayAdded(const gfx::Display& /*new_display*/) override {}
49   virtual void OnDisplayRemoved(const gfx::Display& /*old_display*/) override {}
50   virtual void OnDisplayMetricsChanged(const gfx::Display& display,
51                                        uint32_t metrics) override {
52     DCHECK(ui_task_runner_->BelongsToCurrentThread());
53     if (!(metrics & DISPLAY_METRIC_ROTATION))
54       return;
55     SendDisplayRotation(display);
56   }
57
58   void AddObserverOnUIThread() {
59     DCHECK(ui_task_runner_->BelongsToCurrentThread());
60     gfx::Screen* screen =
61         gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
62     if (screen) {
63       screen->AddObserver(this);
64       SendDisplayRotation(screen->GetPrimaryDisplay());
65     }
66   }
67
68   void RemoveObserverOnUIThread() {
69     DCHECK(ui_task_runner_->BelongsToCurrentThread());
70     gfx::Screen* screen =
71         gfx::Screen::GetScreenByType(gfx::SCREEN_TYPE_ALTERNATE);
72     if (screen)
73       screen->RemoveObserver(this);
74   }
75
76   // Post the screen rotation change from the UI thread to capture thread
77   void SendDisplayRotation(const gfx::Display& display) {
78     DCHECK(ui_task_runner_->BelongsToCurrentThread());
79     capture_task_runner_->PostTask(
80         FROM_HERE,
81         base::Bind(&ScreenObserverDelegate::SendDisplayRotationOnCaptureThread,
82                    this, display));
83   }
84
85   void SendDisplayRotationOnCaptureThread(const gfx::Display& display) {
86     DCHECK(capture_task_runner_->BelongsToCurrentThread());
87     if (capture_device_)
88       capture_device_->SetDisplayRotation(display);
89   }
90
91   VideoCaptureDeviceChromeOS* capture_device_;
92   scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
93   scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner_;
94   DISALLOW_IMPLICIT_CONSTRUCTORS(ScreenObserverDelegate);
95 };
96
97
98 VideoCaptureDeviceChromeOS::VideoCaptureDeviceChromeOS(
99     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
100     const Name& device_name)
101     : VideoCaptureDeviceLinux(device_name),
102       screen_observer_delegate_(new ScreenObserverDelegate(this,
103                                                            ui_task_runner)) {
104 }
105
106 VideoCaptureDeviceChromeOS::~VideoCaptureDeviceChromeOS() {
107   screen_observer_delegate_->RemoveObserver();
108 }
109
110 void VideoCaptureDeviceChromeOS::SetDisplayRotation(
111     const gfx::Display& display) {
112   if (display.IsInternal())
113     SetRotation(display.rotation() * 90);
114 }
115
116 }  // namespace media