If a site contains mixed content or the https connection has an error then the Website Settings UI automatically selects the connection when it is opened.

BUG=143922

Review URL: https://chromiumcodereview.appspot.com/10829452

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154137 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm b/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
index 4010af1a..0f4ebd2 100644
--- a/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
+++ b/chrome/browser/ui/cocoa/website_settings_bubble_controller.mm
@@ -346,7 +346,7 @@
       [[NSSegmentedControl alloc] initWithFrame:initialFrame]);
   [segmentedControl_ setCell:
       [[[WebsiteSettingsTabSegmentedCell alloc] init] autorelease]];
-  [segmentedControl_ setSegmentCount:2];
+  [segmentedControl_ setSegmentCount:WebsiteSettingsUI::NUM_TAB_IDS];
   [segmentedControl_ setTarget:self];
   [segmentedControl_ setAction:@selector(tabSelected:)];
 
@@ -363,6 +363,8 @@
                    forSegment:WebsiteSettingsUI::TAB_ID_PERMISSIONS];
   NSSize textSize = [label sizeWithAttributes:textAttributes];
   CGFloat tabWidth = textSize.width + 2 * kTabLabelXPadding;
+  [segmentedControl_ setWidth:tabWidth + kTabStripXPadding
+                   forSegment:WebsiteSettingsUI::TAB_ID_PERMISSIONS];
 
   // Create the "Connection" tab.
   label = l10n_util::GetNSString(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION);
@@ -370,13 +372,17 @@
   [segmentedControl_ setLabel:label
                    forSegment:WebsiteSettingsUI::TAB_ID_CONNECTION];
 
+  DCHECK_EQ([segmentedControl_ segmentCount], WebsiteSettingsUI::NUM_TAB_IDS);
+
   // Make both tabs the width of the widest. The first segment has some
   // additional padding that is not part of the tab, which is used for drawing
   // the background of the tab strip.
   tabWidth = std::max(tabWidth,
                       textSize.width + 2 * kTabLabelXPadding);
-  [segmentedControl_ setWidth:tabWidth + kTabStripXPadding forSegment:0];
-  [segmentedControl_ setWidth:tabWidth forSegment:1];
+  [segmentedControl_ setWidth:tabWidth + kTabStripXPadding
+                   forSegment:WebsiteSettingsUI::TAB_ID_PERMISSIONS];
+  [segmentedControl_ setWidth:tabWidth
+                   forSegment:WebsiteSettingsUI::TAB_ID_CONNECTION];
 
   [segmentedControl_ setFont:smallSystemFont];
   [contentView_ addSubview:segmentedControl_];
diff --git a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
index 930f2d6..fc33a01 100644
--- a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
+++ b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.cc
@@ -216,6 +216,7 @@
       identity_contents_(NULL),
       connection_contents_(NULL),
       first_visit_contents_(NULL),
+      notebook_(NULL),
       presenter_(NULL) {
   BrowserWindowGtk* browser_window =
       BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent);
@@ -313,26 +314,29 @@
                      FALSE, 0);
 
   // Create tab container and add all tabs.
-  GtkWidget* notebook = gtk_notebook_new();
+  notebook_ = gtk_notebook_new();
   if (theme_service_->UsingNativeTheme())
-    gtk_widget_modify_bg(notebook, GTK_STATE_NORMAL, NULL);
+    gtk_widget_modify_bg(notebook_, GTK_STATE_NORMAL, NULL);
   else
-    gtk_widget_modify_bg(notebook, GTK_STATE_NORMAL, &kBackgroundColor);
+    gtk_widget_modify_bg(notebook_, GTK_STATE_NORMAL, &kBackgroundColor);
 
   GtkWidget* label = theme_service_->BuildLabel(
       l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS),
       ui::kGdkBlack);
   gtk_widget_show(label);
-  gtk_notebook_append_page(
-      GTK_NOTEBOOK(notebook), permission_tab_contents, label);
+  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_), permission_tab_contents,
+                           label, TAB_ID_PERMISSIONS);
 
   label = theme_service_->BuildLabel(
       l10n_util::GetStringUTF8(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION),
       ui::kGdkBlack);
   gtk_widget_show(label);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), connection_tab, label);
