diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-19 07:37:12 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-19 07:37:12 +0000 |
commit | 4d67720512d8cf6b92d350a86f3fbacff45b4c75 (patch) | |
tree | ecadf3bd24c2d2d366bf4afb95c540bfc850297d /chrome/browser | |
parent | d5102ee4076aa42ef3797fd276b5190afb8a8141 (diff) | |
download | chromium_src-4d67720512d8cf6b92d350a86f3fbacff45b4c75.zip chromium_src-4d67720512d8cf6b92d350a86f3fbacff45b4c75.tar.gz chromium_src-4d67720512d8cf6b92d350a86f3fbacff45b4c75.tar.bz2 |
Relanding the the refactoring the page info to have a model.
BUG=None
TEST=Make sure clicking the lock/warning icon when visiting a HTTPS page brings the page info and that it reports the correct info. Also check that the "Page/Frame info" right click menu works as well.
TBR=ben
Review URL: http://codereview.chromium.org/155753
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21065 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
25 files changed, 973 insertions, 958 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 252ed9f..2ba73ad 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1988,6 +1988,14 @@ void Browser::ConfirmAddSearchProvider(const TemplateURL* template_url, window()->ConfirmAddSearchProvider(template_url, profile); } +void Browser::ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + window()->ShowPageInfo(parent, profile, url, ssl, show_history); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, SelectFileDialog::Listener implementation: diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 3ae6121..98464b3 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -496,6 +496,11 @@ class Browser : public TabStripModelDelegate, virtual void OnStartDownload(DownloadItem* download); virtual void ConfirmAddSearchProvider(const TemplateURL* template_url, Profile* profile); + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); // Overridden from SelectFileDialog::Listener: virtual void FileSelected(const FilePath& path, int index, void* params); diff --git a/chrome/browser/browser_prefs.cc b/chrome/browser/browser_prefs.cc index 84753d9..348f250 100644 --- a/chrome/browser/browser_prefs.cc +++ b/chrome/browser/browser_prefs.cc @@ -16,7 +16,7 @@ #include "chrome/browser/google_url_tracker.h" #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/net/dns_global.h" -#include "chrome/browser/page_info_window.h" +#include "chrome/browser/page_info_model.h" #include "chrome/browser/password_manager/password_manager.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" #include "chrome/browser/renderer_host/web_cache_manager.h" @@ -49,7 +49,7 @@ void RegisterAllPrefs(PrefService* user_prefs, PrefService* local_state) { browser_shutdown::RegisterPrefs(local_state); chrome_browser_net::RegisterPrefs(local_state); bookmark_utils::RegisterPrefs(local_state); - PageInfoWindow::RegisterPrefs(local_state); + PageInfoModel::RegisterPrefs(local_state); #if defined(TOOLKIT_VIEWS) // TODO(port): whittle this down as we port BrowserView::RegisterBrowserViewPrefs(local_state); TaskManager::RegisterPrefs(local_state); diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index ffbcbe1..ae07777 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_BROWSER_WINDOW_H_ #include "base/gfx/native_widget_types.h" +#include "chrome/browser/tab_contents/navigation_entry.h" class Browser; class BrowserWindowTesting; @@ -220,6 +221,16 @@ class BrowserWindow { // on the page). virtual void TabContentsFocused(TabContents* tab_contents) = 0; + // Shows the page info using the specified information. + // |url| is the url of the page/frame the info applies to, |ssl| is the SSL + // information for that page/frame. If |show_history| is true, a section + // showing how many times that URL has been visited is added to the page info. + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) = 0; + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 4d5da19..74eab33 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -77,6 +77,11 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void UserChangedTheme(); virtual int GetExtraRenderViewHeight() const; virtual void TabContentsFocused(TabContents* tab_contents); + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); // Overridden from NotificationObserver virtual void Observe(NotificationType type, diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 2493a93..7e72184 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -10,6 +10,7 @@ #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/clear_browsing_data_controller.h" #import "chrome/browser/cocoa/download_shelf_controller.h" +#include "chrome/browser/cocoa/page_info_window_mac.h" #include "chrome/browser/browser.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/common/notification_service.h" @@ -268,6 +269,14 @@ void BrowserWindowCocoa::TabContentsFocused(TabContents* tab_contents) { NOTIMPLEMENTED(); } +void BrowserWindowCocoa::ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + PageInfoWindowMac::ShowPageInfo(parent, profile, url, ssl, show_history); +} + void BrowserWindowCocoa::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/cocoa/page_info_window_controller.h b/chrome/browser/cocoa/page_info_window_controller.h index 7c8fce5..132c684 100644 --- a/chrome/browser/cocoa/page_info_window_controller.h +++ b/chrome/browser/cocoa/page_info_window_controller.h @@ -7,7 +7,6 @@ #include "base/scoped_nsobject.h" #include "base/scoped_ptr.h" -class PageInfoWindow; class PageInfoWindowMac; // This NSWindowController subclass implements the Cocoa window for @@ -44,8 +43,8 @@ class PageInfoWindowMac; @property(readwrite, copy) NSString* historyMsg; @property(readwrite) BOOL enableCertButton; -// Returns the bridge between Cocoa and Chromium. -- (PageInfoWindow*)pageInfo; +// Sets the bridge between Cocoa and Chromium. +- (void)setPageInfo:(PageInfoWindowMac*)pageInfo; // Returns the good and bad image refs. - (NSImage*)goodImg; diff --git a/chrome/browser/cocoa/page_info_window_controller.mm b/chrome/browser/cocoa/page_info_window_controller.mm index 0e895e1..a14d8b9 100644 --- a/chrome/browser/cocoa/page_info_window_controller.mm +++ b/chrome/browser/cocoa/page_info_window_controller.mm @@ -20,8 +20,6 @@ NSBundle* bundle = mac_util::MainAppBundle(); NSString* nibpath = [bundle pathForResource:@"PageInfo" ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - pageInfo_.reset(new PageInfoWindowMac(self)); - // Load the image refs. NSImage* img = [[NSImage alloc] initByReferencingFile: [bundle pathForResource:@"pageinfo_good" ofType:@"png"]]; @@ -49,8 +47,8 @@ [super dealloc]; } -- (PageInfoWindow*)pageInfo { - return pageInfo_.get(); +- (void)setPageInfo:(PageInfoWindowMac*)pageInfo { + pageInfo_.reset(pageInfo); } - (NSImage*)goodImg { diff --git a/chrome/browser/cocoa/page_info_window_mac.h b/chrome/browser/cocoa/page_info_window_mac.h index 1665b79..0d1d660 100644 --- a/chrome/browser/cocoa/page_info_window_mac.h +++ b/chrome/browser/cocoa/page_info_window_mac.h @@ -5,46 +5,49 @@ #ifndef CHROME_BROWSER_COCOA_PAGE_INFO_WINDOW_MAC_H_ #define CHROME_BROWSER_COCOA_PAGE_INFO_WINDOW_MAC_H_ -#include "chrome/browser/history/history.h" +#include "chrome/browser/page_info_model.h" #include "chrome/browser/page_info_window.h" -class CancelableRequestConsumerBase; class Profile; @class PageInfoWindowController; -namespace base { -class Time; -} - -class PageInfoWindowMac : public PageInfoWindow { +class PageInfoWindowMac : public PageInfoModel::PageInfoModelObserver { public: - PageInfoWindowMac(PageInfoWindowController* controller); virtual ~PageInfoWindowMac(); - // This is the main initializer that creates the window. - virtual void Init(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history, - gfx::NativeView parent); - - virtual void Show(); + // Creates and shows the page info. + static void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); // Shows various information for the specified certificate in a new dialog. // The argument is ignored here and we use the |cert_id_| member that was // passed to us in Init(). virtual void ShowCertDialog(int); + // PageInfoModelObserver implementation. + virtual void ModelChanged(); + private: - void OnGotVisitCountToHost(HistoryService::Handle handle, - bool found_visits, - int count, - base::Time first_visit); + PageInfoWindowMac(PageInfoWindowController* controller, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); + + void LayoutSections(); + + void Show(); - CancelableRequestConsumer request_consumer_; // Used for getting visit count. PageInfoWindowController* controller_; // WEAK, owns us. + PageInfoModel model_; + + // The certificate ID for the page, 0 if the page is not over HTTPS. + int cert_id_; + DISALLOW_COPY_AND_ASSIGN(PageInfoWindowMac); }; diff --git a/chrome/browser/cocoa/page_info_window_mac.mm b/chrome/browser/cocoa/page_info_window_mac.mm index b76d74d..f7dfaca 100644 --- a/chrome/browser/cocoa/page_info_window_mac.mm +++ b/chrome/browser/cocoa/page_info_window_mac.mm @@ -18,18 +18,33 @@ #include "net/base/cert_status_flags.h" #include "net/base/x509_certificate.h" -using base::Time; - -PageInfoWindow* PageInfoWindow::Factory() { +void PageInfoWindowMac::ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { // The controller will clean itself up after the NSWindow it manages closes. // We do not manage it as it owns us. PageInfoWindowController* controller = [[PageInfoWindowController alloc] init]; - return [controller pageInfo]; + PageInfoWindowMac* page_info = new PageInfoWindowMac(controller, + profile, + url, + ssl, + show_history); + [controller setPageInfo:page_info]; + page_info->LayoutSections(); + page_info->Show(); } -PageInfoWindowMac::PageInfoWindowMac(PageInfoWindowController* controller) - : PageInfoWindow(), controller_(controller) { +PageInfoWindowMac::PageInfoWindowMac(PageInfoWindowController* controller, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) + : controller_(controller), + model_(profile, url, ssl, show_history, this), + cert_id_(ssl.cert_id()) { } PageInfoWindowMac::~PageInfoWindowMac() { @@ -67,149 +82,51 @@ void PageInfoWindowMac::ShowCertDialog(int) { ]; } -void PageInfoWindowMac::Init(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history, - gfx::NativeView parent) { +void PageInfoWindowMac::LayoutSections() { // These wstring's will be converted to NSString's and passed to the // window controller when we're done figuring out what text should go in them. std::wstring identity_msg; std::wstring connection_msg; - // Set all the images to "good" mode. - [controller_ setIdentityImg:[controller_ goodImg]]; - [controller_ setConnectionImg:[controller_ goodImg]]; - - cert_id_ = ssl.cert_id(); - scoped_refptr<net::X509Certificate> cert; - // Identity section - std::wstring identity_title; - std::wstring subject_name(UTF8ToWide(url.host())); - bool empty_subject_name = subject_name.empty(); - if (empty_subject_name) { - subject_name.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); - } - if (page_type == NavigationEntry::NORMAL_PAGE && cert_id_ && - CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert) && - !net::IsCertStatusError(ssl.cert_status())) { - // OK HTTPS page - if ((ssl.cert_status() & net::CERT_STATUS_IS_EV) != 0) { - DCHECK(!cert->subject().organization_names.empty()); - identity_title = - l10n_util::GetStringF(IDS_PAGE_INFO_EV_IDENTITY_TITLE, - UTF8ToWide(cert->subject().organization_names[0]), - UTF8ToWide(url.host())); - // An EV cert is required to have a city (localityName) and country but - // state is "if any". - DCHECK(!cert->subject().locality_name.empty()); - DCHECK(!cert->subject().country_name.empty()); - std::wstring locality; - if (!cert->subject().state_or_province_name.empty()) { - locality = l10n_util::GetStringF( - IDS_PAGEINFO_ADDRESS, - UTF8ToWide(cert->subject().locality_name), - UTF8ToWide(cert->subject().state_or_province_name), - UTF8ToWide(cert->subject().country_name)); - } else { - locality = l10n_util::GetStringF( - IDS_PAGEINFO_PARTIAL_ADDRESS, - UTF8ToWide(cert->subject().locality_name), - UTF8ToWide(cert->subject().country_name)); - } - DCHECK(!cert->subject().organization_names.empty()); - identity_msg.assign(l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV, - UTF8ToWide(cert->subject().organization_names[0]), - locality, - UTF8ToWide(PageInfoWindow::GetIssuerName(cert->issuer())))); - } else { - // Non EV OK HTTPS. - if (empty_subject_name) - identity_title.clear(); // Don't display any title. - else - identity_title.assign(subject_name); - std::wstring issuer_name(UTF8ToWide( - PageInfoWindow::GetIssuerName(cert->issuer()))); - if (issuer_name.empty()) { - issuer_name.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); - } else { - identity_msg.assign( - l10n_util::GetStringF(IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, - issuer_name)); - } - } - } else { - // Bad HTTPS. - identity_msg.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); + PageInfoModel::SectionInfo identity_section = + model_.GetSectionInfo(PageInfoModel::IDENTITY); + if (identity_section.state) + [controller_ setIdentityImg:[controller_ goodImg]]; + else [controller_ setIdentityImg:[controller_ badImg]]; - } + [controller_ setIdentityMsg:base::SysWideToNSString( + identity_section.description)]; // Connection section. - // We consider anything less than 80 bits encryption to be weak encryption. - // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and - // weakly encrypted connections. - if (ssl.security_bits() <= 0) { - [controller_ setConnectionImg:[controller_ badImg]]; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, - subject_name)); - } else if (ssl.security_bits() < 80) { + PageInfoModel::SectionInfo connection_section = + model_.GetSectionInfo(PageInfoModel::CONNECTION); + if (connection_section.state) + [controller_ setConnectionImg:[controller_ goodImg]]; + else [controller_ setConnectionImg:[controller_ badImg]]; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, - subject_name)); - } else { - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, - subject_name, - IntToWString(ssl.security_bits()))); - if (ssl.has_mixed_content()) { - [controller_ setConnectionImg:[controller_ badImg]]; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, - connection_msg, - l10n_util::GetString( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_MIXED_CONTENT_WARNING))); - } else if (ssl.has_unsafe_content()) { - [controller_ setConnectionImg:[controller_ badImg]]; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, - connection_msg, - l10n_util::GetString( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_BAD_HTTPS_WARNING))); - } - } + [controller_ setConnectionMsg: + base::SysWideToNSString(connection_section.description)]; + + if (model_.GetSectionCount() > 2) { + // We have the history info. + PageInfoModel::SectionInfo history_section = + model_.GetSectionInfo(PageInfoModel::HISTORY); + if (history_section.state) + [controller_ setHistoryImg:[controller_ goodImg]]; + else + [controller_ setHistoryImg:[controller_ badImg]]; - // We've figured out the messages that we want to appear in the page info - // window and we now hand them up to the NSWindowController, which binds them - // to the Cocoa view. - [controller_ setIdentityMsg:base::SysWideToNSString(identity_msg)]; - [controller_ setConnectionMsg:base::SysWideToNSString(connection_msg)]; - - // Request the number of visits. - HistoryService* history = profile->GetHistoryService( - Profile::EXPLICIT_ACCESS); - if (show_history && history) { - history->GetVisitCountToHost( - url, - &request_consumer_, - NewCallback(this, &PageInfoWindowMac::OnGotVisitCountToHost)); + [controller_ setHistoryMsg: + base::SysWideToNSString(history_section.description)]; } // By default, assume that we don't have certificate information to show. [controller_ setEnableCertButton:NO]; if (cert_id_) { + scoped_refptr<net::X509Certificate> cert; + CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert); + // Don't bother showing certificates if there isn't one. Gears runs with no // os root certificate. if (cert.get() && cert->os_cert_handle()) { @@ -218,37 +135,9 @@ void PageInfoWindowMac::Init(Profile* profile, } } -void PageInfoWindowMac::OnGotVisitCountToHost(HistoryService::Handle handle, - bool found_visits, - int count, - Time first_visit) { - if (!found_visits) { - // This indicates an error, such as the page wasn't http/https; do nothing. - return; - } - +void PageInfoWindowMac::ModelChanged() { // We have history information, so show the box and extend the window frame. [controller_ setShowHistoryBox:YES]; - - bool visited_before_today = false; - if (count) { - Time today = Time::Now().LocalMidnight(); - Time first_visit_midnight = first_visit.LocalMidnight(); - visited_before_today = (first_visit_midnight < today); - } - - if (!visited_before_today) { - [controller_ setHistoryImg:[controller_ badImg]]; - [controller_ setHistoryMsg: - base::SysWideToNSString( - l10n_util::GetString( - IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY))]; - } else { - [controller_ setHistoryImg:[controller_ goodImg]]; - [controller_ setHistoryMsg: - base::SysWideToNSString( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_VISITED_BEFORE_TODAY, - base::TimeFormatShortDate(first_visit)))]; - } + LayoutSections(); } + diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 2505733..b10f357 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -787,6 +787,15 @@ void BrowserWindowGtk::TabContentsFocused(TabContents* tab_contents) { NOTIMPLEMENTED(); } +void BrowserWindowGtk::ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + // TODO(port): port PageInfoWindow. + NOTIMPLEMENTED() << "IDS_CONTENT_CONTEXT_VIEWFRAMEINFO"; +} + void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { NOTIMPLEMENTED(); browser_->InProgressDownloadResponse(false); diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index f17e2b4..0267e41 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -103,6 +103,11 @@ class BrowserWindowGtk : public BrowserWindow, virtual void UserChangedTheme(); virtual int GetExtraRenderViewHeight() const; virtual void TabContentsFocused(TabContents* tab_contents); + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/page_info_model.cc b/chrome/browser/page_info_model.cc new file mode 100644 index 0000000..427f905 --- /dev/null +++ b/chrome/browser/page_info_model.cc @@ -0,0 +1,219 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/page_info_model.h" + +#include "app/l10n_util.h" +#include "base/time_format.h" +#include "chrome/browser/cert_store.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/ssl/ssl_manager.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "grit/generated_resources.h" +#include "net/base/cert_status_flags.h" +#include "net/base/x509_certificate.h" + +namespace { + // Returns a name that can be used to represent the issuer. It tries in this + // order CN, O and OU and returns the first non-empty one found. + std::string GetIssuerName(const net::X509Certificate::Principal& issuer) { + if (!issuer.common_name.empty()) + return issuer.common_name; + if (!issuer.organization_names.empty()) + return issuer.organization_names[0]; + if (!issuer.organization_unit_names.empty()) + return issuer.organization_unit_names[0]; + + return std::string(); + } +} + +PageInfoModel::PageInfoModel(Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history, + PageInfoModelObserver* observer) + : observer_(observer) { + bool state = true; + std::wstring head_line; + std::wstring description; + std::wstring connection_msg; + scoped_refptr<net::X509Certificate> cert; + + // Identity section. + std::wstring subject_name(UTF8ToWide(url.host())); + bool empty_subject_name = false; + if (subject_name.empty()) { + subject_name.assign( + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); + empty_subject_name = true; + } + if (ssl.cert_id() && + CertStore::GetSharedInstance()->RetrieveCert(ssl.cert_id(), &cert) && + !net::IsCertStatusError(ssl.cert_status())) { + // OK HTTPS page. + if ((ssl.cert_status() & net::CERT_STATUS_IS_EV) != 0) { + DCHECK(!cert->subject().organization_names.empty()); + head_line = + l10n_util::GetStringF(IDS_PAGE_INFO_EV_IDENTITY_TITLE, + UTF8ToWide(cert->subject().organization_names[0]), + UTF8ToWide(url.host())); + // An EV Cert is required to have a city (localityName) and country but + // state is "if any". + DCHECK(!cert->subject().locality_name.empty()); + DCHECK(!cert->subject().country_name.empty()); + std::wstring locality; + if (!cert->subject().state_or_province_name.empty()) { + locality = l10n_util::GetStringF( + IDS_PAGEINFO_ADDRESS, + UTF8ToWide(cert->subject().locality_name), + UTF8ToWide(cert->subject().state_or_province_name), + UTF8ToWide(cert->subject().country_name)); + } else { + locality = l10n_util::GetStringF( + IDS_PAGEINFO_PARTIAL_ADDRESS, + UTF8ToWide(cert->subject().locality_name), + UTF8ToWide(cert->subject().country_name)); + } + DCHECK(!cert->subject().organization_names.empty()); + description.assign(l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV, + UTF8ToWide(cert->subject().organization_names[0]), + locality, + UTF8ToWide(GetIssuerName(cert->issuer())))); + } else { + // Non EV OK HTTPS. + if (empty_subject_name) + head_line.clear(); // Don't display any title. + else + head_line.assign(subject_name); + std::wstring issuer_name(UTF8ToWide(GetIssuerName(cert->issuer()))); + if (issuer_name.empty()) { + issuer_name.assign( + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); + } else { + description.assign( + l10n_util::GetStringF(IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, + issuer_name)); + } + } + } else { + // Bad HTTPS. + description.assign( + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); + state = false; + } + sections_.push_back(SectionInfo( + state, + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + head_line, + description)); + + // Connection section. + // We consider anything less than 80 bits encryption to be weak encryption. + // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and + // weakly encrypted connections. + state = true; + head_line.clear(); + description.clear(); + if (ssl.security_bits() <= 0) { + state = false; + description.assign( + l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, + subject_name)); + } else if (ssl.security_bits() < 80) { + state = false; + description.assign( + l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, + subject_name)); + } else { + description.assign( + l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, + subject_name, + IntToWString(ssl.security_bits()))); + if (ssl.has_mixed_content()) { + state = false; + description.assign( + l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, + connection_msg, + l10n_util::GetString( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_MIXED_CONTENT_WARNING))); + } else if (ssl.has_unsafe_content()) { + state = false; + description.assign( + l10n_util::GetStringF( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, + connection_msg, + l10n_util::GetString( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_BAD_HTTPS_WARNING))); + } + } + sections_.push_back(SectionInfo( + state, + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + head_line, + description)); + + // Request the number of visits. + HistoryService* history = profile->GetHistoryService( + Profile::EXPLICIT_ACCESS); + if (show_history && history) { + history->GetVisitCountToHost( + url, + &request_consumer_, + NewCallback(this, &PageInfoModel::OnGotVisitCountToHost)); + } +} + +int PageInfoModel::GetSectionCount() { + return sections_.size(); +} + +PageInfoModel::SectionInfo PageInfoModel::GetSectionInfo(int index) { + DCHECK(index < static_cast<int>(sections_.size())); + return sections_[index]; +} + +void PageInfoModel::OnGotVisitCountToHost(HistoryService::Handle handle, + bool found_visits, + int count, + base::Time first_visit) { + if (!found_visits) { + // This indicates an error, such as the page wasn't http/https; do nothing. + return; + } + + bool visited_before_today = false; + if (count) { + base::Time today = base::Time::Now().LocalMidnight(); + base::Time first_visit_midnight = first_visit.LocalMidnight(); + visited_before_today = (first_visit_midnight < today); + } + + if (!visited_before_today) { + sections_.push_back(SectionInfo( + false, + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), + std::wstring(), + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY))); + } else { + sections_.push_back(SectionInfo( + true, + l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), + std::wstring(), + l10n_util::GetStringF(IDS_PAGE_INFO_SECURITY_TAB_VISITED_BEFORE_TODAY, + base::TimeFormatShortDate(first_visit)))); + } + observer_->ModelChanged(); +} + +// static +void PageInfoModel::RegisterPrefs(PrefService* prefs) { + prefs->RegisterDictionaryPref(prefs::kPageInfoWindowPlacement); +} diff --git a/chrome/browser/page_info_model.h b/chrome/browser/page_info_model.h new file mode 100644 index 0000000..5d32979 --- /dev/null +++ b/chrome/browser/page_info_model.h @@ -0,0 +1,90 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PAGE_INFO_MODEL_H +#define CHROME_BROWSER_PAGE_INFO_MODEL_H + +#include <string> +#include <vector> + +#include "chrome/browser/cancelable_request.h" +#include "chrome/browser/history/history.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "googleurl/src/gurl.h" + +class PrefService; +class Profile; + +// The model that provides the information that should be displayed in the page +// info dialog. +class PageInfoModel { + public: + class PageInfoModelObserver { + public: + virtual void ModelChanged() = 0; + }; + + // Because the UI on the Mac is statically laid-out, this enum provides the + // section type for the associated index. It is only used on Mac. + // Ideally the view wouldn't have to know anything regarding the semantics of + // the model and would only use GetSectionCount()/GetSectionInfo(). + enum SectionType { + IDENTITY = 0, + CONNECTION, + HISTORY + }; + + struct SectionInfo { + SectionInfo(bool state, + std::wstring title, + std::wstring head_line, + std::wstring description) + : state(state), + title(title), + head_line(head_line), + description(description) { + } + + bool state; // True if state is OK, false otherwise (ex of bad states: + // unverified identity over HTTPS). + + // The title of the section. + std::wstring title; + + // A single line describing the section, optional. + std::wstring head_line; + + // The full description of what this section is. + std::wstring description; + }; + + PageInfoModel(Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history, + PageInfoModelObserver* observer); + + int GetSectionCount(); + SectionInfo GetSectionInfo(int index); + + // Callback from history service with number of visits to url. + void OnGotVisitCountToHost(HistoryService::Handle handle, + bool found_visits, + int count, + base::Time first_visit); + + static void RegisterPrefs(PrefService* prefs); + + private: + PageInfoModelObserver* observer_; + + std::vector<SectionInfo> sections_; + + // Used to request number of visits. + CancelableRequestConsumer request_consumer_; + + DISALLOW_COPY_AND_ASSIGN(PageInfoModel); +}; + +#endif // CHROME_BROWSER_PAGE_INFO_MODEL_H diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index ecc6e5c..e7099ac 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -458,7 +458,7 @@ bool RenderViewContextMenu::ItemIsChecked(int id) const { return (params_.media_params.player_state & ContextMenuMediaParams::PLAYER_LOOP) != 0; } - + // Check box for 'Check the Spelling of this field'. if (id == IDC_CHECK_SPELLING_OF_THIS_FIELD) { return (params_.spellcheck_enabled && @@ -571,18 +571,10 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) { break; case IDS_CONTENT_CONTEXT_VIEWPAGEINFO: { -#if defined(OS_WIN) || defined(OS_MACOSX) NavigationEntry* nav_entry = source_tab_contents_->controller().GetActiveEntry(); - PageInfoWindow::CreatePageInfo( - profile_, - nav_entry, - source_tab_contents_->GetContentNativeView(), - PageInfoWindow::SECURITY); -#else - // TODO(port): port PageInfoWindow. - NOTIMPLEMENTED() << "IDS_CONTENT_CONTEXT_VIEWPAGEINFO"; -#endif + source_tab_contents_->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), + true); break; } @@ -626,17 +618,8 @@ void RenderViewContextMenu::ExecuteItemCommand(int id) { ssl.set_cert_status(cert_status); ssl.set_security_bits(security_bits); } -#if defined(OS_WIN) || defined(OS_MACOSX) - PageInfoWindow::CreateFrameInfo( - profile_, - params_.frame_url, - ssl, - source_tab_contents_->GetContentNativeView(), - PageInfoWindow::SECURITY); -#else - // TODO(port): port PageInfoWindow. - NOTIMPLEMENTED() << "IDS_CONTENT_CONTEXT_VIEWFRAMEINFO"; -#endif + source_tab_contents_->ShowPageInfo(params_.frame_url, ssl, + false); // Don't show the history. break; } diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 38b7a3e..ffb6d7d 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -751,6 +751,16 @@ void TabContents::CreateShortcut() { render_view_host()->GetApplicationInfo(pending_install_.page_id); } +void TabContents::ShowPageInfo(const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + if (!delegate_) + return; + + delegate_->ShowPageInfo(GetContentNativeView(), profile(), url, ssl, + show_history); +} + #if defined(OS_WIN) || defined(OS_LINUX) ConstrainedWindow* TabContents::CreateConstrainedDialog( ConstrainedWindowDelegate* delegate) { diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index e974f8e..67e7ccd 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -26,6 +26,7 @@ #include "chrome/browser/tab_contents/constrained_window.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/page_navigator.h" #include "chrome/browser/tab_contents/render_view_host_manager.h" #include "chrome/common/gears_api.h" @@ -327,6 +328,11 @@ class TabContents : public PageNavigator, // Tell Gears to create a shortcut for the current page. void CreateShortcut(); + // Shows the page info. + void ShowPageInfo(const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); + // Window management --------------------------------------------------------- #if defined(OS_WIN) || defined(OS_LINUX) diff --git a/chrome/browser/tab_contents/tab_contents_delegate.h b/chrome/browser/tab_contents/tab_contents_delegate.h index b00f31f..6db5e4a 100644 --- a/chrome/browser/tab_contents/tab_contents_delegate.h +++ b/chrome/browser/tab_contents/tab_contents_delegate.h @@ -8,6 +8,8 @@ #include "base/basictypes.h" #include "base/gfx/native_widget_types.h" #include "base/gfx/rect.h" + +#include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/page_transition_types.h" #include "chrome/common/renderer_preferences.h" @@ -206,6 +208,17 @@ class TabContentsDelegate { Profile* profile) { } + // Shows the page info using the specified information. + // |url| is the url of the page/frame the info applies to, |ssl| is the SSL + // information for that page/frame. If |show_history| is true, a section + // showing how many times that URL has been visited is added to the page info. + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + } + // Allows delegates to handle unhandled keyboard messages coming back from // the renderer. // Returns true if the keyboard message was handled. diff --git a/chrome/browser/views/browser_dialogs.h b/chrome/browser/views/browser_dialogs.h index c2b13f3..58253ad 100644 --- a/chrome/browser/views/browser_dialogs.h +++ b/chrome/browser/views/browser_dialogs.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_ #include "base/gfx/native_widget_types.h" +#include "chrome/browser/tab_contents/navigation_entry.h" // This file contains functions for running a variety of browser dialogs and // popups. The dialogs here are the ones that the caller does not need to @@ -97,6 +98,16 @@ void EditSearchEngine(gfx::NativeWindow parent, EditSearchEngineControllerDelegate* delegate, Profile* profile); +// Shows the page info using the specified information. +// |url| is the url of the page/frame the info applies to, |ssl| is the SSL +// information for that page/frame. If |show_history| is true, a section +// showing how many times that URL has been visited is added to the page info. +void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); + } // namespace browser #endif // CHROME_BROWSER_VIEWS_BROWSER_DIALOGS_H_ diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 9df6216..99ecc8a 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -967,6 +967,14 @@ void BrowserView::TabContentsFocused(TabContents* tab_contents) { contents_container_->TabContentsFocused(tab_contents); } +void BrowserView::ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + browser::ShowPageInfo(parent, profile, url, ssl, show_history); +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindowTesting implementation: diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index e2dc48d..1f64249 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -244,6 +244,11 @@ class BrowserView : public BrowserWindow, virtual void UserChangedTheme(); virtual int GetExtraRenderViewHeight() const; virtual void TabContentsFocused(TabContents* source); + virtual void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); // Overridden from BrowserWindowTesting: virtual BookmarkBarView* GetBookmarkBarView() const; diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc index d92b5b4..1e12760 100644 --- a/chrome/browser/views/location_bar_view.cc +++ b/chrome/browser/views/location_bar_view.cc @@ -1109,17 +1109,13 @@ void LocationBarView::SecurityImageView::SetImageShown(Image image) { bool LocationBarView::SecurityImageView::OnMousePressed( const views::MouseEvent& event) { - NavigationEntry* nav_entry = - BrowserList::GetLastActive()->GetSelectedTabContents()-> - controller().GetActiveEntry(); + TabContents* tab = BrowserList::GetLastActive()->GetSelectedTabContents(); + NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); if (!nav_entry) { NOTREACHED(); return true; } - PageInfoWindow::CreatePageInfo(profile_, - nav_entry, - GetRootView()->GetWidget()->GetNativeView(), - PageInfoWindow::SECURITY); + tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); return true; } diff --git a/chrome/browser/views/page_info_window_view.cc b/chrome/browser/views/page_info_window_view.cc new file mode 100644 index 0000000..38e5696 --- /dev/null +++ b/chrome/browser/views/page_info_window_view.cc @@ -0,0 +1,467 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "build/build_config.h" + +#if defined(OS_WIN) +#include <windows.h> +#include <cryptuiapi.h> +#pragma comment(lib, "cryptui.lib") +#endif + +#include "app/resource_bundle.h" +#include "app/l10n_util.h" +#include "base/compiler_specific.h" +#include "chrome/browser/cert_store.h" +#include "chrome/browser/page_info_model.h" +#include "chrome/common/pref_names.h" +#include "grit/locale_settings.h" +#include "grit/generated_resources.h" +#include "net/base/x509_certificate.h" +#include "views/background.h" +#include "views/grid_layout.h" +#include "views/controls/button/native_button.h" +#include "views/controls/button/button.h" +#include "views/controls/image_view.h" +#include "views/controls/label.h" +#include "views/controls/separator.h" +#include "views/standard_layout.h" +#include "views/window/dialog_delegate.h" +#include "views/window/window.h" + +#if defined(OS_WIN) +#include "app/win_util.h" +#endif + +namespace { + +// Layout constants. +const int kHGapToBorder = 6; +const int kHGapTitleToSeparator = 2; +const int kVGapTitleToImage = 6; +const int kHGapImageToDescription = 6; +const int kVGapHeadLineToDescription = 2; +const int kHExtraSeparatorPadding = 2; +const int kHorizontalPadding = 10; +const int kVerticalPadding = 20; + +class PageInfoWindowView : public views::View, + public views::DialogDelegate, + public views::ButtonListener, + public PageInfoModel::PageInfoModelObserver { + public: + PageInfoWindowView(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history); + virtual ~PageInfoWindowView(); + + // This is the main initializer that creates the window. + virtual void Init(gfx::NativeView parent); + + // views::View overrides: + virtual gfx::Size GetPreferredSize(); + + // views::Window overridden method. + virtual void Show(); + + virtual void ShowCertDialog(int cert_id); + + // views::ButtonListener method. + virtual void ButtonPressed(views::Button* sender); + + // views::DialogDelegate methods: + virtual int GetDialogButtons() const; + virtual std::wstring GetWindowTitle() const; + virtual std::wstring GetWindowName() const; + virtual views::View* GetContentsView(); + virtual views::View* GetExtraView(); + virtual bool CanResize() const { return true; } + + // PageInfoModel::PageInfoModelObserver method. + virtual void ModelChanged(); + + private: + // This retreives the sections from the model and lay them out. + void LayoutSections(); + + // Offsets the specified rectangle so it is showing on the screen and shifted + // from its original location. + void CalculateWindowBounds(gfx::Rect* bounds); + + views::NativeButton* cert_info_button_; + + // The model providing the various section info. + PageInfoModel model_; + + // The id of the certificate for this page. + int cert_id_; + + // A counter of how many page info windows are currently opened. + static int opened_window_count_; + + DISALLOW_COPY_AND_ASSIGN(PageInfoWindowView); +}; + +// A section contains an image that shows a status (good or bad), a title, an +// optional head-line (in bold) and a description. +class Section : public views::View { + public: + Section(const std::wstring& title, + bool state, + const std::wstring& head_line, + const std::wstring& description); + virtual ~Section(); + + virtual int GetHeightForWidth(int w); + virtual void Layout(); + + private: + // The text placed on top of the section (on the left of the separator bar). + std::wstring title_; + + // Whether to show the good/bad icon. + bool state_; + + // The first line of the description, show in bold. + std::wstring head_line_; + + // The description, displayed below the head line. + std::wstring description_; + + static SkBitmap* good_state_icon_; + static SkBitmap* bad_state_icon_; + + views::Label* title_label_; + views::Separator* separator_; + views::ImageView* status_image_; + views::Label* head_line_label_; + views::Label* description_label_; + + DISALLOW_COPY_AND_ASSIGN(Section); +}; + +// static +SkBitmap* Section::good_state_icon_ = NULL; +SkBitmap* Section::bad_state_icon_ = NULL; +int PageInfoWindowView::opened_window_count_ = 0; + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// PageInfoWindowViews + +PageInfoWindowView::PageInfoWindowView(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) + : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl, + show_history, this)), + cert_id_(ssl.cert_id()) { + Init(parent); +} + +PageInfoWindowView::~PageInfoWindowView() { + DCHECK(opened_window_count_ > 0); + opened_window_count_--; +} + +void PageInfoWindowView::Init(gfx::NativeView parent) { + DWORD sys_color = ::GetSysColor(COLOR_3DFACE); + SkColor color = SkColorSetRGB(GetRValue(sys_color), GetGValue(sys_color), + GetBValue(sys_color)); + set_background(views::Background::CreateSolidBackground(color)); + + LayoutSections(); + + if (opened_window_count_ > 0) { + // There already is a PageInfo window opened. Let's shift the location of + // the new PageInfo window so they don't overlap entirely. + // Window::Init will position the window from the stored location. + gfx::Rect bounds; + bool maximized = false; + if (GetSavedWindowBounds(&bounds) && GetSavedMaximizedState(&maximized)) { + CalculateWindowBounds(&bounds); + SaveWindowPlacement(bounds, maximized); + } + } + + views::Window::CreateChromeWindow(parent, gfx::Rect(), this); +} + +gfx::Size PageInfoWindowView::GetPreferredSize() { + return gfx::Size(views::Window::GetLocalizedContentsSize( + IDS_PAGEINFO_DIALOG_WIDTH_CHARS, IDS_PAGEINFO_DIALOG_HEIGHT_LINES)); +} + +void PageInfoWindowView::LayoutSections() { + // Remove all the existing sections. + RemoveAllChildViews(true); + + views::GridLayout* layout = new views::GridLayout(this); + SetLayoutManager(layout); + views::ColumnSet* columns = layout->AddColumnSet(0); + columns->AddPaddingColumn(0, kHorizontalPadding); + columns->AddColumn(views::GridLayout::FILL, // Horizontal resize. + views::GridLayout::FILL, // Vertical resize. + 1, // Resize weight. + views::GridLayout::USE_PREF, // Size type. + 0, // Ignored for USE_PREF. + 0); // Minimum size. + columns->AddPaddingColumn(0, kHorizontalPadding); + + layout->AddPaddingRow(0, kVerticalPadding); + for (int i = 0; i < model_.GetSectionCount(); ++i) { + PageInfoModel::SectionInfo info = model_.GetSectionInfo(i); + layout->StartRow(0, 0); + layout->AddView(new Section(info.title, info.state, info.head_line, + info.description)); + layout->AddPaddingRow(0, kVerticalPadding); + } + layout->AddPaddingRow(1, kVerticalPadding); + + Layout(); +} + +void PageInfoWindowView::Show() { + window()->Show(); + opened_window_count_++; +} + +int PageInfoWindowView::GetDialogButtons() const { + return MessageBoxFlags::DIALOGBUTTON_CANCEL; +} + +std::wstring PageInfoWindowView::GetWindowTitle() const { + return l10n_util::GetString(IDS_PAGEINFO_WINDOW_TITLE); +} + +std::wstring PageInfoWindowView::GetWindowName() const { + return prefs::kPageInfoWindowPlacement; +} + +views::View* PageInfoWindowView::GetContentsView() { + return this; +} + +views::View* PageInfoWindowView::GetExtraView() { + if (!cert_id_) + return NULL; + scoped_refptr<net::X509Certificate> cert; + CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert); + // When running with Gears, we have no os certificate, so there is no cert + // to show. Don't bother showing the cert info button in that case. + if (!cert.get() || !cert->os_cert_handle()) + return NULL; + + // The dialog sizes the extra view to fill the entire available space. + // We use a container to layout it out properly. + views::View* button_container = new views::View(); + views::GridLayout* layout = new views::GridLayout(button_container); + button_container->SetLayoutManager(layout); + + views::ColumnSet* column_set = layout->AddColumnSet(0); + column_set->AddPaddingColumn(0, kHorizontalPadding); + column_set->AddColumn(views::GridLayout::LEADING, + views::GridLayout::LEADING, 0, + views::GridLayout::USE_PREF, 0, 0); + layout->StartRow(0, 0); + layout->AddView(new views::NativeButton(this, + l10n_util::GetString(IDS_PAGEINFO_CERT_INFO_BUTTON))); + + return button_container; +} + +void PageInfoWindowView::ModelChanged() { + LayoutSections(); +} + +void PageInfoWindowView::ButtonPressed(views::Button* sender) { + // So far we only listen for the "Certificate info" button. + DCHECK(cert_id_ != 0); + ShowCertDialog(cert_id_); +} + +void PageInfoWindowView::CalculateWindowBounds(gfx::Rect* bounds) { + const int kDefaultOffset = 15; + + gfx::Rect monitor_bounds(win_util::GetMonitorBoundsForRect(*bounds)); + if (monitor_bounds.IsEmpty()) + return; + + // If necessary, move the window so it is visible on the screen. + gfx::Rect adjusted_bounds = bounds->AdjustToFit(monitor_bounds); + if (adjusted_bounds != *bounds) { + // The bounds have moved, we are done. + *bounds = adjusted_bounds; + return; + } + + // Move the window from its specified position, trying to keep it entirely + // visible. + int x_offset, y_offset; + if (bounds->right() + kDefaultOffset >= monitor_bounds.right() && + abs(monitor_bounds.x() - bounds->x()) >= kDefaultOffset) { + x_offset = -kDefaultOffset; + } else { + x_offset = kDefaultOffset; + } + + if (bounds->bottom() + kDefaultOffset >= monitor_bounds.bottom() && + abs(monitor_bounds.y() - bounds->y()) >= kDefaultOffset) { + y_offset = -kDefaultOffset; + } else { + y_offset = kDefaultOffset; + } + + bounds->Offset(x_offset, y_offset); +} + +void PageInfoWindowView::ShowCertDialog(int cert_id) { +#if defined(OS_WIN) + scoped_refptr<net::X509Certificate> cert; + CertStore::GetSharedInstance()->RetrieveCert(cert_id, &cert); + if (!cert.get()) { + // The certificate was not found. Could be that the renderer crashed before + // we displayed the page info. + return; + } + + CRYPTUI_VIEWCERTIFICATE_STRUCT view_info = { 0 }; + view_info.dwSize = sizeof(view_info); + // We set our parent to the tab window. This makes the cert dialog created + // in CryptUIDlgViewCertificate modal to the browser. + view_info.hwndParent = window()->GetNativeWindow(); + view_info.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | + CRYPTUI_DISABLE_ADDTOSTORE; + view_info.pCertContext = cert->os_cert_handle(); + // Search the cert store that 'cert' is in when building the cert chain. + HCERTSTORE cert_store = view_info.pCertContext->hCertStore; + view_info.cStores = 1; + view_info.rghStores = &cert_store; + BOOL properties_changed; + + // This next call blocks but keeps processing windows messages, making it + // modal to the browser window. + BOOL rv = ::CryptUIDlgViewCertificate(&view_info, &properties_changed); +#else + NOTIMPLEMENTED(); +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +// Section + +Section::Section(const std::wstring& title, + bool state, + const std::wstring& head_line, + const std::wstring& description) + : title_(title), + state_(state), + head_line_(head_line), + description_(description) { + if (!good_state_icon_) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + good_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_GOOD); + bad_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_BAD); + } + title_label_ = new views::Label(title); + title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(title_label_); + + separator_ = new views::Separator(); + AddChildView(separator_); + + status_image_ = new views::ImageView(); + status_image_->SetImage(state ? good_state_icon_ : bad_state_icon_); + AddChildView(status_image_); + + head_line_label_ = new views::Label(head_line); + head_line_label_->SetFont( + head_line_label_->GetFont().DeriveFont(0, gfx::Font::BOLD)); + head_line_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(head_line_label_); + + description_label_ = new views::Label(description); + description_label_->SetMultiLine(true); + description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(description_label_); +} + +Section::~Section() { +} + +int Section::GetHeightForWidth(int width) { + // The height of the section depends on the height of the description label + // (multi-line). We need to know the width of the description label to know + // its height. + int height = 0; + gfx::Size size = title_label_->GetPreferredSize(); + height += size.height() + kVGapTitleToImage; + + gfx::Size image_size = status_image_->GetPreferredSize(); + + int text_height = 0; + if (!head_line_label_->GetText().empty()) { + size = head_line_label_->GetPreferredSize(); + text_height = size.height() + kVGapHeadLineToDescription; + } + + int description_width = + width - image_size.width() - kHGapImageToDescription - kHGapToBorder; + text_height += description_label_->GetHeightForWidth(description_width); + + height += std::max(image_size.height(), text_height); + + return height; +} + +void Section::Layout() { + // First, layout the title and separator. + int x = 0; + int y = 0; + gfx::Size size = title_label_->GetPreferredSize(); + title_label_->SetBounds(x, y, size.width(), size.height()); + x += size.width() + kHGapTitleToSeparator; + separator_->SetBounds(x + kHExtraSeparatorPadding, y, + width() - x - 2 * kHExtraSeparatorPadding, + size.height()); + + // Then the image, head-line and description. + x = kHGapToBorder; + y += title_label_->height() + kVGapTitleToImage; + size = status_image_->GetPreferredSize(); + status_image_->SetBounds(x, y, size.width(), size.height()); + x += size.width() + kHGapImageToDescription; + int w = width() - x; + if (!head_line_label_->GetText().empty()) { + size = head_line_label_->GetPreferredSize(); + head_line_label_->SetBounds(x, y, w > 0 ? w : 0, size.height()); + y += size.height() + kVGapHeadLineToDescription; + } else { + head_line_label_->SetBounds(x, y, 0, 0); + } + if (w > 0) { + description_label_->SetBounds(x, y, w, + description_label_->GetHeightForWidth(w)); + } else { + description_label_->SetBounds(x, y, 0, 0); + } +} + +namespace browser { + +void ShowPageInfo(gfx::NativeView parent, + Profile* profile, + const GURL& url, + const NavigationEntry::SSLStatus& ssl, + bool show_history) { + PageInfoWindowView* page_info_window = + new PageInfoWindowView(parent, profile, url, ssl, show_history); + page_info_window->Show(); +} + +} diff --git a/chrome/browser/views/page_info_window_win.cc b/chrome/browser/views/page_info_window_win.cc deleted file mode 100644 index 1d75602..0000000 --- a/chrome/browser/views/page_info_window_win.cc +++ /dev/null @@ -1,650 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/views/page_info_window_win.h" - -#if defined(OS_WIN) -#include <cryptuiapi.h> -#pragma comment(lib, "cryptui.lib") -#endif - -#include "app/l10n_util.h" -#include "app/resource_bundle.h" -#include "base/string_util.h" -#include "base/time_format.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/cert_store.h" -#include "chrome/browser/history/history.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/ssl/ssl_manager.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/pref_service.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "grit/theme_resources.h" -#include "net/base/cert_status_flags.h" -#include "net/base/x509_certificate.h" -#include "third_party/skia/include/core/SkColor.h" -#include "views/background.h" -#include "views/grid_layout.h" -#include "views/controls/button/native_button.h" -#include "views/controls/button/button.h" -#include "views/controls/image_view.h" -#include "views/controls/label.h" -#include "views/controls/separator.h" -#include "views/standard_layout.h" - -#if defined(OS_WIN) -#include "app/win_util.h" -#endif - -using base::Time; - -const int kVerticalPadding = 10; -const int kHorizontalPadding = 10; - -//////////////////////////////////////////////////////////////////////////////// -// SecurityTabView -class SecurityTabView : public views::View { - public: - SecurityTabView(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history); - virtual ~SecurityTabView(); - - virtual void Layout(); - - // Add a section. - virtual void AddSection(const std::wstring& title, - bool state, - const std::wstring& head_line, - const std::wstring& description); - - private: - // A section contains an image that shows a status (good or bad), a title, - // an optional head-line (in bold) and a description. - class Section : public views::View { - public: - Section(const std::wstring& title, - bool state, - const std::wstring& head_line, - const std::wstring& description); - virtual ~Section(); - - virtual int GetHeightForWidth(int w); - virtual void Layout(); - - private: - // The text placed on top of the section (on the left of the separator bar). - std::wstring title_; - - // Whether to show the good/bad icon. - bool state_; - - // The first line of the description, show in bold. - std::wstring head_line_; - - // The description, displayed below the head line. - std::wstring description_; - - static SkBitmap* good_state_icon_; - static SkBitmap* bad_state_icon_; - - views::Label* title_label_; - views::Separator* separator_; - views::ImageView* status_image_; - views::Label* head_line_label_; - views::Label* description_label_; - - DISALLOW_EVIL_CONSTRUCTORS(Section); - }; - - // Callback from history service with number of visits to url. - void OnGotVisitCountToHost(HistoryService::Handle handle, - bool found_visits, - int count, - Time first_visit); - - std::vector<Section*> sections_; - - // Used to request number of visits. - CancelableRequestConsumer request_consumer_; - - DISALLOW_EVIL_CONSTRUCTORS(SecurityTabView); -}; - -// static -SkBitmap* SecurityTabView::Section::good_state_icon_ = NULL; -SkBitmap* SecurityTabView::Section::bad_state_icon_ = NULL; - -// Layout constants. -static const int kHGapToBorder = 6; -static const int kVGapToBorder = 6; -static const int kHGapTitleToSeparator = 2; -static const int kVGapTitleToImage = 6; -static const int kHGapImageToDescription = 6; -static const int kVGapHeadLineToDescription = 2; -static const int kVGapBetweenSections = 20; -static const int kHExtraSeparatorPadding = 2; - -SecurityTabView::Section::Section(const std::wstring& title, bool state, - const std::wstring& head_line, - const std::wstring& description) - : title_(title), - state_(state), - head_line_(head_line), - description_(description) { - if (!good_state_icon_) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - good_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_GOOD); - bad_state_icon_ = rb.GetBitmapNamed(IDR_PAGEINFO_BAD); - } - title_label_ = new views::Label(title); - title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(title_label_); - - separator_ = new views::Separator(); - AddChildView(separator_); - - status_image_ = new views::ImageView(); - status_image_->SetImage(state ? good_state_icon_ : bad_state_icon_); - AddChildView(status_image_); - - head_line_label_ = new views::Label(head_line); - head_line_label_->SetFont( - head_line_label_->GetFont().DeriveFont(0, gfx::Font::BOLD)); - head_line_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(head_line_label_); - - description_label_ = new views::Label(description); - description_label_->SetMultiLine(true); - description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); - AddChildView(description_label_); -} - -SecurityTabView::Section::~Section() { -} - -int SecurityTabView::Section::GetHeightForWidth(int width) { - // The height of the section depends on the height of the description label - // (multi-line). We need to know the width of the description label to know - // its height. - int height = 0; - gfx::Size size = title_label_->GetPreferredSize(); - height += size.height() + kVGapTitleToImage; - - gfx::Size image_size = status_image_->GetPreferredSize(); - - int text_height = 0; - if (!head_line_label_->GetText().empty()) { - size = head_line_label_->GetPreferredSize(); - text_height = size.height() + kVGapHeadLineToDescription; - } - - int description_width = - width - image_size.width() - kHGapImageToDescription - kHGapToBorder; - text_height += description_label_->GetHeightForWidth(description_width); - - height += std::max(image_size.height(), text_height); - - return height; -} - -void SecurityTabView::Section::Layout() { - // First, layout the title and separator. - int x = 0; - int y = 0; - gfx::Size size = title_label_->GetPreferredSize(); - title_label_->SetBounds(x, y, size.width(), size.height()); - x += size.width() + kHGapTitleToSeparator; - separator_->SetBounds(x + kHExtraSeparatorPadding, y, - width() - x - 2 * kHExtraSeparatorPadding, - size.height()); - - // Then the image, head-line and description. - x = kHGapToBorder; - y += title_label_->height() + kVGapTitleToImage; - size = status_image_->GetPreferredSize(); - status_image_->SetBounds(x, y, size.width(), size.height()); - x += size.width() + kHGapImageToDescription; - int w = width() - x; - if (!head_line_label_->GetText().empty()) { - size = head_line_label_->GetPreferredSize(); - head_line_label_->SetBounds(x, y, w > 0 ? w : 0, size.height()); - y += size.height() + kVGapHeadLineToDescription; - } else { - head_line_label_->SetBounds(x, y, 0, 0); - } - if (w > 0) { - description_label_->SetBounds(x, y, w, - description_label_->GetHeightForWidth(w)); - } else { - description_label_->SetBounds(x, y, 0, 0); - } -} - -SecurityTabView::SecurityTabView(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history) { - bool identity_ok = true; - bool connection_ok = true; - std::wstring identity_title; - std::wstring identity_msg; - std::wstring connection_msg; - scoped_refptr<net::X509Certificate> cert; - - // Identity section. - std::wstring subject_name(UTF8ToWide(url.host())); - bool empty_subject_name = false; - if (subject_name.empty()) { - subject_name.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); - empty_subject_name = true; - } - if (page_type == NavigationEntry::NORMAL_PAGE && ssl.cert_id() && - CertStore::GetSharedInstance()->RetrieveCert(ssl.cert_id(), &cert) && - !net::IsCertStatusError(ssl.cert_status())) { - // OK HTTPS page. - if ((ssl.cert_status() & net::CERT_STATUS_IS_EV) != 0) { - DCHECK(!cert->subject().organization_names.empty()); - identity_title = - l10n_util::GetStringF(IDS_PAGE_INFO_EV_IDENTITY_TITLE, - UTF8ToWide(cert->subject().organization_names[0]), - UTF8ToWide(url.host())); - // An EV Cert is required to have a city (localityName) and country but - // state is "if any". - DCHECK(!cert->subject().locality_name.empty()); - DCHECK(!cert->subject().country_name.empty()); - std::wstring locality; - if (!cert->subject().state_or_province_name.empty()) { - locality = l10n_util::GetStringF( - IDS_PAGEINFO_ADDRESS, - UTF8ToWide(cert->subject().locality_name), - UTF8ToWide(cert->subject().state_or_province_name), - UTF8ToWide(cert->subject().country_name)); - } else { - locality = l10n_util::GetStringF( - IDS_PAGEINFO_PARTIAL_ADDRESS, - UTF8ToWide(cert->subject().locality_name), - UTF8ToWide(cert->subject().country_name)); - } - DCHECK(!cert->subject().organization_names.empty()); - identity_msg.assign(l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV, - UTF8ToWide(cert->subject().organization_names[0]), - locality, - UTF8ToWide(PageInfoWindow::GetIssuerName(cert->issuer())))); - } else { - // Non EV OK HTTPS. - if (empty_subject_name) - identity_title.clear(); // Don't display any title. - else - identity_title.assign(subject_name); - std::wstring issuer_name(UTF8ToWide( - PageInfoWindow::GetIssuerName(cert->issuer()))); - if (issuer_name.empty()) { - issuer_name.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY)); - } else { - identity_msg.assign( - l10n_util::GetStringF(IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, - issuer_name)); - } - } - } else { - // Bad HTTPS. - identity_msg.assign( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY)); - identity_ok = false; - } - - // Connection section. - // We consider anything less than 80 bits encryption to be weak encryption. - // TODO(wtc): Bug 1198735: report mixed/unsafe content for unencrypted and - // weakly encrypted connections. - if (ssl.security_bits() <= 0) { - connection_ok = false; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, - subject_name)); - } else if (ssl.security_bits() < 80) { - connection_ok = false; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT, - subject_name)); - } else { - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, - subject_name, - IntToWString(ssl.security_bits()))); - if (ssl.has_mixed_content()) { - connection_ok = false; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, - connection_msg, - l10n_util::GetString( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_MIXED_CONTENT_WARNING))); - } else if (ssl.has_unsafe_content()) { - connection_ok = false; - connection_msg.assign( - l10n_util::GetStringF( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, - connection_msg, - l10n_util::GetString( - IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_BAD_HTTPS_WARNING))); - } - } - - // Let's add the different sections. - AddSection(l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), - identity_ok, identity_title, identity_msg); - AddSection(l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), - connection_ok, std::wstring(), connection_msg); - - // Request the number of visits. - HistoryService* history = profile->GetHistoryService( - Profile::EXPLICIT_ACCESS); - if (show_history && history) { - history->GetVisitCountToHost( - url, - &request_consumer_, - NewCallback(this, &SecurityTabView::OnGotVisitCountToHost)); - } -} - -SecurityTabView::~SecurityTabView() { -} - -void SecurityTabView::AddSection(const std::wstring& title, - bool state, - const std::wstring& head_line, - const std::wstring& description) { - Section* section = new Section(title, state, head_line, description); - sections_.push_back(section); - AddChildView(section); -} - -void SecurityTabView::Layout() { - int tab_width = width() - 2 * kHGapToBorder; - int x = kHGapToBorder; - int y = kVGapToBorder; - for (std::vector<Section*>::const_iterator iter = sections_.begin(); - iter != sections_.end(); ++iter) { - Section* section = *iter; - int h = section->GetHeightForWidth(tab_width); - section->SetBounds(x, y, tab_width, h); - section->Layout(); - y += h + kVGapBetweenSections; - } -} - -void SecurityTabView::OnGotVisitCountToHost(HistoryService::Handle handle, - bool found_visits, - int count, - Time first_visit) { - if (!found_visits) { - // This indicates an error, such as the page wasn't http/https; do nothing. - return; - } - - bool visited_before_today = false; - if (count) { - Time today = Time::Now().LocalMidnight(); - Time first_visit_midnight = first_visit.LocalMidnight(); - visited_before_today = (first_visit_midnight < today); - } - - if (!visited_before_today) { - AddSection( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), - false, std::wstring(), - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY)); - } else { - AddSection( - l10n_util::GetString(IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), - true, std::wstring(), - l10n_util::GetStringF(IDS_PAGE_INFO_SECURITY_TAB_VISITED_BEFORE_TODAY, - base::TimeFormatShortDate(first_visit))); - } - Layout(); - SchedulePaint(); -} - -//////////////////////////////////////////////////////////////////////////////// -// PageInfoContentView -class PageInfoContentView : public views::View { - public: - PageInfoContentView() : cert_viewer_button_(NULL) {} - - void set_cert_viewer_button(views::NativeButton* cert_viewer_button) { - cert_viewer_button_ = cert_viewer_button; - } - - // views::View overrides: - virtual gfx::Size GetPreferredSize() { - return gfx::Size(views::Window::GetLocalizedContentsSize( - IDS_PAGEINFO_DIALOG_WIDTH_CHARS, - IDS_PAGEINFO_DIALOG_HEIGHT_LINES)); - } - - virtual void Layout() { - if (cert_viewer_button_) { - gfx::Size ps = cert_viewer_button_->GetPreferredSize(); - - gfx::Rect parent_bounds = GetParent()->GetLocalBounds(false); - int y_buttons = - parent_bounds.bottom() - ps.height() - kButtonVEdgeMargin; - cert_viewer_button_->SetBounds(kPanelHorizMargin, y_buttons, ps.width(), - ps.height()); - } - View::Layout(); - } - - private: - views::NativeButton* cert_viewer_button_; - - DISALLOW_EVIL_CONSTRUCTORS(PageInfoContentView); -}; - -//////////////////////////////////////////////////////////////////////////////// -// PageInfoWindowWin - -int PageInfoWindowWin::opened_window_count_ = 0; - -PageInfoWindow* PageInfoWindow::Factory() { - return new PageInfoWindowWin(); -} - -PageInfoWindowWin::PageInfoWindowWin() - : PageInfoWindow() { -} - -PageInfoWindowWin::~PageInfoWindowWin() { - DCHECK(opened_window_count_ > 0); - opened_window_count_--; -} - -void PageInfoWindowWin::Init(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history, - gfx::NativeView parent) { - cert_id_ = ssl.cert_id(); - - cert_info_button_ = new views::NativeButton( - this, l10n_util::GetString(IDS_PAGEINFO_CERT_INFO_BUTTON)); - - contents_ = new PageInfoContentView(); - DWORD sys_color = ::GetSysColor(COLOR_3DFACE); - SkColor color = SkColorSetRGB(GetRValue(sys_color), GetGValue(sys_color), - GetBValue(sys_color)); - contents_->set_background(views::Background::CreateSolidBackground(color)); - - views::GridLayout* layout = new views::GridLayout(contents_); - contents_->SetLayoutManager(layout); - views::ColumnSet* columns = layout->AddColumnSet(0); - columns->AddPaddingColumn(0, kHorizontalPadding); - columns->AddColumn(views::GridLayout::FILL, // Horizontal resize. - views::GridLayout::FILL, // Vertical resize. - 1, // Resize weight. - views::GridLayout::USE_PREF, // Size type. - 0, // Ignored for USE_PREF. - 0); // Minimum size. - columns->AddColumn(views::GridLayout::FILL, // Horizontal resize. - views::GridLayout::FILL, // Vertical resize. - 1, // Resize weight. - views::GridLayout::USE_PREF, // Size type. - 0, // Ignored for USE_PREF. - 0); // Minimum size. - columns->AddPaddingColumn(0, kHorizontalPadding); - - layout->AddPaddingRow(0, kHorizontalPadding); - layout->StartRow(1, 0); - layout->AddView(CreateSecurityTabView(profile, url, ssl, page_type, - show_history), 2, 1); - - layout->AddPaddingRow(0, kHorizontalPadding); - - if (opened_window_count_ > 0) { - // There already is a PageInfo window opened. Let's shift the location of - // the new PageInfo window so they don't overlap entirely. - // Window::Init will position the window from the stored location. - gfx::Rect bounds; - bool maximized = false; - if (GetSavedWindowBounds(&bounds) && GetSavedMaximizedState(&maximized)) { - CalculateWindowBounds(&bounds); - SaveWindowPlacement(bounds, maximized); - } - } - - views::Window::CreateChromeWindow(parent, gfx::Rect(), this); - // TODO(beng): (Cleanup) - cert viewer button should use GetExtraView. - - if (cert_id_) { - scoped_refptr<net::X509Certificate> cert; - CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert); - // When running with Gears, we have no os certificate, so there is no cert - // to show. Don't bother showing the cert info button in that case. - if (cert.get() && cert->os_cert_handle()) { - contents_->GetParent()->AddChildView(cert_info_button_); - contents_->set_cert_viewer_button(cert_info_button_); - contents_->Layout(); - } - } -} - -views::View* PageInfoWindowWin::CreateGeneralTabView() { - return new views::View(); -} - -views::View* PageInfoWindowWin::CreateSecurityTabView( - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history) { - return new SecurityTabView(profile, url, ssl, page_type, show_history); -} - -void PageInfoWindowWin::Show() { - window()->Show(); - opened_window_count_++; -} - -int PageInfoWindowWin::GetDialogButtons() const { - return MessageBoxFlags::DIALOGBUTTON_CANCEL; -} - -std::wstring PageInfoWindowWin::GetWindowTitle() const { - return l10n_util::GetString(IDS_PAGEINFO_WINDOW_TITLE); -} - -std::wstring PageInfoWindowWin::GetWindowName() const { - return prefs::kPageInfoWindowPlacement; -} - -views::View* PageInfoWindowWin::GetContentsView() { - return contents_; -} - -void PageInfoWindowWin::ButtonPressed(views::Button* sender) { - if (sender == cert_info_button_) { - DCHECK(cert_id_ != 0); - ShowCertDialog(cert_id_); - } else { - NOTREACHED(); - } -} - -void PageInfoWindowWin::CalculateWindowBounds(gfx::Rect* bounds) { - const int kDefaultOffset = 15; - - gfx::Rect monitor_bounds(win_util::GetMonitorBoundsForRect(*bounds)); - if (monitor_bounds.IsEmpty()) - return; - - // If necessary, move the window so it is visible on the screen. - gfx::Rect adjusted_bounds = bounds->AdjustToFit(monitor_bounds); - if (adjusted_bounds != *bounds) { - // The bounds have moved, we are done. - *bounds = adjusted_bounds; - return; - } - - // Move the window from its specified position, trying to keep it entirely - // visible. - int x_offset, y_offset; - if (bounds->right() + kDefaultOffset >= monitor_bounds.right() && - abs(monitor_bounds.x() - bounds->x()) >= kDefaultOffset) { - x_offset = -kDefaultOffset; - } else { - x_offset = kDefaultOffset; - } - - if (bounds->bottom() + kDefaultOffset >= monitor_bounds.bottom() && - abs(monitor_bounds.y() - bounds->y()) >= kDefaultOffset) { - y_offset = -kDefaultOffset; - } else { - y_offset = kDefaultOffset; - } - - bounds->Offset(x_offset, y_offset); -} - -void PageInfoWindowWin::ShowCertDialog(int cert_id) { - scoped_refptr<net::X509Certificate> cert; - CertStore::GetSharedInstance()->RetrieveCert(cert_id, &cert); - if (!cert.get()) { - // The certificate was not found. Could be that the renderer crashed before - // we displayed the page info. - return; - } - - CRYPTUI_VIEWCERTIFICATE_STRUCT view_info = { 0 }; - view_info.dwSize = sizeof(view_info); - // We set our parent to the tab window. This makes the cert dialog created - // in CryptUIDlgViewCertificate modal to the browser. - view_info.hwndParent = window()->GetNativeWindow(); - view_info.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | - CRYPTUI_DISABLE_ADDTOSTORE; - view_info.pCertContext = cert->os_cert_handle(); - // Search the cert store that 'cert' is in when building the cert chain. - HCERTSTORE cert_store = view_info.pCertContext->hCertStore; - view_info.cStores = 1; - view_info.rghStores = &cert_store; - BOOL properties_changed; - - // This next call blocks but keeps processing windows messages, making it - // modal to the browser window. - BOOL rv = ::CryptUIDlgViewCertificate(&view_info, &properties_changed); -} diff --git a/chrome/browser/views/page_info_window_win.h b/chrome/browser/views/page_info_window_win.h deleted file mode 100644 index fba4a48..0000000 --- a/chrome/browser/views/page_info_window_win.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_VIEWS_PAGE_INFO_WINDOW_WIN_H__ -#define CHROME_BROWSER_VIEWS_PAGE_INFO_WINDOW_WIN_H__ - -#include "chrome/browser/page_info_window.h" -#include "chrome/browser/tab_contents/navigation_entry.h" -#include "googleurl/src/gurl.h" -#include "views/controls/button/button.h" -#include "views/window/dialog_delegate.h" -#include "views/window/window.h" - -// The page info window displays information regarding the current page, -// including security information. - -namespace views { -class TabbedPane; -} - -class NavigationEntry; -class PageInfoContentView; -class PrefService; -class Profile; -class X509Certificate; -class SecurityTabView; - -class PageInfoWindowWin : public PageInfoWindow, - public views::DialogDelegate, - public views::ButtonListener { - public: - // We need access to PageInfoWindow::GetIssuerName() which is protected - friend class SecurityTabView; - - PageInfoWindowWin(); - virtual ~PageInfoWindowWin(); - - // This is the main initializer that creates the window. - virtual void Init(Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history, - gfx::NativeView parent); - - // views::Window overridden method. - virtual void Show(); - virtual void ShowCertDialog(int cert_id); - - // views::ButtonListener method. - virtual void ButtonPressed(views::Button* sender); - - // views::DialogDelegate methods: - virtual int GetDialogButtons() const; - virtual std::wstring GetWindowTitle() const; - virtual std::wstring GetWindowName() const; - virtual views::View* GetContentsView(); - - private: - virtual views::View* CreateGeneralTabView(); - virtual views::View* CreateSecurityTabView( - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - NavigationEntry::PageType page_type, - bool show_history); - - // Offsets the specified rectangle so it is showing on the screen and shifted - // from its original location. - void CalculateWindowBounds(gfx::Rect* bounds); - - views::NativeButton* cert_info_button_; - - // The page info contents. - PageInfoContentView* contents_; - - // A counter of how many page info windows are currently opened. - static int opened_window_count_; - - DISALLOW_COPY_AND_ASSIGN(PageInfoWindowWin); -}; - -#endif // #define CHROME_BROWSER_VIEWS_PAGE_INFO_WINDOW_WIN_H__ |