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 <stddef.h>
6 #include <stdint.h>
7
8 #include "base/android/jni_android.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/bind.h"
11 #include "jni/WatcherImpl_jni.h"
12 #include "mojo/public/cpp/system/handle.h"
13 #include "mojo/public/cpp/system/simple_watcher.h"
14
15 namespace mojo {
16 namespace android {
17
18 using base::android::JavaParamRef;
19
20 namespace {
21
22 class WatcherImpl {
23 public:
WatcherImpl()24 WatcherImpl()
25 : watcher_(FROM_HERE,
26 SimpleWatcher::ArmingPolicy::AUTOMATIC,
27 base::SequencedTaskRunnerHandle::Get()) {}
28
29 ~WatcherImpl() = default;
30
Start(JNIEnv * env,const JavaParamRef<jobject> & jcaller,jint mojo_handle,jint signals)31 jint Start(JNIEnv* env,
32 const JavaParamRef<jobject>& jcaller,
33 jint mojo_handle,
34 jint signals) {
35 java_watcher_.Reset(env, jcaller);
36
37 auto ready_callback = base::BindRepeating(&WatcherImpl::OnHandleReady,
38 base::Unretained(this));
39
40 MojoResult result =
41 watcher_.Watch(mojo::Handle(static_cast<MojoHandle>(mojo_handle)),
42 static_cast<MojoHandleSignals>(signals), ready_callback);
43 if (result != MOJO_RESULT_OK)
44 java_watcher_.Reset();
45
46 return result;
47 }
48
Cancel()49 void Cancel() {
50 java_watcher_.Reset();
51 watcher_.Cancel();
52 }
53
54 private:
OnHandleReady(MojoResult result)55 void OnHandleReady(MojoResult result) {
56 DCHECK(!java_watcher_.is_null());
57
58 base::android::ScopedJavaGlobalRef<jobject> java_watcher_preserver;
59 if (result == MOJO_RESULT_CANCELLED)
60 java_watcher_preserver = std::move(java_watcher_);
61
62 Java_WatcherImpl_onHandleReady(
63 base::android::AttachCurrentThread(),
64 java_watcher_.is_null() ? java_watcher_preserver : java_watcher_,
65 result);
66 }
67
68 SimpleWatcher watcher_;
69 base::android::ScopedJavaGlobalRef<jobject> java_watcher_;
70
71 DISALLOW_COPY_AND_ASSIGN(WatcherImpl);
72 };
73
74 } // namespace
75
JNI_WatcherImpl_CreateWatcher(JNIEnv * env,const JavaParamRef<jobject> & jcaller)76 static jlong JNI_WatcherImpl_CreateWatcher(
77 JNIEnv* env,
78 const JavaParamRef<jobject>& jcaller) {
79 return reinterpret_cast<jlong>(new WatcherImpl);
80 }
81
JNI_WatcherImpl_Start(JNIEnv * env,const JavaParamRef<jobject> & jcaller,jlong watcher_ptr,jint mojo_handle,jint signals)82 static jint JNI_WatcherImpl_Start(JNIEnv* env,
83 const JavaParamRef<jobject>& jcaller,
84 jlong watcher_ptr,
85 jint mojo_handle,
86 jint signals) {
87 auto* watcher = reinterpret_cast<WatcherImpl*>(watcher_ptr);
88 return watcher->Start(env, jcaller, mojo_handle, signals);
89 }
90
JNI_WatcherImpl_Cancel(JNIEnv * env,const JavaParamRef<jobject> & jcaller,jlong watcher_ptr)91 static void JNI_WatcherImpl_Cancel(JNIEnv* env,
92 const JavaParamRef<jobject>& jcaller,
93 jlong watcher_ptr) {
94 reinterpret_cast<WatcherImpl*>(watcher_ptr)->Cancel();
95 }
96
JNI_WatcherImpl_Delete(JNIEnv * env,const JavaParamRef<jobject> & jcaller,jlong watcher_ptr)97 static void JNI_WatcherImpl_Delete(JNIEnv* env,
98 const JavaParamRef<jobject>& jcaller,
99 jlong watcher_ptr) {
100 delete reinterpret_cast<WatcherImpl*>(watcher_ptr);
101 }
102
103 } // namespace android
104 } // namespace mojo
105