| 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/extension_disabled_ui.h" | 5 #include "chrome/browser/extensions/extension_disabled_ui.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } | 134 } |
| 135 | 135 |
| 136 // ExtensionDisabledGlobalError ----------------------------------------------- | 136 // ExtensionDisabledGlobalError ----------------------------------------------- |
| 137 | 137 |
| 138 class ExtensionDisabledGlobalError : public GlobalErrorWithStandardBubble, | 138 class ExtensionDisabledGlobalError : public GlobalErrorWithStandardBubble, |
| 139 public content::NotificationObserver, | 139 public content::NotificationObserver, |
| 140 public ExtensionUninstallDialog::Delegate { | 140 public ExtensionUninstallDialog::Delegate { |
| 141 public: | 141 public: |
| 142 ExtensionDisabledGlobalError(ExtensionService* service, | 142 ExtensionDisabledGlobalError(ExtensionService* service, |
| 143 const Extension* extension, | 143 const Extension* extension, |
| 144 int disable_reasons, |
| 144 const gfx::Image& icon); | 145 const gfx::Image& icon); |
| 145 virtual ~ExtensionDisabledGlobalError(); | 146 virtual ~ExtensionDisabledGlobalError(); |
| 146 | 147 |
| 147 // GlobalError implementation. | 148 // GlobalError implementation. |
| 148 virtual Severity GetSeverity() OVERRIDE; | 149 virtual Severity GetSeverity() OVERRIDE; |
| 149 virtual bool HasMenuItem() OVERRIDE; | 150 virtual bool HasMenuItem() OVERRIDE; |
| 150 virtual int MenuItemCommandID() OVERRIDE; | 151 virtual int MenuItemCommandID() OVERRIDE; |
| 151 virtual base::string16 MenuItemLabel() OVERRIDE; | 152 virtual base::string16 MenuItemLabel() OVERRIDE; |
| 152 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE; | 153 virtual void ExecuteMenuItem(Browser* browser) OVERRIDE; |
| 153 virtual gfx::Image GetBubbleViewIcon() OVERRIDE; | 154 virtual gfx::Image GetBubbleViewIcon() OVERRIDE; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 164 virtual void ExtensionUninstallCanceled() OVERRIDE; | 165 virtual void ExtensionUninstallCanceled() OVERRIDE; |
| 165 | 166 |
| 166 // content::NotificationObserver implementation. | 167 // content::NotificationObserver implementation. |
| 167 virtual void Observe(int type, | 168 virtual void Observe(int type, |
| 168 const content::NotificationSource& source, | 169 const content::NotificationSource& source, |
| 169 const content::NotificationDetails& details) OVERRIDE; | 170 const content::NotificationDetails& details) OVERRIDE; |
| 170 | 171 |
| 171 private: | 172 private: |
| 172 ExtensionService* service_; | 173 ExtensionService* service_; |
| 173 const Extension* extension_; | 174 const Extension* extension_; |
| 175 int disable_reasons_; |
| 174 gfx::Image icon_; | 176 gfx::Image icon_; |
| 175 | 177 |
| 176 // How the user responded to the error; used for metrics. | 178 // How the user responded to the error; used for metrics. |
| 177 enum UserResponse { | 179 enum UserResponse { |
| 178 IGNORED, | 180 IGNORED, |
| 179 REENABLE, | 181 REENABLE, |
| 180 UNINSTALL, | 182 UNINSTALL, |
| 181 EXTENSION_DISABLED_UI_BUCKET_BOUNDARY | 183 EXTENSION_DISABLED_UI_BUCKET_BOUNDARY |
| 182 }; | 184 }; |
| 183 UserResponse user_response_; | 185 UserResponse user_response_; |
| 184 | 186 |
| 185 scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_; | 187 scoped_ptr<ExtensionUninstallDialog> uninstall_dialog_; |
| 186 | 188 |
| 187 // Menu command ID assigned for this extension's error. | 189 // Menu command ID assigned for this extension's error. |
| 188 int menu_command_id_; | 190 int menu_command_id_; |
| 189 | 191 |
| 190 content::NotificationRegistrar registrar_; | 192 content::NotificationRegistrar registrar_; |
| 191 }; | 193 }; |
| 192 | 194 |
| 193 // TODO(yoz): create error at startup for disabled extensions. | 195 // TODO(yoz): create error at startup for disabled extensions. |
| 194 ExtensionDisabledGlobalError::ExtensionDisabledGlobalError( | 196 ExtensionDisabledGlobalError::ExtensionDisabledGlobalError( |
| 195 ExtensionService* service, | 197 ExtensionService* service, |
| 196 const Extension* extension, | 198 const Extension* extension, |
| 199 int disable_reasons, |
| 197 const gfx::Image& icon) | 200 const gfx::Image& icon) |
| 198 : service_(service), | 201 : service_(service), |
| 199 extension_(extension), | 202 extension_(extension), |
| 203 disable_reasons_(disable_reasons), |
| 200 icon_(icon), | 204 icon_(icon), |
| 201 user_response_(IGNORED), | 205 user_response_(IGNORED), |
| 202 menu_command_id_(GetMenuCommandID()) { | 206 menu_command_id_(GetMenuCommandID()) { |
| 203 if (icon_.IsEmpty()) { | 207 if (icon_.IsEmpty()) { |
| 204 icon_ = gfx::Image( | 208 icon_ = gfx::Image( |
| 205 gfx::ImageSkiaOperations::CreateResizedImage( | 209 gfx::ImageSkiaOperations::CreateResizedImage( |
| 206 extension_->is_app() ? | 210 extension_->is_app() ? |
| 207 extensions::IconsInfo::GetDefaultAppIcon() : | 211 extensions::IconsInfo::GetDefaultAppIcon() : |
| 208 extensions::IconsInfo::GetDefaultExtensionIcon(), | 212 extensions::IconsInfo::GetDefaultExtensionIcon(), |
| 209 skia::ImageOperations::RESIZE_BEST, | 213 skia::ImageOperations::RESIZE_BEST, |
| 210 gfx::Size(kIconSize, kIconSize))); | 214 gfx::Size(kIconSize, kIconSize))); |
| 211 } | 215 } |
| 212 registrar_.Add(this, | 216 registrar_.Add(this, |
| 213 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, | 217 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, |
| 214 content::Source<Profile>(service->profile())); | 218 content::Source<Profile>(service->profile())); |
| 215 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, | 219 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_REMOVED, |
| 216 content::Source<Profile>(service->profile())); | 220 content::Source<Profile>(service->profile())); |
| 217 } | 221 } |
| 218 | 222 |
| 219 ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() { | 223 ExtensionDisabledGlobalError::~ExtensionDisabledGlobalError() { |
| 220 ReleaseMenuCommandID(menu_command_id_); | 224 ReleaseMenuCommandID(menu_command_id_); |
| 221 UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse", | 225 if (disable_reasons_ & Extension::DISABLE_REMOTE_INSTALL) |
| 222 user_response_, | 226 UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponseRemoteInstall", |
| 223 EXTENSION_DISABLED_UI_BUCKET_BOUNDARY); | 227 user_response_, |
| 228 EXTENSION_DISABLED_UI_BUCKET_BOUNDARY); |
| 229 else |
| 230 UMA_HISTOGRAM_ENUMERATION("Extensions.DisabledUIUserResponse", |
| 231 user_response_, |
| 232 EXTENSION_DISABLED_UI_BUCKET_BOUNDARY); |
| 224 } | 233 } |
| 225 | 234 |
| 226 GlobalError::Severity ExtensionDisabledGlobalError::GetSeverity() { | 235 GlobalError::Severity ExtensionDisabledGlobalError::GetSeverity() { |
| 227 return SEVERITY_LOW; | 236 return SEVERITY_LOW; |
| 228 } | 237 } |
| 229 | 238 |
| 230 bool ExtensionDisabledGlobalError::HasMenuItem() { | 239 bool ExtensionDisabledGlobalError::HasMenuItem() { |
| 231 return true; | 240 return true; |
| 232 } | 241 } |
| 233 | 242 |
| 234 int ExtensionDisabledGlobalError::MenuItemCommandID() { | 243 int ExtensionDisabledGlobalError::MenuItemCommandID() { |
| 235 return menu_command_id_; | 244 return menu_command_id_; |
| 236 } | 245 } |
| 237 | 246 |
| 238 base::string16 ExtensionDisabledGlobalError::MenuItemLabel() { | 247 base::string16 ExtensionDisabledGlobalError::MenuItemLabel() { |
| 239 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE, | 248 if (disable_reasons_ & Extension::DISABLE_REMOTE_INSTALL) |
| 240 base::UTF8ToUTF16(extension_->name())); | 249 return l10n_util::GetStringFUTF16( |
| 250 IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_TITLE, |
| 251 base::UTF8ToUTF16(extension_->name())); |
| 252 else |
| 253 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE, |
| 254 base::UTF8ToUTF16(extension_->name())); |
| 241 } | 255 } |
| 242 | 256 |
| 243 void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) { | 257 void ExtensionDisabledGlobalError::ExecuteMenuItem(Browser* browser) { |
| 244 ShowBubbleView(browser); | 258 ShowBubbleView(browser); |
| 245 } | 259 } |
| 246 | 260 |
| 247 gfx::Image ExtensionDisabledGlobalError::GetBubbleViewIcon() { | 261 gfx::Image ExtensionDisabledGlobalError::GetBubbleViewIcon() { |
| 248 return icon_; | 262 return icon_; |
| 249 } | 263 } |
| 250 | 264 |
| 251 base::string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() { | 265 base::string16 ExtensionDisabledGlobalError::GetBubbleViewTitle() { |
| 252 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE, | 266 if (disable_reasons_ & Extension::DISABLE_REMOTE_INSTALL) |
| 253 base::UTF8ToUTF16(extension_->name())); | 267 return l10n_util::GetStringFUTF16( |
| 268 IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_TITLE, |
| 269 base::UTF8ToUTF16(extension_->name())); |
| 270 else |
| 271 return l10n_util::GetStringFUTF16(IDS_EXTENSION_DISABLED_ERROR_TITLE, |
| 272 base::UTF8ToUTF16(extension_->name())); |
| 254 } | 273 } |
| 255 | 274 |
| 256 std::vector<base::string16> | 275 std::vector<base::string16> |
| 257 ExtensionDisabledGlobalError::GetBubbleViewMessages() { | 276 ExtensionDisabledGlobalError::GetBubbleViewMessages() { |
| 258 std::vector<base::string16> messages; | 277 std::vector<base::string16> messages; |
| 259 messages.push_back(l10n_util::GetStringFUTF16( | |
| 260 extension_->is_app() ? | |
| 261 IDS_APP_DISABLED_ERROR_LABEL : IDS_EXTENSION_DISABLED_ERROR_LABEL, | |
| 262 base::UTF8ToUTF16(extension_->name()))); | |
| 263 messages.push_back(l10n_util::GetStringUTF16( | |
| 264 IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO)); | |
| 265 std::vector<base::string16> permission_warnings = | 278 std::vector<base::string16> permission_warnings = |
| 266 extensions::PermissionMessageProvider::Get()->GetWarningMessages( | 279 extensions::PermissionMessageProvider::Get()->GetWarningMessages( |
| 267 extension_->GetActivePermissions(), extension_->GetType()); | 280 extension_->GetActivePermissions(), extension_->GetType()); |
| 281 if (disable_reasons_ & Extension::DISABLE_REMOTE_INSTALL) { |
| 282 messages.push_back(l10n_util::GetStringFUTF16( |
| 283 extension_->is_app() |
| 284 ? IDS_APP_DISABLED_REMOTE_INSTALL_ERROR_LABEL |
| 285 : IDS_EXTENSION_DISABLED_REMOTE_INSTALL_ERROR_LABEL, |
| 286 base::UTF8ToUTF16(extension_->name()))); |
| 287 if (!permission_warnings.empty()) |
| 288 messages.push_back( |
| 289 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WILL_HAVE_ACCESS_TO)); |
| 290 } else { |
| 291 messages.push_back(l10n_util::GetStringFUTF16( |
| 292 extension_->is_app() ? IDS_APP_DISABLED_ERROR_LABEL |
| 293 : IDS_EXTENSION_DISABLED_ERROR_LABEL, |
| 294 base::UTF8ToUTF16(extension_->name()))); |
| 295 messages.push_back(l10n_util::GetStringUTF16( |
| 296 IDS_EXTENSION_PROMPT_WILL_NOW_HAVE_ACCESS_TO)); |
| 297 } |
| 268 for (size_t i = 0; i < permission_warnings.size(); ++i) { | 298 for (size_t i = 0; i < permission_warnings.size(); ++i) { |
| 269 messages.push_back(l10n_util::GetStringFUTF16( | 299 messages.push_back(l10n_util::GetStringFUTF16( |
| 270 IDS_EXTENSION_PERMISSION_LINE, permission_warnings[i])); | 300 IDS_EXTENSION_PERMISSION_LINE, permission_warnings[i])); |
| 271 } | 301 } |
| 272 return messages; | 302 return messages; |
| 273 } | 303 } |
| 274 | 304 |
| 275 base::string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() { | 305 base::string16 ExtensionDisabledGlobalError::GetBubbleViewAcceptButtonLabel() { |
| 276 return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON); | 306 if (disable_reasons_ & Extension::DISABLE_REMOTE_INSTALL) |
| 307 return l10n_util::GetStringUTF16( |
| 308 IDS_EXTENSION_PROMPT_REMOTE_INSTALL_BUTTON); |
| 309 else |
| 310 return l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_RE_ENABLE_BUTTON); |
| 277 } | 311 } |
| 278 | 312 |
| 279 base::string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() { | 313 base::string16 ExtensionDisabledGlobalError::GetBubbleViewCancelButtonLabel() { |
| 280 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL); | 314 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL); |
| 281 } | 315 } |
| 282 | 316 |
| 283 void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) { | 317 void ExtensionDisabledGlobalError::OnBubbleViewDidClose(Browser* browser) { |
| 284 } | 318 } |
| 285 | 319 |
| 286 void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed( | 320 void ExtensionDisabledGlobalError::BubbleViewAcceptButtonPressed( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 user_response_ = UNINSTALL; | 365 user_response_ = UNINSTALL; |
| 332 delete this; | 366 delete this; |
| 333 } | 367 } |
| 334 | 368 |
| 335 // Globals -------------------------------------------------------------------- | 369 // Globals -------------------------------------------------------------------- |
| 336 | 370 |
| 337 namespace extensions { | 371 namespace extensions { |
| 338 | 372 |
| 339 void AddExtensionDisabledErrorWithIcon(base::WeakPtr<ExtensionService> service, | 373 void AddExtensionDisabledErrorWithIcon(base::WeakPtr<ExtensionService> service, |
| 340 const std::string& extension_id, | 374 const std::string& extension_id, |
| 375 int disable_reasons, |
| 341 const gfx::Image& icon) { | 376 const gfx::Image& icon) { |
| 342 if (!service.get()) | 377 if (!service.get()) |
| 343 return; | 378 return; |
| 344 const Extension* extension = service->GetInstalledExtension(extension_id); | 379 const Extension* extension = service->GetInstalledExtension(extension_id); |
| 345 if (extension) { | 380 if (extension) { |
| 346 GlobalErrorServiceFactory::GetForProfile(service->profile()) | 381 GlobalErrorServiceFactory::GetForProfile(service->profile()) |
| 347 ->AddGlobalError( | 382 ->AddGlobalError(new ExtensionDisabledGlobalError( |
| 348 new ExtensionDisabledGlobalError(service.get(), extension, icon)); | 383 service.get(), extension, disable_reasons, icon)); |
| 349 } | 384 } |
| 350 } | 385 } |
| 351 | 386 |
| 352 void AddExtensionDisabledError(ExtensionService* service, | 387 void AddExtensionDisabledError(ExtensionService* service, |
| 353 const Extension* extension) { | 388 const Extension* extension, |
| 389 int disable_reasons) { |
| 354 // Do not display notifications for ephemeral apps that have been disabled. | 390 // Do not display notifications for ephemeral apps that have been disabled. |
| 355 // Instead, a prompt will be shown the next time the app is launched. | 391 // Instead, a prompt will be shown the next time the app is launched. |
| 356 if (extension->is_ephemeral()) | 392 if (extension->is_ephemeral()) |
| 357 return; | 393 return; |
| 358 | 394 |
| 359 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource( | 395 extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource( |
| 360 extension, kIconSize, ExtensionIconSet::MATCH_BIGGER); | 396 extension, kIconSize, ExtensionIconSet::MATCH_BIGGER); |
| 361 gfx::Size size(kIconSize, kIconSize); | 397 gfx::Size size(kIconSize, kIconSize); |
| 362 ImageLoader::Get(service->profile())->LoadImageAsync( | 398 ImageLoader::Get(service->profile()) |
| 363 extension, image, size, | 399 ->LoadImageAsync(extension, |
| 364 base::Bind(&AddExtensionDisabledErrorWithIcon, | 400 image, |
| 365 service->AsWeakPtr(), extension->id())); | 401 size, |
| 402 base::Bind(&AddExtensionDisabledErrorWithIcon, |
| 403 service->AsWeakPtr(), |
| 404 extension->id(), |
| 405 disable_reasons)); |
| 366 } | 406 } |
| 367 | 407 |
| 368 void ShowExtensionDisabledDialog(ExtensionService* service, | 408 void ShowExtensionDisabledDialog(ExtensionService* service, |
| 369 content::WebContents* web_contents, | 409 content::WebContents* web_contents, |
| 370 const Extension* extension) { | 410 const Extension* extension) { |
| 371 scoped_ptr<ExtensionInstallPrompt> install_ui( | 411 scoped_ptr<ExtensionInstallPrompt> install_ui( |
| 372 new ExtensionInstallPrompt(web_contents)); | 412 new ExtensionInstallPrompt(web_contents)); |
| 373 // This object manages its own lifetime. | 413 // This object manages its own lifetime. |
| 374 new ExtensionDisabledDialogDelegate(service, install_ui.Pass(), extension); | 414 new ExtensionDisabledDialogDelegate(service, install_ui.Pass(), extension); |
| 375 } | 415 } |
| 376 | 416 |
| 377 } // namespace extensions | 417 } // namespace extensions |
| OLD | NEW |