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