1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef MOJO_BINDINGS_JS_HANDLE_H_ 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define MOJO_BINDINGS_JS_HANDLE_H_ 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/observer_list.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "gin/converter.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "gin/handle.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "gin/wrappable.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/core.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace gin { 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass HandleCloseObserver; 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Wrapper for mojo Handles exposed to JavaScript. This ensures the Handle 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// is Closed when its JS object is garbage collected. 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass HandleWrapper : public gin::Wrappable<HandleWrapper> { 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static gin::WrapperInfo kWrapperInfo; 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch static gin::Handle<HandleWrapper> Create(v8::Isolate* isolate, 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MojoHandle handle) { 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return gin::CreateHandle(isolate, new HandleWrapper(handle)); 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch mojo::Handle get() const { return handle_.get(); } 29c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch mojo::Handle release() { return handle_.release(); } 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void Close(); 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void AddCloseObserver(HandleCloseObserver* observer); 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void RemoveCloseObserver(HandleCloseObserver* observer); 34c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch protected: 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch HandleWrapper(MojoHandle handle); 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~HandleWrapper(); 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void NotifyCloseObservers(); 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch mojo::ScopedHandle handle_; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObserverList<HandleCloseObserver> close_observers_; 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Note: It's important to use this converter rather than the one for 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// MojoHandle, since that will do a simple int32 conversion. It's unfortunate 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// there's no way to prevent against accidental use. 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// TODO(mpcomplete): define converters for all Handle subtypes. 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)template<> 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)struct Converter<mojo::Handle> { 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const mojo::Handle& val); 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mojo::Handle* out); 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// We need to specialize the normal gin::Handle converter in order to handle 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// converting |null| to a wrapper for an empty mojo::Handle. 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template<> 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)struct Converter<gin::Handle<gin::HandleWrapper> > { 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static v8::Handle<v8::Value> ToV8( 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) v8::Isolate* isolate, const gin::Handle<gin::HandleWrapper>& val) { 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return val.ToV8(); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gin::Handle<gin::HandleWrapper>* out) { 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (val->IsNull()) { 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *out = HandleWrapper::Create(isolate, MOJO_HANDLE_INVALID); 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gin::HandleWrapper* object = NULL; 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!Converter<gin::HandleWrapper*>::FromV8(isolate, val, &object)) { 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) *out = gin::Handle<gin::HandleWrapper>(val, object); 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} // namespace gin 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif // MOJO_BINDINGS_JS_HANDLE_H_ 84