Chromium Code Reviews| 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 | |
| 18 namespace TabCapture = extensions::api::tab_capture; | |
| 19 namespace GetCapturedTabs = TabCapture::GetCapturedTabs; | |
| 20 | |
| 21 namespace extensions { | |
| 22 | |
| 23 namespace { | |
| 24 | |
| 25 const char kPermissionError[] = "Extension does not have tabs permission"; | |
| 26 const char kErrorTabIdNotFound[] = "Could not find the specified tab."; | |
| 27 const char kCapturingSameTab[] = "Cannot capture a tab with an active stream."; | |
| 28 | |
| 29 // Keys/values for media stream constraints. | |
| 30 const char kMediaStreamSource[] = "chromeMediaSource"; | |
| 31 const char kMediaStreamSourceId[] = "chromeMediaSourceId"; | |
| 32 const char kMediaStreamSourceTab[] = "tab"; | |
| 33 | |
| 34 } // namespace | |
| 35 | |
| 36 TabCaptureCaptureFunction::TabCaptureCaptureFunction() { } | |
| 37 TabCaptureCaptureFunction::~TabCaptureCaptureFunction() { } | |
| 38 | |
| 39 bool TabCaptureCaptureFunction::Prepare() { | |
| 40 if (!GetExtension()->HasAPIPermission(APIPermission::kTab)) { | |
|
Aaron Boodman
2012/10/16 04:19:27
Two things:
(1) The 'tabs' permission is not the
justinlin
2012/10/17 08:32:26
Changed it back to kTabCapture permission as sugge
| |
| 41 error_ = kPermissionError; | |
| 42 return false; | |
| 43 } | |
| 44 | |
| 45 params_ = TabCapture::Capture::Params::Create(*args_); | |
| 46 EXTENSION_FUNCTION_VALIDATE(params_.get()); | |
| 47 return true; | |
| 48 } | |
| 49 | |
| 50 void TabCaptureCaptureFunction::Work() { | |
|
Aaron Boodman
2012/10/16 04:19:27
Wait a second... Why are you using AsyncApiFunctio
justinlin
2012/10/17 08:32:26
Converting process and tab id to process and routi
Aaron Boodman
2012/10/17 20:28:14
You can get both the routing and process ID for a
justinlin
2012/10/17 23:41:48
Done. OK, sorry for the contention surrounding Asy
| |
| 51 ExtensionTabIdMap* tab_id_map = ExtensionTabIdMap::GetInstance(); | |
| 52 int render_process_id = -1; | |
| 53 int routing_id = -1; | |
| 54 int tab_id = *params_->tab_id.get(); | |
| 55 if (!tab_id_map || | |
| 56 !tab_id_map->GetProcessAndRoutingId(tab_id, | |
| 57 &render_process_id, | |
| 58 &routing_id)) { | |
| 59 error_ = kErrorTabIdNotFound; | |
| 60 SetResult(base::Value::CreateIntegerValue(0)); | |
| 61 return; | |
| 62 } | |
| 63 | |
| 64 std::string device_id = base::StringPrintf("%i:%i", render_process_id, | |
| 65 routing_id); | |
| 66 | |
| 67 request_key_ = device_id; | |
| 68 request_ = | |
| 69 (TabCaptureRegistry::TabCaptureRequest) { GetExtension()->id(), tab_id, | |
|
Aaron Boodman
2012/10/16 04:19:27
Is the cast necessary? Seems like it wouldn't be.
justinlin
2012/10/17 08:32:26
Done.
| |
| 70 tab_capture::TAB_CAPTURE_TAB_CAPTURE_STATE_NONE }; | |
| 71 | |
| 72 bool audio = false; | |
| 73 bool video = false; | |
| 74 if (params_->options.get()) { | |
| 75 if (params_->options->audio.get()) { | |
|
Aaron Boodman
2012/10/16 04:19:27
Nit: this brace is not necessary. It's optional th
justinlin
2012/10/17 08:32:26
Done.
| |
| 76 audio = *params_->options->audio.get(); | |
| 77 } | |
| 78 if (params_->options->video.get()) { | |
| 79 video = *params_->options->video.get(); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 base::DictionaryValue* result = new base::DictionaryValue(); | |
|
Aaron Boodman
2012/10/16 04:19:27
JSON Schema Compiler generates structs you can use
justinlin
2012/10/17 08:32:26
These are sort of intermediate results that we are
Aaron Boodman
2012/10/17 20:28:14
I see.
| |
| 84 if (video) { | |
| 85 result->SetString(std::string("videoConstraints.mandatory.") + | |
|
Aaron Boodman
2012/10/16 04:19:27
Question: why "constraints". Seem more like "detai
Aaron Boodman
2012/10/16 04:22:28
I take this back. 'constraints' is fine.
justinlin
2012/10/17 08:32:26
On 2012/10/16 04:22:28, Aaron Boodman wrote:
> On
justinlin
2012/10/17 08:32:26
On 2012/10/16 04:19:27, Aaron Boodman wrote:
> Que
| |
| 86 kMediaStreamSource, kMediaStreamSourceTab); | |
| 87 result->SetString(std::string("videoConstraints.mandatory.") + | |
| 88 kMediaStreamSourceId, device_id); | |
| 89 } else { | |
| 90 result->SetBoolean(std::string("videoConstraints"), false); | |
| 91 } | |
| 92 | |
| 93 if (audio) { | |
| 94 result->SetString(std::string("audioConstraints.mandatory.") + | |
| 95 kMediaStreamSource, kMediaStreamSourceTab); | |
| 96 result->SetString(std::string("audioConstraints.mandatory.") + | |
| 97 kMediaStreamSourceId, device_id); | |
| 98 } else { | |
| 99 result->SetBoolean(std::string("audioConstraints"), false); | |
| 100 } | |
| 101 | |
| 102 SetResult(result); | |
| 103 } | |
| 104 | |
| 105 bool TabCaptureCaptureFunction::Respond() { | |
| 106 extensions::TabCaptureRegistry* registry = | |
| 107 extensions::TabCaptureRegistryFactory::GetForProfile(profile()); | |
| 108 if (!request_key_.empty() && !registry->AddRequest(request_key_, request_)) { | |
| 109 error_ = kCapturingSameTab; | |
| 110 SetResult(base::Value::CreateIntegerValue(0)); | |
| 111 } | |
| 112 | |
| 113 return error_.empty(); | |
| 114 } | |
| 115 | |
| 116 bool TabCaptureGetCapturedTabsFunction::RunImpl() { | |
| 117 if (!GetExtension()->HasAPIPermission(APIPermission::kTab)) { | |
| 118 error_ = kPermissionError; | |
| 119 return false; | |
| 120 } | |
| 121 | |
| 122 extensions::TabCaptureRegistry* registry = | |
| 123 extensions::TabCaptureRegistryFactory::GetForProfile(profile()); | |
| 124 | |
| 125 const TabCaptureRegistry::CaptureRequestList& captured_tabs = | |
| 126 registry->GetCapturedTabs(GetExtension()->id()); | |
| 127 | |
| 128 base::ListValue *list = new base::ListValue(); | |
| 129 for (TabCaptureRegistry::CaptureRequestList::const_iterator it = | |
| 130 captured_tabs.begin(); it != captured_tabs.end(); it++) { | |
| 131 scoped_ptr<tab_capture::CaptureInfo> info(new tab_capture::CaptureInfo()); | |
| 132 info->tab_id = it->tab_id; | |
| 133 info->status = it->status; | |
| 134 list->Append(info->ToValue().release()); | |
| 135 } | |
| 136 | |
| 137 SetResult(list); | |
| 138 return true; | |
| 139 } | |
| 140 | |
| 141 } // namespace extensions | |
| OLD | NEW |