// Copyright (c) 2012 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/pepper_broker_observer.h" #include "base/memory/scoped_ptr.h" #include "chrome/browser/api/infobars/confirm_infobar_delegate.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/infobars/infobar_tab_helper.h" #include "chrome/browser/plugins/plugin_finder.h" #include "chrome/browser/plugins/plugin_metadata.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "net/base/net_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "webkit/plugins/npapi/plugin_list.h" #include "webkit/plugins/webplugininfo.h" using content::OpenURLParams; using content::Referrer; using content::WebContents; DEFINE_WEB_CONTENTS_USER_DATA_KEY(PepperBrokerObserver) namespace { // The URL for the "learn more" article about the PPAPI broker. const char kPpapiBrokerLearnMoreUrl[] = "https://support.google.com/chrome/?p=ib_pepper_broker"; class PepperBrokerInfoBarDelegate : public ConfirmInfoBarDelegate { public: static void Show( content::WebContents* web_contents, const GURL& url, const FilePath& plugin_path, const base::Callback& callback); PepperBrokerInfoBarDelegate( InfoBarTabHelper* helper, const GURL& url, const FilePath& plugin_path, const std::string& languages, HostContentSettingsMap* content_settings, const base::Callback& callback); virtual ~PepperBrokerInfoBarDelegate(); // ConfirmInfoBarDelegate: virtual string16 GetMessageText() const OVERRIDE; virtual int GetButtons() const OVERRIDE; virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; virtual bool Accept() OVERRIDE; virtual bool Cancel() OVERRIDE; virtual string16 GetLinkText() const OVERRIDE; virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE; virtual gfx::Image* GetIcon() const OVERRIDE; private: const GURL url_; const FilePath plugin_path_; const std::string languages_; HostContentSettingsMap* content_settings_; base::Callback callback_; DISALLOW_COPY_AND_ASSIGN(PepperBrokerInfoBarDelegate); }; PepperBrokerInfoBarDelegate::PepperBrokerInfoBarDelegate( InfoBarTabHelper* helper, const GURL& url, const FilePath& plugin_path, const std::string& languages, HostContentSettingsMap* content_settings, const base::Callback& callback) : ConfirmInfoBarDelegate(helper), url_(url), plugin_path_(plugin_path), languages_(languages), content_settings_(content_settings), callback_(callback) { } PepperBrokerInfoBarDelegate::~PepperBrokerInfoBarDelegate() { if (!callback_.is_null()) callback_.Run(false); } string16 PepperBrokerInfoBarDelegate::GetMessageText() const { content::PluginService* plugin_service = content::PluginService::GetInstance(); webkit::WebPluginInfo plugin; bool success = plugin_service->GetPluginInfoByPath(plugin_path_, &plugin); DCHECK(success); scoped_ptr plugin_metadata( PluginFinder::GetInstance()->GetPluginMetadata(plugin)); return l10n_util::GetStringFUTF16(IDS_PEPPER_BROKER_MESSAGE, plugin_metadata->name(), net::FormatUrl(url_.GetOrigin(), languages_)); } int PepperBrokerInfoBarDelegate::GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; } string16 PepperBrokerInfoBarDelegate::GetButtonLabel( InfoBarButton button) const { switch (button) { case BUTTON_OK: return l10n_util::GetStringUTF16(IDS_PEPPER_BROKER_ALLOW_BUTTON); case BUTTON_CANCEL: return l10n_util::GetStringUTF16(IDS_PEPPER_BROKER_DENY_BUTTON); default: NOTREACHED(); return string16(); } } bool PepperBrokerInfoBarDelegate::Accept() { content::RecordAction( content::UserMetricsAction("PPAPI.BrokerInfobarClickedAllow")); callback_.Run(true); callback_ = base::Callback(); content_settings_->SetContentSetting( ContentSettingsPattern::FromURLNoWildcard(url_), ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_PPAPI_BROKER, std::string(), CONTENT_SETTING_ALLOW); return true; } bool PepperBrokerInfoBarDelegate::Cancel() { content::RecordAction( content::UserMetricsAction("PPAPI.BrokerInfobarClickedDeny")); callback_.Run(false); callback_ = base::Callback(); return true; } string16 PepperBrokerInfoBarDelegate::GetLinkText() const { return l10n_util::GetStringUTF16(IDS_LEARN_MORE); } bool PepperBrokerInfoBarDelegate::LinkClicked( WindowOpenDisposition disposition) { OpenURLParams params( GURL(kPpapiBrokerLearnMoreUrl), Referrer(), (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, content::PAGE_TRANSITION_LINK, false); owner()->GetWebContents()->OpenURL(params); return false; } gfx::Image* PepperBrokerInfoBarDelegate::GetIcon() const { return &ResourceBundle::GetSharedInstance().GetNativeImageNamed( IDR_INFOBAR_PLUGIN_INSTALL); } } // namespace PepperBrokerObserver::PepperBrokerObserver(WebContents* web_contents) : WebContentsObserver(web_contents) {} PepperBrokerObserver::~PepperBrokerObserver() {} bool PepperBrokerObserver::RequestPpapiBrokerPermission( WebContents* web_contents, const GURL& url, const FilePath& plugin_path, const base::Callback& callback) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); // TODO(wad): Add ephemeral device ID support for broker in guest mode. if (Profile::IsGuestSession()) { callback.Run(false); return true; } HostContentSettingsMap* content_settings = profile->GetHostContentSettingsMap(); ContentSetting setting = content_settings->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_PPAPI_BROKER, std::string()); switch (setting) { case CONTENT_SETTING_ALLOW: { content::RecordAction( content::UserMetricsAction("PPAPI.BrokerSettingAllow")); callback.Run(true); break; } case CONTENT_SETTING_BLOCK: { content::RecordAction( content::UserMetricsAction("PPAPI.BrokerSettingDeny")); callback.Run(false); break; } case CONTENT_SETTING_ASK: { content::RecordAction( content::UserMetricsAction("PPAPI.BrokerInfobarDisplayed")); InfoBarTabHelper* infobar_helper = InfoBarTabHelper::FromWebContents(web_contents); std::string languages = profile->GetPrefs()->GetString(prefs::kAcceptLanguages); infobar_helper->AddInfoBar( new PepperBrokerInfoBarDelegate( infobar_helper, url, plugin_path, languages, content_settings, callback)); break; } default: NOTREACHED(); } return true; }