+  gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_), connection_tab, label,
+                           TAB_ID_CONNECTION);
 
-  gtk_box_pack_start(GTK_BOX(contents_), notebook, FALSE, FALSE, 0);
+  DCHECK_EQ(gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)), NUM_TAB_IDS);
+
+  gtk_box_pack_start(GTK_BOX(contents_), notebook_, FALSE, FALSE, 0);
   gtk_widget_show_all(contents_);
 }
 
@@ -542,6 +546,12 @@
   gtk_widget_show_all(permissions_section_contents_);
 }
 
+void WebsiteSettingsPopupGtk::SetSelectedTab(TabId tab_id) {
+  DCHECK(notebook_);
+  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_),
+                                static_cast<gint>(tab_id));
+}
+
 void WebsiteSettingsPopupGtk::OnCookiesLinkClicked(GtkWidget* widget) {
   new CollectedCookiesGtk(GTK_WINDOW(parent_),
                           tab_contents_);
diff --git a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.h b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.h
index 6f48b5d..f0ae021 100644
--- a/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.h
+++ b/chrome/browser/ui/gtk/website_settings/website_settings_popup_gtk.h
@@ -57,6 +57,7 @@
       const PermissionInfoList& permission_info_list) OVERRIDE;
   virtual void SetIdentityInfo(const IdentityInfo& identity_info) OVERRIDE;
   virtual void SetFirstVisit(const string16& first_visit) OVERRIDE;
+  virtual void SetSelectedTab(WebsiteSettingsUI::TabId tab_id) OVERRIDE;
 
   // PermissionSelectorObserver implementations.
   virtual void OnPermissionChanged(PermissionSelector* selector) OVERRIDE;
@@ -121,6 +122,9 @@
   // Container for the information about the first visit date of the website.
   GtkWidget* first_visit_contents_;
 
+  // The widget that contains the tabs display on the popup.
+  GtkWidget* notebook_;
+
   // The UI translates user actions to specific events and forwards them to the
   // |presenter_|. The |presenter_| handles these events and updates the UI.
   scoped_ptr<WebsiteSettings> presenter_;
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
index a243ee6..a045592 100644
--- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
+++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.cc
@@ -281,6 +281,7 @@
       site_data_content_(NULL),
       cookie_dialog_link_(NULL),
       permissions_content_(NULL),
+      connection_tab_(NULL),
       identity_info_content_(NULL),
       certificate_dialog_link_(NULL),
       cert_id_(0),
@@ -313,14 +314,19 @@
   // hierachy.  Adding the |tabbed_pane_| to the views hierachy triggers the
   // initialization of the native tab UI element. If the native tab UI
   // element is not initalized adding a tab will result in a NULL pointer
-  // excetion.
-  tabbed_pane_->AddTab(
+  // exception.
+  tabbed_pane_->AddTabAtIndex(
+      TAB_ID_PERMISSIONS,
       l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_PERMISSIONS),
-      CreatePermissionsTab());
-  tabbed_pane_->AddTab(
+      CreatePermissionsTab(),
+      true);
+  connection_tab_ = CreateConnectionTab();
+  tabbed_pane_->AddTabAtIndex(
+      TAB_ID_CONNECTION,
       l10n_util::GetStringUTF16(IDS_WEBSITE_SETTINGS_TAB_LABEL_CONNECTION),
-      CreateConnectionTab());
-  tabbed_pane_->SelectTabAt(0);
+      connection_tab_,
+      true);
+  DCHECK_EQ(tabbed_pane_->GetTabCount(), NUM_TAB_IDS);
   tabbed_pane_->set_listener(this);
 
   set_margins(gfx::Insets(kPopupMarginTop, kPopupMarginLeft,
@@ -363,7 +369,7 @@
   } else if (source == certificate_dialog_link_) {
     gfx::NativeWindow parent =
         anchor_view() ? anchor_view()->GetWidget()->GetNativeWindow() : NULL;
-ShowCertificateViewerByID(tab_contents_->web_contents(), parent, cert_id_);
+    ShowCertificateViewerByID(tab_contents_->web_contents(), parent, cert_id_);
   }
   // The popup closes automatically when the collected cookies dialog or the
   // certificate viewer opens.
@@ -522,6 +528,7 @@
       UTF8ToUTF16(identity_info.connection_status_description),
       NULL);
 
