Home | History | Annotate | Download | only in extensions
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
      6 #define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
      7 
      8 #include "chrome/browser/extensions/extension_install_prompt.h"
      9 #include "ui/gfx/animation/animation_delegate.h"
     10 #include "ui/gfx/animation/slide_animation.h"
     11 #include "ui/views/controls/button/button.h"
     12 #include "ui/views/controls/link_listener.h"
     13 #include "ui/views/view.h"
     14 #include "ui/views/window/dialog_delegate.h"
     15 
     16 typedef std::vector<base::string16> PermissionDetails;
     17 class ExpandableContainerView;
     18 
     19 namespace content {
     20 class PageNavigator;
     21 }
     22 
     23 namespace extensions {
     24 class ExperienceSamplingEvent;
     25 }
     26 
     27 namespace ui {
     28 class ResourceBundle;
     29 }
     30 
     31 namespace views {
     32 class GridLayout;
     33 class ImageButton;
     34 class Label;
     35 class Link;
     36 }
     37 
     38 // A custom scrollable view implementation for the dialog.
     39 class CustomScrollableView : public views::View {
     40  public:
     41   CustomScrollableView();
     42   virtual ~CustomScrollableView();
     43 
     44  private:
     45   virtual void Layout() OVERRIDE;
     46 
     47   DISALLOW_COPY_AND_ASSIGN(CustomScrollableView);
     48 };
     49 
     50 // Implements the extension installation dialog for TOOLKIT_VIEWS.
     51 class ExtensionInstallDialogView : public views::DialogDelegateView,
     52                                    public views::LinkListener,
     53                                    public views::ButtonListener {
     54  public:
     55   ExtensionInstallDialogView(
     56       content::PageNavigator* navigator,
     57       ExtensionInstallPrompt::Delegate* delegate,
     58       scoped_refptr<ExtensionInstallPrompt::Prompt> prompt);
     59   virtual ~ExtensionInstallDialogView();
     60 
     61   // Returns the interior ScrollView of the dialog. This allows us to inspect
     62   // the contents of the DialogView.
     63   const views::ScrollView* scroll_view() const { return scroll_view_; }
     64 
     65   // Called when one of the child elements has expanded/collapsed.
     66   void ContentsChanged();
     67 
     68  private:
     69   // views::DialogDelegateView:
     70   virtual int GetDialogButtons() const OVERRIDE;
     71   virtual base::string16 GetDialogButtonLabel(
     72       ui::DialogButton button) const OVERRIDE;
     73   virtual int GetDefaultDialogButton() const OVERRIDE;
     74   virtual bool Cancel() OVERRIDE;
     75   virtual bool Accept() OVERRIDE;
     76   virtual ui::ModalType GetModalType() const OVERRIDE;
     77   virtual base::string16 GetWindowTitle() const OVERRIDE;
     78   virtual void Layout() OVERRIDE;
     79   virtual gfx::Size GetPreferredSize() const OVERRIDE;
     80   virtual void ViewHierarchyChanged(
     81       const ViewHierarchyChangedDetails& details) OVERRIDE;
     82 
     83   // views::LinkListener:
     84   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
     85 
     86   // views::ButtonListener:
     87   virtual void ButtonPressed(views::Button* sender,
     88                              const ui::Event& event) OVERRIDE;
     89 
     90   // Experimental: Toggles inline permission explanations with an animation.
     91   void ToggleInlineExplanations();
     92 
     93   // Initializes the dialog view, adding in permissions if they exist.
     94   void InitView();
     95 
     96   // Adds permissions of |perm_type| to the dialog view if they exist.
     97   bool AddPermissions(views::GridLayout* layout,
     98                       ui::ResourceBundle& rb,
     99                       int column_set_id,
    100                       int left_column_width,
    101                       ExtensionInstallPrompt::PermissionsType perm_type);
    102 
    103   // Creates a layout consisting of dialog header, extension name and icon.
    104   views::GridLayout* CreateLayout(
    105       views::View* parent,
    106       int left_column_width,
    107       int column_set_id,
    108       bool single_detail_row) const;
    109 
    110   bool is_inline_install() const {
    111     return prompt_->type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT;
    112   }
    113 
    114   bool is_bundle_install() const {
    115     return prompt_->type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT;
    116   }
    117 
    118   bool is_external_install() const {
    119     return prompt_->type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT;
    120   }
    121 
    122   // Updates the histogram that holds installation accepted/aborted data.
    123   void UpdateInstallResultHistogram(bool accepted) const;
    124 
    125   // Updates the histogram that holds data about whether "Show details" or
    126   // "Show permissions" links were shown and/or clicked.
    127   void UpdateLinkActionHistogram(int action_type) const;
    128 
    129   content::PageNavigator* navigator_;
    130   ExtensionInstallPrompt::Delegate* delegate_;
    131   scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_;
    132 
    133   // The scroll view containing all the details for the dialog (including all
    134   // collapsible/expandable sections).
    135   views::ScrollView* scroll_view_;
    136 
    137   // The container view for the scroll view.
    138   CustomScrollableView* scrollable_;
    139 
    140   // The container for the simpler view with only the dialog header and the
    141   // extension icon. Used for the experiment where the permissions are
    142   // initially hidden when the dialog shows.
    143   CustomScrollableView* scrollable_header_only_;
    144 
    145   // The preferred size of the dialog.
    146   gfx::Size dialog_size_;
    147 
    148   // Experimental: "Show details" link to expand inline explanations and reveal
    149   // permision dialog.
    150   views::Link* show_details_link_;
    151 
    152   // Experimental: Label for showing information about the checkboxes.
    153   views::Label* checkbox_info_label_;
    154 
    155   // Experimental: Contains pointers to inline explanation views.
    156   typedef std::vector<ExpandableContainerView*> InlineExplanations;
    157   InlineExplanations inline_explanations_;
    158 
    159   // Experimental: Number of unchecked checkboxes in the permission list.
    160   // If this becomes zero, the accept button is enabled, otherwise disabled.
    161   int unchecked_boxes_;
    162 
    163   // ExperienceSampling: Track this UI event.
    164   scoped_ptr<extensions::ExperienceSamplingEvent> sampling_event_;
    165 
    166   // Set to true once the user's selection has been received and the
    167   // |delegate_| has been notified.
    168   bool handled_result_;
    169 
    170   DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView);
    171 };
    172 
    173 // A simple view that prepends a view with a bullet with the help of a grid
    174 // layout.
    175 class BulletedView : public views::View {
    176  public:
    177   explicit BulletedView(views::View* view);
    178  private:
    179   DISALLOW_COPY_AND_ASSIGN(BulletedView);
    180 };
    181 
    182 // A simple view that prepends a view with a checkbox with the help of a grid
    183 // layout. Used for the permission experiment.
    184 // TODO(meacer): Remove once the experiment is completed.
    185 class CheckboxedView : public views::View {
    186  public:
    187   CheckboxedView(views::View* view, views::ButtonListener* listener);
    188  private:
    189   DISALLOW_COPY_AND_ASSIGN(CheckboxedView);
    190 };
    191 
    192 // A view to display text with an expandable details section.
    193 class ExpandableContainerView : public views::View,
    194                                 public views::ButtonListener,
    195                                 public views::LinkListener,
    196                                 public gfx::AnimationDelegate {
    197  public:
    198   ExpandableContainerView(ExtensionInstallDialogView* owner,
    199                           const base::string16& description,
    200                           const PermissionDetails& details,
    201                           int horizontal_space,
    202                           bool parent_bulleted,
    203                           bool show_expand_link,
    204                           bool lighter_color_details);
    205   virtual ~ExpandableContainerView();
    206 
    207   // views::View:
    208   virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
    209 
    210   // views::ButtonListener:
    211   virtual void ButtonPressed(views::Button* sender,
    212                              const ui::Event& event) OVERRIDE;
    213 
    214   // views::LinkListener:
    215   virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
    216 
    217   // gfx::AnimationDelegate:
    218   virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
    219   virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
    220 
    221   // Expand/Collapse the detail section for this ExpandableContainerView.
    222   void ToggleDetailLevel();
    223 
    224   // Expand the detail section without any animation.
    225   // TODO(meacer): Remove once the experiment is completed.
    226   void ExpandWithoutAnimation();
    227 
    228  private:
    229   // A view which displays all the details of an IssueAdviceInfoEntry.
    230   class DetailsView : public views::View {
    231    public:
    232     explicit DetailsView(int horizontal_space, bool parent_bulleted,
    233                          bool lighter_color);
    234     virtual ~DetailsView() {}
    235 
    236     // views::View:
    237     virtual gfx::Size GetPreferredSize() const OVERRIDE;
    238 
    239     void AddDetail(const base::string16& detail);
    240 
    241     // Animates this to be a height proportional to |state|.
    242     void AnimateToState(double state);
    243 
    244    private:
    245     views::GridLayout* layout_;
    246     double state_;
    247 
    248     // Whether the detail text should be shown with a lighter color.
    249     bool lighter_color_;
    250 
    251     DISALLOW_COPY_AND_ASSIGN(DetailsView);
    252   };
    253 
    254   // The dialog that owns |this|. It's also an ancestor in the View hierarchy.
    255   ExtensionInstallDialogView* owner_;
    256 
    257   // A view for showing |issue_advice.details|.
    258   DetailsView* details_view_;
    259 
    260   // The 'more details' link shown under the heading (changes to 'hide details'
    261   // when the details section is expanded).
    262   views::Link* more_details_;
    263 
    264   gfx::SlideAnimation slide_animation_;
    265 
    266   // The up/down arrow next to the 'more detail' link (points up/down depending
    267   // on whether the details section is expanded).
    268   views::ImageButton* arrow_toggle_;
    269 
    270   // Whether the details section is expanded.
    271   bool expanded_;
    272 
    273   DISALLOW_COPY_AND_ASSIGN(ExpandableContainerView);
    274 };
    275 
    276 void ShowExtensionInstallDialogImpl(
    277     const ExtensionInstallPrompt::ShowParams& show_params,
    278     ExtensionInstallPrompt::Delegate* delegate,
    279     scoped_refptr<ExtensionInstallPrompt::Prompt> prompt);
    280 
    281 #endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
    282