blob: f69169e93e938151c7b2a8131f89b097533ceb6b [file] [log] [blame]
[email protected]11158e2d2013-02-01 02:31:561// Copyright (c) 2012 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 "content/browser/media/media_internals.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/string16.h"
9#include "base/stringprintf.h"
10#include "content/public/browser/browser_thread.h"
11#include "content/public/browser/web_ui.h"
12#include "media/base/media_log.h"
13#include "media/base/media_log_event.h"
14
15namespace content {
16
17MediaInternals* MediaInternals::GetInstance() {
18 return Singleton<MediaInternals>::get();
19}
20
21MediaInternals::~MediaInternals() {}
22
23void MediaInternals::OnDeleteAudioStream(void* host, int stream_id) {
24 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
25 std::string stream = base::StringPrintf("audio_streams.%p:%d",
26 host, stream_id);
27 DeleteItem(stream);
28}
29
30void MediaInternals::OnSetAudioStreamPlaying(
31 void* host, int stream_id, bool playing) {
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
33 UpdateAudioStream(host, stream_id,
[email protected]0cd50aa2013-02-12 22:28:0134 "playing", new base::FundamentalValue(playing));
[email protected]11158e2d2013-02-01 02:31:5635}
36
37void MediaInternals::OnSetAudioStreamStatus(
38 void* host, int stream_id, const std::string& status) {
39 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
40 UpdateAudioStream(host, stream_id,
[email protected]0cd50aa2013-02-12 22:28:0141 "status", new base::StringValue(status));
[email protected]11158e2d2013-02-01 02:31:5642}
43
44void MediaInternals::OnSetAudioStreamVolume(
45 void* host, int stream_id, double volume) {
46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
47 UpdateAudioStream(host, stream_id,
[email protected]0cd50aa2013-02-12 22:28:0148 "volume", new base::FundamentalValue(volume));
[email protected]11158e2d2013-02-01 02:31:5649}
50
[email protected]0e7ee582013-05-04 14:06:5951void MediaInternals::OnMediaEvents(
52 int render_process_id, const std::vector<media::MediaLogEvent>& events) {
[email protected]11158e2d2013-02-01 02:31:5653 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
54
55 // Notify observers that |event| has occured.
[email protected]0e7ee582013-05-04 14:06:5956 for (std::vector<media::MediaLogEvent>::const_iterator event = events.begin();
57 event != events.end(); ++event) {
58 base::DictionaryValue dict;
59 dict.SetInteger("renderer", render_process_id);
60 dict.SetInteger("player", event->id);
61 dict.SetString("type", media::MediaLog::EventTypeToString(event->type));
62 dict.SetDouble("time", event->time.ToDoubleT());
63 dict.Set("params", event->params.DeepCopy());
64 SendUpdate("media.onMediaEvent", &dict);
65 }
[email protected]11158e2d2013-02-01 02:31:5666}
67
68void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) {
69 update_callbacks_.push_back(callback);
70}
71
72void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) {
73 for (size_t i = 0; i < update_callbacks_.size(); ++i) {
74 if (update_callbacks_[i].Equals(callback)) {
75 update_callbacks_.erase(update_callbacks_.begin() + i);
76 return;
77 }
78 }
79 NOTREACHED();
80}
81
82void MediaInternals::SendEverything() {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
84 SendUpdate("media.onReceiveEverything", &data_);
85}
86
87MediaInternals::MediaInternals() {
88}
89
[email protected]0cd50aa2013-02-12 22:28:0190void MediaInternals::UpdateAudioStream(void* host,
91 int stream_id,
92 const std::string& property,
93 base::Value* value) {
[email protected]11158e2d2013-02-01 02:31:5694 std::string stream = base::StringPrintf("audio_streams.%p:%d",
95 host, stream_id);
96 UpdateItem("media.addAudioStream", stream, property, value);
97}
98
99void MediaInternals::DeleteItem(const std::string& item) {
100 data_.Remove(item, NULL);
[email protected]0cd50aa2013-02-12 22:28:01101 scoped_ptr<base::Value> value(new base::StringValue(item));
[email protected]11158e2d2013-02-01 02:31:56102 SendUpdate("media.onItemDeleted", value.get());
103}
104
105void MediaInternals::UpdateItem(
106 const std::string& update_fn, const std::string& id,
[email protected]0cd50aa2013-02-12 22:28:01107 const std::string& property, base::Value* value) {
108 base::DictionaryValue* item_properties;
[email protected]11158e2d2013-02-01 02:31:56109 if (!data_.GetDictionary(id, &item_properties)) {
[email protected]0cd50aa2013-02-12 22:28:01110 item_properties = new base::DictionaryValue();
[email protected]11158e2d2013-02-01 02:31:56111 data_.Set(id, item_properties);
112 item_properties->SetString("id", id);
113 }
114 item_properties->Set(property, value);
115 SendUpdate(update_fn, item_properties);
116}
117
[email protected]0cd50aa2013-02-12 22:28:01118void MediaInternals::SendUpdate(const std::string& function,
119 base::Value* value) {
[email protected]11158e2d2013-02-01 02:31:56120 // Only bother serializing the update to JSON if someone is watching.
121 if (update_callbacks_.empty())
122 return;
123
[email protected]0cd50aa2013-02-12 22:28:01124 std::vector<const base::Value*> args;
[email protected]11158e2d2013-02-01 02:31:56125 args.push_back(value);
126 string16 update = WebUI::GetJavascriptCall(function, args);
127 for (size_t i = 0; i < update_callbacks_.size(); i++)
128 update_callbacks_[i].Run(update);
129}
130
131} // namespace content