1 // Copyright 2014 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 #ifndef MOJO_EDK_JS_HANDLE_H_ 6 #define MOJO_EDK_JS_HANDLE_H_ 7 8 #include <stdint.h> 9 10 #include "base/observer_list.h" 11 #include "gin/converter.h" 12 #include "gin/handle.h" 13 #include "gin/wrappable.h" 14 #include "mojo/public/cpp/system/core.h" 15 16 namespace mojo { 17 namespace edk { 18 namespace js { 19 20 class HandleCloseObserver; 21 22 // Wrapper for mojo Handles exposed to JavaScript. This ensures the Handle 23 // is Closed when its JS object is garbage collected. 24 class HandleWrapper : public gin::Wrappable<HandleWrapper> { 25 public: 26 static gin::WrapperInfo kWrapperInfo; 27 Create(v8::Isolate * isolate,MojoHandle handle)28 static gin::Handle<HandleWrapper> Create(v8::Isolate* isolate, 29 MojoHandle handle) { 30 return gin::CreateHandle(isolate, new HandleWrapper(handle)); 31 } 32 get()33 mojo::Handle get() const { return handle_.get(); } release()34 mojo::Handle release() { return handle_.release(); } 35 void Close(); 36 37 void AddCloseObserver(HandleCloseObserver* observer); 38 void RemoveCloseObserver(HandleCloseObserver* observer); 39 40 protected: 41 HandleWrapper(MojoHandle handle); 42 ~HandleWrapper() override; 43 void NotifyCloseObservers(); 44 45 mojo::ScopedHandle handle_; 46 base::ObserverList<HandleCloseObserver> close_observers_; 47 }; 48 49 } // namespace js 50 } // namespace edk 51 } // namespace mojo 52 53 namespace gin { 54 55 // Note: It's important to use this converter rather than the one for 56 // MojoHandle, since that will do a simple int32_t conversion. It's unfortunate 57 // there's no way to prevent against accidental use. 58 // TODO(mpcomplete): define converters for all Handle subtypes. 59 template<> 60 struct Converter<mojo::Handle> { 61 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, 62 const mojo::Handle& val); 63 static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, 64 mojo::Handle* out); 65 }; 66 67 template<> 68 struct Converter<mojo::MessagePipeHandle> { 69 static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, 70 mojo::MessagePipeHandle val); 71 static bool FromV8(v8::Isolate* isolate, 72 v8::Handle<v8::Value> val, 73 mojo::MessagePipeHandle* out); 74 }; 75 76 // We need to specialize the normal gin::Handle converter in order to handle 77 // converting |null| to a wrapper for an empty mojo::Handle. 78 template <> 79 struct Converter<gin::Handle<mojo::edk::js::HandleWrapper>> { 80 static v8::Handle<v8::Value> ToV8( 81 v8::Isolate* isolate, 82 const gin::Handle<mojo::edk::js::HandleWrapper>& val) { 83 return val.ToV8(); 84 } 85 86 static bool FromV8(v8::Isolate* isolate, 87 v8::Handle<v8::Value> val, 88 gin::Handle<mojo::edk::js::HandleWrapper>* out) { 89 if (val->IsNull()) { 90 *out = mojo::edk::js::HandleWrapper::Create(isolate, MOJO_HANDLE_INVALID); 91 return true; 92 } 93 94 mojo::edk::js::HandleWrapper* object = NULL; 95 if (!Converter<mojo::edk::js::HandleWrapper*>::FromV8(isolate, val, 96 &object)) { 97 return false; 98 } 99 *out = gin::Handle<mojo::edk::js::HandleWrapper>(val, object); 100 return true; 101 } 102 }; 103 104 } // namespace gin 105 106 #endif // MOJO_EDK_JS_HANDLE_H_ 107