1f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// found in the LICENSE file.
4f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/media/midi_dispatcher_host.h"
6f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
7f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/bind.h"
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/browser/frame_host/render_frame_host_impl.h"
10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/common/media/midi_messages.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/browser_context.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/content_browser_client.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/web_contents.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "url/gurl.h"
18f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
19f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)namespace content {
20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
21f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MidiDispatcherHost::PendingPermission::PendingPermission(
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_process_id,
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int render_frame_id,
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int bridge_id)
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : render_process_id(render_process_id),
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_frame_id(render_frame_id),
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bridge_id(bridge_id) {
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MidiDispatcherHost::PendingPermission::~PendingPermission() {
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MidiDispatcherHost::MidiDispatcherHost(WebContents* web_contents)
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    : WebContentsObserver(web_contents),
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      weak_factory_(this) {
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MidiDispatcherHost::~MidiDispatcherHost() {
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool MidiDispatcherHost::OnMessageReceived(const IPC::Message& message,
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                           RenderFrameHost* render_frame_host) {
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool handled = true;
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(MidiDispatcherHost, message,
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                   render_frame_host)
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(MidiHostMsg_RequestSysExPermission,
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnRequestSysExPermission)
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(MidiHostMsg_CancelSysExPermissionRequest,
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnCancelSysExPermissionRequest)
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return handled;
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void MidiDispatcherHost::OnRequestSysExPermission(
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RenderFrameHost* render_frame_host,
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int bridge_id,
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const GURL& origin,
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool user_gesture) {
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_process_id = render_frame_host->GetProcess()->GetID();
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_frame_id = render_frame_host->GetRoutingID();
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PendingPermission pending_permission(
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      render_process_id, render_frame_id, bridge_id);
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  pending_permissions_.push_back(pending_permission);
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetContentClient()->browser()->RequestMidiSysExPermission(
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      web_contents(),
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      bridge_id,
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      origin,
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      user_gesture,
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&MidiDispatcherHost::WasSysExPermissionGranted,
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 render_process_id, render_frame_id, bridge_id),
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      &pending_permissions_.back().cancel);
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void MidiDispatcherHost::OnCancelSysExPermissionRequest(
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    RenderFrameHost* render_frame_host,
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    int bridge_id,
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const GURL& requesting_frame) {
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_process_id = render_frame_host->GetProcess()->GetID();
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int render_frame_id = render_frame_host->GetRoutingID();
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < pending_permissions_.size(); ++i) {
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pending_permissions_[i].render_process_id == render_process_id &&
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].render_frame_id == render_frame_id &&
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].bridge_id == bridge_id) {
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (!pending_permissions_[i].cancel.is_null())
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].cancel.Run();
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_permissions_.erase(pending_permissions_.begin() + i);
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void MidiDispatcherHost::WasSysExPermissionGranted(int render_process_id,
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                   int render_frame_id,
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                   int bridge_id,
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                   bool is_allowed) {
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  for (size_t i = 0; i < pending_permissions_.size(); ++i) {
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (pending_permissions_[i].render_process_id == render_process_id &&
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].render_frame_id == render_frame_id &&
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        pending_permissions_[i].bridge_id == bridge_id) {
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      RenderFrameHost* render_frame_host =
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          RenderFrameHost::FromID(render_process_id, render_frame_id);
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (render_frame_host) {
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        render_frame_host->Send(new MidiMsg_SysExPermissionApproved(
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            render_frame_id, bridge_id, is_allowed));
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (is_allowed) {
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        ChildProcessSecurityPolicyImpl::GetInstance()->
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            GrantSendMidiSysExMessage(render_process_id);
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      }
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      pending_permissions_.erase(pending_permissions_.begin() + i);
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      return;
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}  // namespace content
124