File: api_binding.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (136 lines) | stat: -rw-r--r-- 4,606 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_RENDERER_API_BINDING_H_
#define EXTENSIONS_RENDERER_API_BINDING_H_

#include <map>
#include <memory>
#include <string>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/supports_user_data.h"
#include "extensions/renderer/argument_spec.h"
#include "v8/include/v8.h"

namespace base {
class ListValue;
}

namespace gin {
class Arguments;
}

namespace extensions {
class APIBindingHooks;
class APIEventHandler;
class APIRequestHandler;
class APISignature;

// A class that vends v8::Objects for extension APIs. These APIs have function
// interceptors for all exposed methods, which call back into the APIBinding.
// The APIBinding then matches the calling arguments against an expected method
// signature, throwing an error if they don't match.
// There should only need to be a single APIBinding object for each API, and
// each can vend multiple v8::Objects for different contexts.
// This object is designed to be one-per-isolate, but used across separate
// contexts.
class APIBinding {
 public:
  // TODO(devlin): We may want to coalesce this with the
  // ExtensionHostMsg_Request_Params IPC struct.
  struct Request {
    Request();
    ~Request();

    int request_id = -1;
    std::string method_name;
    bool has_callback = false;
    bool has_user_gesture = false;
    std::unique_ptr<base::ListValue> arguments;

   private:
    DISALLOW_COPY_AND_ASSIGN(Request);
  };

  using SendRequestMethod =
      base::Callback<void(std::unique_ptr<Request>, v8::Local<v8::Context>)>;

  // The callback for determining if a given API method (specified by |name|)
  // is available.
  using AvailabilityCallback = base::Callback<bool(const std::string& name)>;

  // The callback type for handling an API call.
  using HandlerCallback = base::Callback<void(gin::Arguments*)>;

  // The ArgumentSpec::RefMap is required to outlive this object.
  // |function_definitions|, |type_definitions| and |event_definitions|
  // may be null if the API does not specify any of that category.
  APIBinding(const std::string& name,
             const base::ListValue* function_definitions,
             const base::ListValue* type_definitions,
             const base::ListValue* event_definitions,
             const SendRequestMethod& callback,
             std::unique_ptr<APIBindingHooks> binding_hooks,
             ArgumentSpec::RefMap* type_refs,
             APIRequestHandler* request_handler);
  ~APIBinding();

  // Returns a new v8::Object for the API this APIBinding represents.
  v8::Local<v8::Object> CreateInstance(
      v8::Local<v8::Context> context,
      v8::Isolate* isolate,
      APIEventHandler* event_handler,
      const AvailabilityCallback& is_available);

  // Returns the JS interface to use when registering hooks with legacy custom
  // bindings.
  v8::Local<v8::Object> GetJSHookInterface(v8::Local<v8::Context> context);

 private:
  // Handles a call an API method with the given |name| and matches the
  // arguments against |signature|.
  void HandleCall(const std::string& name,
                  const APISignature* signature,
                  gin::Arguments* args);

  // The root name of the API, e.g. "tabs" for chrome.tabs.
  std::string api_name_;

  // A map from method name to method data.
  struct MethodData;
  std::map<std::string, std::unique_ptr<MethodData>> methods_;

  // The names of all events associated with this API.
  std::vector<std::string> event_names_;

  // The pair for enum entry is <original, js-ified>. JS enum entries use
  // SCREAMING_STYLE (whereas our API enums are just inconsistent).
  using EnumEntry = std::pair<std::string, std::string>;
  // A map of <name, values> for the enums on this API.
  std::map<std::string, std::vector<EnumEntry>> enums_;

  // The callback to use when an API is invoked with valid arguments.
  SendRequestMethod method_callback_;

  // The registered hooks for this API.
  std::unique_ptr<APIBindingHooks> binding_hooks_;

  // The reference map for all known types; required to outlive this object.
  const ArgumentSpec::RefMap* type_refs_;

  // The associated request handler, shared between this and other bindings.
  // Required to outlive this object.
  APIRequestHandler* request_handler_;

  base::WeakPtrFactory<APIBinding> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(APIBinding);
};

}  // namespace extensions

#endif  // EXTENSIONS_RENDERER_API_BINDING_H_