OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/ui/views/extensions/extension_message_bubble_view.h" | 5 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h" |
6 | 6 |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" | 10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" |
11 #include "chrome/browser/extensions/extension_action_manager.h" | 11 #include "chrome/browser/extensions/extension_action_manager.h" |
12 #include "chrome/browser/extensions/extension_message_bubble_controller.h" | 12 #include "chrome/browser/extensions/extension_message_bubble_controller.h" |
13 #include "chrome/browser/extensions/extension_service.h" | 13 #include "chrome/browser/extensions/extension_service.h" |
14 #include "chrome/browser/extensions/proxy_overridden_bubble_controller.h" | |
15 #include "chrome/browser/extensions/settings_api_bubble_controller.h" | 14 #include "chrome/browser/extensions/settings_api_bubble_controller.h" |
16 #include "chrome/browser/extensions/settings_api_helpers.h" | 15 #include "chrome/browser/extensions/settings_api_helpers.h" |
17 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h" | 16 #include "chrome/browser/extensions/suspicious_extension_bubble_controller.h" |
18 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/view_ids.h" | |
20 #include "chrome/browser/ui/views/frame/browser_view.h" | 18 #include "chrome/browser/ui/views/frame/browser_view.h" |
21 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" | 19 #include "chrome/browser/ui/views/toolbar/browser_actions_container.h" |
22 #include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h" | 20 #include "chrome/browser/ui/views/toolbar/browser_actions_container_observer.h" |
23 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" | 21 #include "chrome/browser/ui/views/toolbar/toolbar_view.h" |
24 #include "extensions/browser/extension_prefs.h" | 22 #include "extensions/browser/extension_prefs.h" |
25 #include "extensions/browser/extension_system.h" | 23 #include "extensions/browser/extension_system.h" |
26 #include "grit/locale_settings.h" | 24 #include "grit/locale_settings.h" |
27 #include "ui/accessibility/ax_view_state.h" | 25 #include "ui/accessibility/ax_view_state.h" |
28 #include "ui/base/resource/resource_bundle.h" | 26 #include "ui/base/resource/resource_bundle.h" |
29 #include "ui/views/controls/button/label_button.h" | 27 #include "ui/views/controls/button/label_button.h" |
(...skipping 27 matching lines...) Expand all Loading... |
57 | 55 |
58 namespace extensions { | 56 namespace extensions { |
59 | 57 |
60 ExtensionMessageBubbleView::ExtensionMessageBubbleView( | 58 ExtensionMessageBubbleView::ExtensionMessageBubbleView( |
61 views::View* anchor_view, | 59 views::View* anchor_view, |
62 views::BubbleBorder::Arrow arrow_location, | 60 views::BubbleBorder::Arrow arrow_location, |
63 scoped_ptr<extensions::ExtensionMessageBubbleController> controller) | 61 scoped_ptr<extensions::ExtensionMessageBubbleController> controller) |
64 : BubbleDelegateView(anchor_view, arrow_location), | 62 : BubbleDelegateView(anchor_view, arrow_location), |
65 weak_factory_(this), | 63 weak_factory_(this), |
66 controller_(controller.Pass()), | 64 controller_(controller.Pass()), |
67 anchor_view_(anchor_view), | |
68 headline_(NULL), | 65 headline_(NULL), |
69 learn_more_(NULL), | 66 learn_more_(NULL), |
70 dismiss_button_(NULL), | 67 dismiss_button_(NULL), |
71 link_clicked_(false), | 68 link_clicked_(false), |
72 action_taken_(false) { | 69 action_taken_(false) { |
73 DCHECK(anchor_view->GetWidget()); | 70 DCHECK(anchor_view->GetWidget()); |
74 set_close_on_deactivate(controller_->CloseOnDeactivate()); | 71 set_close_on_deactivate(controller_->CloseOnDeactivate()); |
75 set_close_on_esc(true); | 72 set_close_on_esc(true); |
76 | 73 |
77 // Compensate for built-in vertical padding in the anchor view's image. | 74 // Compensate for built-in vertical padding in the anchor view's image. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 const int text_column_set_id = 1; | 149 const int text_column_set_id = 1; |
153 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); | 150 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); |
154 upper_columns->AddColumn( | 151 upper_columns->AddColumn( |
155 views::GridLayout::LEADING, views::GridLayout::LEADING, | 152 views::GridLayout::LEADING, views::GridLayout::LEADING, |
156 0, views::GridLayout::USE_PREF, 0, 0); | 153 0, views::GridLayout::USE_PREF, 0, 0); |
157 layout->StartRow(0, text_column_set_id); | 154 layout->StartRow(0, text_column_set_id); |
158 | 155 |
159 views::Label* message = new views::Label(); | 156 views::Label* message = new views::Label(); |
160 message->SetMultiLine(true); | 157 message->SetMultiLine(true); |
161 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 158 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
162 message->SetText(delegate->GetMessageBody( | 159 message->SetText(delegate->GetMessageBody()); |
163 anchor_view_->id() == VIEW_ID_BROWSER_ACTION)); | |
164 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 160 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
165 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 161 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
166 layout->AddView(message); | 162 layout->AddView(message); |
167 | 163 |
168 if (delegate->ShouldShowExtensionList()) { | 164 if (delegate->ShouldShowExtensionList()) { |
169 const int extension_list_column_set_id = 2; | 165 const int extension_list_column_set_id = 2; |
170 views::ColumnSet* middle_columns = | 166 views::ColumnSet* middle_columns = |
171 layout->AddColumnSet(extension_list_column_set_id); | 167 layout->AddColumnSet(extension_list_column_set_id); |
172 middle_columns->AddPaddingColumn(0, kExtensionListPadding); | 168 middle_columns->AddPaddingColumn(0, kExtensionListPadding); |
173 middle_columns->AddColumn( | 169 middle_columns->AddColumn( |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 //////////////////////////////////////////////////////////////////////////////// | 265 //////////////////////////////////////////////////////////////////////////////// |
270 // ExtensionMessageBubbleFactory | 266 // ExtensionMessageBubbleFactory |
271 | 267 |
272 ExtensionMessageBubbleFactory::ExtensionMessageBubbleFactory( | 268 ExtensionMessageBubbleFactory::ExtensionMessageBubbleFactory( |
273 Profile* profile, | 269 Profile* profile, |
274 ToolbarView* toolbar_view) | 270 ToolbarView* toolbar_view) |
275 : profile_(profile), | 271 : profile_(profile), |
276 toolbar_view_(toolbar_view), | 272 toolbar_view_(toolbar_view), |
277 shown_suspicious_extensions_bubble_(false), | 273 shown_suspicious_extensions_bubble_(false), |
278 shown_startup_override_extensions_bubble_(false), | 274 shown_startup_override_extensions_bubble_(false), |
279 shown_proxy_override_extensions_bubble_(false), | |
280 shown_dev_mode_extensions_bubble_(false), | 275 shown_dev_mode_extensions_bubble_(false), |
281 is_observing_(false), | 276 is_observing_(false), |
282 stage_(STAGE_START), | 277 stage_(STAGE_START), |
283 container_(NULL), | 278 container_(NULL), |
284 anchor_view_(NULL) {} | 279 anchor_view_(NULL) {} |
285 | 280 |
286 ExtensionMessageBubbleFactory::~ExtensionMessageBubbleFactory() { | 281 ExtensionMessageBubbleFactory::~ExtensionMessageBubbleFactory() { |
287 MaybeStopObserving(); | 282 MaybeStopObserving(); |
288 } | 283 } |
289 | 284 |
(...skipping 12 matching lines...) Expand all Loading... |
302 // way, we're not too spammy with the bubbles. | 297 // way, we're not too spammy with the bubbles. |
303 if (!shown_suspicious_extensions_bubble_ && | 298 if (!shown_suspicious_extensions_bubble_ && |
304 MaybeShowSuspiciousExtensionsBubble(anchor_view)) | 299 MaybeShowSuspiciousExtensionsBubble(anchor_view)) |
305 return; | 300 return; |
306 | 301 |
307 if (!shown_startup_override_extensions_bubble_ && | 302 if (!shown_startup_override_extensions_bubble_ && |
308 is_initial_check && | 303 is_initial_check && |
309 MaybeShowStartupOverrideExtensionsBubble(anchor_view)) | 304 MaybeShowStartupOverrideExtensionsBubble(anchor_view)) |
310 return; | 305 return; |
311 | 306 |
312 if (!shown_proxy_override_extensions_bubble_ && | |
313 MaybeShowProxyOverrideExtensionsBubble(anchor_view)) | |
314 return; | |
315 | |
316 if (!shown_dev_mode_extensions_bubble_) | 307 if (!shown_dev_mode_extensions_bubble_) |
317 MaybeShowDevModeExtensionsBubble(anchor_view); | 308 MaybeShowDevModeExtensionsBubble(anchor_view); |
318 #endif // OS_WIN | 309 #endif // OS_WIN |
319 } | 310 } |
320 | 311 |
321 bool ExtensionMessageBubbleFactory::MaybeShowSuspiciousExtensionsBubble( | 312 bool ExtensionMessageBubbleFactory::MaybeShowSuspiciousExtensionsBubble( |
322 views::View* anchor_view) { | 313 views::View* anchor_view) { |
323 DCHECK(!shown_suspicious_extensions_bubble_); | 314 DCHECK(!shown_suspicious_extensions_bubble_); |
324 | 315 |
325 scoped_ptr<SuspiciousExtensionBubbleController> suspicious_extensions( | 316 scoped_ptr<SuspiciousExtensionBubbleController> suspicious_extensions( |
(...skipping 12 matching lines...) Expand all Loading... |
338 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 329 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
339 weak_controller->Show(bubble_delegate); | 330 weak_controller->Show(bubble_delegate); |
340 | 331 |
341 return true; | 332 return true; |
342 } | 333 } |
343 | 334 |
344 bool ExtensionMessageBubbleFactory::MaybeShowStartupOverrideExtensionsBubble( | 335 bool ExtensionMessageBubbleFactory::MaybeShowStartupOverrideExtensionsBubble( |
345 views::View* anchor_view) { | 336 views::View* anchor_view) { |
346 #if !defined(OS_WIN) | 337 #if !defined(OS_WIN) |
347 return false; | 338 return false; |
348 #else | 339 #endif |
| 340 |
349 DCHECK(!shown_startup_override_extensions_bubble_); | 341 DCHECK(!shown_startup_override_extensions_bubble_); |
350 | 342 |
351 const Extension* extension = | 343 const Extension* extension = OverridesStartupPages(profile_, NULL); |
352 GetExtensionOverridingStartupPages(profile_, NULL); | |
353 if (!extension) | 344 if (!extension) |
354 return false; | 345 return false; |
355 | 346 |
356 scoped_ptr<SettingsApiBubbleController> settings_api_bubble( | 347 scoped_ptr<SettingsApiBubbleController> settings_api_bubble( |
357 new SettingsApiBubbleController(profile_, | 348 new SettingsApiBubbleController(profile_, |
358 BUBBLE_TYPE_STARTUP_PAGES)); | 349 BUBBLE_TYPE_STARTUP_PAGES)); |
359 if (!settings_api_bubble->ShouldShow(extension->id())) | 350 if (!settings_api_bubble->ShouldShow(extension->id())) |
360 return false; | 351 return false; |
361 | 352 |
362 shown_startup_override_extensions_bubble_ = true; | 353 shown_startup_override_extensions_bubble_ = true; |
363 PrepareToHighlightExtensions( | 354 SettingsApiBubbleController* weak_controller = settings_api_bubble.get(); |
364 settings_api_bubble.PassAs<ExtensionMessageBubbleController>(), | 355 ExtensionMessageBubbleView* bubble_delegate = new ExtensionMessageBubbleView( |
365 anchor_view); | 356 anchor_view, |
| 357 views::BubbleBorder::TOP_RIGHT, |
| 358 settings_api_bubble.PassAs<ExtensionMessageBubbleController>()); |
| 359 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 360 weak_controller->Show(bubble_delegate); |
| 361 |
366 return true; | 362 return true; |
367 #endif | |
368 } | |
369 | |
370 bool ExtensionMessageBubbleFactory::MaybeShowProxyOverrideExtensionsBubble( | |
371 views::View* anchor_view) { | |
372 #if !defined(OS_WIN) | |
373 return false; | |
374 #else | |
375 DCHECK(!shown_proxy_override_extensions_bubble_); | |
376 | |
377 const Extension* extension = GetExtensionOverridingProxy(profile_); | |
378 if (!extension) | |
379 return false; | |
380 | |
381 scoped_ptr<ProxyOverriddenBubbleController> proxy_bubble( | |
382 new ProxyOverriddenBubbleController(profile_)); | |
383 if (!proxy_bubble->ShouldShow(extension->id())) | |
384 return false; | |
385 | |
386 shown_proxy_override_extensions_bubble_ = true; | |
387 PrepareToHighlightExtensions( | |
388 proxy_bubble.PassAs<ExtensionMessageBubbleController>(), anchor_view); | |
389 return true; | |
390 #endif | |
391 } | 363 } |
392 | 364 |
393 bool ExtensionMessageBubbleFactory::MaybeShowDevModeExtensionsBubble( | 365 bool ExtensionMessageBubbleFactory::MaybeShowDevModeExtensionsBubble( |
394 views::View* anchor_view) { | 366 views::View* anchor_view) { |
395 DCHECK(!shown_dev_mode_extensions_bubble_); | 367 DCHECK(!shown_dev_mode_extensions_bubble_); |
396 | 368 |
397 // Check the Developer Mode extensions. | 369 // Check the Developer Mode extensions. |
398 scoped_ptr<DevModeBubbleController> dev_mode_extensions( | 370 scoped_ptr<DevModeBubbleController> dev_mode_extensions( |
399 new DevModeBubbleController(profile_)); | 371 new DevModeBubbleController(profile_)); |
400 | 372 |
401 // Return early if we have none to show. | 373 // Return early if we have none to show. |
402 if (!dev_mode_extensions->ShouldShow()) | 374 if (!dev_mode_extensions->ShouldShow()) |
403 return false; | 375 return false; |
404 | 376 |
405 shown_dev_mode_extensions_bubble_ = true; | 377 shown_dev_mode_extensions_bubble_ = true; |
406 PrepareToHighlightExtensions( | 378 |
407 dev_mode_extensions.PassAs<ExtensionMessageBubbleController>(), | 379 // We should be in the start stage (i.e., should not have a pending attempt to |
408 anchor_view); | 380 // show a bubble). |
| 381 DCHECK_EQ(stage_, STAGE_START); |
| 382 |
| 383 // Prepare to display and highlight the developer mode extensions before |
| 384 // showing the bubble. Since this is an asynchronous process, set member |
| 385 // variables for later use. |
| 386 controller_ = dev_mode_extensions.Pass(); |
| 387 anchor_view_ = anchor_view; |
| 388 container_ = toolbar_view_->browser_actions(); |
| 389 |
| 390 if (container_->animating()) |
| 391 MaybeObserve(); |
| 392 else |
| 393 HighlightDevModeExtensions(); |
| 394 |
409 return true; | 395 return true; |
410 } | 396 } |
411 | 397 |
412 void ExtensionMessageBubbleFactory::MaybeObserve() { | 398 void ExtensionMessageBubbleFactory::MaybeObserve() { |
413 if (!is_observing_) { | 399 if (!is_observing_) { |
414 is_observing_ = true; | 400 is_observing_ = true; |
415 container_->AddObserver(this); | 401 container_->AddObserver(this); |
416 } | 402 } |
417 } | 403 } |
418 | 404 |
419 void ExtensionMessageBubbleFactory::MaybeStopObserving() { | 405 void ExtensionMessageBubbleFactory::MaybeStopObserving() { |
420 if (is_observing_) { | 406 if (is_observing_) { |
421 is_observing_ = false; | 407 is_observing_ = false; |
422 container_->RemoveObserver(this); | 408 container_->RemoveObserver(this); |
423 } | 409 } |
424 } | 410 } |
425 | 411 |
426 void ExtensionMessageBubbleFactory::RecordProfileCheck(Profile* profile) { | 412 void ExtensionMessageBubbleFactory::RecordProfileCheck(Profile* profile) { |
427 g_profiles_evaluated.Get().insert(profile); | 413 g_profiles_evaluated.Get().insert(profile); |
428 } | 414 } |
429 | 415 |
430 bool ExtensionMessageBubbleFactory::IsInitialProfileCheck(Profile* profile) { | 416 bool ExtensionMessageBubbleFactory::IsInitialProfileCheck(Profile* profile) { |
431 return g_profiles_evaluated.Get().count(profile) == 0; | 417 return g_profiles_evaluated.Get().count(profile) == 0; |
432 } | 418 } |
433 | 419 |
434 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerAnimationEnded() { | 420 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerAnimationEnded() { |
435 MaybeStopObserving(); | 421 MaybeStopObserving(); |
436 if (stage_ == STAGE_START) { | 422 if (stage_ == STAGE_START) { |
437 HighlightExtensions(); | 423 HighlightDevModeExtensions(); |
438 } else if (stage_ == STAGE_HIGHLIGHTED) { | 424 } else if (stage_ == STAGE_HIGHLIGHTED) { |
439 ShowHighlightingBubble(); | 425 ShowDevModeBubble(); |
440 } else { // We shouldn't be observing if we've completed the process. | 426 } else { // We shouldn't be observing if we've completed the process. |
441 NOTREACHED(); | 427 NOTREACHED(); |
442 Finish(); | 428 Finish(); |
443 } | 429 } |
444 } | 430 } |
445 | 431 |
446 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerDestroyed() { | 432 void ExtensionMessageBubbleFactory::OnBrowserActionsContainerDestroyed() { |
447 // If the container associated with the bubble is destroyed, abandon the | 433 // If the container associated with the bubble is destroyed, abandon the |
448 // process. | 434 // process. |
449 Finish(); | 435 Finish(); |
450 } | 436 } |
451 | 437 |
452 void ExtensionMessageBubbleFactory::PrepareToHighlightExtensions( | 438 void ExtensionMessageBubbleFactory::HighlightDevModeExtensions() { |
453 scoped_ptr<ExtensionMessageBubbleController> controller, | |
454 views::View* anchor_view) { | |
455 // We should be in the start stage (i.e., should not have a pending attempt to | |
456 // show a bubble). | |
457 DCHECK_EQ(stage_, STAGE_START); | |
458 | |
459 // Prepare to display and highlight the extensions before showing the bubble. | |
460 // Since this is an asynchronous process, set member variables for later use. | |
461 controller_ = controller.Pass(); | |
462 anchor_view_ = anchor_view; | |
463 container_ = toolbar_view_->browser_actions(); | |
464 | |
465 if (container_->animating()) | |
466 MaybeObserve(); | |
467 else | |
468 HighlightExtensions(); | |
469 } | |
470 | |
471 void ExtensionMessageBubbleFactory::HighlightExtensions() { | |
472 DCHECK_EQ(STAGE_START, stage_); | 439 DCHECK_EQ(STAGE_START, stage_); |
473 stage_ = STAGE_HIGHLIGHTED; | 440 stage_ = STAGE_HIGHLIGHTED; |
474 | 441 |
475 const ExtensionIdList extension_list = controller_->GetExtensionIdList(); | 442 const ExtensionIdList extension_list = controller_->GetExtensionIdList(); |
476 DCHECK(!extension_list.empty()); | 443 DCHECK(!extension_list.empty()); |
477 ExtensionToolbarModel::Get(profile_)->HighlightExtensions(extension_list); | 444 ExtensionToolbarModel::Get(profile_)->HighlightExtensions(extension_list); |
478 if (container_->animating()) | 445 if (container_->animating()) |
479 MaybeObserve(); | 446 MaybeObserve(); |
480 else | 447 else |
481 ShowHighlightingBubble(); | 448 ShowDevModeBubble(); |
482 } | 449 } |
483 | 450 |
484 void ExtensionMessageBubbleFactory::ShowHighlightingBubble() { | 451 void ExtensionMessageBubbleFactory::ShowDevModeBubble() { |
485 DCHECK_EQ(stage_, STAGE_HIGHLIGHTED); | 452 DCHECK_EQ(stage_, STAGE_HIGHLIGHTED); |
486 stage_ = STAGE_COMPLETE; | 453 stage_ = STAGE_COMPLETE; |
487 | 454 |
488 views::View* reference_view = NULL; | 455 views::View* reference_view = NULL; |
489 if (container_->num_browser_actions() > 0) | 456 if (container_->num_browser_actions() > 0) |
490 reference_view = container_->GetBrowserActionViewAt(0); | 457 reference_view = container_->GetBrowserActionViewAt(0); |
491 if (reference_view && reference_view->visible()) | 458 if (reference_view && reference_view->visible()) |
492 anchor_view_ = reference_view; | 459 anchor_view_ = reference_view; |
493 | 460 |
494 ExtensionMessageBubbleController* weak_controller = controller_.get(); | 461 DevModeBubbleController* weak_controller = controller_.get(); |
495 ExtensionMessageBubbleView* bubble_delegate = | 462 ExtensionMessageBubbleView* bubble_delegate = new ExtensionMessageBubbleView( |
496 new ExtensionMessageBubbleView( | 463 anchor_view_, |
497 anchor_view_, | 464 views::BubbleBorder::TOP_RIGHT, |
498 views::BubbleBorder::TOP_RIGHT, | 465 scoped_ptr<ExtensionMessageBubbleController>(controller_.release())); |
499 scoped_ptr<ExtensionMessageBubbleController>( | |
500 controller_.release())); | |
501 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 466 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
502 weak_controller->Show(bubble_delegate); | 467 weak_controller->Show(bubble_delegate); |
503 | 468 |
504 Finish(); | 469 Finish(); |
505 } | 470 } |
506 | 471 |
507 void ExtensionMessageBubbleFactory::Finish() { | 472 void ExtensionMessageBubbleFactory::Finish() { |
508 MaybeStopObserving(); | 473 MaybeStopObserving(); |
509 controller_.reset(); | 474 controller_.reset(); |
510 anchor_view_ = NULL; | 475 anchor_view_ = NULL; |
511 container_ = NULL; | 476 container_ = NULL; |
512 } | 477 } |
513 | 478 |
514 } // namespace extensions | 479 } // namespace extensions |
OLD | NEW |