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