1// 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 "chrome/browser/ui/webui/options/media_devices_selection_handler.h"
6
7#include "base/bind.h"
8#include "base/prefs/pref_service.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/common/pref_names.h"
11
12namespace {
13
14const char kAudio[] = "mic";
15const char kVideo[] = "camera";
16
17}  // namespace
18
19namespace options {
20
21MediaDevicesSelectionHandler::MediaDevicesSelectionHandler() {}
22
23MediaDevicesSelectionHandler::~MediaDevicesSelectionHandler() {
24  MediaCaptureDevicesDispatcher::GetInstance()->RemoveObserver(this);
25}
26
27void MediaDevicesSelectionHandler::GetLocalizedValues(
28    base::DictionaryValue* values) {
29  DCHECK(values);
30
31  static OptionsStringResource resources[] = {
32    { "mediaSelectMicLabel", IDS_MEDIA_SELECTED_MIC_LABEL },
33    { "mediaSelectCameraLabel", IDS_MEDIA_SELECTED_CAMERA_LABEL },
34  };
35
36  RegisterStrings(values, resources, arraysize(resources));
37}
38
39void MediaDevicesSelectionHandler::InitializePage() {
40  // Register to the device observer list to get up-to-date device lists.
41  MediaCaptureDevicesDispatcher::GetInstance()->AddObserver(this);
42
43  // Update the device selection menus.
44  UpdateDevicesMenuForType(AUDIO);
45  UpdateDevicesMenuForType(VIDEO);
46}
47
48void MediaDevicesSelectionHandler::RegisterMessages() {
49  web_ui()->RegisterMessageCallback("setDefaultCaptureDevice",
50      base::Bind(&MediaDevicesSelectionHandler::SetDefaultCaptureDevice,
51                 base::Unretained(this)));
52}
53
54void MediaDevicesSelectionHandler::OnUpdateAudioDevices(
55    const content::MediaStreamDevices& devices) {
56  UpdateDevicesMenu(AUDIO, devices);
57}
58
59void MediaDevicesSelectionHandler::OnUpdateVideoDevices(
60    const content::MediaStreamDevices& devices) {
61  UpdateDevicesMenu(VIDEO, devices);
62}
63
64void MediaDevicesSelectionHandler::SetDefaultCaptureDevice(
65    const base::ListValue* args) {
66  DCHECK_EQ(2U, args->GetSize());
67  std::string type, device;
68  if (!(args->GetString(0, &type) && args->GetString(1, &device))) {
69    NOTREACHED();
70    return;
71  }
72
73  DCHECK(!type.empty());
74  DCHECK(!device.empty());
75
76  Profile* profile = Profile::FromWebUI(web_ui());
77  PrefService* prefs = profile->GetPrefs();
78  if (type == kAudio)
79    prefs->SetString(prefs::kDefaultAudioCaptureDevice, device);
80  else if (type == kVideo)
81    prefs->SetString(prefs::kDefaultVideoCaptureDevice, device);
82  else
83    NOTREACHED();
84}
85
86void MediaDevicesSelectionHandler::UpdateDevicesMenu(
87    DeviceType type, const content::MediaStreamDevices& devices) {
88  // Get the default device unique id from prefs.
89  Profile* profile = Profile::FromWebUI(web_ui());
90  PrefService* prefs = profile->GetPrefs();
91  std::string default_device;
92  std::string device_type;
93  switch (type) {
94    case AUDIO:
95      default_device = prefs->GetString(prefs::kDefaultAudioCaptureDevice);
96      device_type = kAudio;
97      break;
98    case VIDEO:
99      default_device = prefs->GetString(prefs::kDefaultVideoCaptureDevice);
100      device_type = kVideo;
101      break;
102  }
103
104  // Build the list of devices to send to JS.
105  std::string default_id;
106  base::ListValue device_list;
107  for (size_t i = 0; i < devices.size(); ++i) {
108    base::DictionaryValue* entry = new base::DictionaryValue();
109    entry->SetString("name", devices[i].name);
110    entry->SetString("id",  devices[i].id);
111    device_list.Append(entry);
112    if (devices[i].id == default_device)
113      default_id = default_device;
114  }
115
116  // Use the first device as the default device if the preferred default device
117  // does not exist in the OS.
118  if (!devices.empty() && default_id.empty())
119    default_id = devices[0].id;
120
121  base::StringValue default_value(default_id);
122  base::StringValue type_value(device_type);
123  web_ui()->CallJavascriptFunction("ContentSettings.updateDevicesMenu",
124                                   type_value,
125                                   device_list,
126                                   default_value);
127}
128
129void MediaDevicesSelectionHandler::UpdateDevicesMenuForType(DeviceType type) {
130  content::MediaStreamDevices devices;
131  switch (type) {
132    case AUDIO:
133      devices = MediaCaptureDevicesDispatcher::GetInstance()->
134          GetAudioCaptureDevices();
135      break;
136    case VIDEO:
137      devices = MediaCaptureDevicesDispatcher::GetInstance()->
138          GetVideoCaptureDevices();
139      break;
140  }
141
142  UpdateDevicesMenu(type, devices);
143}
144
145}  // namespace options
146