+  connection_tab_->InvalidateLayout();
   Layout();
   SizeToContents();
 }
@@ -533,10 +540,15 @@
       l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE),
       first_visit,
       NULL);
+  connection_tab_->InvalidateLayout();
   Layout();
   SizeToContents();
 }
 
+void WebsiteSettingsPopupView::SetSelectedTab(TabId tab_id) {
+  tabbed_pane_->SelectTabAt(tab_id);
+}
+
 views::View* WebsiteSettingsPopupView::CreatePermissionsTab() {
   views::View* pane = new views::View();
   pane->SetLayoutManager(
diff --git a/chrome/browser/ui/views/website_settings/website_settings_popup_view.h b/chrome/browser/ui/views/website_settings/website_settings_popup_view.h
index 55fe78bd..e8a507a 100644
--- a/chrome/browser/ui/views/website_settings/website_settings_popup_view.h
+++ b/chrome/browser/ui/views/website_settings/website_settings_popup_view.h
@@ -82,6 +82,7 @@
       const PermissionInfoList& permission_info_list) OVERRIDE;
   virtual void SetIdentityInfo(const IdentityInfo& identity_info) OVERRIDE;
   virtual void SetFirstVisit(const string16& first_visit) OVERRIDE;
+  virtual void SetSelectedTab(TabId tab_id) OVERRIDE;
 
   // Creates the contents of the "Permissions" tab. The ownership of the
   // returned view is transferred to the caller.
@@ -132,6 +133,8 @@
   // "Permissions" tab.
   views::View* permissions_content_;
 
+  // The view that contains the connection tab contents.
+  views::View* connection_tab_;
   // The view that contains the ui elements for displaying information about
   // the site's identity.
   views::View* identity_info_content_;
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc
index d21a54c..da576162 100644
--- a/chrome/browser/ui/website_settings/website_settings.cc
+++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -417,6 +417,20 @@
           IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE);
     }
   }
+
+  // By default select the permissions tab that displays all the site
+  // permissions. In case of a connection error or an issue with the
+  // certificate presented by the website, select the connection tab to draw
+  // the user's attention to the issue. If the site does not provide a
+  // certificate because it was loaded over an unencrypted connection, don't
+  // select the connection tab.
+  WebsiteSettingsUI::TabId tab_id = WebsiteSettingsUI::TAB_ID_PERMISSIONS;
+  if (site_connection_status_ == SITE_CONNECTION_STATUS_ENCRYPTED_ERROR ||
+      site_connection_status_ == SITE_CONNECTION_STATUS_MIXED_CONTENT ||
+      site_identity_status_ == SITE_IDENTITY_STATUS_ERROR ||
+      site_identity_status_ == SITE_IDENTITY_STATUS_CERT_REVOCATION_UNKNOWN)
+    tab_id = WebsiteSettingsUI::TAB_ID_CONNECTION;
+  ui_->SetSelectedTab(tab_id);
 }
 
 void WebsiteSettings::PresentSitePermissions() {
diff --git a/chrome/browser/ui/website_settings/website_settings_ui.h b/chrome/browser/ui/website_settings/website_settings_ui.h
index e159df0..e316289 100644
--- a/chrome/browser/ui/website_settings/website_settings_ui.h
+++ b/chrome/browser/ui/website_settings/website_settings_ui.h
@@ -37,8 +37,9 @@
   // The Website Settings UI contains several tabs. Each tab is assiciated with
   // a unique tab id. The enum |TabId| contains all the ids for the tabs.
   enum TabId {
-    TAB_ID_PERMISSIONS,
+    TAB_ID_PERMISSIONS = 0,
     TAB_ID_CONNECTION,
+    NUM_TAB_IDS,
   };
 
   // |CookieInfo| contains information about the cookies from a specific source.
@@ -142,9 +143,7 @@
   virtual void SetFirstVisit(const string16& first_visit) = 0;
 
   // Selects the tab with the given |tab_id|.
-  // TODO(markusheintz): Implement this on other platforms and make it a pure
-  // virtual function.
-  virtual void SetSelectedTab(TabId tab_id) {}
+  virtual void SetSelectedTab(TabId tab_id) = 0;
 };
 
 typedef WebsiteSettingsUI::CookieInfoList CookieInfoList;
