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

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

Issue 2178973004: DialogSurfaceManager implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: cleanup Created 3 years, 10 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/android_overlay_callback.h"
6
7 #include <map>
8
9 #include "base/android/jni_android.h"
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/synchronization/lock.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "jni/AndroidOverlayCallback_jni.h"
16
17 using base::android::AttachCurrentThread;
18
19 namespace media {
20
21 static long next_id_ = 1;
22
23 scoped_refptr<base::SingleThreadTaskRunner>
24 AndroidOverlayCallback::task_runner_;
25
26 // Map of ids to AndroidOverlayCallbacks. This is called from multiple threads.
27 class AndroidOverlayCallbackmap {
28 public:
29 // Associate |thiz| with |id| from any thread.
30 void Insert(long id, AndroidOverlayCallback* thiz) {
31 base::AutoLock _l(lock_);
32 DCHECK(map_.find(id) == map_.end());
33 map_[id] = thiz;
34 }
35
36 // Forget about |id| from any thread. It's okay if it's not present.
37 // if it's not present.
38 void Erase(long id) {
39 base::AutoLock _l(lock_);
40 map_.erase(id);
41 }
42
43 // Return the associated callback for |id|, or null, from any thread.
44 AndroidOverlayCallback* Lookup(long id) {
45 base::AutoLock _l(lock_);
46 return LookupLocked(id);
47 }
48
49 private:
50 // Lookup |id|. The caller must hold |lock_|.
51 AndroidOverlayCallback* LookupLocked(long id) {
52 lock_.AssertAcquired();
53 AndroidOverlayCallback* thiz = nullptr;
54 Map::const_iterator it = map_.find(id);
55 if (it != map_.end())
56 thiz = it->second;
57
58 return thiz;
59 }
60
61 // Alternatively, we could put in a callback that is bound to the correct
62 // thread, and use a weak ref. However, since we still need a default
63 // action when the weak ref is cleared to unblock the callback, it ends up
64 // not being any simpler.
65 using Map = std::map<long, AndroidOverlayCallback*>;
66 Map map_;
67
68 base::Lock lock_;
69 };
70
71 static base::LazyInstance<AndroidOverlayCallbackmap>::Leaky g_map =
72 LAZY_INSTANCE_INITIALIZER;
73
74 AndroidOverlayCallback::AndroidOverlayCallback(
75 const AndroidOverlayProxy::Callback& callback)
76 : id_(next_id_++), callback_(callback) {
77 if (!task_runner_)
78 task_runner_ = base::ThreadTaskRunnerHandle::Get();
boliu 2017/02/08 00:01:58 else DCHECK it's still the same thread?
79
80 JNIEnv* env = AttachCurrentThread();
81 j_surface_callback_.Reset(Java_AndroidOverlayCallback_create(env, id_));
82
83 g_map.Pointer()->Insert(id_, this);
84 }
85
86 AndroidOverlayCallback::~AndroidOverlayCallback() {
87 DCHECK(thread_checker_.CalledOnValidThread());
88 g_map.Pointer()->Erase(id_);
89 }
90
91 void AndroidOverlayCallback::SetAndroidSurfaceCB(
92 const AndroidSurfaceCB& android_surface_cb) {
93 android_surface_cb_ = android_surface_cb;
94 }
95
96 bool AndroidOverlayCallback::RegisterAndroidOverlayCallback(JNIEnv* env) {
97 return RegisterNativesImpl(env);
98 }
99
100 scoped_refptr<base::SingleThreadTaskRunner>
101 AndroidOverlayCallback::GetTaskRunner() {
102 // May be called on any thread.
103 return task_runner_;
104 }
105
106 bool AndroidOverlayCallback::CalledOnValidThread() const {
107 return thread_checker_.CalledOnValidThread();
108 }
109
110 void AndroidOverlayCallback::OnCallbackProperThread(
111 long id,
112 AndroidOverlayProxy::CallbackOp what,
113 base::android::ScopedJavaGlobalRef<jobject> jobject_opt,
114 base::android::ScopedJavaGlobalRef<jobject> jcompletion_opt) {
115 // A callback has happened on some other thread. We're run on the correct
116 // thread in response to it.
117 AndroidOverlayCallback* thiz = g_map.Pointer()->Lookup(id);
118 // |thiz| cannot be deleted here, since we're on the main thread. However,
119 // it might have been deleted earlier, so it can be null.
120
121 if (thiz) {
122 // If this is SURFACE_DESTROYED, then no further callbacks are permitted.
123 // Erase the map entry in case the IAndroidOverlay decides to send another.
124 if (what == AndroidOverlayProxy::CallbackOp::SURFACE_DESTROYED)
125 g_map.Pointer()->Erase(id);
126
127 DCHECK(thiz->CalledOnValidThread());
128 // Send the java surface to the AndroidOverlay before the callback.
129 if (what == AndroidOverlayProxy::CallbackOp::SURFACE_CREATED &&
130 !thiz->android_surface_cb_.is_null()) {
131 thiz->android_surface_cb_.Run(jobject_opt);
132 }
133
134 // Run the client-supplied callback.
135 thiz->callback_.Run(what);
136 }
137
138 // If this is a synchronous callback, then signal that we've completed.
139 if (!jcompletion_opt.is_null()) {
140 JNIEnv* env = AttachCurrentThread();
141 Java_AndroidOverlayCallback_signalCompletion(env, jcompletion_opt);
142 }
143 }
144
145 void OnAndroidOverlayCallbackCreated(
146 JNIEnv* env,
147 const base::android::JavaParamRef<jclass>& jcaller,
148 jlong id,
149 const base::android::JavaParamRef<jobject>& jsurface) {
150 // Called from some random thread in java.
151 // Post back to the main thread. We get a strong ref here to the task
152 // runner, so that it's okay if the controller is deleted. Holding the
153 // lock during the callback is not safe; the caller might require it to
154 // complete the callback.
155 // Remember that we're on a random thread, but |g_map| is thread safe.
156 base::Closure cb = base::Bind(
157 &AndroidOverlayCallback::OnCallbackProperThread, id,
158 AndroidOverlayProxy::CallbackOp::SURFACE_CREATED,
159 base::android::ScopedJavaGlobalRef<jobject>(jsurface), nullptr);
160 #if 1
161 AndroidOverlayCallback::GetTaskRunner()->PostTask(FROM_HERE, cb);
162 #else
163 // DO NOT COMMIT -- just so that picture buffer manager can wait.
164 // (I'll remove this before landing)
165 LOG(ERROR) << "AVDA: DO NOT COMMIT";
166 cb.Run();
167 #endif
168 }
169
170 void OnAndroidOverlayCallbackDestroyed(
171 JNIEnv* env,
172 const base::android::JavaParamRef<jclass>& jcaller,
173 jlong id,
174 const base::android::JavaParamRef<jobject>& jcompletion) {
175 // Called from some random thread in java.
176 base::Closure cb =
177 base::Bind(&AndroidOverlayCallback::OnCallbackProperThread, id,
178 AndroidOverlayProxy::CallbackOp::SURFACE_DESTROYED, nullptr,
179 base::android::ScopedJavaGlobalRef<jobject>(jcompletion));
180 AndroidOverlayCallback::GetTaskRunner()->PostTask(FROM_HERE, cb);
181 }
182
183 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698