Skip to content

Commit

Permalink
Refactor ProtectedMediaIdentifierPermissionContext to derive from Per…
Browse files Browse the repository at this point in the history
…missionContextBase.

Refactoring of ProtectedMediaIdentifierPermissionContext to derive from
PermissionContextBase class to conform with other APIs like geolocation
and midi. This has the advantage of less code and a consistent path for
all permissions. Also it makes it easier to implement PermissionService
because some functionality like HasPermission() can be implemented at
the level of PermissionContextBase.

Also add the corresponding UMA bits in histograms.xml and
permission_context_uma_util.cc.

BUG=

Review URL: https://codereview.chromium.org/769103002

Cr-Commit-Position: refs/heads/master@{#308100}
  • Loading branch information
timvolodine authored and Commit bot committed Dec 12, 2014
1 parent 5a17b56 commit 1baa388
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 251 deletions.
12 changes: 7 additions & 5 deletions chrome/browser/chrome_content_browser_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1915,8 +1915,11 @@ void ChromeContentBrowserClient::RequestPermission(
case content::PERMISSION_PROTECTED_MEDIA:
#if defined(OS_ANDROID)
ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile)
->RequestProtectedMediaIdentifierPermission(
web_contents, requesting_frame, result_callback);
->RequestPermission(web_contents,
request_id,
requesting_frame.GetOrigin(),
user_gesture,
result_callback);
#else
NOTIMPLEMENTED();
#endif
Expand Down Expand Up @@ -2012,8 +2015,7 @@ void ChromeContentBrowserClient::CancelPermissionRequest(
case content::PERMISSION_PROTECTED_MEDIA:
#if defined(OS_ANDROID)
ProtectedMediaIdentifierPermissionContextFactory::GetForProfile(profile)
->CancelProtectedMediaIdentifierPermissionRequests(
render_process_id, render_view_id, requesting_frame);
->CancelPermissionRequest(web_contents, request_id);
#else
NOTIMPLEMENTED();
#endif
Expand All @@ -2039,7 +2041,7 @@ static ContentSettingsType PermissionToContentSetting(
return CONTENT_SETTINGS_TYPE_NOTIFICATIONS;
case content::PERMISSION_GEOLOCATION:
return CONTENT_SETTINGS_TYPE_GEOLOCATION;
#if defined(OS_ANDROID)
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
case content::PERMISSION_PROTECTED_MEDIA:
return CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER;
#endif
Expand Down
4 changes: 4 additions & 0 deletions chrome/browser/content_settings/permission_context_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ PermissionQueueController* PermissionContextBase::GetQueueController() {
return permission_queue_controller_.get();
}

Profile* PermissionContextBase::profile() const {
return profile_;
}

void PermissionContextBase::NotifyPermissionSet(
const PermissionRequestID& id,
const GURL& requesting_origin,
Expand Down
3 changes: 3 additions & 0 deletions chrome/browser/content_settings/permission_context_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class PermissionContextBase : public KeyedService {
// Return an instance of the infobar queue controller, creating it if needed.
PermissionQueueController* GetQueueController();

// Returns the profile associated with this permission context.
Profile* profile() const;

// Store the decided permission as a content setting.
// virtual since the permission might be stored with different restrictions
// (for example for desktop notifications).
Expand Down
15 changes: 12 additions & 3 deletions chrome/browser/content_settings/permission_context_uma_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,14 @@ void RecordPermissionAction(
"ContentSettings.PermissionActionsInsecureOrigin_PushMessaging",
action);
break;
#if defined(OS_ANDROID)
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
// TODO(miguelg): support protected media through
// the generic permission class.
PERMISSION_ACTION_UMA(
secure_origin,
"ContentSettings.PermissionActions_ProtectedMedia",
"ContentSettings.PermissionActionsSecureOrigin_ProtectedMedia",
"ContentSettings.PermissionActionsInsecureOrigin_ProtectedMedia",
action);
break;
#endif
default:
Expand All @@ -105,6 +109,11 @@ void RecordPermissionRequest(
case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
type = content::PERMISSION_PUSH_MESSAGING;
break;
#if defined(OS_ANDROID) || defined(OS_CHROMEOS)
case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
type = content::PERMISSION_PROTECTED_MEDIA;
break;
#endif
default:
NOTREACHED() << "PERMISSION " << permission << " not accounted for";
return;
Expand Down
171 changes: 26 additions & 145 deletions chrome/browser/media/protected_media_identifier_permission_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,12 @@

#include "chrome/browser/media/protected_media_identifier_permission_context.h"

#include <functional>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/permission_request_id.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"

#if defined(ENABLE_EXTENSIONS)
Expand All @@ -34,30 +24,23 @@ using extensions::APIPermission;

ProtectedMediaIdentifierPermissionContext::
ProtectedMediaIdentifierPermissionContext(Profile* profile)
: profile_(profile), shutting_down_(false) {}
: PermissionContextBase(profile,
CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER) {
}

ProtectedMediaIdentifierPermissionContext::
~ProtectedMediaIdentifierPermissionContext() {
// ProtectedMediaIdentifierPermissionContext may be destroyed on either
// the UI thread or the IO thread, but the PermissionQueueController must have
// been destroyed on the UI thread.
DCHECK(!permission_queue_controller_.get());
}

void ProtectedMediaIdentifierPermissionContext::
RequestProtectedMediaIdentifierPermission(
content::WebContents* web_contents,
const GURL& origin,
base::Callback<void(bool)> result_callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (shutting_down_)
return;

int render_process_id = web_contents->GetRenderProcessHost()->GetID();
int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
void ProtectedMediaIdentifierPermissionContext::RequestPermission(
content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame_origin,
bool user_gesture,
const BrowserPermissionCallback& callback) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

const PermissionRequestID id(
render_process_id, render_view_id, 0, origin);
GURL embedder = web_contents->GetLastCommittedURL().GetOrigin();

#if defined(ENABLE_EXTENSIONS)
if (extensions::GetViewType(web_contents) !=
Expand All @@ -67,152 +50,50 @@ void ProtectedMediaIdentifierPermissionContext::
<< "Attempt to use protected media identifier in tabless renderer: "
<< id.ToString()
<< " (can't prompt user without a visible tab)";
NotifyPermissionSet(id, origin, result_callback, false);
NotifyPermissionSet(id, origin, embedder, callback, false, false);
return;
}
#endif

GURL embedder = web_contents->GetLastCommittedURL();
if (!origin.is_valid() || !embedder.is_valid()) {
if (!requesting_frame_origin.is_valid() || !embedder.is_valid()) {
LOG(WARNING)
<< "Attempt to use protected media identifier from an invalid URL: "
<< origin << "," << embedder
<< requesting_frame_origin << "," << embedder
<< " (proteced media identifier is not supported in popups)";
NotifyPermissionSet(id, origin, result_callback, false);
NotifyPermissionSet(id, requesting_frame_origin, embedder,
callback, false, false);
return;
}

content::RenderViewHost* rvh = web_contents->GetRenderViewHost();
DecidePermission(id, origin, embedder, rvh, result_callback);
}

void ProtectedMediaIdentifierPermissionContext::
CancelProtectedMediaIdentifierPermissionRequests(
int render_process_id,
int render_view_id,
const GURL& origin) {
CancelPendingInfobarRequests(
render_process_id, render_view_id, origin);
}

void ProtectedMediaIdentifierPermissionContext::DecidePermission(
const PermissionRequestID& id,
const GURL& origin,
const GURL& embedder,
content::RenderViewHost* rvh,
const base::Callback<void(bool)>& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

#if defined(OS_ANDROID)
// Check if the protected media identifier master switch is disabled.
if (!profile()->GetPrefs()->GetBoolean(
prefs::kProtectedMediaIdentifierEnabled)) {
PermissionDecided(id, origin, embedder, callback, false);
NotifyPermissionSet(id, requesting_frame_origin, embedder, callback,
false, false);
return;
}
#endif

ContentSetting content_setting =
profile_->GetHostContentSettingsMap()->GetContentSetting(
origin,
embedder,
CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
std::string());
switch (content_setting) {
case CONTENT_SETTING_BLOCK:
PermissionDecided(id, origin, embedder, callback, false);
break;
case CONTENT_SETTING_ALLOW:
PermissionDecided(id, origin, embedder, callback, true);
break;
case CONTENT_SETTING_ASK:
QueueController()->CreateInfoBarRequest(
id,
origin,
embedder,
base::Bind(&ProtectedMediaIdentifierPermissionContext::
NotifyPermissionSet,
base::Unretained(this),
id,
origin,
callback));
break;
default:
NOTREACHED();
}
}

void ProtectedMediaIdentifierPermissionContext::ShutdownOnUIThread() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
permission_queue_controller_.reset();
shutting_down_ = true;
PermissionContextBase::RequestPermission(web_contents, id,
requesting_frame_origin,
user_gesture,
callback);
}

void ProtectedMediaIdentifierPermissionContext::PermissionDecided(
void ProtectedMediaIdentifierPermissionContext::UpdateTabContext(
const PermissionRequestID& id,
const GURL& origin,
const GURL& embedder,
const base::Callback<void(bool)>& callback,
const GURL& requesting_frame,
bool allowed) {
NotifyPermissionSet(id, origin, callback, allowed);
}

void ProtectedMediaIdentifierPermissionContext::NotifyPermissionSet(
const PermissionRequestID& id,
const GURL& origin,
const base::Callback<void(bool)>& callback,
bool allowed) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

// WebContents may have gone away.
TabSpecificContentSettings* content_settings =
TabSpecificContentSettings::Get(id.render_process_id(),
id.render_view_id());
if (content_settings) {
content_settings->OnProtectedMediaIdentifierPermissionSet(
origin.GetOrigin(), allowed);
requesting_frame.GetOrigin(), allowed);
}

callback.Run(allowed);
}

PermissionQueueController*
ProtectedMediaIdentifierPermissionContext::QueueController() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!shutting_down_);
if (!permission_queue_controller_)
permission_queue_controller_.reset(CreateQueueController());
return permission_queue_controller_.get();
}

PermissionQueueController*
ProtectedMediaIdentifierPermissionContext::CreateQueueController() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
return new PermissionQueueController(
profile(), CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER);
}

void
ProtectedMediaIdentifierPermissionContext::CancelPendingInfobarRequests(
int render_process_id,
int render_view_id,
const GURL& origin) {
if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
content::BrowserThread::PostTask(
content::BrowserThread::UI,
FROM_HERE,
base::Bind(&ProtectedMediaIdentifierPermissionContext::
CancelPendingInfobarRequests,
this,
render_process_id,
render_view_id,
origin));
return;
}
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (shutting_down_)
return;
QueueController()->CancelInfoBarRequest(
PermissionRequestID(render_process_id, render_view_id, 0,
origin));
}
Loading

0 comments on commit 1baa388

Please sign in to comment.