| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Implements the Chrome Extensions Tab Capture API. | 5 // Implements the Chrome Extensions Tab Capture API. |
| 6 | 6 |
| 7 #include "chrome/browser/extensions/api/tab_capture/tab_capture_api.h" | 7 #include "chrome/browser/extensions/api/tab_capture/tab_capture_api.h" |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" | 16 #include "chrome/browser/extensions/api/tab_capture/tab_capture_registry.h" |
| 17 #include "chrome/browser/extensions/extension_renderer_state.h" | 17 #include "chrome/browser/extensions/extension_renderer_state.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/sessions/session_tab_helper.h" | 19 #include "chrome/browser/sessions/session_id.h" |
| 20 #include "chrome/browser/ui/browser.h" | 20 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/browser/ui/browser_finder.h" | 21 #include "chrome/browser/ui/browser_finder.h" |
| 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 23 #include "content/public/browser/render_frame_host.h" |
| 23 #include "content/public/browser/render_process_host.h" | 24 #include "content/public/browser/render_process_host.h" |
| 24 #include "content/public/browser/render_view_host.h" | |
| 25 #include "extensions/common/features/feature.h" | 25 #include "extensions/common/features/feature.h" |
| 26 #include "extensions/common/features/feature_provider.h" | 26 #include "extensions/common/features/feature_provider.h" |
| 27 #include "extensions/common/features/simple_feature.h" | 27 #include "extensions/common/features/simple_feature.h" |
| 28 #include "extensions/common/permissions/permissions_data.h" | 28 #include "extensions/common/permissions/permissions_data.h" |
| 29 #include "extensions/common/switches.h" | 29 #include "extensions/common/switches.h" |
| 30 | 30 |
| 31 using extensions::api::tab_capture::MediaStreamConstraint; | 31 using extensions::api::tab_capture::MediaStreamConstraint; |
| 32 | 32 |
| 33 namespace TabCapture = extensions::api::tab_capture; | 33 namespace TabCapture = extensions::api::tab_capture; |
| 34 namespace GetCapturedTabs = TabCapture::GetCapturedTabs; | 34 namespace GetCapturedTabs = TabCapture::GetCapturedTabs; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 content::WebContents* target_contents = | 78 content::WebContents* target_contents = |
| 79 target_browser->tab_strip_model()->GetActiveWebContents(); | 79 target_browser->tab_strip_model()->GetActiveWebContents(); |
| 80 if (!target_contents) { | 80 if (!target_contents) { |
| 81 error_ = kFindingTabError; | 81 error_ = kFindingTabError; |
| 82 return false; | 82 return false; |
| 83 } | 83 } |
| 84 | 84 |
| 85 const Extension* extension = GetExtension(); | 85 const Extension* extension = GetExtension(); |
| 86 const std::string& extension_id = extension->id(); | 86 const std::string& extension_id = extension->id(); |
| 87 | 87 |
| 88 const int tab_id = SessionID::IdForTab(target_contents); | |
| 89 | |
| 90 // Make sure either we have been granted permission to capture through an | 88 // Make sure either we have been granted permission to capture through an |
| 91 // extension icon click or our extension is whitelisted. | 89 // extension icon click or our extension is whitelisted. |
| 92 if (!extension->permissions_data()->HasAPIPermissionForTab( | 90 if (!extension->permissions_data()->HasAPIPermissionForTab( |
| 93 tab_id, APIPermission::kTabCaptureForTab) && | 91 SessionID::IdForTab(target_contents), |
| 92 APIPermission::kTabCaptureForTab) && |
| 94 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | 93 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| 95 switches::kWhitelistedExtensionID) != extension_id && | 94 switches::kWhitelistedExtensionID) != extension_id && |
| 96 !SimpleFeature::IsIdInList( | 95 !SimpleFeature::IsIdInList( |
| 97 extension_id, | 96 extension_id, |
| 98 std::set<std::string>( | 97 std::set<std::string>( |
| 99 whitelisted_extensions, | 98 whitelisted_extensions, |
| 100 whitelisted_extensions + arraysize(whitelisted_extensions)))) { | 99 whitelisted_extensions + arraysize(whitelisted_extensions)))) { |
| 101 error_ = kGrantError; | 100 error_ = kGrantError; |
| 102 return false; | 101 return false; |
| 103 } | 102 } |
| 104 | 103 |
| 105 content::RenderViewHost* const rvh = target_contents->GetRenderViewHost(); | |
| 106 int render_process_id = rvh->GetProcess()->GetID(); | |
| 107 int routing_id = rvh->GetRoutingID(); | |
| 108 | |
| 109 // Create a constraints vector. We will modify all the constraints in this | 104 // Create a constraints vector. We will modify all the constraints in this |
| 110 // vector to append our chrome specific constraints. | 105 // vector to append our chrome specific constraints. |
| 111 std::vector<MediaStreamConstraint*> constraints; | 106 std::vector<MediaStreamConstraint*> constraints; |
| 112 bool has_audio = params->options.audio.get() && *params->options.audio.get(); | 107 bool has_audio = params->options.audio.get() && *params->options.audio.get(); |
| 113 bool has_video = params->options.video.get() && *params->options.video.get(); | 108 bool has_video = params->options.video.get() && *params->options.video.get(); |
| 114 | 109 |
| 115 if (!has_audio && !has_video) { | 110 if (!has_audio && !has_video) { |
| 116 error_ = kNoAudioOrVideo; | 111 error_ = kNoAudioOrVideo; |
| 117 return false; | 112 return false; |
| 118 } | 113 } |
| 119 | 114 |
| 120 if (has_audio) { | 115 if (has_audio) { |
| 121 if (!params->options.audio_constraints.get()) | 116 if (!params->options.audio_constraints.get()) |
| 122 params->options.audio_constraints.reset(new MediaStreamConstraint); | 117 params->options.audio_constraints.reset(new MediaStreamConstraint); |
| 123 | 118 |
| 124 constraints.push_back(params->options.audio_constraints.get()); | 119 constraints.push_back(params->options.audio_constraints.get()); |
| 125 } | 120 } |
| 126 if (has_video) { | 121 if (has_video) { |
| 127 if (!params->options.video_constraints.get()) | 122 if (!params->options.video_constraints.get()) |
| 128 params->options.video_constraints.reset(new MediaStreamConstraint); | 123 params->options.video_constraints.reset(new MediaStreamConstraint); |
| 129 | 124 |
| 130 constraints.push_back(params->options.video_constraints.get()); | 125 constraints.push_back(params->options.video_constraints.get()); |
| 131 } | 126 } |
| 132 | 127 |
| 133 // Device id we use for Tab Capture. | 128 // Device id we use for Tab Capture. |
| 134 std::string device_id = | 129 content::RenderFrameHost* const main_frame = target_contents->GetMainFrame(); |
| 135 base::StringPrintf("%i:%i", render_process_id, routing_id); | 130 // TODO(miu): We should instead use a "randomly generated device ID" scheme, |
| 131 // like that employed by the desktop capture API. http://crbug.com/163100 |
| 132 const std::string device_id = base::StringPrintf( |
| 133 "web-contents-media-stream://%i:%i", |
| 134 main_frame->GetProcess()->GetID(), |
| 135 main_frame->GetRoutingID()); |
| 136 | 136 |
| 137 // Append chrome specific tab constraints. | 137 // Append chrome specific tab constraints. |
| 138 for (std::vector<MediaStreamConstraint*>::iterator it = constraints.begin(); | 138 for (std::vector<MediaStreamConstraint*>::iterator it = constraints.begin(); |
| 139 it != constraints.end(); ++it) { | 139 it != constraints.end(); ++it) { |
| 140 base::DictionaryValue* constraint = &(*it)->mandatory.additional_properties; | 140 base::DictionaryValue* constraint = &(*it)->mandatory.additional_properties; |
| 141 constraint->SetString(kMediaStreamSource, kMediaStreamSourceTab); | 141 constraint->SetString(kMediaStreamSource, kMediaStreamSourceTab); |
| 142 constraint->SetString(kMediaStreamSourceId, device_id); | 142 constraint->SetString(kMediaStreamSourceId, device_id); |
| 143 } | 143 } |
| 144 | 144 |
| 145 extensions::TabCaptureRegistry* registry = | 145 extensions::TabCaptureRegistry* registry = |
| 146 extensions::TabCaptureRegistry::Get(GetProfile()); | 146 extensions::TabCaptureRegistry::Get(GetProfile()); |
| 147 if (!registry->AddRequest(render_process_id, | 147 if (!registry->AddRequest(target_contents, extension_id)) { |
| 148 routing_id, | |
| 149 extension_id, | |
| 150 tab_id, | |
| 151 tab_capture::TAB_CAPTURE_STATE_NONE)) { | |
| 152 error_ = kCapturingSameTab; | 148 error_ = kCapturingSameTab; |
| 153 return false; | 149 return false; |
| 154 } | 150 } |
| 155 | 151 |
| 156 // Copy the result from our modified input parameters. This will be | 152 // Copy the result from our modified input parameters. This will be |
| 157 // intercepted by custom bindings which will build and send the special | 153 // intercepted by custom bindings which will build and send the special |
| 158 // WebRTC user media request. | 154 // WebRTC user media request. |
| 159 base::DictionaryValue* result = new base::DictionaryValue(); | 155 base::DictionaryValue* result = new base::DictionaryValue(); |
| 160 result->MergeDictionary(params->options.ToValue().get()); | 156 result->MergeDictionary(params->options.ToValue().get()); |
| 161 | 157 |
| 162 SetResult(result); | 158 SetResult(result); |
| 163 return true; | 159 return true; |
| 164 } | 160 } |
| 165 | 161 |
| 166 bool TabCaptureGetCapturedTabsFunction::RunSync() { | 162 bool TabCaptureGetCapturedTabsFunction::RunSync() { |
| 167 extensions::TabCaptureRegistry* registry = | 163 extensions::TabCaptureRegistry* registry = |
| 168 extensions::TabCaptureRegistry::Get(GetProfile()); | 164 extensions::TabCaptureRegistry::Get(GetProfile()); |
| 169 | 165 base::ListValue* const list = new base::ListValue(); |
| 170 const TabCaptureRegistry::RegistryCaptureInfo& captured_tabs = | 166 if (registry) |
| 171 registry->GetCapturedTabs(GetExtension()->id()); | 167 registry->GetCapturedTabs(GetExtension()->id(), list); |
| 172 | |
| 173 base::ListValue *list = new base::ListValue(); | |
| 174 for (TabCaptureRegistry::RegistryCaptureInfo::const_iterator it = | |
| 175 captured_tabs.begin(); it != captured_tabs.end(); ++it) { | |
| 176 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo()); | |
| 177 info->tab_id = it->first; | |
| 178 info->status = it->second; | |
| 179 list->Append(info->ToValue().release()); | |
| 180 } | |
| 181 | |
| 182 SetResult(list); | 168 SetResult(list); |
| 183 return true; | 169 return true; |
| 184 } | 170 } |
| 185 | 171 |
| 186 } // namespace extensions | 172 } // namespace extensions |
| OLD | NEW |