• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/pepper_broker_infobar_delegate.h"
6 
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/content_settings/host_content_settings_map.h"
9 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
10 #include "chrome/browser/infobars/infobar.h"
11 #include "chrome/browser/infobars/infobar_service.h"
12 #include "chrome/browser/plugins/plugin_finder.h"
13 #include "chrome/browser/plugins/plugin_metadata.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/pref_names.h"
16 #include "content/public/browser/page_navigator.h"
17 #include "content/public/browser/plugin_service.h"
18 #include "content/public/browser/user_metrics.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/referrer.h"
21 #include "content/public/common/webplugininfo.h"
22 #include "grit/generated_resources.h"
23 #include "grit/theme_resources.h"
24 #include "net/base/net_util.h"
25 #include "ui/base/l10n/l10n_util.h"
26 
27 #if defined(GOOGLE_TV)
28 #include "base/android/context_types.h"
29 #endif
30 
31 
32 // static
Create(content::WebContents * web_contents,const GURL & url,const base::FilePath & plugin_path,const base::Callback<void (bool)> & callback)33 void PepperBrokerInfoBarDelegate::Create(
34     content::WebContents* web_contents,
35     const GURL& url,
36     const base::FilePath& plugin_path,
37     const base::Callback<void(bool)>& callback) {
38   Profile* profile =
39       Profile::FromBrowserContext(web_contents->GetBrowserContext());
40   // TODO(wad): Add ephemeral device ID support for broker in guest mode.
41   if (profile->IsGuestSession()) {
42     callback.Run(false);
43     return;
44   }
45 
46   TabSpecificContentSettings* tab_content_settings =
47       TabSpecificContentSettings::FromWebContents(web_contents);
48 
49 #if defined(OS_CHROMEOS)
50   // On ChromeOS, we're ok with granting broker access to the Netflix and
51   // Widevine plugins, since they can only come installed with the OS.
52   const char kWidevinePluginFileName[] = "libwidevinecdmadapter.so";
53   const char kNetflixDomain[] = "netflix.com";
54 
55   base::FilePath plugin_file_name = plugin_path.BaseName();
56   if (plugin_file_name.value() == FILE_PATH_LITERAL(kWidevinePluginFileName) &&
57       url.DomainIs(kNetflixDomain)) {
58     tab_content_settings->SetPepperBrokerAllowed(true);
59     callback.Run(true);
60     return;
61   }
62 #endif
63 
64 #if defined(GOOGLE_TV)
65   // On GoogleTV, Netflix crypto/mdx plugin and DRM server adapter plugin can
66   // only come pre-installed with the OS, so we're willing to auto-grant access
67   // to them. PluginRootName should be matched with PEPPER_PLUGIN_ROOT
68   // in PepperPluginManager.java.
69   const char kPluginRootName[] = "/system/lib/pepperplugin";
70   const char kNetflixCryptoPluginFileName[] = "libnrddpicrypto.so";
71   const char kNetflixMdxPluginFileName[] = "libnrdmdx.so";
72   const char kDrmServerAdapterPluginFileName[] = "libdrmserveradapter.so";
73   base::FilePath::StringType plugin_dir_name = plugin_path.DirName().value();
74   base::FilePath::StringType plugin_file_name = plugin_path.BaseName().value();
75   if (base::android::IsRunningInWebapp() &&
76       plugin_dir_name == FILE_PATH_LITERAL(kPluginRootName) &&
77       (plugin_file_name == FILE_PATH_LITERAL(kNetflixCryptoPluginFileName) ||
78        plugin_file_name == FILE_PATH_LITERAL(kNetflixMdxPluginFileName) ||
79        plugin_file_name ==
80           FILE_PATH_LITERAL(kDrmServerAdapterPluginFileName))) {
81     tab_content_settings->SetPepperBrokerAllowed(true);
82     callback.Run(true);
83     return;
84   }
85 #endif
86 
87   HostContentSettingsMap* content_settings =
88       profile->GetHostContentSettingsMap();
89   ContentSetting setting =
90       content_settings->GetContentSetting(url, url,
91                                           CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
92                                           std::string());
93 
94   if (setting == CONTENT_SETTING_ASK) {
95     content::RecordAction(
96         content::UserMetricsAction("PPAPI.BrokerInfobarDisplayed"));
97     InfoBarService* infobar_service =
98         InfoBarService::FromWebContents(web_contents);
99     infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
100         scoped_ptr<ConfirmInfoBarDelegate>(new PepperBrokerInfoBarDelegate(
101             url, plugin_path,
102             profile->GetPrefs()->GetString(prefs::kAcceptLanguages),
103             content_settings, tab_content_settings, callback))));
104     return;
105   }
106 
107   bool allowed = (setting == CONTENT_SETTING_ALLOW);
108   content::RecordAction(allowed ?
109       content::UserMetricsAction("PPAPI.BrokerSettingAllow") :
110       content::UserMetricsAction("PPAPI.BrokerSettingDeny"));
111   tab_content_settings->SetPepperBrokerAllowed(allowed);
112   callback.Run(allowed);
113 }
114 
PepperBrokerInfoBarDelegate(const GURL & url,const base::FilePath & plugin_path,const std::string & languages,HostContentSettingsMap * content_settings,TabSpecificContentSettings * tab_content_settings,const base::Callback<void (bool)> & callback)115 PepperBrokerInfoBarDelegate::PepperBrokerInfoBarDelegate(
116     const GURL& url,
117     const base::FilePath& plugin_path,
118     const std::string& languages,
119     HostContentSettingsMap* content_settings,
120     TabSpecificContentSettings* tab_content_settings,
121     const base::Callback<void(bool)>& callback)
122     : ConfirmInfoBarDelegate(),
123       url_(url),
124       plugin_path_(plugin_path),
125       languages_(languages),
126       content_settings_(content_settings),
127       tab_content_settings_(tab_content_settings),
128       callback_(callback) {
129 }
130 
~PepperBrokerInfoBarDelegate()131 PepperBrokerInfoBarDelegate::~PepperBrokerInfoBarDelegate() {
132   if (!callback_.is_null())
133     callback_.Run(false);
134 }
135 
GetIconID() const136 int PepperBrokerInfoBarDelegate::GetIconID() const {
137   return IDR_INFOBAR_PLUGIN_INSTALL;
138 }
139 
GetMessageText() const140 base::string16 PepperBrokerInfoBarDelegate::GetMessageText() const {
141   content::PluginService* plugin_service =
142       content::PluginService::GetInstance();
143   content::WebPluginInfo plugin;
144   bool success = plugin_service->GetPluginInfoByPath(plugin_path_, &plugin);
145   DCHECK(success);
146   scoped_ptr<PluginMetadata> plugin_metadata(
147       PluginFinder::GetInstance()->GetPluginMetadata(plugin));
148   return l10n_util::GetStringFUTF16(IDS_PEPPER_BROKER_MESSAGE,
149                                     plugin_metadata->name(),
150                                     net::FormatUrl(url_.GetOrigin(),
151                                                    languages_));
152 }
153 
GetButtonLabel(InfoBarButton button) const154 base::string16 PepperBrokerInfoBarDelegate::GetButtonLabel(
155     InfoBarButton button) const {
156   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
157       IDS_PEPPER_BROKER_ALLOW_BUTTON : IDS_PEPPER_BROKER_DENY_BUTTON);
158 }
159 
Accept()160 bool PepperBrokerInfoBarDelegate::Accept() {
161   DispatchCallback(true);
162   return true;
163 }
164 
Cancel()165 bool PepperBrokerInfoBarDelegate::Cancel() {
166   DispatchCallback(false);
167   return true;
168 }
169 
GetLinkText() const170 base::string16 PepperBrokerInfoBarDelegate::GetLinkText() const {
171   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
172 }
173 
LinkClicked(WindowOpenDisposition disposition)174 bool PepperBrokerInfoBarDelegate::LinkClicked(
175     WindowOpenDisposition disposition) {
176   GURL learn_more_url("https://support.google.com/chrome/?p=ib_pepper_broker");
177   web_contents()->OpenURL(content::OpenURLParams(
178       learn_more_url, content::Referrer(),
179       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
180       content::PAGE_TRANSITION_LINK, false));
181   return false;
182 }
183 
DispatchCallback(bool result)184 void PepperBrokerInfoBarDelegate::DispatchCallback(bool result) {
185   content::RecordAction(result ?
186       content::UserMetricsAction("PPAPI.BrokerInfobarClickedAllow") :
187       content::UserMetricsAction("PPAPI.BrokerInfobarClickedDeny"));
188   callback_.Run(result);
189   callback_ = base::Callback<void(bool)>();
190   content_settings_->SetContentSetting(
191       ContentSettingsPattern::FromURLNoWildcard(url_),
192       ContentSettingsPattern::Wildcard(),
193       CONTENT_SETTINGS_TYPE_PPAPI_BROKER,
194       std::string(), result ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
195   tab_content_settings_->SetPepperBrokerAllowed(result);
196 }
197