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 #include "chrome/browser/extensions/api/management/management_api.h" | 5 #include "extensions/browser/api/management/management_api.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/memory/linked_ptr.h" | 15 #include "base/memory/linked_ptr.h" |
16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
21 #include "chrome/browser/extensions/api/management/management_api_constants.h" | 21 #include "content/public/browser/browser_context.h" |
22 #include "chrome/browser/extensions/extension_service.h" | 22 #include "extensions/browser/api/extensions_api_client.h" |
23 #include "chrome/browser/extensions/extension_ui_util.h" | 23 #include "extensions/browser/api/management/management_api_constants.h" |
24 #include "chrome/browser/extensions/extension_uninstall_dialog.h" | |
25 #include "chrome/browser/extensions/extension_util.h" | |
26 #include "chrome/browser/extensions/launch_util.h" | |
27 #include "chrome/browser/favicon/favicon_service_factory.h" | |
28 #include "chrome/browser/profiles/profile.h" | |
29 #include "chrome/browser/ui/browser_dialogs.h" | |
30 #include "chrome/browser/ui/browser_finder.h" | |
31 #include "chrome/browser/ui/browser_window.h" | |
32 #include "chrome/browser/ui/extensions/application_launch.h" | |
33 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | |
34 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" | |
35 #include "chrome/common/extensions/api/management.h" | |
36 #include "chrome/common/extensions/chrome_utility_extensions_messages.h" | |
37 #include "chrome/common/extensions/extension_constants.h" | |
38 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | |
39 #include "content/public/browser/utility_process_host.h" | |
40 #include "content/public/browser/utility_process_host_client.h" | |
41 #include "extensions/browser/event_router.h" | 24 #include "extensions/browser/event_router.h" |
42 #include "extensions/browser/extension_prefs.h" | 25 #include "extensions/browser/extension_prefs.h" |
43 #include "extensions/browser/extension_registry.h" | 26 #include "extensions/browser/extension_registry.h" |
44 #include "extensions/browser/extension_system.h" | 27 #include "extensions/browser/extension_system.h" |
45 #include "extensions/browser/management_policy.h" | 28 #include "extensions/browser/management_policy.h" |
46 #include "extensions/browser/uninstall_reason.h" | 29 #include "extensions/browser/uninstall_reason.h" |
| 30 #include "extensions/common/api/management.h" |
47 #include "extensions/common/constants.h" | 31 #include "extensions/common/constants.h" |
48 #include "extensions/common/error_utils.h" | 32 #include "extensions/common/error_utils.h" |
49 #include "extensions/common/extension.h" | 33 #include "extensions/common/extension.h" |
50 #include "extensions/common/extension_icon_set.h" | 34 #include "extensions/common/extension_icon_set.h" |
51 #include "extensions/common/manifest_handlers/icons_handler.h" | 35 #include "extensions/common/manifest_handlers/icons_handler.h" |
52 #include "extensions/common/manifest_handlers/offline_enabled_info.h" | 36 #include "extensions/common/manifest_handlers/offline_enabled_info.h" |
53 #include "extensions/common/manifest_handlers/options_page_info.h" | 37 #include "extensions/common/manifest_handlers/options_page_info.h" |
54 #include "extensions/common/manifest_url_handlers.h" | 38 #include "extensions/common/manifest_url_handlers.h" |
55 #include "extensions/common/permissions/permission_set.h" | 39 #include "extensions/common/permissions/permission_set.h" |
56 #include "extensions/common/permissions/permissions_data.h" | 40 #include "extensions/common/permissions/permissions_data.h" |
57 #include "extensions/common/url_pattern.h" | 41 #include "extensions/common/url_pattern.h" |
58 | 42 |
59 using base::IntToString; | 43 using base::IntToString; |
60 using content::BrowserThread; | 44 using content::BrowserThread; |
61 using content::UtilityProcessHost; | |
62 using content::UtilityProcessHostClient; | |
63 | 45 |
64 namespace keys = extension_management_api_constants; | 46 namespace keys = extension_management_api_constants; |
65 | 47 |
66 namespace extensions { | 48 namespace extensions { |
67 | 49 |
68 namespace management = api::management; | 50 namespace management = core_api::management; |
69 | 51 |
70 namespace { | 52 namespace { |
71 | 53 |
72 typedef std::vector<linked_ptr<management::ExtensionInfo> > ExtensionInfoList; | 54 typedef std::vector<linked_ptr<management::ExtensionInfo>> ExtensionInfoList; |
73 typedef std::vector<linked_ptr<management::IconInfo> > IconInfoList; | 55 typedef std::vector<linked_ptr<management::IconInfo>> IconInfoList; |
74 | 56 |
75 enum AutoConfirmForTest { | 57 enum AutoConfirmForTest { DO_NOT_SKIP = 0, PROCEED, ABORT }; |
76 DO_NOT_SKIP = 0, | |
77 PROCEED, | |
78 ABORT | |
79 }; | |
80 | 58 |
81 AutoConfirmForTest auto_confirm_for_test = DO_NOT_SKIP; | 59 AutoConfirmForTest auto_confirm_for_test = DO_NOT_SKIP; |
82 | 60 |
83 std::vector<std::string> CreateWarningsList(const Extension* extension) { | 61 std::vector<std::string> CreateWarningsList(const Extension* extension) { |
84 std::vector<std::string> warnings_list; | 62 std::vector<std::string> warnings_list; |
85 PermissionMessages warnings = | 63 PermissionMessages warnings = |
86 extension->permissions_data()->GetPermissionMessages(); | 64 extension->permissions_data()->GetPermissionMessages(); |
87 for (PermissionMessages::const_iterator iter = warnings.begin(); | 65 for (PermissionMessages::const_iterator iter = warnings.begin(); |
88 iter != warnings.end(); ++iter) { | 66 iter != warnings.end(); |
| 67 ++iter) { |
89 warnings_list.push_back(base::UTF16ToUTF8(iter->message())); | 68 warnings_list.push_back(base::UTF16ToUTF8(iter->message())); |
90 } | 69 } |
91 | 70 |
92 return warnings_list; | 71 return warnings_list; |
93 } | 72 } |
94 | 73 |
95 std::vector<management::LaunchType> GetAvailableLaunchTypes( | 74 std::vector<management::LaunchType> GetAvailableLaunchTypes( |
96 const Extension& extension) { | 75 const Extension& extension, |
| 76 const ManagementAPIDelegate* delegate) { |
97 std::vector<management::LaunchType> launch_type_list; | 77 std::vector<management::LaunchType> launch_type_list; |
98 if (extension.is_platform_app()) { | 78 if (extension.is_platform_app()) { |
99 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); | 79 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); |
100 return launch_type_list; | 80 return launch_type_list; |
101 } | 81 } |
102 | 82 |
103 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB); | 83 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB); |
104 | 84 |
105 #if !defined(OS_MACOSX) | 85 #if !defined(OS_MACOSX) |
106 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); | 86 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_WINDOW); |
107 #endif | 87 #endif |
108 | 88 |
109 if (!util::IsStreamlinedHostedAppsEnabled()) { | 89 if (!delegate->IsStreamlinedHostedAppsEnabled()) { |
110 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB); | 90 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB); |
111 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_FULL_SCREEN); | 91 launch_type_list.push_back(management::LAUNCH_TYPE_OPEN_FULL_SCREEN); |
112 } | 92 } |
113 return launch_type_list; | 93 return launch_type_list; |
114 } | 94 } |
115 | 95 |
116 scoped_ptr<management::ExtensionInfo> CreateExtensionInfo( | 96 scoped_ptr<management::ExtensionInfo> CreateExtensionInfo( |
117 const Extension& extension, | 97 const Extension& extension, |
118 ExtensionSystem* system) { | 98 content::BrowserContext* context) { |
| 99 ExtensionSystem* system = ExtensionSystem::Get(context); |
| 100 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
| 101 const ManagementAPIDelegate* delegate = |
| 102 ManagementAPI::GetFactoryInstance()->Get(context)->GetDelegate(); |
119 scoped_ptr<management::ExtensionInfo> info(new management::ExtensionInfo()); | 103 scoped_ptr<management::ExtensionInfo> info(new management::ExtensionInfo()); |
120 ExtensionService* service = system->extension_service(); | |
121 | 104 |
122 info->id = extension.id(); | 105 info->id = extension.id(); |
123 info->name = extension.name(); | 106 info->name = extension.name(); |
124 info->short_name = extension.short_name(); | 107 info->short_name = extension.short_name(); |
125 info->enabled = service->IsExtensionEnabled(info->id); | 108 info->enabled = registry->enabled_extensions().Contains(info->id); |
126 info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension); | 109 info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&extension); |
127 info->version = extension.VersionString(); | 110 info->version = extension.VersionString(); |
128 info->description = extension.description(); | 111 info->description = extension.description(); |
129 info->options_url = OptionsPageInfo::GetOptionsPage(&extension).spec(); | 112 info->options_url = OptionsPageInfo::GetOptionsPage(&extension).spec(); |
130 info->homepage_url.reset(new std::string( | 113 info->homepage_url.reset( |
131 ManifestURL::GetHomepageURL(&extension).spec())); | 114 new std::string(ManifestURL::GetHomepageURL(&extension).spec())); |
132 info->may_disable = system->management_policy()-> | 115 info->may_disable = |
133 UserMayModifySettings(&extension, NULL); | 116 system->management_policy()->UserMayModifySettings(&extension, NULL); |
134 info->is_app = extension.is_app(); | 117 info->is_app = extension.is_app(); |
135 if (info->is_app) { | 118 if (info->is_app) { |
136 if (extension.is_legacy_packaged_app()) | 119 if (extension.is_legacy_packaged_app()) |
137 info->type = management::ExtensionInfo::TYPE_LEGACY_PACKAGED_APP; | 120 info->type = management::ExtensionInfo::TYPE_LEGACY_PACKAGED_APP; |
138 else if (extension.is_hosted_app()) | 121 else if (extension.is_hosted_app()) |
139 info->type = management::ExtensionInfo::TYPE_HOSTED_APP; | 122 info->type = management::ExtensionInfo::TYPE_HOSTED_APP; |
140 else | 123 else |
141 info->type = management::ExtensionInfo::TYPE_PACKAGED_APP; | 124 info->type = management::ExtensionInfo::TYPE_PACKAGED_APP; |
142 } else if (extension.is_theme()) { | 125 } else if (extension.is_theme()) { |
143 info->type = management::ExtensionInfo::TYPE_THEME; | 126 info->type = management::ExtensionInfo::TYPE_THEME; |
144 } else { | 127 } else { |
145 info->type = management::ExtensionInfo::TYPE_EXTENSION; | 128 info->type = management::ExtensionInfo::TYPE_EXTENSION; |
146 } | 129 } |
147 | 130 |
148 if (info->enabled) { | 131 if (info->enabled) { |
149 info->disabled_reason = management::ExtensionInfo::DISABLED_REASON_NONE; | 132 info->disabled_reason = management::ExtensionInfo::DISABLED_REASON_NONE; |
150 } else { | 133 } else { |
151 ExtensionPrefs* prefs = ExtensionPrefs::Get(service->profile()); | 134 ExtensionPrefs* prefs = ExtensionPrefs::Get(context); |
152 if (prefs->DidExtensionEscalatePermissions(extension.id())) { | 135 if (prefs->DidExtensionEscalatePermissions(extension.id())) { |
153 info->disabled_reason = | 136 info->disabled_reason = |
154 management::ExtensionInfo::DISABLED_REASON_PERMISSIONS_INCREASE; | 137 management::ExtensionInfo::DISABLED_REASON_PERMISSIONS_INCREASE; |
155 } else { | 138 } else { |
156 info->disabled_reason = | 139 info->disabled_reason = |
157 management::ExtensionInfo::DISABLED_REASON_UNKNOWN; | 140 management::ExtensionInfo::DISABLED_REASON_UNKNOWN; |
158 } | 141 } |
159 } | 142 } |
160 | 143 |
161 if (!ManifestURL::GetUpdateURL(&extension).is_empty()) { | 144 if (!ManifestURL::GetUpdateURL(&extension).is_empty()) { |
162 info->update_url.reset(new std::string( | 145 info->update_url.reset( |
163 ManifestURL::GetUpdateURL(&extension).spec())); | 146 new std::string(ManifestURL::GetUpdateURL(&extension).spec())); |
164 } | 147 } |
165 | 148 |
166 if (extension.is_app()) { | 149 if (extension.is_app()) { |
167 info->app_launch_url.reset(new std::string( | 150 info->app_launch_url.reset( |
168 AppLaunchInfo::GetFullLaunchURL(&extension).spec())); | 151 new std::string(delegate->GetFullLaunchURL(&extension).spec())); |
169 } | 152 } |
170 | 153 |
171 const ExtensionIconSet::IconMap& icons = | 154 const ExtensionIconSet::IconMap& icons = |
172 IconsInfo::GetIcons(&extension).map(); | 155 IconsInfo::GetIcons(&extension).map(); |
173 if (!icons.empty()) { | 156 if (!icons.empty()) { |
174 info->icons.reset(new IconInfoList()); | 157 info->icons.reset(new IconInfoList()); |
175 ExtensionIconSet::IconMap::const_iterator icon_iter; | 158 ExtensionIconSet::IconMap::const_iterator icon_iter; |
176 for (icon_iter = icons.begin(); icon_iter != icons.end(); ++icon_iter) { | 159 for (icon_iter = icons.begin(); icon_iter != icons.end(); ++icon_iter) { |
177 management::IconInfo* icon_info = new management::IconInfo(); | 160 management::IconInfo* icon_info = new management::IconInfo(); |
178 icon_info->size = icon_iter->first; | 161 icon_info->size = icon_iter->first; |
179 GURL url = ExtensionIconSource::GetIconURL( | 162 GURL url = delegate->GetIconURL(&extension, |
180 &extension, icon_info->size, ExtensionIconSet::MATCH_EXACTLY, false, | 163 icon_info->size, |
181 NULL); | 164 ExtensionIconSet::MATCH_EXACTLY, |
| 165 false, |
| 166 nullptr); |
182 icon_info->url = url.spec(); | 167 icon_info->url = url.spec(); |
183 info->icons->push_back(make_linked_ptr<management::IconInfo>(icon_info)); | 168 info->icons->push_back(make_linked_ptr<management::IconInfo>(icon_info)); |
184 } | 169 } |
185 } | 170 } |
186 | 171 |
187 const std::set<std::string> perms = | 172 const std::set<std::string> perms = |
188 extension.permissions_data()->active_permissions()->GetAPIsAsStrings(); | 173 extension.permissions_data()->active_permissions()->GetAPIsAsStrings(); |
189 if (!perms.empty()) { | 174 if (!perms.empty()) { |
190 std::set<std::string>::const_iterator perms_iter; | 175 std::set<std::string>::const_iterator perms_iter; |
191 for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter) | 176 for (perms_iter = perms.begin(); perms_iter != perms.end(); ++perms_iter) |
192 info->permissions.push_back(*perms_iter); | 177 info->permissions.push_back(*perms_iter); |
193 } | 178 } |
194 | 179 |
195 if (!extension.is_hosted_app()) { | 180 if (!extension.is_hosted_app()) { |
196 // Skip host permissions for hosted apps. | 181 // Skip host permissions for hosted apps. |
197 const URLPatternSet host_perms = | 182 const URLPatternSet host_perms = |
198 extension.permissions_data()->active_permissions()->explicit_hosts(); | 183 extension.permissions_data()->active_permissions()->explicit_hosts(); |
199 if (!host_perms.is_empty()) { | 184 if (!host_perms.is_empty()) { |
200 for (URLPatternSet::const_iterator iter = host_perms.begin(); | 185 for (URLPatternSet::const_iterator iter = host_perms.begin(); |
201 iter != host_perms.end(); ++iter) { | 186 iter != host_perms.end(); |
| 187 ++iter) { |
202 info->host_permissions.push_back(iter->GetAsString()); | 188 info->host_permissions.push_back(iter->GetAsString()); |
203 } | 189 } |
204 } | 190 } |
205 } | 191 } |
206 | 192 |
207 switch (extension.location()) { | 193 switch (extension.location()) { |
208 case Manifest::INTERNAL: | 194 case Manifest::INTERNAL: |
209 info->install_type = management::ExtensionInfo::INSTALL_TYPE_NORMAL; | 195 info->install_type = management::ExtensionInfo::INSTALL_TYPE_NORMAL; |
210 break; | 196 break; |
211 case Manifest::UNPACKED: | 197 case Manifest::UNPACKED: |
(...skipping 18 matching lines...) Expand all Loading... |
230 break; | 216 break; |
231 } | 217 } |
232 | 218 |
233 info->launch_type = management::LAUNCH_TYPE_NONE; | 219 info->launch_type = management::LAUNCH_TYPE_NONE; |
234 if (extension.is_app()) { | 220 if (extension.is_app()) { |
235 LaunchType launch_type; | 221 LaunchType launch_type; |
236 if (extension.is_platform_app()) { | 222 if (extension.is_platform_app()) { |
237 launch_type = LAUNCH_TYPE_WINDOW; | 223 launch_type = LAUNCH_TYPE_WINDOW; |
238 } else { | 224 } else { |
239 launch_type = | 225 launch_type = |
240 GetLaunchType(ExtensionPrefs::Get(service->profile()), &extension); | 226 delegate->GetLaunchType(ExtensionPrefs::Get(context), &extension); |
241 } | 227 } |
242 | 228 |
243 switch (launch_type) { | 229 switch (launch_type) { |
244 case LAUNCH_TYPE_PINNED: | 230 case LAUNCH_TYPE_PINNED: |
245 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB; | 231 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB; |
246 break; | 232 break; |
247 case LAUNCH_TYPE_REGULAR: | 233 case LAUNCH_TYPE_REGULAR: |
248 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB; | 234 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB; |
249 break; | 235 break; |
250 case LAUNCH_TYPE_FULLSCREEN: | 236 case LAUNCH_TYPE_FULLSCREEN: |
251 info->launch_type = management::LAUNCH_TYPE_OPEN_FULL_SCREEN; | 237 info->launch_type = management::LAUNCH_TYPE_OPEN_FULL_SCREEN; |
252 break; | 238 break; |
253 case LAUNCH_TYPE_WINDOW: | 239 case LAUNCH_TYPE_WINDOW: |
254 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_WINDOW; | 240 info->launch_type = management::LAUNCH_TYPE_OPEN_AS_WINDOW; |
255 break; | 241 break; |
256 case LAUNCH_TYPE_INVALID: | 242 case LAUNCH_TYPE_INVALID: |
257 case NUM_LAUNCH_TYPES: | 243 case NUM_LAUNCH_TYPES: |
258 NOTREACHED(); | 244 NOTREACHED(); |
259 } | 245 } |
260 | 246 |
261 info->available_launch_types.reset(new std::vector<management::LaunchType>( | 247 info->available_launch_types.reset(new std::vector<management::LaunchType>( |
262 GetAvailableLaunchTypes(extension))); | 248 GetAvailableLaunchTypes(extension, delegate))); |
263 } | 249 } |
264 | 250 |
265 return info.Pass(); | 251 return info.Pass(); |
266 } | 252 } |
267 | 253 |
| 254 bool ShouldNotBeVisible(const Extension* extension, |
| 255 content::BrowserContext* context) { |
| 256 return (extension->ShouldNotBeVisible() || |
| 257 ExtensionPrefs::Get(context)->IsEphemeralApp(extension->id())); |
| 258 } |
| 259 |
268 void AddExtensionInfo(const ExtensionSet& extensions, | 260 void AddExtensionInfo(const ExtensionSet& extensions, |
269 ExtensionSystem* system, | 261 ExtensionInfoList* extension_list, |
270 ExtensionInfoList* extension_list, | 262 content::BrowserContext* context) { |
271 content::BrowserContext* context) { | |
272 for (ExtensionSet::const_iterator iter = extensions.begin(); | 263 for (ExtensionSet::const_iterator iter = extensions.begin(); |
273 iter != extensions.end(); ++iter) { | 264 iter != extensions.end(); |
| 265 ++iter) { |
274 const Extension& extension = *iter->get(); | 266 const Extension& extension = *iter->get(); |
275 | 267 |
276 if (ui_util::ShouldNotBeVisible(&extension, context)) | 268 if (ShouldNotBeVisible(&extension, context)) |
277 continue; // Skip built-in extensions/apps. | 269 continue; // Skip built-in extensions/apps. |
278 | 270 |
279 extension_list->push_back(make_linked_ptr<management::ExtensionInfo>( | 271 extension_list->push_back(make_linked_ptr<management::ExtensionInfo>( |
280 CreateExtensionInfo(extension, system).release())); | 272 CreateExtensionInfo(extension, context).release())); |
281 } | 273 } |
282 } | 274 } |
283 | 275 |
284 } // namespace | 276 } // namespace |
285 | 277 |
286 ExtensionService* ManagementFunction::service() { | |
287 return ExtensionSystem::Get(GetProfile())->extension_service(); | |
288 } | |
289 | |
290 ExtensionService* AsyncManagementFunction::service() { | |
291 return ExtensionSystem::Get(GetProfile())->extension_service(); | |
292 } | |
293 | |
294 bool ManagementGetAllFunction::RunSync() { | 278 bool ManagementGetAllFunction::RunSync() { |
295 ExtensionInfoList extensions; | 279 ExtensionInfoList extensions; |
296 ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile()); | 280 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); |
297 ExtensionSystem* system = ExtensionSystem::Get(GetProfile()); | |
298 | 281 |
299 AddExtensionInfo(registry->enabled_extensions(), | 282 AddExtensionInfo( |
300 system, &extensions, browser_context()); | 283 registry->enabled_extensions(), &extensions, browser_context()); |
301 AddExtensionInfo(registry->disabled_extensions(), | 284 AddExtensionInfo( |
302 system, &extensions, browser_context()); | 285 registry->disabled_extensions(), &extensions, browser_context()); |
303 AddExtensionInfo(registry->terminated_extensions(), | 286 AddExtensionInfo( |
304 system, &extensions, browser_context()); | 287 registry->terminated_extensions(), &extensions, browser_context()); |
305 | 288 |
306 results_ = management::GetAll::Results::Create(extensions); | 289 results_ = management::GetAll::Results::Create(extensions); |
307 return true; | 290 return true; |
308 } | 291 } |
309 | 292 |
310 bool ManagementGetFunction::RunSync() { | 293 bool ManagementGetFunction::RunSync() { |
311 scoped_ptr<management::Get::Params> params( | 294 scoped_ptr<management::Get::Params> params( |
312 management::Get::Params::Create(*args_)); | 295 management::Get::Params::Create(*args_)); |
313 EXTENSION_FUNCTION_VALIDATE(params.get()); | 296 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 297 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); |
314 | 298 |
315 const Extension* extension = service()->GetExtensionById(params->id, true); | 299 const Extension* extension = |
| 300 registry->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); |
316 if (!extension) { | 301 if (!extension) { |
317 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, | 302 error_ = |
318 params->id); | 303 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); |
319 return false; | 304 return false; |
320 } | 305 } |
321 | 306 |
322 scoped_ptr<management::ExtensionInfo> info = | 307 scoped_ptr<management::ExtensionInfo> info = |
323 CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile())); | 308 CreateExtensionInfo(*extension, browser_context()); |
324 results_ = management::Get::Results::Create(*info); | 309 results_ = management::Get::Results::Create(*info); |
325 | 310 |
326 return true; | 311 return true; |
327 } | 312 } |
328 | 313 |
329 bool ManagementGetSelfFunction::RunSync() { | 314 bool ManagementGetSelfFunction::RunSync() { |
330 scoped_ptr<management::ExtensionInfo> info = | 315 scoped_ptr<management::ExtensionInfo> info = |
331 CreateExtensionInfo(*extension_, ExtensionSystem::Get(GetProfile())); | 316 CreateExtensionInfo(*extension_, browser_context()); |
332 results_ = management::Get::Results::Create(*info); | 317 results_ = management::Get::Results::Create(*info); |
333 | 318 |
334 return true; | 319 return true; |
335 } | 320 } |
336 | 321 |
337 bool ManagementGetPermissionWarningsByIdFunction::RunSync() { | 322 bool ManagementGetPermissionWarningsByIdFunction::RunSync() { |
338 scoped_ptr<management::GetPermissionWarningsById::Params> params( | 323 scoped_ptr<management::GetPermissionWarningsById::Params> params( |
339 management::GetPermissionWarningsById::Params::Create(*args_)); | 324 management::GetPermissionWarningsById::Params::Create(*args_)); |
340 EXTENSION_FUNCTION_VALIDATE(params.get()); | 325 EXTENSION_FUNCTION_VALIDATE(params.get()); |
341 | 326 |
342 const Extension* extension = service()->GetExtensionById(params->id, true); | 327 const Extension* extension = |
| 328 ExtensionRegistry::Get(browser_context()) |
| 329 ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); |
343 if (!extension) { | 330 if (!extension) { |
344 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, | 331 error_ = |
345 params->id); | 332 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); |
346 return false; | 333 return false; |
347 } | 334 } |
348 | 335 |
349 std::vector<std::string> warnings = CreateWarningsList(extension); | 336 std::vector<std::string> warnings = CreateWarningsList(extension); |
350 results_ = management::GetPermissionWarningsById::Results::Create(warnings); | 337 results_ = management::GetPermissionWarningsById::Results::Create(warnings); |
351 return true; | 338 return true; |
352 } | 339 } |
353 | 340 |
354 namespace { | |
355 | |
356 // This class helps ManagementGetPermissionWarningsByManifestFunction manage | |
357 // sending manifest JSON strings to the utility process for parsing. | |
358 class SafeManifestJSONParser : public UtilityProcessHostClient { | |
359 public: | |
360 SafeManifestJSONParser( | |
361 ManagementGetPermissionWarningsByManifestFunction* client, | |
362 const std::string& manifest) | |
363 : client_(client), | |
364 manifest_(manifest) {} | |
365 | |
366 void Start() { | |
367 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
368 BrowserThread::PostTask( | |
369 BrowserThread::IO, | |
370 FROM_HERE, | |
371 base::Bind(&SafeManifestJSONParser::StartWorkOnIOThread, this)); | |
372 } | |
373 | |
374 void StartWorkOnIOThread() { | |
375 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
376 UtilityProcessHost* host = UtilityProcessHost::Create( | |
377 this, base::MessageLoopProxy::current().get()); | |
378 host->Send(new ChromeUtilityMsg_ParseJSON(manifest_)); | |
379 } | |
380 | |
381 bool OnMessageReceived(const IPC::Message& message) override { | |
382 bool handled = true; | |
383 IPC_BEGIN_MESSAGE_MAP(SafeManifestJSONParser, message) | |
384 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded, | |
385 OnJSONParseSucceeded) | |
386 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed, | |
387 OnJSONParseFailed) | |
388 IPC_MESSAGE_UNHANDLED(handled = false) | |
389 IPC_END_MESSAGE_MAP() | |
390 return handled; | |
391 } | |
392 | |
393 void OnJSONParseSucceeded(const base::ListValue& wrapper) { | |
394 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
395 const base::Value* value = NULL; | |
396 CHECK(wrapper.Get(0, &value)); | |
397 if (value->IsType(base::Value::TYPE_DICTIONARY)) | |
398 parsed_manifest_.reset( | |
399 static_cast<const base::DictionaryValue*>(value)->DeepCopy()); | |
400 else | |
401 error_ = keys::kManifestParseError; | |
402 | |
403 BrowserThread::PostTask( | |
404 BrowserThread::UI, | |
405 FROM_HERE, | |
406 base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this)); | |
407 } | |
408 | |
409 void OnJSONParseFailed(const std::string& error) { | |
410 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
411 error_ = error; | |
412 BrowserThread::PostTask( | |
413 BrowserThread::UI, | |
414 FROM_HERE, | |
415 base::Bind(&SafeManifestJSONParser::ReportResultFromUIThread, this)); | |
416 } | |
417 | |
418 void ReportResultFromUIThread() { | |
419 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
420 if (error_.empty() && parsed_manifest_.get()) | |
421 client_->OnParseSuccess(parsed_manifest_.Pass()); | |
422 else | |
423 client_->OnParseFailure(error_); | |
424 } | |
425 | |
426 private: | |
427 ~SafeManifestJSONParser() override {} | |
428 | |
429 // The client who we'll report results back to. | |
430 ManagementGetPermissionWarningsByManifestFunction* client_; | |
431 | |
432 // Data to parse. | |
433 std::string manifest_; | |
434 | |
435 // Results of parsing. | |
436 scoped_ptr<base::DictionaryValue> parsed_manifest_; | |
437 | |
438 std::string error_; | |
439 }; | |
440 | |
441 } // namespace | |
442 | |
443 bool ManagementGetPermissionWarningsByManifestFunction::RunAsync() { | 341 bool ManagementGetPermissionWarningsByManifestFunction::RunAsync() { |
444 scoped_ptr<management::GetPermissionWarningsByManifest::Params> params( | 342 scoped_ptr<management::GetPermissionWarningsByManifest::Params> params( |
445 management::GetPermissionWarningsByManifest::Params::Create(*args_)); | 343 management::GetPermissionWarningsByManifest::Params::Create(*args_)); |
446 EXTENSION_FUNCTION_VALIDATE(params.get()); | 344 EXTENSION_FUNCTION_VALIDATE(params.get()); |
447 | 345 |
448 scoped_refptr<SafeManifestJSONParser> parser = | 346 const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() |
449 new SafeManifestJSONParser(this, params->manifest_str); | 347 ->Get(browser_context()) |
450 parser->Start(); | 348 ->GetDelegate(); |
451 | 349 |
452 // Matched with a Release() in OnParseSuccess/Failure(). | 350 if (delegate) { |
453 AddRef(); | 351 delegate->GetPermissionWarningsByManifestFunctionDelegate( |
| 352 this, params->manifest_str); |
454 | 353 |
455 // Response is sent async in OnParseSuccess/Failure(). | 354 // Matched with a Release() in OnParseSuccess/Failure(). |
456 return true; | 355 AddRef(); |
| 356 |
| 357 // Response is sent async in OnParseSuccess/Failure(). |
| 358 return true; |
| 359 } else { |
| 360 // TODO(lfg) add error string |
| 361 OnParseFailure(""); |
| 362 return false; |
| 363 } |
457 } | 364 } |
458 | 365 |
459 void ManagementGetPermissionWarningsByManifestFunction::OnParseSuccess( | 366 void ManagementGetPermissionWarningsByManifestFunction::OnParseSuccess( |
460 scoped_ptr<base::DictionaryValue> parsed_manifest) { | 367 scoped_ptr<base::DictionaryValue> parsed_manifest) { |
461 CHECK(parsed_manifest.get()); | 368 CHECK(parsed_manifest.get()); |
462 | 369 |
463 scoped_refptr<Extension> extension = Extension::Create( | 370 scoped_refptr<Extension> extension = |
464 base::FilePath(), Manifest::INVALID_LOCATION, *parsed_manifest, | 371 Extension::Create(base::FilePath(), |
465 Extension::NO_FLAGS, &error_); | 372 Manifest::INVALID_LOCATION, |
| 373 *parsed_manifest, |
| 374 Extension::NO_FLAGS, |
| 375 &error_); |
466 if (!extension.get()) { | 376 if (!extension.get()) { |
467 OnParseFailure(keys::kExtensionCreateError); | 377 OnParseFailure(keys::kExtensionCreateError); |
468 return; | 378 return; |
469 } | 379 } |
470 | 380 |
471 std::vector<std::string> warnings = CreateWarningsList(extension.get()); | 381 std::vector<std::string> warnings = CreateWarningsList(extension.get()); |
472 results_ = | 382 results_ = |
473 management::GetPermissionWarningsByManifest::Results::Create(warnings); | 383 management::GetPermissionWarningsByManifest::Results::Create(warnings); |
474 SendResponse(true); | 384 SendResponse(true); |
475 | 385 |
476 // Matched with AddRef() in RunAsync(). | 386 // Matched with AddRef() in RunAsync(). |
477 Release(); | 387 Release(); |
478 } | 388 } |
479 | 389 |
480 void ManagementGetPermissionWarningsByManifestFunction::OnParseFailure( | 390 void ManagementGetPermissionWarningsByManifestFunction::OnParseFailure( |
481 const std::string& error) { | 391 const std::string& error) { |
482 error_ = error; | 392 error_ = error; |
483 SendResponse(false); | 393 SendResponse(false); |
484 | 394 |
485 // Matched with AddRef() in RunAsync(). | 395 // Matched with AddRef() in RunAsync(). |
486 Release(); | 396 Release(); |
487 } | 397 } |
488 | 398 |
489 bool ManagementLaunchAppFunction::RunSync() { | 399 bool ManagementLaunchAppFunction::RunSync() { |
490 scoped_ptr<management::LaunchApp::Params> params( | 400 scoped_ptr<management::LaunchApp::Params> params( |
491 management::LaunchApp::Params::Create(*args_)); | 401 management::LaunchApp::Params::Create(*args_)); |
492 EXTENSION_FUNCTION_VALIDATE(params.get()); | 402 EXTENSION_FUNCTION_VALIDATE(params.get()); |
493 const Extension* extension = service()->GetExtensionById(params->id, true); | 403 const Extension* extension = |
| 404 ExtensionRegistry::Get(browser_context()) |
| 405 ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); |
494 if (!extension) { | 406 if (!extension) { |
495 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, | 407 error_ = |
496 params->id); | 408 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); |
497 return false; | 409 return false; |
498 } | 410 } |
499 if (!extension->is_app()) { | 411 if (!extension->is_app()) { |
500 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, | 412 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); |
501 params->id); | |
502 return false; | 413 return false; |
503 } | 414 } |
504 | 415 |
505 // Look at prefs to find the right launch container. | 416 const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() |
506 // If the user has not set a preference, the default launch value will be | 417 ->Get(browser_context()) |
507 // returned. | 418 ->GetDelegate(); |
508 LaunchContainer launch_container = | 419 return delegate->LaunchAppFunctionDelegate(extension, browser_context()); |
509 GetLaunchContainer(ExtensionPrefs::Get(GetProfile()), extension); | |
510 OpenApplication(AppLaunchParams( | |
511 GetProfile(), extension, launch_container, NEW_FOREGROUND_TAB)); | |
512 CoreAppLauncherHandler::RecordAppLaunchType( | |
513 extension_misc::APP_LAUNCH_EXTENSION_API, | |
514 extension->GetType()); | |
515 | |
516 return true; | |
517 } | 420 } |
518 | 421 |
519 ManagementSetEnabledFunction::ManagementSetEnabledFunction() { | 422 ManagementSetEnabledFunction::ManagementSetEnabledFunction() { |
520 } | 423 } |
521 | 424 |
522 ManagementSetEnabledFunction::~ManagementSetEnabledFunction() { | 425 ManagementSetEnabledFunction::~ManagementSetEnabledFunction() { |
523 } | 426 } |
524 | 427 |
525 bool ManagementSetEnabledFunction::RunAsync() { | 428 bool ManagementSetEnabledFunction::RunAsync() { |
526 scoped_ptr<management::SetEnabled::Params> params( | 429 scoped_ptr<management::SetEnabled::Params> params( |
527 management::SetEnabled::Params::Create(*args_)); | 430 management::SetEnabled::Params::Create(*args_)); |
528 EXTENSION_FUNCTION_VALIDATE(params.get()); | 431 EXTENSION_FUNCTION_VALIDATE(params.get()); |
| 432 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); |
| 433 const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() |
| 434 ->Get(browser_context()) |
| 435 ->GetDelegate(); |
529 | 436 |
530 extension_id_ = params->id; | 437 extension_id_ = params->id; |
531 | 438 |
532 const Extension* extension = | 439 const Extension* extension = |
533 ExtensionRegistry::Get(GetProfile()) | 440 registry->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); |
534 ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); | 441 if (!extension || ShouldNotBeVisible(extension, browser_context())) { |
535 if (!extension || ui_util::ShouldNotBeVisible(extension, browser_context())) { | 442 error_ = |
536 error_ = ErrorUtils::FormatErrorMessage( | 443 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, extension_id_); |
537 keys::kNoExtensionError, extension_id_); | |
538 return false; | 444 return false; |
539 } | 445 } |
540 | 446 |
541 const ManagementPolicy* policy = | 447 const ManagementPolicy* policy = |
542 ExtensionSystem::Get(GetProfile())->management_policy(); | 448 ExtensionSystem::Get(browser_context())->management_policy(); |
543 if (!policy->UserMayModifySettings(extension, NULL) || | 449 if (!policy->UserMayModifySettings(extension, NULL) || |
544 (!params->enabled && policy->MustRemainEnabled(extension, NULL)) || | 450 (!params->enabled && policy->MustRemainEnabled(extension, NULL)) || |
545 (params->enabled && policy->MustRemainDisabled(extension, NULL, NULL))) { | 451 (params->enabled && policy->MustRemainDisabled(extension, NULL, NULL))) { |
546 error_ = ErrorUtils::FormatErrorMessage( | 452 error_ = ErrorUtils::FormatErrorMessage(keys::kUserCantModifyError, |
547 keys::kUserCantModifyError, extension_id_); | 453 extension_id_); |
548 return false; | 454 return false; |
549 } | 455 } |
550 | 456 |
551 bool currently_enabled = service()->IsExtensionEnabled(extension_id_); | 457 bool currently_enabled = |
| 458 registry->enabled_extensions().Contains(extension_id_) || |
| 459 registry->terminated_extensions().Contains(extension_id_); |
552 | 460 |
553 if (!currently_enabled && params->enabled) { | 461 if (!currently_enabled && params->enabled) { |
554 ExtensionPrefs* prefs = ExtensionPrefs::Get(GetProfile()); | 462 ExtensionPrefs* prefs = ExtensionPrefs::Get(browser_context()); |
555 if (prefs->DidExtensionEscalatePermissions(extension_id_)) { | 463 if (prefs->DidExtensionEscalatePermissions(extension_id_)) { |
556 if (!user_gesture()) { | 464 if (!user_gesture()) { |
557 error_ = keys::kGestureNeededForEscalationError; | 465 SetError(keys::kGestureNeededForEscalationError); |
558 return false; | 466 return false; |
559 } | 467 } |
560 AddRef(); // Matched in InstallUIProceed/InstallUIAbort | 468 AddRef(); // Matched in InstallUIProceed/InstallUIAbort |
561 install_prompt_.reset( | 469 install_prompt_ = delegate->SetEnabledFunctionDelegate(this, extension); |
562 new ExtensionInstallPrompt(GetAssociatedWebContents())); | |
563 install_prompt_->ConfirmReEnable(this, extension); | |
564 return true; | 470 return true; |
565 } | 471 } |
566 service()->EnableExtension(extension_id_); | 472 delegate->EnableExtension(browser_context(), extension_id_); |
567 } else if (currently_enabled && !params->enabled) { | 473 } else if (currently_enabled && !params->enabled) { |
568 service()->DisableExtension(extension_id_, Extension::DISABLE_USER_ACTION); | 474 delegate->DisableExtension( |
| 475 browser_context(), extension_id_, Extension::DISABLE_USER_ACTION); |
569 } | 476 } |
570 | 477 |
571 BrowserThread::PostTask( | 478 BrowserThread::PostTask( |
572 BrowserThread::UI, | 479 BrowserThread::UI, |
573 FROM_HERE, | 480 FROM_HERE, |
574 base::Bind(&ManagementSetEnabledFunction::SendResponse, this, true)); | 481 base::Bind(&ManagementSetEnabledFunction::SendResponse, this, true)); |
575 | 482 |
576 return true; | 483 return true; |
577 } | 484 } |
578 | 485 |
579 void ManagementSetEnabledFunction::InstallUIProceed() { | 486 void ManagementSetEnabledFunction::InstallUIProceed() { |
580 service()->EnableExtension(extension_id_); | 487 ManagementAPI::GetFactoryInstance() |
| 488 ->Get(browser_context()) |
| 489 ->GetDelegate() |
| 490 ->EnableExtension(browser_context(), extension_id_); |
581 SendResponse(true); | 491 SendResponse(true); |
582 Release(); | 492 Release(); |
583 } | 493 } |
584 | 494 |
585 void ManagementSetEnabledFunction::InstallUIAbort(bool user_initiated) { | 495 void ManagementSetEnabledFunction::InstallUIAbort(bool user_initiated) { |
586 error_ = keys::kUserDidNotReEnableError; | 496 error_ = keys::kUserDidNotReEnableError; |
587 SendResponse(false); | 497 SendResponse(false); |
588 Release(); | 498 Release(); |
589 } | 499 } |
590 | 500 |
591 ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() { | 501 ManagementUninstallFunctionBase::ManagementUninstallFunctionBase() { |
592 } | 502 } |
593 | 503 |
594 ManagementUninstallFunctionBase::~ManagementUninstallFunctionBase() { | 504 ManagementUninstallFunctionBase::~ManagementUninstallFunctionBase() { |
595 } | 505 } |
596 | 506 |
597 bool ManagementUninstallFunctionBase::Uninstall( | 507 bool ManagementUninstallFunctionBase::Uninstall( |
598 const std::string& target_extension_id, | 508 const std::string& target_extension_id, |
599 bool show_confirm_dialog) { | 509 bool show_confirm_dialog) { |
| 510 const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() |
| 511 ->Get(browser_context()) |
| 512 ->GetDelegate(); |
600 extension_id_ = target_extension_id; | 513 extension_id_ = target_extension_id; |
601 const Extension* target_extension = | 514 const Extension* target_extension = |
602 extensions::ExtensionRegistry::Get(browser_context())-> | 515 extensions::ExtensionRegistry::Get(browser_context()) |
603 GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); | 516 ->GetExtensionById(extension_id_, ExtensionRegistry::EVERYTHING); |
604 if (!target_extension || | 517 if (!target_extension || |
605 ui_util::ShouldNotBeVisible(target_extension, browser_context())) { | 518 ShouldNotBeVisible(target_extension, browser_context())) { |
606 error_ = ErrorUtils::FormatErrorMessage( | 519 error_ = |
607 keys::kNoExtensionError, extension_id_); | 520 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, extension_id_); |
608 return false; | 521 return false; |
609 } | 522 } |
610 | 523 |
611 if (!ExtensionSystem::Get(GetProfile()) | 524 if (!ExtensionSystem::Get(browser_context()) |
612 ->management_policy() | 525 ->management_policy() |
613 ->UserMayModifySettings(target_extension, NULL)) { | 526 ->UserMayModifySettings(target_extension, NULL)) { |
614 error_ = ErrorUtils::FormatErrorMessage( | 527 error_ = ErrorUtils::FormatErrorMessage(keys::kUserCantModifyError, |
615 keys::kUserCantModifyError, extension_id_); | 528 extension_id_); |
616 return false; | 529 return false; |
617 } | 530 } |
618 | 531 |
619 if (auto_confirm_for_test == DO_NOT_SKIP) { | 532 if (auto_confirm_for_test == DO_NOT_SKIP) { |
620 if (show_confirm_dialog) { | 533 if (show_confirm_dialog) { |
621 AddRef(); // Balanced in ExtensionUninstallAccepted/Canceled | 534 AddRef(); // Balanced in ExtensionUninstallAccepted/Canceled |
622 content::WebContents* web_contents = GetAssociatedWebContents(); | 535 delegate->UninstallFunctionDelegate(this, target_extension_id); |
623 extension_uninstall_dialog_.reset(ExtensionUninstallDialog::Create( | |
624 GetProfile(), | |
625 web_contents ? web_contents->GetTopLevelNativeWindow() : NULL, | |
626 this)); | |
627 if (extension_id() != target_extension_id) { | |
628 extension_uninstall_dialog_->ConfirmProgrammaticUninstall( | |
629 target_extension, extension()); | |
630 } else { | |
631 // If this is a self uninstall, show the generic uninstall dialog. | |
632 extension_uninstall_dialog_->ConfirmUninstall(target_extension); | |
633 } | |
634 } else { | 536 } else { |
635 Finish(true); | 537 Finish(true); |
636 } | 538 } |
637 } else { | 539 } else { |
638 Finish(auto_confirm_for_test == PROCEED); | 540 Finish(auto_confirm_for_test == PROCEED); |
639 } | 541 } |
640 | 542 |
641 return true; | 543 return true; |
642 } | 544 } |
643 | 545 |
644 // static | 546 // static |
645 void ManagementUninstallFunctionBase::SetAutoConfirmForTest( | 547 void ManagementUninstallFunctionBase::SetAutoConfirmForTest( |
646 bool should_proceed) { | 548 bool should_proceed) { |
647 auto_confirm_for_test = should_proceed ? PROCEED : ABORT; | 549 auto_confirm_for_test = should_proceed ? PROCEED : ABORT; |
648 } | 550 } |
649 | 551 |
650 void ManagementUninstallFunctionBase::Finish(bool should_uninstall) { | 552 void ManagementUninstallFunctionBase::Finish(bool should_uninstall) { |
651 if (should_uninstall) { | 553 if (should_uninstall) { |
652 // The extension can be uninstalled in another window while the UI was | 554 // The extension can be uninstalled in another window while the UI was |
653 // showing. Do nothing in that case. | 555 // showing. Do nothing in that case. |
654 ExtensionRegistry* registry = ExtensionRegistry::Get(GetProfile()); | 556 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); |
655 const Extension* extension = registry->GetExtensionById( | 557 const Extension* extension = registry->GetExtensionById( |
656 extension_id_, ExtensionRegistry::EVERYTHING); | 558 extension_id_, ExtensionRegistry::EVERYTHING); |
657 if (!extension) { | 559 if (!extension) { |
658 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, | 560 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, |
659 extension_id_); | 561 extension_id_); |
660 SendResponse(false); | 562 SendResponse(false); |
661 } else { | 563 } else { |
662 bool success = service()->UninstallExtension( | 564 const ManagementAPIDelegate* delegate = |
| 565 ManagementAPI::GetFactoryInstance() |
| 566 ->Get(browser_context()) |
| 567 ->GetDelegate(); |
| 568 bool success = delegate->UninstallExtension( |
| 569 browser_context(), |
663 extension_id_, | 570 extension_id_, |
664 extensions::UNINSTALL_REASON_MANAGEMENT_API, | 571 extensions::UNINSTALL_REASON_MANAGEMENT_API, |
665 base::Bind(&base::DoNothing), | 572 base::Bind(&base::DoNothing), |
666 NULL); | 573 NULL); |
667 | 574 |
668 // TODO set error_ if !success | 575 // TODO set error_ if !success |
669 SendResponse(success); | 576 SendResponse(success); |
670 } | 577 } |
671 } else { | 578 } else { |
672 error_ = ErrorUtils::FormatErrorMessage( | 579 error_ = ErrorUtils::FormatErrorMessage(keys::kUninstallCanceledError, |
673 keys::kUninstallCanceledError, extension_id_); | 580 extension_id_); |
674 SendResponse(false); | 581 SendResponse(false); |
675 } | 582 } |
676 } | 583 } |
677 | 584 |
678 void ManagementUninstallFunctionBase::ExtensionUninstallAccepted() { | 585 void ManagementUninstallFunctionBase::ExtensionUninstallAccepted() { |
679 Finish(true); | 586 Finish(true); |
680 Release(); | 587 Release(); |
681 } | 588 } |
682 | 589 |
683 void ManagementUninstallFunctionBase::ExtensionUninstallCanceled() { | 590 void ManagementUninstallFunctionBase::ExtensionUninstallCanceled() { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 | 657 |
751 bool ManagementCreateAppShortcutFunction::RunAsync() { | 658 bool ManagementCreateAppShortcutFunction::RunAsync() { |
752 if (!user_gesture()) { | 659 if (!user_gesture()) { |
753 error_ = keys::kGestureNeededForCreateAppShortcutError; | 660 error_ = keys::kGestureNeededForCreateAppShortcutError; |
754 return false; | 661 return false; |
755 } | 662 } |
756 | 663 |
757 scoped_ptr<management::CreateAppShortcut::Params> params( | 664 scoped_ptr<management::CreateAppShortcut::Params> params( |
758 management::CreateAppShortcut::Params::Create(*args_)); | 665 management::CreateAppShortcut::Params::Create(*args_)); |
759 EXTENSION_FUNCTION_VALIDATE(params.get()); | 666 EXTENSION_FUNCTION_VALIDATE(params.get()); |
760 const Extension* extension = service()->GetExtensionById(params->id, true); | 667 const Extension* extension = |
| 668 ExtensionRegistry::Get(browser_context()) |
| 669 ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); |
761 if (!extension) { | 670 if (!extension) { |
762 error_ = ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, | 671 error_ = |
763 params->id); | 672 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); |
764 return false; | 673 return false; |
765 } | 674 } |
766 | 675 |
767 if (!extension->is_app()) { | 676 if (!extension->is_app()) { |
768 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); | 677 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); |
769 return false; | 678 return false; |
770 } | 679 } |
771 | 680 |
772 #if defined(OS_MACOSX) | 681 #if defined(OS_MACOSX) |
773 if (!extension->is_platform_app()) { | 682 if (!extension->is_platform_app()) { |
774 error_ = keys::kCreateOnlyPackagedAppShortcutMac; | 683 error_ = keys::kCreateOnlyPackagedAppShortcutMac; |
775 return false; | 684 return false; |
776 } | 685 } |
777 #endif | 686 #endif |
778 | 687 |
779 Browser* browser = chrome::FindBrowserWithProfile( | 688 if (auto_confirm_for_test != DO_NOT_SKIP) { |
780 GetProfile(), chrome::HOST_DESKTOP_TYPE_NATIVE); | 689 // Matched with a Release() in OnCloseShortcutPrompt(). |
781 if (!browser) { | 690 AddRef(); |
782 // Shouldn't happen if we have user gesture. | 691 |
783 error_ = keys::kNoBrowserToCreateShortcut; | 692 OnCloseShortcutPrompt(auto_confirm_for_test == PROCEED); |
784 return false; | 693 |
| 694 return true; |
785 } | 695 } |
786 | 696 |
787 // Matched with a Release() in OnCloseShortcutPrompt(). | 697 if (ManagementAPI::GetFactoryInstance() |
788 AddRef(); | 698 ->Get(browser_context()) |
789 | 699 ->GetDelegate() |
790 if (auto_confirm_for_test == DO_NOT_SKIP) { | 700 ->CreateAppShortcutFunctionDelegate(this, extension)) { |
791 chrome::ShowCreateChromeAppShortcutsDialog( | 701 // Matched with a Release() in OnCloseShortcutPrompt(). |
792 browser->window()->GetNativeWindow(), browser->profile(), extension, | 702 AddRef(); |
793 base::Bind(&ManagementCreateAppShortcutFunction::OnCloseShortcutPrompt, | |
794 this)); | |
795 } else { | |
796 OnCloseShortcutPrompt(auto_confirm_for_test == PROCEED); | |
797 } | 703 } |
798 | 704 |
799 // Response is sent async in OnCloseShortcutPrompt(). | 705 // Response is sent async in OnCloseShortcutPrompt(). |
800 return true; | 706 return true; |
801 } | 707 } |
802 | 708 |
803 bool ManagementSetLaunchTypeFunction::RunSync() { | 709 bool ManagementSetLaunchTypeFunction::RunSync() { |
804 if (!user_gesture()) { | 710 if (!user_gesture()) { |
805 error_ = keys::kGestureNeededForSetLaunchTypeError; | 711 error_ = keys::kGestureNeededForSetLaunchTypeError; |
806 return false; | 712 return false; |
807 } | 713 } |
808 | 714 |
809 scoped_ptr<management::SetLaunchType::Params> params( | 715 scoped_ptr<management::SetLaunchType::Params> params( |
810 management::SetLaunchType::Params::Create(*args_)); | 716 management::SetLaunchType::Params::Create(*args_)); |
811 EXTENSION_FUNCTION_VALIDATE(params.get()); | 717 EXTENSION_FUNCTION_VALIDATE(params.get()); |
812 const Extension* extension = service()->GetExtensionById(params->id, true); | 718 const Extension* extension = |
| 719 ExtensionRegistry::Get(browser_context()) |
| 720 ->GetExtensionById(params->id, ExtensionRegistry::EVERYTHING); |
| 721 const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance() |
| 722 ->Get(browser_context()) |
| 723 ->GetDelegate(); |
813 if (!extension) { | 724 if (!extension) { |
814 error_ = | 725 error_ = |
815 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); | 726 ErrorUtils::FormatErrorMessage(keys::kNoExtensionError, params->id); |
816 return false; | 727 return false; |
817 } | 728 } |
818 | 729 |
819 if (!extension->is_app()) { | 730 if (!extension->is_app()) { |
820 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); | 731 error_ = ErrorUtils::FormatErrorMessage(keys::kNotAnAppError, params->id); |
821 return false; | 732 return false; |
822 } | 733 } |
823 | 734 |
824 std::vector<management::LaunchType> available_launch_types = | 735 std::vector<management::LaunchType> available_launch_types = |
825 GetAvailableLaunchTypes(*extension); | 736 GetAvailableLaunchTypes(*extension, delegate); |
826 | 737 |
827 management::LaunchType app_launch_type = params->launch_type; | 738 management::LaunchType app_launch_type = params->launch_type; |
828 if (std::find(available_launch_types.begin(), | 739 if (std::find(available_launch_types.begin(), |
829 available_launch_types.end(), | 740 available_launch_types.end(), |
830 app_launch_type) == available_launch_types.end()) { | 741 app_launch_type) == available_launch_types.end()) { |
831 error_ = keys::kLaunchTypeNotAvailableError; | 742 error_ = keys::kLaunchTypeNotAvailableError; |
832 return false; | 743 return false; |
833 } | 744 } |
834 | 745 |
835 LaunchType launch_type = LAUNCH_TYPE_DEFAULT; | 746 LaunchType launch_type = LAUNCH_TYPE_DEFAULT; |
836 switch (app_launch_type) { | 747 switch (app_launch_type) { |
837 case management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB: | 748 case management::LAUNCH_TYPE_OPEN_AS_PINNED_TAB: |
838 launch_type = LAUNCH_TYPE_PINNED; | 749 launch_type = LAUNCH_TYPE_PINNED; |
839 break; | 750 break; |
840 case management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB: | 751 case management::LAUNCH_TYPE_OPEN_AS_REGULAR_TAB: |
841 launch_type = LAUNCH_TYPE_REGULAR; | 752 launch_type = LAUNCH_TYPE_REGULAR; |
842 break; | 753 break; |
843 case management::LAUNCH_TYPE_OPEN_FULL_SCREEN: | 754 case management::LAUNCH_TYPE_OPEN_FULL_SCREEN: |
844 launch_type = LAUNCH_TYPE_FULLSCREEN; | 755 launch_type = LAUNCH_TYPE_FULLSCREEN; |
845 break; | 756 break; |
846 case management::LAUNCH_TYPE_OPEN_AS_WINDOW: | 757 case management::LAUNCH_TYPE_OPEN_AS_WINDOW: |
847 launch_type = LAUNCH_TYPE_WINDOW; | 758 launch_type = LAUNCH_TYPE_WINDOW; |
848 break; | 759 break; |
849 case management::LAUNCH_TYPE_NONE: | 760 case management::LAUNCH_TYPE_NONE: |
850 NOTREACHED(); | 761 NOTREACHED(); |
851 } | 762 } |
852 | 763 |
853 SetLaunchType(service(), params->id, launch_type); | 764 delegate->SetLaunchType(browser_context(), params->id, launch_type); |
854 | 765 |
855 return true; | 766 return true; |
856 } | 767 } |
857 | 768 |
858 ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() { | 769 ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() { |
859 } | 770 } |
860 | 771 |
861 ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() { | 772 ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() { |
862 } | 773 } |
863 | 774 |
864 void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp( | 775 void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp( |
865 const Extension* extension, | 776 const Extension* extension, |
866 const WebApplicationInfo& web_app_info) { | 777 const WebApplicationInfo& web_app_info) { |
867 if (extension) { | 778 if (extension) { |
868 scoped_ptr<management::ExtensionInfo> info = | 779 scoped_ptr<management::ExtensionInfo> info = |
869 CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile())); | 780 CreateExtensionInfo(*extension, browser_context()); |
870 results_ = management::GenerateAppForLink::Results::Create(*info); | 781 results_ = management::GenerateAppForLink::Results::Create(*info); |
871 | 782 |
872 SendResponse(true); | 783 SendResponse(true); |
873 Release(); | 784 Release(); |
874 } else { | 785 } else { |
875 error_ = keys::kGenerateAppForLinkInstallError; | 786 error_ = keys::kGenerateAppForLinkInstallError; |
876 SendResponse(false); | 787 SendResponse(false); |
877 Release(); | 788 Release(); |
878 } | 789 } |
879 } | 790 } |
880 | 791 |
881 void ManagementGenerateAppForLinkFunction::OnFaviconForApp( | |
882 const favicon_base::FaviconImageResult& image_result) { | |
883 WebApplicationInfo web_app; | |
884 web_app.title = base::UTF8ToUTF16(title_); | |
885 web_app.app_url = launch_url_; | |
886 | |
887 if (!image_result.image.IsEmpty()) { | |
888 WebApplicationInfo::IconInfo icon; | |
889 icon.data = image_result.image.AsBitmap(); | |
890 icon.width = icon.data.width(); | |
891 icon.height = icon.data.height(); | |
892 web_app.icons.push_back(icon); | |
893 } | |
894 | |
895 bookmark_app_helper_.reset(new BookmarkAppHelper(service(), web_app, NULL)); | |
896 bookmark_app_helper_->Create(base::Bind( | |
897 &ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp, this)); | |
898 } | |
899 | |
900 bool ManagementGenerateAppForLinkFunction::RunAsync() { | 792 bool ManagementGenerateAppForLinkFunction::RunAsync() { |
901 if (!user_gesture()) { | 793 if (!user_gesture()) { |
902 error_ = keys::kGestureNeededForGenerateAppForLinkError; | 794 error_ = keys::kGestureNeededForGenerateAppForLinkError; |
903 return false; | 795 return false; |
904 } | 796 } |
905 | 797 |
906 scoped_ptr<management::GenerateAppForLink::Params> params( | 798 scoped_ptr<management::GenerateAppForLink::Params> params( |
907 management::GenerateAppForLink::Params::Create(*args_)); | 799 management::GenerateAppForLink::Params::Create(*args_)); |
908 EXTENSION_FUNCTION_VALIDATE(params.get()); | 800 EXTENSION_FUNCTION_VALIDATE(params.get()); |
909 | 801 |
910 GURL launch_url(params->url); | 802 GURL launch_url(params->url); |
911 if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) { | 803 if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) { |
912 error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidURLError, | 804 error_ = |
913 params->url); | 805 ErrorUtils::FormatErrorMessage(keys::kInvalidURLError, params->url); |
914 return false; | 806 return false; |
915 } | 807 } |
916 | 808 |
917 if (params->title.empty()) { | 809 if (params->title.empty()) { |
918 error_ = keys::kEmptyTitleError; | 810 error_ = keys::kEmptyTitleError; |
919 return false; | 811 return false; |
920 } | 812 } |
921 | 813 |
922 FaviconService* favicon_service = | 814 app_for_link_delegate_ = |
923 FaviconServiceFactory::GetForProfile(GetProfile(), | 815 ManagementAPI::GetFactoryInstance() |
924 Profile::EXPLICIT_ACCESS); | 816 ->Get(browser_context()) |
925 DCHECK(favicon_service); | 817 ->GetDelegate() |
| 818 ->GenerateAppForLinkFunctionDelegate( |
| 819 this, browser_context(), params->title, launch_url); |
926 | 820 |
927 title_ = params->title; | 821 // Matched with a Release() in FinishCreateBookmarkApp(). |
928 launch_url_ = launch_url; | |
929 | |
930 favicon_service->GetFaviconImageForPageURL( | |
931 launch_url, | |
932 base::Bind(&ManagementGenerateAppForLinkFunction::OnFaviconForApp, this), | |
933 &cancelable_task_tracker_); | |
934 | |
935 // Matched with a Release() in OnExtensionLoaded(). | |
936 AddRef(); | 822 AddRef(); |
937 | 823 |
938 // Response is sent async in OnExtensionLoaded(). | 824 // Response is sent async in FinishCreateBookmarkApp(). |
939 return true; | 825 return true; |
940 } | 826 } |
941 | 827 |
942 ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context) | 828 ManagementEventRouter::ManagementEventRouter(content::BrowserContext* context) |
943 : browser_context_(context), extension_registry_observer_(this) { | 829 : browser_context_(context), extension_registry_observer_(this) { |
944 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); | 830 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
945 } | 831 } |
946 | 832 |
947 ManagementEventRouter::~ManagementEventRouter() {} | 833 ManagementEventRouter::~ManagementEventRouter() { |
| 834 } |
948 | 835 |
949 void ManagementEventRouter::OnExtensionLoaded( | 836 void ManagementEventRouter::OnExtensionLoaded( |
950 content::BrowserContext* browser_context, | 837 content::BrowserContext* browser_context, |
951 const Extension* extension) { | 838 const Extension* extension) { |
952 BroadcastEvent(extension, management::OnEnabled::kEventName); | 839 BroadcastEvent(extension, management::OnEnabled::kEventName); |
953 } | 840 } |
954 | 841 |
955 void ManagementEventRouter::OnExtensionUnloaded( | 842 void ManagementEventRouter::OnExtensionUnloaded( |
956 content::BrowserContext* browser_context, | 843 content::BrowserContext* browser_context, |
957 const Extension* extension, | 844 const Extension* extension, |
(...skipping 10 matching lines...) Expand all Loading... |
968 | 855 |
969 void ManagementEventRouter::OnExtensionUninstalled( | 856 void ManagementEventRouter::OnExtensionUninstalled( |
970 content::BrowserContext* browser_context, | 857 content::BrowserContext* browser_context, |
971 const Extension* extension, | 858 const Extension* extension, |
972 extensions::UninstallReason reason) { | 859 extensions::UninstallReason reason) { |
973 BroadcastEvent(extension, management::OnUninstalled::kEventName); | 860 BroadcastEvent(extension, management::OnUninstalled::kEventName); |
974 } | 861 } |
975 | 862 |
976 void ManagementEventRouter::BroadcastEvent(const Extension* extension, | 863 void ManagementEventRouter::BroadcastEvent(const Extension* extension, |
977 const char* event_name) { | 864 const char* event_name) { |
978 if (ui_util::ShouldNotBeVisible(extension, browser_context_)) | 865 if (ShouldNotBeVisible(extension, browser_context_)) |
979 return; // Don't dispatch events for built-in extenions. | 866 return; // Don't dispatch events for built-in extenions. |
980 scoped_ptr<base::ListValue> args(new base::ListValue()); | 867 scoped_ptr<base::ListValue> args(new base::ListValue()); |
981 if (event_name == management::OnUninstalled::kEventName) { | 868 if (event_name == management::OnUninstalled::kEventName) { |
982 args->Append(new base::StringValue(extension->id())); | 869 args->Append(new base::StringValue(extension->id())); |
983 } else { | 870 } else { |
984 scoped_ptr<management::ExtensionInfo> info = | 871 scoped_ptr<management::ExtensionInfo> info = |
985 CreateExtensionInfo(*extension, ExtensionSystem::Get(browser_context_)); | 872 CreateExtensionInfo(*extension, browser_context_); |
986 args->Append(info->ToValue().release()); | 873 args->Append(info->ToValue().release()); |
987 } | 874 } |
988 | 875 |
989 EventRouter::Get(browser_context_) | 876 EventRouter::Get(browser_context_) |
990 ->BroadcastEvent(scoped_ptr<Event>(new Event(event_name, args.Pass()))); | 877 ->BroadcastEvent(scoped_ptr<Event>(new Event(event_name, args.Pass()))); |
991 } | 878 } |
992 | 879 |
993 ManagementAPI::ManagementAPI(content::BrowserContext* context) | 880 ManagementAPI::ManagementAPI(content::BrowserContext* context) |
994 : browser_context_(context) { | 881 : browser_context_(context), |
| 882 delegate_(ExtensionsAPIClient::Get()->CreateManagementAPIDelegate()) { |
995 EventRouter* event_router = EventRouter::Get(browser_context_); | 883 EventRouter* event_router = EventRouter::Get(browser_context_); |
996 event_router->RegisterObserver(this, management::OnInstalled::kEventName); | 884 event_router->RegisterObserver(this, management::OnInstalled::kEventName); |
997 event_router->RegisterObserver(this, management::OnUninstalled::kEventName); | 885 event_router->RegisterObserver(this, management::OnUninstalled::kEventName); |
998 event_router->RegisterObserver(this, management::OnEnabled::kEventName); | 886 event_router->RegisterObserver(this, management::OnEnabled::kEventName); |
999 event_router->RegisterObserver(this, management::OnDisabled::kEventName); | 887 event_router->RegisterObserver(this, management::OnDisabled::kEventName); |
1000 } | 888 } |
1001 | 889 |
1002 ManagementAPI::~ManagementAPI() { | 890 ManagementAPI::~ManagementAPI() { |
1003 } | 891 } |
1004 | 892 |
1005 void ManagementAPI::Shutdown() { | 893 void ManagementAPI::Shutdown() { |
1006 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 894 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
1007 } | 895 } |
1008 | 896 |
1009 static base::LazyInstance<BrowserContextKeyedAPIFactory<ManagementAPI> > | 897 static base::LazyInstance<BrowserContextKeyedAPIFactory<ManagementAPI>> |
1010 g_factory = LAZY_INSTANCE_INITIALIZER; | 898 g_factory = LAZY_INSTANCE_INITIALIZER; |
1011 | 899 |
1012 // static | 900 // static |
1013 BrowserContextKeyedAPIFactory<ManagementAPI>* | 901 BrowserContextKeyedAPIFactory<ManagementAPI>* |
1014 ManagementAPI::GetFactoryInstance() { | 902 ManagementAPI::GetFactoryInstance() { |
1015 return g_factory.Pointer(); | 903 return g_factory.Pointer(); |
1016 } | 904 } |
1017 | 905 |
1018 void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) { | 906 void ManagementAPI::OnListenerAdded(const EventListenerInfo& details) { |
1019 management_event_router_.reset(new ManagementEventRouter(browser_context_)); | 907 management_event_router_.reset(new ManagementEventRouter(browser_context_)); |
1020 EventRouter::Get(browser_context_)->UnregisterObserver(this); | 908 EventRouter::Get(browser_context_)->UnregisterObserver(this); |
1021 } | 909 } |
1022 | 910 |
1023 } // namespace extensions | 911 } // namespace extensions |
OLD | NEW |