Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc

Issue 23461013: Refactor out duplicate code from GTK/Views extension installed bubble. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/ui/views/extensions/extension_installed_bubble.h" 5 #include "chrome/browser/ui/views/extensions/extension_installed_bubble_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h"
11 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/chrome_notification_types.h"
15 #include "chrome/browser/extensions/api/commands/command_service.h" 13 #include "chrome/browser/extensions/api/commands/command_service.h"
16 #include "chrome/browser/extensions/extension_action.h" 14 #include "chrome/browser/extensions/extension_action.h"
17 #include "chrome/browser/extensions/extension_action_manager.h" 15 #include "chrome/browser/extensions/extension_action_manager.h"
18 #include "chrome/browser/extensions/extension_install_ui.h" 16 #include "chrome/browser/extensions/extension_install_ui.h"
19 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/signin/signin_promo.h" 18 #include "chrome/browser/signin/signin_promo.h"
21 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
22 #include "chrome/browser/ui/browser_window.h" 20 #include "chrome/browser/ui/browser_window.h"
23 #include "chrome/browser/ui/singleton_tabs.h" 21 #include "chrome/browser/ui/singleton_tabs.h"
24 #include "chrome/browser/ui/sync/sync_promo_ui.h" 22 #include "chrome/browser/ui/sync/sync_promo_ui.h"
25 #include "chrome/browser/ui/views/browser_action_view.h" 23 #include "chrome/browser/ui/views/browser_action_view.h"
26 #include "chrome/browser/ui/views/browser_actions_container.h" 24 #include "chrome/browser/ui/views/browser_actions_container.h"
27 #include "chrome/browser/ui/views/frame/browser_view.h" 25 #include "chrome/browser/ui/views/frame/browser_view.h"
28 #include "chrome/browser/ui/views/location_bar/location_bar_view.h" 26 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
29 #include "chrome/browser/ui/views/tabs/tab_strip.h" 27 #include "chrome/browser/ui/views/tabs/tab_strip.h"
30 #include "chrome/browser/ui/views/toolbar_view.h" 28 #include "chrome/browser/ui/views/toolbar_view.h"
31 #include "chrome/common/extensions/api/extension_action/action_info.h"
32 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h" 29 #include "chrome/common/extensions/api/omnibox/omnibox_handler.h"
33 #include "chrome/common/extensions/extension.h" 30 #include "chrome/common/extensions/extension.h"
34 #include "chrome/common/extensions/sync_helper.h" 31 #include "chrome/common/extensions/sync_helper.h"
35 #include "chrome/common/url_constants.h" 32 #include "chrome/common/url_constants.h"
36 #include "content/public/browser/notification_details.h"
37 #include "content/public/browser/notification_source.h"
38 #include "grit/chromium_strings.h" 33 #include "grit/chromium_strings.h"
39 #include "grit/generated_resources.h" 34 #include "grit/generated_resources.h"
40 #include "grit/ui_resources.h" 35 #include "grit/ui_resources.h"
41 #include "ui/base/l10n/l10n_util.h" 36 #include "ui/base/l10n/l10n_util.h"
42 #include "ui/base/resource/resource_bundle.h" 37 #include "ui/base/resource/resource_bundle.h"
43 #include "ui/base/text/text_elider.h" 38 #include "ui/base/text/text_elider.h"
44 #include "ui/gfx/render_text.h" 39 #include "ui/gfx/render_text.h"
45 #include "ui/views/controls/button/image_button.h" 40 #include "ui/views/controls/button/image_button.h"
46 #include "ui/views/controls/image_view.h" 41 #include "ui/views/controls/image_view.h"
47 #include "ui/views/controls/label.h" 42 #include "ui/views/controls/label.h"
(...skipping 17 matching lines...) Expand all
65 const int kHorizOuterMargin = views::kPanelHorizMargin - kOuterMarginInset; 60 const int kHorizOuterMargin = views::kPanelHorizMargin - kOuterMarginInset;
66 const int kVertOuterMargin = views::kPanelVertMargin - kOuterMarginInset; 61 const int kVertOuterMargin = views::kPanelVertMargin - kOuterMarginInset;
67 62
68 // Interior vertical margin is 8px smaller than standard 63 // Interior vertical margin is 8px smaller than standard
69 const int kVertInnerMargin = views::kPanelVertMargin - 8; 64 const int kVertInnerMargin = views::kPanelVertMargin - 8;
70 65
71 // We want to shift the right column (which contains the header and text) up 66 // We want to shift the right column (which contains the header and text) up
72 // 4px to align with icon. 67 // 4px to align with icon.
73 const int kRightcolumnVerticalShift = -4; 68 const int kRightcolumnVerticalShift = -4;
74 69
75 // How long to wait for browser action animations to complete before retrying.
76 const int kAnimationWaitTime = 50;
77
78 // How often we retry when waiting for browser action animation to end.
79 const int kAnimationWaitMaxRetry = 10;
80
81 } // namespace 70 } // namespace
82 71
83 namespace chrome { 72 namespace chrome {
84 73
85 void ShowExtensionInstalledBubble(const Extension* extension, 74 void ShowExtensionInstalledBubble(const Extension* extension,
86 Browser* browser, 75 Browser* browser,
87 const SkBitmap& icon) { 76 const SkBitmap& icon) {
88 ExtensionInstalledBubble::Show(extension, browser, icon); 77 ExtensionInstalledBubbleView::Show(extension, browser, icon);
89 } 78 }
90 79
91 } // namespace chrome 80 } // namespace chrome
92 81
93 // InstalledBubbleContent is the content view which is placed in the 82 // InstalledBubbleContent is the content view which is placed in the
94 // ExtensionInstalledBubble. It displays the install icon and explanatory 83 // ExtensionInstalledBubbleView. It displays the install icon and explanatory
95 // text about the installed extension. 84 // text about the installed extension.
96 class InstalledBubbleContent : public views::View, 85 class InstalledBubbleContent : public views::View,
97 public views::ButtonListener, 86 public views::ButtonListener,
98 public views::LinkListener { 87 public views::LinkListener {
99 public: 88 public:
100 InstalledBubbleContent(Browser* browser, 89 InstalledBubbleContent(Browser* browser,
101 const Extension* extension, 90 const Extension* extension,
102 ExtensionInstalledBubble::BubbleType type, 91 ExtensionInstalledBubble::BubbleType type,
103 SkBitmap* icon, 92 const SkBitmap* icon,
104 ExtensionInstalledBubble* bubble) 93 ExtensionInstalledBubbleView* bubble)
105 : browser_(browser), 94 : browser_(browser),
106 extension_id_(extension->id()), 95 extension_id_(extension->id()),
107 bubble_(bubble), 96 bubble_(bubble),
108 type_(type), 97 type_(type),
109 flavors_(NONE), 98 flavors_(NONE),
110 height_of_signin_promo_(0u), 99 height_of_signin_promo_(0u),
111 how_to_use_(NULL), 100 how_to_use_(NULL),
112 sign_in_link_(NULL), 101 sign_in_link_(NULL),
113 manage_(NULL), 102 manage_(NULL),
114 manage_shortcut_(NULL) { 103 manage_shortcut_(NULL) {
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 477
489 views::View::OnPaint(canvas); 478 views::View::OnPaint(canvas);
490 } 479 }
491 480
492 // The browser we're associated with. 481 // The browser we're associated with.
493 Browser* browser_; 482 Browser* browser_;
494 483
495 // The id of the extension just installed. 484 // The id of the extension just installed.
496 const std::string extension_id_; 485 const std::string extension_id_;
497 486
498 // The ExtensionInstalledBubble showing us. 487 // The ExtensionInstalledBubbleView showing us.
499 ExtensionInstalledBubble* bubble_; 488 ExtensionInstalledBubbleView* bubble_;
500 489
501 // The string that contains the link text at the beginning of the sign-in 490 // The string that contains the link text at the beginning of the sign-in
502 // promo text. 491 // promo text.
503 string16 signin_promo_link_text_; 492 string16 signin_promo_link_text_;
504 // The remaining text of the sign-in promo text. 493 // The remaining text of the sign-in promo text.
505 string16 signin_promo_text_; 494 string16 signin_promo_text_;
506 495
507 // A vector of RenderText objects representing the full sign-in promo 496 // A vector of RenderText objects representing the full sign-in promo
508 // paragraph as layed out within the bubble, but has the text of the link 497 // paragraph as layed out within the bubble, but has the text of the link
509 // whited out so the link can be drawn in its place. 498 // whited out so the link can be drawn in its place.
(...skipping 12 matching lines...) Expand all
522 views::Label* heading_; 511 views::Label* heading_;
523 views::Label* how_to_use_; 512 views::Label* how_to_use_;
524 views::Link* sign_in_link_; 513 views::Link* sign_in_link_;
525 views::Label* manage_; 514 views::Label* manage_;
526 views::Link* manage_shortcut_; 515 views::Link* manage_shortcut_;
527 views::ImageButton* close_button_; 516 views::ImageButton* close_button_;
528 517
529 DISALLOW_COPY_AND_ASSIGN(InstalledBubbleContent); 518 DISALLOW_COPY_AND_ASSIGN(InstalledBubbleContent);
530 }; 519 };
531 520
532 void ExtensionInstalledBubble::Show(const Extension* extension, 521 void ExtensionInstalledBubbleView::Show(const Extension* extension,
533 Browser *browser, 522 Browser *browser,
534 const SkBitmap& icon) { 523 const SkBitmap& icon) {
535 new ExtensionInstalledBubble(extension, browser, icon); 524 new ExtensionInstalledBubbleView(extension, browser, icon);
536 } 525 }
537 526
538 ExtensionInstalledBubble::ExtensionInstalledBubble(const Extension* extension, 527 ExtensionInstalledBubbleView::ExtensionInstalledBubbleView(
539 Browser *browser, 528 const Extension* extension, Browser *browser, const SkBitmap& icon)
540 const SkBitmap& icon) 529 : bubble_(this, extension, browser, icon) {
541 : extension_(extension),
542 browser_(browser),
543 icon_(icon),
544 animation_wait_retries_(0),
545 weak_factory_(this) {
546 if (!extensions::OmniboxInfo::GetKeyword(extension).empty())
547 type_ = OMNIBOX_KEYWORD;
548 else if (extensions::ActionInfo::GetBrowserActionInfo(extension))
549 type_ = BROWSER_ACTION;
550 else if (extensions::ActionInfo::GetPageActionInfo(extension) &&
551 extensions::ActionInfo::IsVerboseInstallMessage(extension))
552 type_ = PAGE_ACTION;
553 else
554 type_ = GENERIC;
555
556 // |extension| has been initialized but not loaded at this point. We need
557 // to wait on showing the Bubble until not only the EXTENSION_LOADED gets
558 // fired, but all of the EXTENSION_LOADED Observers have run. Only then can we
559 // be sure that a BrowserAction or PageAction has had views created which we
560 // can inspect for the purpose of previewing of pointing to them.
561 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
562 content::Source<Profile>(browser->profile()));
563 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
564 content::Source<Profile>(browser->profile()));
565 registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSING,
566 content::Source<Browser>(browser));
567 } 530 }
568 531
569 ExtensionInstalledBubble::~ExtensionInstalledBubble() {} 532 ExtensionInstalledBubbleView::~ExtensionInstalledBubbleView() {}
570 533
571 void ExtensionInstalledBubble::Observe( 534 void ExtensionInstalledBubbleView::ShowInternal() {
572 int type, 535 BrowserView* browser_view =
573 const content::NotificationSource& source, 536 BrowserView::GetBrowserViewForBrowser(bubble_.browser());
574 const content::NotificationDetails& details) {
575 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
576 const Extension* extension =
577 content::Details<const Extension>(details).ptr();
578 if (extension == extension_) {
579 animation_wait_retries_ = 0;
580 // PostTask to ourself to allow all EXTENSION_LOADED Observers to run.
581 base::MessageLoopForUI::current()->PostTask(
582 FROM_HERE,
583 base::Bind(&ExtensionInstalledBubble::ShowInternal,
584 weak_factory_.GetWeakPtr()));
585 }
586 } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
587 const Extension* extension =
588 content::Details<extensions::UnloadedExtensionInfo>(details)->extension;
589 if (extension == extension_) {
590 // Extension is going away, make sure ShowInternal won't be called.
591 weak_factory_.InvalidateWeakPtrs();
592 extension_ = NULL;
593 }
594 } else if (type == chrome::NOTIFICATION_BROWSER_CLOSING) {
595 delete this;
596 } else {
597 NOTREACHED() << L"Received unexpected notification";
598 }
599 }
600
601 void ExtensionInstalledBubble::ShowInternal() {
602 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_);
603 extensions::ExtensionActionManager* extension_action_manager = 537 extensions::ExtensionActionManager* extension_action_manager =
604 extensions::ExtensionActionManager::Get(browser_->profile()); 538 extensions::ExtensionActionManager::Get(bubble_.browser()->profile());
605 539
606 views::View* reference_view = NULL; 540 views::View* reference_view = NULL;
607 if (type_ == BROWSER_ACTION) { 541 if (bubble_.type() == bubble_.BROWSER_ACTION) {
608 BrowserActionsContainer* container = 542 BrowserActionsContainer* container =
609 browser_view->GetToolbarView()->browser_actions(); 543 browser_view->GetToolbarView()->browser_actions();
610 if (container->animating() && 544 if (container->animating()) {
611 animation_wait_retries_++ < kAnimationWaitMaxRetry) { 545 bubble_.MaybeShowLater();
612 // We don't know where the view will be until the container has stopped
613 // animating, so check back in a little while.
614 base::MessageLoopForUI::current()->PostDelayedTask(
615 FROM_HERE,
616 base::Bind(&ExtensionInstalledBubble::ShowInternal,
617 weak_factory_.GetWeakPtr()),
618 base::TimeDelta::FromMilliseconds(kAnimationWaitTime));
619 return; 546 return;
620 } 547 }
548
621 reference_view = container->GetBrowserActionView( 549 reference_view = container->GetBrowserActionView(
622 extension_action_manager->GetBrowserAction(*extension_)); 550 extension_action_manager->GetBrowserAction(*bubble_.extension()));
623 // If the view is not visible then it is in the chevron, so point the 551 // If the view is not visible then it is in the chevron, so point the
624 // install bubble to the chevron instead. If this is an incognito window, 552 // install bubble to the chevron instead. If this is an incognito window,
625 // both could be invisible. 553 // both could be invisible.
626 if (!reference_view || !reference_view->visible()) { 554 if (!reference_view || !reference_view->visible()) {
627 reference_view = container->chevron(); 555 reference_view = container->chevron();
628 if (!reference_view || !reference_view->visible()) 556 if (!reference_view || !reference_view->visible())
629 reference_view = NULL; // fall back to app menu below. 557 reference_view = NULL; // fall back to app menu below.
630 } 558 }
631 } else if (type_ == PAGE_ACTION) { 559 } else if (bubble_.type() == bubble_.PAGE_ACTION) {
632 LocationBarView* location_bar_view = browser_view->GetLocationBarView(); 560 LocationBarView* location_bar_view = browser_view->GetLocationBarView();
633 ExtensionAction* page_action = 561 ExtensionAction* page_action =
634 extension_action_manager->GetPageAction(*extension_); 562 extension_action_manager->GetPageAction(*bubble_.extension());
635 location_bar_view->SetPreviewEnabledPageAction(page_action, 563 location_bar_view->SetPreviewEnabledPageAction(page_action,
636 true); // preview_enabled 564 true); // preview_enabled
637 reference_view = location_bar_view->GetPageActionView(page_action); 565 reference_view = location_bar_view->GetPageActionView(page_action);
638 DCHECK(reference_view); 566 DCHECK(reference_view);
639 } else if (type_ == OMNIBOX_KEYWORD) { 567 } else if (bubble_.type() == bubble_.OMNIBOX_KEYWORD) {
640 LocationBarView* location_bar_view = browser_view->GetLocationBarView(); 568 LocationBarView* location_bar_view = browser_view->GetLocationBarView();
641 reference_view = location_bar_view; 569 reference_view = location_bar_view;
642 DCHECK(reference_view); 570 DCHECK(reference_view);
643 } 571 }
644 572
645 // Default case. 573 // Default case.
646 if (reference_view == NULL) 574 if (reference_view == NULL)
647 reference_view = browser_view->GetToolbarView()->app_menu(); 575 reference_view = browser_view->GetToolbarView()->app_menu();
648 set_anchor_view(reference_view); 576 set_anchor_view(reference_view);
649 577
650 set_arrow(type_ == OMNIBOX_KEYWORD ? views::BubbleBorder::TOP_LEFT : 578 set_arrow(bubble_.type() == bubble_.OMNIBOX_KEYWORD ?
651 views::BubbleBorder::TOP_RIGHT); 579 views::BubbleBorder::TOP_LEFT :
580 views::BubbleBorder::TOP_RIGHT);
652 SetLayoutManager(new views::FillLayout()); 581 SetLayoutManager(new views::FillLayout());
653 AddChildView( 582 AddChildView(new InstalledBubbleContent(
654 new InstalledBubbleContent(browser_, extension_, type_, &icon_, this)); 583 bubble_.browser(), bubble_.extension(), bubble_.type(),
584 &bubble_.icon(), this));
655 585
656 views::BubbleDelegateView::CreateBubble(this); 586 views::BubbleDelegateView::CreateBubble(this);
657 587
658 // The bubble widget is now the parent and owner of |this| and takes care of 588 // The bubble widget is now the parent and owner of |this| and takes care of
659 // deletion when the bubble or browser go away. 589 // deletion when the bubble or browser go away.
660 registrar_.Remove(this, chrome::NOTIFICATION_BROWSER_CLOSING, 590 bubble_.IgnoreBrowserClosing();
661 content::Source<Browser>(browser_));
662 591
663 StartFade(true); 592 StartFade(true);
664 } 593 }
665 594
666 gfx::Rect ExtensionInstalledBubble::GetAnchorRect() { 595 void ExtensionInstalledBubbleView::OnBrowserClosing() {
596 delete this;
597 }
598
599 gfx::Rect ExtensionInstalledBubbleView::GetAnchorRect() {
667 // For omnibox keyword bubbles, move the arrow to point to the left edge 600 // For omnibox keyword bubbles, move the arrow to point to the left edge
668 // of the omnibox, just to the right of the icon. 601 // of the omnibox, just to the right of the icon.
669 if (type_ == OMNIBOX_KEYWORD) { 602 if (bubble_.type() == bubble_.OMNIBOX_KEYWORD) {
670 LocationBarView* location_bar_view = 603 LocationBarView* location_bar_view =
671 BrowserView::GetBrowserViewForBrowser(browser_)->GetLocationBarView(); 604 BrowserView::GetBrowserViewForBrowser(bubble_.browser())->
605 GetLocationBarView();
672 return gfx::Rect(location_bar_view->GetLocationEntryOrigin(), 606 return gfx::Rect(location_bar_view->GetLocationEntryOrigin(),
673 gfx::Size(0, location_bar_view->location_entry_view()->height())); 607 gfx::Size(0, location_bar_view->location_entry_view()->height()));
674 } 608 }
675 return views::BubbleDelegateView::GetAnchorRect(); 609 return views::BubbleDelegateView::GetAnchorRect();
676 } 610 }
677 611
678 void ExtensionInstalledBubble::WindowClosing() { 612 void ExtensionInstalledBubbleView::WindowClosing() {
679 if (extension_ && type_ == PAGE_ACTION) { 613 if (bubble_.extension() && bubble_.type() == bubble_.PAGE_ACTION) {
680 BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser_); 614 BrowserView* browser_view =
615 BrowserView::GetBrowserViewForBrowser(bubble_.browser());
681 browser_view->GetLocationBarView()->SetPreviewEnabledPageAction( 616 browser_view->GetLocationBarView()->SetPreviewEnabledPageAction(
682 extensions::ExtensionActionManager::Get(browser_->profile())-> 617 extensions::ExtensionActionManager::Get(bubble_.browser()->profile())->
683 GetPageAction(*extension_), 618 GetPageAction(*bubble_.extension()),
684 false); // preview_enabled 619 false); // preview_enabled
685 } 620 }
686 } 621 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698