diff --git a/chrome/browser/ui/website_settings/website_settings_unittest.cc b/chrome/browser/ui/website_settings/website_settings_unittest.cc
index 7f657d6..24ccf5a 100644
--- a/chrome/browser/ui/website_settings/website_settings_unittest.cc
+++ b/chrome/browser/ui/website_settings/website_settings_unittest.cc
@@ -65,6 +65,7 @@
                void(const PermissionInfoList& permission_info_list));
   MOCK_METHOD1(SetIdentityInfo, void(const IdentityInfo& identity_info));
   MOCK_METHOD1(SetFirstVisit, void(const string16& first_visit));
+  MOCK_METHOD1(SetSelectedTab, void(TabId tab_id));
 };
 
 class WebsiteSettingsTest : public ChromeRenderViewHostTestHarness {
@@ -189,6 +190,8 @@
 #else
   EXPECT_CALL(*mock_ui(), SetPermissionInfo(_)).Times(1);
 #endif
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
 
   // Execute code under tests.
   website_settings()->OnSitePermissionChanged(CONTENT_SETTINGS_TYPE_POPUPS,
@@ -220,12 +223,16 @@
   EXPECT_CALL(*mock_ui(), SetIdentityInfo(_));
   EXPECT_CALL(*mock_ui(), SetFirstVisit(string16()));
   EXPECT_CALL(*mock_ui(), SetCookieInfo(_)).Times(2);
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
 
   website_settings()->OnSiteDataAccessed();
 }
 
 TEST_F(WebsiteSettingsTest, HTTPConnection) {
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_UNENCRYPTED,
             website_settings()->site_connection_status());
   EXPECT_EQ(WebsiteSettings::SITE_IDENTITY_STATUS_NO_CERT,
@@ -244,6 +251,8 @@
   ssl_.connection_status = status;
 
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
 
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED,
             website_settings()->site_connection_status());
@@ -264,6 +273,7 @@
   ssl_.connection_status = status;
 
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(WebsiteSettingsUI::TAB_ID_CONNECTION));
 
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT,
             website_settings()->site_connection_status());
@@ -292,6 +302,7 @@
   ssl_.connection_status = status;
 
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(WebsiteSettingsUI::TAB_ID_CONNECTION));
 
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_MIXED_CONTENT,
             website_settings()->site_connection_status());
@@ -311,6 +322,7 @@
   ssl_.connection_status = status;
 
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(WebsiteSettingsUI::TAB_ID_CONNECTION));
 
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED,
             website_settings()->site_connection_status());
@@ -330,6 +342,7 @@
   ssl_.connection_status = status;
 
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(WebsiteSettingsUI::TAB_ID_CONNECTION));
 
   EXPECT_EQ(WebsiteSettings::SITE_CONNECTION_STATUS_ENCRYPTED_ERROR,
             website_settings()->site_connection_status());
@@ -340,6 +353,8 @@
 
 TEST_F(WebsiteSettingsTest, NoInfoBar) {
   SetDefaultUIExpectations(mock_ui());
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
   EXPECT_EQ(0u, infobar_tab_helper()->GetInfoBarCount());
   website_settings()->OnUIClosing();
   EXPECT_EQ(0u, infobar_tab_helper()->GetInfoBarCount());
@@ -359,6 +374,8 @@
   EXPECT_CALL(*mock_ui(), SetPermissionInfo(_)).Times(1);
 #endif
 
+  EXPECT_CALL(*mock_ui(), SetSelectedTab(
+      WebsiteSettingsUI::TAB_ID_PERMISSIONS));
   EXPECT_EQ(0u, infobar_tab_helper()->GetInfoBarCount());
   website_settings()->OnSitePermissionChanged(
       CONTENT_SETTINGS_TYPE_GEOLOCATION, CONTENT_SETTING_ALLOW);