b705fcae6e82dbc808449f94652f3ed2fec1db0c
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / chrome_midi_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/chrome_midi_permission_context.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/permission_queue_controller.h"
10 #include "chrome/browser/content_settings/permission_request_id.h"
11 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/tab_contents/tab_util.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/web_contents.h"
16
17 ChromeMIDIPermissionContext::ChromeMIDIPermissionContext(Profile* profile)
18     : profile_(profile),
19       shutting_down_(false) {
20   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
21 }
22
23 ChromeMIDIPermissionContext::~ChromeMIDIPermissionContext() {
24   DCHECK(!permission_queue_controller_);
25   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
26 }
27
28 void ChromeMIDIPermissionContext::Shutdown() {
29   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
30   permission_queue_controller_.reset();
31   shutting_down_ = true;
32 }
33
34 void ChromeMIDIPermissionContext::RequestMIDISysExPermission(
35     int render_process_id,
36     int render_view_id,
37     int bridge_id,
38     const GURL& requesting_frame,
39     const content::BrowserContext::MIDISysExPermissionCallback& callback) {
40   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
41   DCHECK(!shutting_down_);
42
43   // TODO(toyoshim): Support Extension's manifest declared permission.
44   // http://crbug.com/266338 .
45
46   content::WebContents* web_contents =
47     tab_util::GetWebContentsByID(render_process_id, render_view_id);
48
49   // The page doesn't exist any more.
50   if (!web_contents)
51     return;
52
53   const PermissionRequestID id(render_process_id, render_view_id, bridge_id, 0);
54
55   GURL embedder = web_contents->GetURL();
56   // |requesting_frame| can be empty and invalid when the frame is a local
57   // file. Here local files should be granted to show an infobar.
58   // Any user's action will not be stored to content settings data base.
59   if ((!requesting_frame.is_valid() && !requesting_frame.is_empty()) ||
60       !embedder.is_valid()) {
61     LOG(WARNING) << "Attempt to use MIDI sysex from an invalid URL: "
62                  << requesting_frame << "," << embedder
63                  << " (Web MIDI is not supported in popups)";
64     PermissionDecided(id, requesting_frame, embedder, callback, false);
65     return;
66   }
67
68   DecidePermission(id, requesting_frame, embedder, callback);
69 }
70
71 void ChromeMIDIPermissionContext::CancelMIDISysExPermissionRequest(
72     int render_process_id,
73     int render_view_id,
74     int bridge_id,
75     const GURL& requesting_frame) {
76   CancelPendingInfobarRequest(
77       PermissionRequestID(render_process_id, render_view_id, bridge_id, 0));
78 }
79
80 void ChromeMIDIPermissionContext::DecidePermission(
81     const PermissionRequestID& id,
82     const GURL& requesting_frame,
83     const GURL& embedder,
84     const content::BrowserContext::MIDISysExPermissionCallback& callback) {
85   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
86
87   ContentSetting content_setting =
88       profile_->GetHostContentSettingsMap()->GetContentSetting(
89           requesting_frame,
90           embedder,
91           CONTENT_SETTINGS_TYPE_MIDI_SYSEX,
92           std::string());
93   switch (content_setting) {
94     case CONTENT_SETTING_BLOCK:
95       PermissionDecided(id, requesting_frame, embedder, callback, false);
96       break;
97     case CONTENT_SETTING_ALLOW:
98       PermissionDecided(id, requesting_frame, embedder, callback, true);
99       break;
100     default:
101       GetQueueController()->CreateInfoBarRequest(
102           id, requesting_frame, embedder, base::Bind(
103               &ChromeMIDIPermissionContext::NotifyPermissionSet,
104               base::Unretained(this), id, requesting_frame, callback));
105   }
106 }
107
108 void ChromeMIDIPermissionContext::PermissionDecided(
109     const PermissionRequestID& id,
110     const GURL& requesting_frame,
111     const GURL& embedder,
112     const content::BrowserContext::MIDISysExPermissionCallback& callback,
113     bool allowed) {
114   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
115   NotifyPermissionSet(id, requesting_frame, callback, allowed);
116 }
117
118 void ChromeMIDIPermissionContext::NotifyPermissionSet(
119     const PermissionRequestID& id,
120     const GURL& requesting_frame,
121     const content::BrowserContext::MIDISysExPermissionCallback& callback,
122     bool allowed) {
123   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
124
125   TabSpecificContentSettings* content_settings =
126       TabSpecificContentSettings::Get(id.render_process_id(),
127                                       id.render_view_id());
128   if (content_settings) {
129     if (allowed)
130       content_settings->OnMIDISysExAccessed(requesting_frame);
131     else
132       content_settings->OnMIDISysExAccessBlocked(requesting_frame);
133   }
134
135   callback.Run(allowed);
136 }
137
138 PermissionQueueController* ChromeMIDIPermissionContext::GetQueueController() {
139   if (!permission_queue_controller_) {
140     permission_queue_controller_.reset(
141         new PermissionQueueController(profile_,
142                                       CONTENT_SETTINGS_TYPE_MIDI_SYSEX));
143   }
144   return permission_queue_controller_.get();
145 }
146
147 void ChromeMIDIPermissionContext::CancelPendingInfobarRequest(
148     const PermissionRequestID& id) {
149   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
150   if (shutting_down_)
151     return;
152   GetQueueController()->CancelInfoBarRequest(id);
153 }