1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/ash/media_delegate_chromeos.h" 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/shell.h" 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ash/system/tray/system_tray_notifier.h" 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/message_loop/message_loop.h" 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/extensions/media_player_api.h" 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/chromeos/extensions/media_player_event_router.h" 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/media/media_stream_capture_indicator.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/render_view_host.h" 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/public/browser/web_contents.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/app_window/app_window_registry.h" 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/extension_system.h" 23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/process_manager.h" 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace { 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GetMediaCaptureState( 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const MediaStreamCaptureIndicator* indicator, 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents, 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int* media_state_out) { 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (indicator->IsCapturingVideo(web_contents)) 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *media_state_out |= ash::MEDIA_CAPTURE_VIDEO; 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (indicator->IsCapturingAudio(web_contents)) 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) *media_state_out |= ash::MEDIA_CAPTURE_AUDIO; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GetBrowserMediaCaptureState( 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const MediaStreamCaptureIndicator* indicator, 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::BrowserContext* context, 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int* media_state_out) { 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const BrowserList* desktop_list = 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (BrowserList::BrowserVector::const_iterator iter = desktop_list->begin(); 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) iter != desktop_list->end(); 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++iter) { 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TabStripModel* tab_strip_model = (*iter)->tab_strip_model(); 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (int i = 0; i < tab_strip_model->count(); ++i) { 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents = tab_strip_model->GetWebContentsAt(i); 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (web_contents->GetBrowserContext() != context) 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetMediaCaptureState(indicator, web_contents, media_state_out); 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO) 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GetAppMediaCaptureState( 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const MediaStreamCaptureIndicator* indicator, 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int* media_state_out) { 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const extensions::AppWindowRegistry::AppWindowList& apps = 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extensions::AppWindowRegistry::Get(context)->app_windows(); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (extensions::AppWindowRegistry::AppWindowList::const_iterator iter = 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) apps.begin(); 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) iter != apps.end(); 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++iter) { 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetMediaCaptureState(indicator, (*iter)->web_contents(), media_state_out); 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO) 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void GetExtensionMediaCaptureState( 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const MediaStreamCaptureIndicator* indicator, 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context, 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int* media_state_out) { 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extensions::ProcessManager* process_manager = 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extensions::ExtensionSystem::Get(context)->process_manager(); 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const extensions::ProcessManager::ViewSet view_set = 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) process_manager->GetAllViews(); 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) for (extensions::ProcessManager::ViewSet::const_iterator iter = 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) view_set.begin(); 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) iter != view_set.end(); 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ++iter) { 88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents* web_contents = 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::WebContents::FromRenderViewHost(*iter); 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // RVH may not have web contents. 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!web_contents) 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) continue; 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetMediaCaptureState(indicator, web_contents, media_state_out); 94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (*media_state_out == ash::MEDIA_CAPTURE_AUDIO_VIDEO) 95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ash::MediaCaptureState GetMediaCaptureStateOfAllWebContents( 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context) { 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!context) 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ash::MEDIA_CAPTURE_NONE; 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<MediaStreamCaptureIndicator> indicator = 105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance() 106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->GetMediaStreamCaptureIndicator(); 107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int media_state = ash::MEDIA_CAPTURE_NONE; 109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Browser windows 110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetBrowserMediaCaptureState(indicator.get(), context, &media_state); 111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (media_state == ash::MEDIA_CAPTURE_AUDIO_VIDEO) 112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ash::MEDIA_CAPTURE_AUDIO_VIDEO; 113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // App windows 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetAppMediaCaptureState(indicator.get(), context, &media_state); 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (media_state == ash::MEDIA_CAPTURE_AUDIO_VIDEO) 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return ash::MEDIA_CAPTURE_AUDIO_VIDEO; 118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Extensions 120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) GetExtensionMediaCaptureState(indicator.get(), context, &media_state); 121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return static_cast<ash::MediaCaptureState>(media_state); 123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace 126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)MediaDelegateChromeOS::MediaDelegateChromeOS() : weak_ptr_factory_(this) { 128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this); 129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)MediaDelegateChromeOS::~MediaDelegateChromeOS() { 132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this); 133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void MediaDelegateChromeOS::HandleMediaNextTrack() { 136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile()) 137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->media_player_event_router() 138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->NotifyNextTrack(); 139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void MediaDelegateChromeOS::HandleMediaPlayPause() { 142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile()) 143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->media_player_event_router() 144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->NotifyTogglePlayState(); 145010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 146010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void MediaDelegateChromeOS::HandleMediaPrevTrack() { 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) extensions::MediaPlayerAPI::Get(ProfileManager::GetActiveUserProfile()) 149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->media_player_event_router() 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->NotifyPrevTrack(); 151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)ash::MediaCaptureState MediaDelegateChromeOS::GetMediaCaptureState( 154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) content::BrowserContext* context) { 155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return GetMediaCaptureStateOfAllWebContents(context); 156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void MediaDelegateChromeOS::OnRequestUpdate( 159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int render_process_id, 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch int render_frame_id, 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::MediaStreamType stream_type, 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const content::MediaRequestState state) { 163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::MessageLoopForUI::current()->PostTask( 164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&MediaDelegateChromeOS::NotifyMediaCaptureChange, 166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void MediaDelegateChromeOS::NotifyMediaCaptureChange() { 170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ash::Shell::GetInstance() 171010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->system_tray_notifier() 172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ->NotifyMediaCaptureChanged(); 173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 174