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