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 #include "chrome/browser/extensions/api/developer_private/developer_private_api. h" | |
| 6 | |
| 7 #include "base/string_number_conversions.h" | |
| 8 #include "base/values.h" | |
| 9 #include "chrome/browser/debugger/devtools_window.h" | |
| 10 #include "chrome/browser/extensions/api/developer_private/developer_private_api_ factory.h" | |
| 11 #include "chrome/browser/extensions/extension_service.h" | |
| 12 #include "chrome/browser/extensions/extension_system.h" | |
| 13 #include "chrome/browser/extensions/management_policy.h" | |
| 14 #include "chrome/browser/extensions/updater/extension_updater.h" | |
| 15 #include "chrome/browser/profiles/profile.h" | |
| 16 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | |
| 17 #include "chrome/browser/view_type_utils.h" | |
| 18 #include "chrome/common/extensions/api/developer_private.h" | |
| 19 #include "content/public/browser/browser_thread.h" | |
| 20 #include "content/public/browser/render_process_host.h" | |
| 21 #include "content/public/browser/render_view_host.h" | |
| 22 #include "content/public/browser/web_contents.h" | |
| 23 #include "grit/generated_resources.h" | |
| 24 | |
| 25 using content::RenderViewHost; | |
| 26 using extensions::DeveloperPrivateAPI; | |
| 27 using extensions::Extension; | |
| 28 using extensions::ExtensionSystem; | |
| 29 | |
| 30 namespace { | |
| 31 | |
| 32 extensions::ExtensionUpdater* GetExtensionUpdater(Profile* profile) { | |
| 33 return profile->GetExtensionService()->updater(); | |
| 34 } | |
| 35 | |
| 36 } // namespace | |
|
miket_OOO
2012/12/06 19:31:15
always two spaces before //
(please fix all insta
| |
| 37 | |
| 38 namespace extensions { | |
| 39 | |
| 40 DeveloperPrivateAPI* DeveloperPrivateAPI::Get(Profile* profile) { | |
| 41 return DeveloperPrivateAPIFactory::GetForProfile(profile); | |
| 42 } | |
| 43 | |
| 44 DeveloperPrivateAPI::DeveloperPrivateAPI(Profile* profile) | |
| 45 : profile_(profile), | |
| 46 deleting_rvh_(NULL) { | |
| 47 RegisterNotifications(); | |
| 48 } | |
| 49 | |
| 50 scoped_ptr<developer::ItemInfo> DeveloperPrivateAPI::CreateItemInfo( | |
| 51 const Extension& item, | |
| 52 ExtensionSystem* system, | |
| 53 bool item_is_enabled) { | |
| 54 scoped_ptr<developer::ItemInfo> info(new developer::ItemInfo()); | |
| 55 ExtensionService* service = system->extension_service(); | |
| 56 | |
| 57 info->id = item.id(); | |
| 58 info->name = item.name(); | |
| 59 info->enabled = service->IsExtensionEnabled(info->id); | |
| 60 info->offline_enabled = item.offline_enabled(); | |
| 61 info->version = item.VersionString(); | |
| 62 info->description = item.description(); | |
| 63 | |
| 64 if (item.is_app()) { | |
| 65 if (item.is_legacy_packaged_app()) | |
| 66 info->type = developer::DEVELOPER_PRIVATE_ITEM_TYPE_LEGACY_PACKAGED_APP; | |
| 67 else if (item.is_hosted_app()) | |
| 68 info->type = developer::DEVELOPER_PRIVATE_ITEM_TYPE_HOSTED_APP; | |
| 69 else | |
| 70 info->type = developer::DEVELOPER_PRIVATE_ITEM_TYPE_PACKAGED_APP; | |
| 71 } else if (item.is_theme()) { | |
| 72 info->type = developer::DEVELOPER_PRIVATE_ITEM_TYPE_THEME; | |
| 73 } else { | |
| 74 info->type = developer::DEVELOPER_PRIVATE_ITEM_TYPE_EXTENSION; | |
| 75 } | |
|
miket_OOO
2012/12/06 19:31:15
Consider some defensive checks here that your catc
Gaurav
2012/12/12 02:23:38
Done.
| |
| 76 | |
| 77 if (item.location() == Extension::LOAD) { | |
| 78 info->path.reset(new std::string(item.path().value())); | |
| 79 } | |
| 80 | |
| 81 info->enabled_incognito = service->IsIncognitoEnabled(item.id()); | |
| 82 info->wants_file_access = item.wants_file_access(); | |
| 83 info->allow_file_access = service->AllowFileAccess(&item); | |
| 84 info->allow_reload = (item.location() == Extension::LOAD); | |
| 85 info->is_unpacked = (item.location() == Extension::LOAD); | |
| 86 | |
| 87 GURL icon = | |
| 88 ExtensionIconSource::GetIconURL(&item, | |
| 89 extension_misc::EXTENSION_ICON_MEDIUM, | |
| 90 ExtensionIconSet::MATCH_BIGGER, | |
| 91 !info->enabled, | |
| 92 NULL); | |
| 93 info->icon = icon.spec(); | |
| 94 | |
| 95 info->homepage_url.reset(new std::string(item.GetHomepageURL().spec())); | |
| 96 if (!item.options_url().is_empty()) { | |
| 97 info->options_url.reset(new std::string(item.options_url().spec())); | |
| 98 } | |
| 99 | |
| 100 if (!item.update_url().is_empty()) { | |
| 101 info->update_url.reset(new std::string( | |
| 102 item.update_url().spec())); | |
|
miket_OOO
2012/12/06 19:31:15
is this wrapping necessary?
Gaurav
2012/12/12 02:23:38
update_url is optional parameter and is a string p
| |
| 103 } | |
| 104 | |
| 105 if (item.is_app()) { | |
| 106 info->app_launch_url.reset(new std::string( | |
| 107 item.GetFullLaunchURL().spec())); | |
| 108 } | |
| 109 | |
| 110 info->may_disable = system->management_policy()-> | |
| 111 UserMayModifySettings(&item, NULL); | |
| 112 info->is_app = item.is_app(); | |
| 113 info->views = GetInspectablePagesForExtension(&item, item_is_enabled); | |
| 114 | |
| 115 return info.Pass(); | |
| 116 } | |
| 117 | |
| 118 void DeveloperPrivateAPI::AddItemsInfo(const ExtensionSet& items, | |
| 119 ExtensionSystem* system, | |
| 120 ItemInfoList* item_list) { | |
| 121 | |
| 122 for (ExtensionSet::const_iterator iter = items.begin(); | |
| 123 iter != items.end(); ++iter) { | |
| 124 const Extension& item = **iter; | |
| 125 if (item.location() == Extension::COMPONENT) | |
| 126 continue; // Skip built-in extensions / apps; | |
| 127 item_list->push_back(make_linked_ptr<developer::ItemInfo>( | |
| 128 CreateItemInfo(item, system, false).release())); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 void DeveloperPrivateAPI::GetInspectablePagesForExtensionProcess( | |
| 133 const std::set<content::RenderViewHost*>& views, | |
| 134 ItemInspectViewList* result) { | |
| 135 for (std::set<content::RenderViewHost*>::const_iterator iter = views.begin(); | |
| 136 iter != views.end(); ++iter) { | |
| 137 content::RenderViewHost* host = *iter; | |
| 138 content::WebContents* web_contents = | |
| 139 content::WebContents::FromRenderViewHost(host); | |
| 140 chrome::ViewType host_type = chrome::GetViewType(web_contents); | |
| 141 if (host == deleting_rvh_ || | |
| 142 chrome::VIEW_TYPE_EXTENSION_POPUP == host_type || | |
| 143 chrome::VIEW_TYPE_EXTENSION_DIALOG == host_type) | |
| 144 continue; | |
| 145 | |
| 146 GURL url = web_contents->GetURL(); | |
| 147 content::RenderProcessHost* process = host->GetProcess(); | |
| 148 linked_ptr<developer::ItemInspectView> | |
| 149 view(new developer::ItemInspectView()); | |
| 150 view->path = url.path().substr(1); | |
| 151 view->render_process_id = process->GetID(); | |
| 152 view->render_view_id = host->GetRoutingID(); | |
| 153 view->incognito = process->GetBrowserContext()->IsOffTheRecord(); | |
| 154 | |
| 155 result->push_back(view); | |
| 156 } | |
| 157 } | |
| 158 | |
| 159 ItemInspectViewList DeveloperPrivateAPI::GetInspectablePagesForExtension( | |
| 160 const extensions::Extension* extension, | |
| 161 bool extension_is_enabled) { | |
| 162 | |
| 163 ItemInspectViewList result; | |
| 164 // Get the extension process's active views. | |
| 165 ExtensionProcessManager* process_manager = | |
| 166 extensions::ExtensionSystem::Get(profile_)->process_manager(); | |
| 167 GetInspectablePagesForExtensionProcess( | |
| 168 process_manager->GetRenderViewHostsForExtension(extension->id()), | |
| 169 &result); | |
| 170 return result; | |
| 171 } | |
| 172 | |
| 173 void DeveloperPrivateAPI::Observe( | |
| 174 int type, | |
| 175 const content::NotificationSource& source, | |
| 176 const content::NotificationDetails& details) { | |
| 177 Profile* source_profile = NULL; | |
| 178 switch (type) { | |
| 179 // TODO(grv): Listen to other notifications. | |
| 180 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: | |
| 181 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED: | |
| 182 deleting_rvh_ = content::Source<RenderViewHost>(source).ptr(); | |
| 183 source_profile = content::Source<Profile>(source).ptr(); | |
| 184 break; | |
| 185 default: | |
| 186 NOTREACHED(); | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 void DeveloperPrivateAPI::RegisterNotifications() { | |
| 191 registrar_.Add(this, | |
| 192 content::NOTIFICATION_RENDER_VIEW_HOST_DELETED, | |
| 193 content::NotificationService::AllBrowserContextsAndSources()); | |
| 194 registrar_.Add(this, | |
| 195 chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED, | |
| 196 content::NotificationService::AllBrowserContextsAndSources()); | |
| 197 | |
| 198 } | |
| 199 | |
| 200 DeveloperPrivateAPI::~DeveloperPrivateAPI() { | |
| 201 } | |
| 202 | |
| 203 void DeveloperPrivateAPI::Shutdown() { | |
| 204 } | |
| 205 | |
| 206 namespace api { | |
| 207 | |
| 208 bool DeveloperPrivateAutoUpdateFunction::RunImpl() { | |
| 209 extensions::ExtensionUpdater* updater = GetExtensionUpdater(profile()); | |
| 210 if (updater) | |
| 211 updater->CheckNow(extensions::ExtensionUpdater::CheckParams()); | |
| 212 SetResult(Value::CreateBooleanValue(true)); | |
| 213 return true; | |
| 214 } | |
| 215 | |
| 216 bool DeveloperPrivateGetItemsInfoFunction::RunImpl() { | |
| 217 ItemInfoList items; | |
| 218 ExtensionSystem* system = ExtensionSystem::Get(profile()); | |
| 219 | |
| 220 DeveloperPrivateAPI::Get(profile())->AddItemsInfo( | |
| 221 *profile()->GetExtensionService()->extensions(), system, &items); | |
| 222 | |
| 223 results_ = developer::GetItemsInfo::Results::Create(items); | |
| 224 return true; | |
| 225 } | |
| 226 | |
| 227 bool DeveloperPrivateInspectFunction::RunImpl() { | |
| 228 scoped_ptr<developer::Inspect::Params> params( | |
| 229 developer::Inspect::Params::Create(*args_)); | |
| 230 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL); | |
| 231 const developer::InspectOptions& options = params->options; | |
| 232 std::string extension_id; | |
|
miket_OOO
2012/12/06 19:31:15
These declarations could be closer to where they'r
Gaurav
2012/12/12 02:23:38
Done.
| |
| 233 int render_process_id; | |
| 234 int render_view_id; | |
| 235 bool incognito = false; | |
| 236 | |
| 237 extension_id = options.extension_id; | |
| 238 base::StringToInt(options.render_process_id, &render_process_id); | |
| 239 base::StringToInt(options.render_view_id, &render_view_id); | |
| 240 incognito = options.incognito; | |
|
miket_OOO
2012/12/06 19:31:15
indentation
Gaurav
2012/12/12 02:23:38
Done.
| |
| 241 | |
| 242 if (render_process_id == -1) { | |
|
miket_OOO
2012/12/06 19:31:15
Not a big deal, but why convert render_view_id to
Gaurav
2012/12/12 02:23:38
Done.
| |
| 243 // This message is for a lazy background page. Start the page if necessary. | |
| 244 ExtensionService* service = profile()->GetExtensionService(); | |
| 245 const Extension* extension = service->extensions()->GetByID(extension_id); | |
| 246 DCHECK(extension); | |
| 247 | |
| 248 if (incognito) | |
|
miket_OOO
2012/12/06 19:31:15
Is this logic out of order? Are you asking the non
Gaurav
2012/12/12 02:23:38
The lazy background pages may return -1 as render_
| |
| 249 service = extensions::ExtensionSystem::Get( | |
| 250 service->profile()->GetOffTheRecordProfile())->extension_service(); | |
| 251 service->InspectBackgroundPage(extension); | |
| 252 return false; | |
| 253 } | |
| 254 | |
| 255 content::RenderViewHost* host = content::RenderViewHost::FromID( | |
| 256 render_process_id, render_view_id); | |
| 257 | |
| 258 if (!host) { | |
| 259 // This can happen if the host has gone away since the page was dispalyed. | |
|
miket_OOO
2012/12/06 19:31:15
spelling
Gaurav
2012/12/12 02:23:38
Done.
| |
| 260 return false; | |
| 261 } | |
| 262 | |
| 263 DevToolsWindow::OpenDevToolsWindow(host); | |
| 264 return true; | |
| 265 } | |
| 266 | |
| 267 } // namespace api | |
|
miket_OOO
2012/12/06 19:31:15
vertical whitespace (please fix all)
Gaurav
2012/12/12 02:23:38
Done.
| |
| 268 } // namespace extensions | |
| OLD | NEW |