12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/media/media_internals.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_ui.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_log.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/media_log_event.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaInternals* MediaInternals::GetInstance() { 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Singleton<MediaInternals>::get(); 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaInternals::~MediaInternals() {} 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::OnDeleteAudioStream(void* host, int stream_id) { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string stream = base::StringPrintf("audio_streams.%p:%d", 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host, stream_id); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeleteItem(stream); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::OnSetAudioStreamPlaying( 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* host, int stream_id, bool playing) { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAudioStream(host, stream_id, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "playing", new base::FundamentalValue(playing)); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::OnSetAudioStreamStatus( 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* host, int stream_id, const std::string& status) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAudioStream(host, stream_id, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "status", new base::StringValue(status)); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::OnSetAudioStreamVolume( 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* host, int stream_id, double volume) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateAudioStream(host, stream_id, 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "volume", new base::FundamentalValue(volume)); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaInternals::OnMediaEvents( 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_process_id, const std::vector<media::MediaLogEvent>& events) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Notify observers that |event| has occured. 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (std::vector<media::MediaLogEvent>::const_iterator event = events.begin(); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event != events.end(); ++event) { 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::DictionaryValue dict; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict.SetInteger("renderer", render_process_id); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict.SetInteger("player", event->id); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict.SetString("type", media::MediaLog::EventTypeToString(event->type)); 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 ticks = event->time.ToInternalValue(); 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch double ticks_millis = 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ticks / static_cast<double>(base::Time::kMicrosecondsPerMillisecond); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dict.SetDouble("ticksMillis", ticks_millis); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) dict.Set("params", event->params.DeepCopy()); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendUpdate("media.onMediaEvent", &dict); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_callbacks_.push_back(callback); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < update_callbacks_.size(); ++i) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update_callbacks_[i].Equals(callback)) { 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_callbacks_.erase(update_callbacks_.begin() + i); 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::SendEverything() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendUpdate("media.onReceiveEverything", &data_); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaInternals::MediaInternals() { 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::UpdateAudioStream(void* host, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int stream_id, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& property, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string stream = base::StringPrintf("audio_streams.%p:%d", 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) host, stream_id); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateItem("media.addAudioStream", stream, property, value); 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::DeleteItem(const std::string& item) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_.Remove(item, NULL); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> value(new base::StringValue(item)); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendUpdate("media.onItemDeleted", value.get()); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::UpdateItem( 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& update_fn, const std::string& id, 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& property, base::Value* value) { 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue* item_properties; 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!data_.GetDictionary(id, &item_properties)) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_properties = new base::DictionaryValue(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_.Set(id, item_properties); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_properties->SetString("id", id); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) item_properties->Set(property, value); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendUpdate(update_fn, item_properties); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaInternals::SendUpdate(const std::string& function, 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* value) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only bother serializing the update to JSON if someone is watching. 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update_callbacks_.empty()) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<const base::Value*> args; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.push_back(value); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) string16 update = WebUI::GetJavascriptCall(function, args); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < update_callbacks_.size(); i++) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_callbacks_[i].Run(update); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 137