1// Copyright (c) 2013 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#include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
5
6#include "base/power_monitor/power_monitor.h"
7#include "content/browser/media/webrtc_internals.h"
8#include "content/common/media/peer_connection_tracker_messages.h"
9#include "content/public/browser/render_process_host.h"
10
11namespace content {
12
13PeerConnectionTrackerHost::PeerConnectionTrackerHost(int render_process_id)
14    : BrowserMessageFilter(PeerConnectionTrackerMsgStart),
15      render_process_id_(render_process_id) {
16}
17
18bool PeerConnectionTrackerHost::OnMessageReceived(const IPC::Message& message) {
19  bool handled = true;
20
21  IPC_BEGIN_MESSAGE_MAP(PeerConnectionTrackerHost, message)
22    IPC_MESSAGE_HANDLER(PeerConnectionTrackerHost_AddPeerConnection,
23                        OnAddPeerConnection)
24    IPC_MESSAGE_HANDLER(PeerConnectionTrackerHost_RemovePeerConnection,
25                        OnRemovePeerConnection)
26    IPC_MESSAGE_HANDLER(PeerConnectionTrackerHost_UpdatePeerConnection,
27                        OnUpdatePeerConnection)
28    IPC_MESSAGE_HANDLER(PeerConnectionTrackerHost_AddStats, OnAddStats)
29    IPC_MESSAGE_HANDLER(PeerConnectionTrackerHost_GetUserMedia, OnGetUserMedia)
30    IPC_MESSAGE_UNHANDLED(handled = false)
31  IPC_END_MESSAGE_MAP()
32  return handled;
33}
34
35void PeerConnectionTrackerHost::OverrideThreadForMessage(
36    const IPC::Message& message, BrowserThread::ID* thread) {
37  if (IPC_MESSAGE_CLASS(message) == PeerConnectionTrackerMsgStart)
38    *thread = BrowserThread::UI;
39}
40
41PeerConnectionTrackerHost::~PeerConnectionTrackerHost() {
42}
43
44void PeerConnectionTrackerHost::OnChannelConnected(int32 peer_pid) {
45  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
46  // Add PowerMonitor when connected to channel rather than in constructor due
47  // to thread safety concerns. Observers of PowerMonitor must be added and
48  // removed on the same thread. BrowserMessageFilter is created on the UI
49  // thread but can be destructed on the UI or IO thread because they are
50  // referenced by RenderProcessHostImpl on the UI thread and ChannelProxy on
51  // the IO thread. Using OnChannelConnected and OnChannelClosing guarantees
52  // execution on the IO thread.
53  base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
54  if (power_monitor)
55    power_monitor->AddObserver(this);
56}
57
58void PeerConnectionTrackerHost::OnChannelClosing() {
59  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
60  base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
61  if (power_monitor)
62    power_monitor->RemoveObserver(this);
63}
64
65void PeerConnectionTrackerHost::OnAddPeerConnection(
66    const PeerConnectionInfo& info) {
67  WebRTCInternals::GetInstance()->OnAddPeerConnection(
68      render_process_id_,
69      peer_pid(),
70      info.lid,
71      info.url,
72      info.rtc_configuration,
73      info.constraints);
74}
75
76void PeerConnectionTrackerHost::OnRemovePeerConnection(int lid) {
77  WebRTCInternals::GetInstance()->OnRemovePeerConnection(peer_pid(), lid);
78}
79
80void PeerConnectionTrackerHost::OnUpdatePeerConnection(
81    int lid, const std::string& type, const std::string& value) {
82  WebRTCInternals::GetInstance()->OnUpdatePeerConnection(
83      peer_pid(),
84      lid,
85      type,
86      value);
87}
88
89void PeerConnectionTrackerHost::OnAddStats(int lid,
90                                           const base::ListValue& value) {
91  WebRTCInternals::GetInstance()->OnAddStats(peer_pid(), lid, value);
92}
93
94void PeerConnectionTrackerHost::OnGetUserMedia(
95    const std::string& origin,
96    bool audio,
97    bool video,
98    const std::string& audio_constraints,
99    const std::string& video_constraints) {
100  WebRTCInternals::GetInstance()->OnGetUserMedia(render_process_id_,
101                                                 peer_pid(),
102                                                 origin,
103                                                 audio,
104                                                 video,
105                                                 audio_constraints,
106                                                 video_constraints);
107}
108
109void PeerConnectionTrackerHost::OnSuspend() {
110  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
111      base::Bind(&PeerConnectionTrackerHost::SendOnSuspendOnUIThread, this));
112}
113
114void PeerConnectionTrackerHost::SendOnSuspendOnUIThread() {
115  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
116  content::RenderProcessHost* host =
117      content::RenderProcessHost::FromID(render_process_id_);
118  if (host)
119    host->Send(new PeerConnectionTracker_OnSuspend());
120}
121
122}  // namespace content
123