Home | History | Annotate | Download | only in system
      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:
     24   WatcherImpl()
     25       : watcher_(FROM_HERE,
     26                  SimpleWatcher::ArmingPolicy::AUTOMATIC,
     27                  base::SequencedTaskRunnerHandle::Get()) {}
     28 
     29   ~WatcherImpl() = default;
     30 
     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 
     49   void Cancel() {
     50     java_watcher_.Reset();
     51     watcher_.Cancel();
     52   }
     53 
     54  private:
     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 
     76 static jlong JNI_WatcherImpl_CreateWatcher(
     77     JNIEnv* env,
     78     const JavaParamRef<jobject>& jcaller) {
     79   return reinterpret_cast<jlong>(new WatcherImpl);
     80 }
     81 
     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 
     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 
     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