Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / protected_media_identifier_permission_context.cc
1 // Copyright 2013 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/media/protected_media_identifier_permission_context.h"
6
7 #include <functional>
8 #include <string>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/tab_contents/tab_util.h"
17 #include "chrome/common/pref_names.h"
18 #include "components/content_settings/core/browser/host_content_settings_map.h"
19 #include "components/content_settings/core/common/permission_request_id.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/render_process_host.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24
25 #if defined(ENABLE_EXTENSIONS)
26 #include "chrome/browser/extensions/extension_service.h"
27 #include "extensions/browser/extension_system.h"
28 #include "extensions/browser/suggest_permission_util.h"
29 #include "extensions/browser/view_type_utils.h"
30 #include "extensions/common/extension.h"
31
32 using extensions::APIPermission;
33 #endif
34
35 ProtectedMediaIdentifierPermissionContext::
36     ProtectedMediaIdentifierPermissionContext(Profile* profile)
37     : profile_(profile), shutting_down_(false) {}
38
39 ProtectedMediaIdentifierPermissionContext::
40     ~ProtectedMediaIdentifierPermissionContext() {
41   // ProtectedMediaIdentifierPermissionContext may be destroyed on either
42   // the UI thread or the IO thread, but the PermissionQueueController must have
43   // been destroyed on the UI thread.
44   DCHECK(!permission_queue_controller_.get());
45 }
46
47 void ProtectedMediaIdentifierPermissionContext::
48     RequestProtectedMediaIdentifierPermission(
49         content::WebContents* web_contents,
50         const GURL& origin,
51         base::Callback<void(bool)> result_callback) {
52   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
53   if (shutting_down_)
54     return;
55
56   int render_process_id = web_contents->GetRenderProcessHost()->GetID();
57   int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
58
59   const PermissionRequestID id(
60       render_process_id, render_view_id, 0, origin);
61
62 #if defined(ENABLE_EXTENSIONS)
63   if (extensions::GetViewType(web_contents) !=
64       extensions::VIEW_TYPE_TAB_CONTENTS) {
65     // The tab may have gone away, or the request may not be from a tab at all.
66     LOG(WARNING)
67         << "Attempt to use protected media identifier in tabless renderer: "
68         << id.ToString()
69         << " (can't prompt user without a visible tab)";
70     NotifyPermissionSet(id, origin, result_callback, false);
71     return;
72   }
73 #endif
74
75   GURL embedder = web_contents->GetLastCommittedURL();
76   if (!origin.is_valid() || !embedder.is_valid()) {
77     LOG(WARNING)
78         << "Attempt to use protected media identifier from an invalid URL: "
79         << origin << "," << embedder
80         << " (proteced media identifier is not supported in popups)";
81     NotifyPermissionSet(id, origin, result_callback, false);
82     return;
83   }
84
85   content::RenderViewHost* rvh = web_contents->GetRenderViewHost();
86   DecidePermission(id, origin, embedder, rvh, result_callback);
87 }
88
89 void ProtectedMediaIdentifierPermissionContext::
90     CancelProtectedMediaIdentifierPermissionRequests(
91         int render_process_id,
92         int render_view_id,
93         const GURL& origin) {
94   CancelPendingInfobarRequests(
95       render_process_id, render_view_id, origin);
96 }
97
98 void ProtectedMediaIdentifierPermissionContext::DecidePermission(
99     const PermissionRequestID& id,
100     const GURL& origin,
101     const GURL& embedder,
102     content::RenderViewHost* rvh,
103     const base::Callback<void(bool)>& callback) {
104   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
105
106 #if defined(OS_ANDROID)
107   // Check if the protected media identifier master switch is disabled.
108   if (!profile()->GetPrefs()->GetBoolean(
109         prefs::kProtectedMediaIdentifierEnabled)) {
110     PermissionDecided(id, origin, embedder, callback, false);
111     return;
112   }
113 #endif
114
115   ContentSetting content_setting =
116      profile_->GetHostContentSettingsMap()->GetContentSetting(
117           origin,
118           embedder,
119           CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
120           std::string());
121   switch (content_setting) {
122     case CONTENT_SETTING_BLOCK:
123       PermissionDecided(id, origin, embedder, callback, false);
124       break;
125     case CONTENT_SETTING_ALLOW:
126       PermissionDecided(id, origin, embedder, callback, true);
127       break;
128     case CONTENT_SETTING_ASK:
129       QueueController()->CreateInfoBarRequest(
130           id,
131           origin,
132           embedder,
133           base::Bind(&ProtectedMediaIdentifierPermissionContext::
134                           NotifyPermissionSet,
135                      base::Unretained(this),
136                      id,
137                      origin,
138                      callback));
139       break;
140     default:
141       NOTREACHED();
142   }
143 }
144
145 void ProtectedMediaIdentifierPermissionContext::ShutdownOnUIThread() {
146   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
147   permission_queue_controller_.reset();
148   shutting_down_ = true;
149 }
150
151 void ProtectedMediaIdentifierPermissionContext::PermissionDecided(
152     const PermissionRequestID& id,
153     const GURL& origin,
154     const GURL& embedder,
155     const base::Callback<void(bool)>& callback,
156     bool allowed) {
157   NotifyPermissionSet(id, origin, callback, allowed);
158 }
159
160 void ProtectedMediaIdentifierPermissionContext::NotifyPermissionSet(
161     const PermissionRequestID& id,
162     const GURL& origin,
163     const base::Callback<void(bool)>& callback,
164     bool allowed) {
165   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
166
167   // WebContents may have gone away.
168   TabSpecificContentSettings* content_settings =
169       TabSpecificContentSettings::Get(id.render_process_id(),
170                                       id.render_view_id());
171   if (content_settings) {
172     content_settings->OnProtectedMediaIdentifierPermissionSet(
173         origin.GetOrigin(), allowed);
174   }
175
176   callback.Run(allowed);
177 }
178
179 PermissionQueueController*
180     ProtectedMediaIdentifierPermissionContext::QueueController() {
181   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
182   DCHECK(!shutting_down_);
183   if (!permission_queue_controller_)
184     permission_queue_controller_.reset(CreateQueueController());
185   return permission_queue_controller_.get();
186 }
187
188 PermissionQueueController*
189     ProtectedMediaIdentifierPermissionContext::CreateQueueController() {
190   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
191   return new PermissionQueueController(
192       profile(), CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
193 }
194
195 void
196 ProtectedMediaIdentifierPermissionContext::CancelPendingInfobarRequests(
197     int render_process_id,
198     int render_view_id,
199     const GURL& origin) {
200   if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
201     content::BrowserThread::PostTask(
202         content::BrowserThread::UI,
203         FROM_HERE,
204         base::Bind(&ProtectedMediaIdentifierPermissionContext::
205                         CancelPendingInfobarRequests,
206                    this,
207                    render_process_id,
208                    render_view_id,
209                    origin));
210     return;
211   }
212   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
213   if (shutting_down_)
214     return;
215   QueueController()->CancelInfoBarRequest(
216       PermissionRequestID(render_process_id, render_view_id, 0,
217                           origin));
218 }