Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / child / permissions / permission_dispatcher_thread_proxy.cc
blob0ecdfa48a8d67654ae985a75db97a1c79dfee993
1 // Copyright 2015 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.
5 #include "content/child/permissions/permission_dispatcher_thread_proxy.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/lazy_instance.h"
10 #include "base/location.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/threading/thread_local.h"
13 #include "content/child/permissions/permission_dispatcher.h"
14 #include "content/child/worker_task_runner.h"
15 #include "third_party/WebKit/public/platform/WebURL.h"
16 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionObserver.h"
18 using base::LazyInstance;
19 using base::ThreadLocalPointer;
21 namespace content {
23 namespace {
25 LazyInstance<ThreadLocalPointer<PermissionDispatcherThreadProxy>>::Leaky
26 g_permission_dispatcher_tls = LAZY_INSTANCE_INITIALIZER;
28 } // anonymous namespace
30 PermissionDispatcherThreadProxy*
31 PermissionDispatcherThreadProxy::GetThreadInstance(
32 base::SingleThreadTaskRunner* main_thread_task_runner,
33 PermissionDispatcher* permission_dispatcher) {
34 if (g_permission_dispatcher_tls.Pointer()->Get())
35 return g_permission_dispatcher_tls.Pointer()->Get();
37 PermissionDispatcherThreadProxy* instance =
38 new PermissionDispatcherThreadProxy(main_thread_task_runner,
39 permission_dispatcher);
40 DCHECK(WorkerTaskRunner::Instance()->CurrentWorkerId());
41 WorkerTaskRunner::Instance()->AddStopObserver(instance);
42 return instance;
45 PermissionDispatcherThreadProxy::PermissionDispatcherThreadProxy(
46 base::SingleThreadTaskRunner* main_thread_task_runner,
47 PermissionDispatcher* permission_dispatcher)
48 : main_thread_task_runner_(main_thread_task_runner),
49 permission_dispatcher_(permission_dispatcher) {
50 g_permission_dispatcher_tls.Pointer()->Set(this);
53 PermissionDispatcherThreadProxy::~PermissionDispatcherThreadProxy() {
54 g_permission_dispatcher_tls.Pointer()->Set(nullptr);
57 void PermissionDispatcherThreadProxy::queryPermission(
58 blink::WebPermissionType type,
59 const blink::WebURL& origin,
60 blink::WebPermissionQueryCallback* callback) {
61 main_thread_task_runner_->PostTask(
62 FROM_HERE,
63 base::Bind(&PermissionDispatcher::QueryPermissionForWorker,
64 base::Unretained(permission_dispatcher_),
65 type,
66 origin.string().utf8(),
67 base::Unretained(callback),
68 WorkerTaskRunner::Instance()->CurrentWorkerId()));
71 void PermissionDispatcherThreadProxy::startListening(
72 blink::WebPermissionType type,
73 const blink::WebURL& origin,
74 blink::WebPermissionObserver* observer) {
75 if (!PermissionDispatcher::IsObservable(type))
76 return;
78 RegisterObserver(observer);
80 main_thread_task_runner_->PostTask(FROM_HERE,
81 base::Bind(&PermissionDispatcher::StartListeningForWorker,
82 base::Unretained(permission_dispatcher_),
83 type,
84 origin.string().utf8(),
85 WorkerTaskRunner::Instance()->CurrentWorkerId(),
86 base::Bind(&PermissionDispatcherThreadProxy::OnPermissionChanged,
87 base::Unretained(this),
88 type,
89 origin.string().utf8(),
90 base::Unretained(observer))));
93 void PermissionDispatcherThreadProxy::stopListening(
94 blink::WebPermissionObserver* observer) {
95 UnregisterObserver(observer);
98 void PermissionDispatcherThreadProxy::OnPermissionChanged(
99 blink::WebPermissionType type,
100 const std::string& origin,
101 blink::WebPermissionObserver* observer,
102 blink::WebPermissionStatus status) {
103 if (!IsObserverRegistered(observer))
104 return;
106 observer->permissionChanged(type, status);
108 main_thread_task_runner_->PostTask(FROM_HERE,
109 base::Bind(&PermissionDispatcher::GetNextPermissionChangeForWorker,
110 base::Unretained(permission_dispatcher_),
111 type,
112 origin,
113 status,
114 WorkerTaskRunner::Instance()->CurrentWorkerId(),
115 base::Bind(&PermissionDispatcherThreadProxy::OnPermissionChanged,
116 base::Unretained(this),
117 type,
118 origin,
119 base::Unretained(observer))));
122 void PermissionDispatcherThreadProxy::OnWorkerRunLoopStopped() {
123 delete this;
126 } // namespace content