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