Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: media/base/android/dialog_surface_callback.cc

Issue 1967553002: DO NOT COMMIT - DialogSurface initial implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "media/base/android/dialog_surface_callback.h"
6
7 #include <algorithm>
8 #include <limits>
9 #include <map>
10 #include <memory>
11 #include <utility>
12
13 #include "base/android/build_info.h"
14 #include "base/android/jni_android.h"
15 #include "base/android/jni_array.h"
16 #include "base/android/jni_string.h"
17 #include "base/bind.h"
18 #include "base/lazy_instance.h"
19 #include "base/location.h"
20 #include "base/logging.h"
21 #include "base/numerics/safe_conversions.h"
22 #include "base/strings/string_util.h"
23 #include "base/synchronization/lock.h"
24 #include "base/synchronization/waitable_event.h"
25 #include "base/threading/thread_task_runner_handle.h"
26 #include "jni/DialogSurfaceCallback_jni.h"
27
28 using base::android::AttachCurrentThread;
29
30 namespace media {
31
32 static long next_id_ = 1;
33
34 // Map of ids to DialogSurfaceCallbacks. This is called from multiple threads.
35 class DialogCallbackMap {
36 public:
37 // Associate |thiz| with |id|.
38 void Insert(long id, DialogSurfaceCallback* thiz) {
39 base::AutoLock _l(lock_);
40 map_[id] = thiz;
41 }
42
43 // Forget about |id|.
44 void Erase(long id) {
45 base::AutoLock _l(lock_);
46 map_.erase(id);
47 }
48
49 // Return the associated callback for |id|, or null.
50 DialogSurfaceCallback* Lookup(long id) {
51 base::AutoLock _l(lock_);
52 return LookupLocked(id);
53 }
54
55 // Map |id| to the correct task runner for callbacks, or null.
56 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(long id) {
57 scoped_refptr<base::SingleThreadTaskRunner> task_runner;
58 base::AutoLock _l(lock_);
59 DialogSurfaceCallback* thiz = LookupLocked(id);
60 // While under lock, |thiz| cannot be removed from the map.
61 if (thiz)
62 task_runner = thiz->GetTaskRunner();
63
64 return task_runner;
65 }
66
67 private:
68 // Lookup |id|. The caller must hold |lock_|.
69 DialogSurfaceCallback* LookupLocked(long id) {
70 DialogSurfaceCallback* thiz = nullptr;
71 Map::const_iterator it = map_.find(id);
72 if (it != map_.end())
73 thiz = it->second;
74
75 return thiz;
76 }
77
78 // Alternatively, we could put in a callback that is bound to the correct
79 // thread, and use a weak ref. However, since we still need a default
80 // action when the weak ref is cleared to unblock the callback, it ends up
81 // not being any simpler.
82 using Map = std::map<long, DialogSurfaceCallback*>;
83 Map map_;
84
85 base::Lock lock_;
86 };
87
88 static base::LazyInstance<DialogCallbackMap>::Leaky g_map =
89 LAZY_INSTANCE_INITIALIZER;
90
91 DialogSurfaceCallback::DialogSurfaceCallback(
92 const DialogSurface::Callback& callback)
93 : task_runner_(base::ThreadTaskRunnerHandle::Get()),
94 id_(next_id_++),
95 callback_(callback) {
96 JNIEnv* env = AttachCurrentThread();
97 CHECK(env);
98 j_surface_callback_.Reset(Java_DialogSurfaceCallback_create(env, id_));
99 g_map.Pointer()->Insert(id_, this);
100 }
101
102 DialogSurfaceCallback::~DialogSurfaceCallback() {
103 DCHECK(thread_checker_.CalledOnValidThread());
104 g_map.Pointer()->Erase(id_);
105 }
106
107 bool DialogSurfaceCallback::RegisterDialogSurfaceCallback(JNIEnv* env) {
108 return RegisterNativesImpl(env);
109 }
110
111 scoped_refptr<base::SingleThreadTaskRunner>
112 DialogSurfaceCallback::GetTaskRunner() const {
113 // May be called on any thread.
114 return task_runner_;
115 }
116
117 bool DialogSurfaceCallback::CalledOnValidThread() const {
118 return thread_checker_.CalledOnValidThread();
119 }
120
121 void DialogSurfaceCallback::OnCallbackProperThread(
122 long id,
123 DialogSurface::CallbackOp what,
124 base::WaitableEvent* event) {
125 // A callback has happened on some other thread. We're run on the correct
126 // thread in response to it.
127 DialogSurfaceCallback* thiz = g_map.Pointer()->Lookup(id);
128 // |thiz| cannot be deleted here, since we're on the main thread. However,
129 // it might have been deleted earlier, so it can be null.
130
131 if (thiz) {
132 DCHECK(thiz->CalledOnValidThread());
133 thiz->callback_.Run(what);
134 }
135
136 // If this is a synchronous callback, then signal that we've completed.
137 if (event)
138 event->Signal();
139 }
140
141 void OnDialogSurfaceCallbackCallback(JNIEnv* env,
142 const JavaParamRef<jclass>& jcaller,
143 jlong id,
144 jint what) {
145 // Post back to the main thread. We get a strong ref here to the task
146 // runner, so that it's okay if the controller is deleted. Holding the
147 // lock during the callback is not safe; the caller might require it to
148 // complete the callback.
149 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
150 g_map.Pointer()->GetTaskRunner(id);
151
152 if (task_runner) {
153 // TODO(liberato): check the thread, and just call if needed. That way,
154 // we'll work regardless of how the java classes handle threading.
155 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
156 base::WaitableEvent::InitialState::NOT_SIGNALED);
157 base::Closure cb =
158 base::Bind(&DialogSurfaceCallback::OnCallbackProperThread, id,
159 static_cast<DialogSurface::CallbackOp>(what), &event);
160 task_runner->PostTask(FROM_HERE, cb);
161 event.Wait();
162 }
163 }
164
165 } // namespace media
OLDNEW
« no previous file with comments | « media/base/android/dialog_surface_callback.h ('k') | media/base/android/dialog_surface_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698