OLD | NEW |
(Empty) | |
| 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 // Implements the Chrome Extensions Tab Capture API. |
| 6 |
| 7 #include "chrome/browser/extensions/api/tab_capture/tab_capture_api.h" |
| 8 |
| 9 #include "base/stringprintf.h" |
| 10 #include "base/values.h" |
| 11 #include "chrome/browser/profiles/profile.h" |
| 12 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 13 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry_factory
.h" |
| 14 #include "chrome/browser/extensions/browser_event_router.h" |
| 15 #include "chrome/browser/extensions/event_names.h" |
| 16 #include "chrome/browser/extensions/extension_tab_id_map.h" |
| 17 #include "chrome/browser/sessions/session_tab_helper.h" |
| 18 #include "chrome/browser/ui/browser.h" |
| 19 #include "chrome/browser/ui/browser_list.h" |
| 20 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 21 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 22 #include "chrome/common/extensions/feature_switch.h" |
| 23 #include "content/public/browser/render_process_host.h" |
| 24 #include "content/public/browser/render_view_host.h" |
| 25 |
| 26 namespace TabCapture = extensions::api::tab_capture; |
| 27 namespace GetCapturedTabs = TabCapture::GetCapturedTabs; |
| 28 |
| 29 namespace extensions { |
| 30 |
| 31 namespace { |
| 32 |
| 33 const char kPermissionError[] = |
| 34 "Extension does not have permission for tab capture."; |
| 35 const char kErrorTabIdNotFound[] = "Could not find the specified tab."; |
| 36 const char kCapturingSameTab[] = "Cannot capture a tab with an active stream."; |
| 37 |
| 38 // Keys/values for media stream constraints. |
| 39 const char kMediaStreamSource[] = "chromeMediaSource"; |
| 40 const char kMediaStreamSourceId[] = "chromeMediaSourceId"; |
| 41 const char kMediaStreamSourceTab[] = "tab"; |
| 42 |
| 43 } // namespace |
| 44 |
| 45 bool TabCaptureCaptureFunction::RunImpl() { |
| 46 if (!GetExtension()->HasAPIPermission(APIPermission::kTabCapture) || |
| 47 !FeatureSwitch::tab_capture()->IsEnabled()) { |
| 48 error_ = kPermissionError; |
| 49 return false; |
| 50 } |
| 51 |
| 52 scoped_ptr<api::tab_capture::Capture::Params> params = |
| 53 TabCapture::Capture::Params::Create(*args_); |
| 54 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 55 |
| 56 int render_process_id = -1; |
| 57 int routing_id = -1; |
| 58 int tab_id = *params->tab_id.get(); |
| 59 bool found_tab = false; |
| 60 |
| 61 for (BrowserList::const_iterator iter = BrowserList::begin(); |
| 62 iter != BrowserList::end(); ++iter) { |
| 63 Browser* target_browser = *iter; |
| 64 TabStripModel* target_tab_strip = target_browser->tab_strip_model(); |
| 65 |
| 66 for (int i = 0; i < target_tab_strip->count(); ++i) { |
| 67 TabContents* target_contents = target_tab_strip->GetTabContentsAt(i); |
| 68 SessionTabHelper* session_tab_helper = |
| 69 SessionTabHelper::FromWebContents(target_contents->web_contents()); |
| 70 if (session_tab_helper->session_id().id() == tab_id) { |
| 71 found_tab = true; |
| 72 content::RenderViewHost* const rvh = |
| 73 target_contents->web_contents()->GetRenderViewHost(); |
| 74 routing_id = rvh->GetRoutingID(); |
| 75 render_process_id = rvh->GetProcess()->GetID(); |
| 76 break; |
| 77 } |
| 78 } |
| 79 } |
| 80 |
| 81 if (!found_tab) { |
| 82 error_ = kErrorTabIdNotFound; |
| 83 SetResult(base::Value::CreateIntegerValue(0)); |
| 84 return false; |
| 85 } |
| 86 |
| 87 std::string device_id = |
| 88 base::StringPrintf("%i:%i", render_process_id, routing_id); |
| 89 |
| 90 bool audio = false; |
| 91 bool video = false; |
| 92 if (params->options.get()) { |
| 93 if (params->options->audio.get()) |
| 94 audio = *params->options->audio.get(); |
| 95 if (params->options->video.get()) |
| 96 video = *params->options->video.get(); |
| 97 } |
| 98 |
| 99 base::DictionaryValue* result = new base::DictionaryValue(); |
| 100 if (video) { |
| 101 result->SetString(std::string("videoConstraints.mandatory.") + |
| 102 kMediaStreamSource, kMediaStreamSourceTab); |
| 103 result->SetString(std::string("videoConstraints.mandatory.") + |
| 104 kMediaStreamSourceId, device_id); |
| 105 } else { |
| 106 result->SetBoolean(std::string("videoConstraints"), false); |
| 107 } |
| 108 |
| 109 if (audio) { |
| 110 result->SetString(std::string("audioConstraints.mandatory.") + |
| 111 kMediaStreamSource, kMediaStreamSourceTab); |
| 112 result->SetString(std::string("audioConstraints.mandatory.") + |
| 113 kMediaStreamSourceId, device_id); |
| 114 } else { |
| 115 result->SetBoolean(std::string("audioConstraints"), false); |
| 116 } |
| 117 |
| 118 extensions::TabCaptureRegistry* registry = |
| 119 extensions::TabCaptureRegistryFactory::GetForProfile(profile()); |
| 120 if (!registry->AddRequest(device_id, TabCaptureRegistry::TabCaptureRequest( |
| 121 GetExtension()->id(), tab_id, |
| 122 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE))) { |
| 123 error_ = kCapturingSameTab; |
| 124 SetResult(base::Value::CreateIntegerValue(0)); |
| 125 return false; |
| 126 } |
| 127 |
| 128 SetResult(result); |
| 129 return true; |
| 130 } |
| 131 |
| 132 bool TabCaptureGetCapturedTabsFunction::RunImpl() { |
| 133 if (!GetExtension()->HasAPIPermission(APIPermission::kTabCapture) || |
| 134 !FeatureSwitch::tab_capture()->IsEnabled()) { |
| 135 error_ = kPermissionError; |
| 136 return false; |
| 137 } |
| 138 |
| 139 extensions::TabCaptureRegistry* registry = |
| 140 extensions::TabCaptureRegistryFactory::GetForProfile(profile()); |
| 141 |
| 142 const TabCaptureRegistry::CaptureRequestList& captured_tabs = |
| 143 registry->GetCapturedTabs(GetExtension()->id()); |
| 144 |
| 145 base::ListValue *list = new base::ListValue(); |
| 146 for (TabCaptureRegistry::CaptureRequestList::const_iterator it = |
| 147 captured_tabs.begin(); it != captured_tabs.end(); it++) { |
| 148 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo()); |
| 149 info->tab_id = it->tab_id; |
| 150 info->status = it->status; |
| 151 list->Append(info->ToValue().release()); |
| 152 } |
| 153 |
| 154 SetResult(list); |
| 155 return true; |
| 156 } |
| 157 |
| 158 } // namespace extensions |
OLD | NEW |