10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#ifndef EXTENSIONS_COMMON_EXTENSION_API_H_
60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#define EXTENSIONS_COMMON_EXTENSION_API_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/gtest_prod_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/features/feature.h"
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "extensions/common/features/feature_provider.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/url_pattern_set.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Value;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GURL;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Feature;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// C++ Wrapper for the JSON API definitions in chrome/common/extensions/api/.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WARNING: This class is accessed on multiple threads in the browser process
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (see ExtensionFunctionDispatcher). No state should be modified after
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// construction.
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class ExtensionAPI {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a single shared instance of this class. This is the typical use
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // case in Chrome.
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(aa): Make this const to enforce thread-safe usage.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ExtensionAPI* GetSharedInstance();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a new instance configured the way ExtensionAPI typically is in
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome. Use the default constructor to get a clean instance.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ExtensionAPI* CreateWithDefaultConfiguration();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Splits a name like "permission:bookmark" into ("permission", "bookmark").
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first part refers to a type of feature, for example "manifest",
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "permission", or "api". The second part is the full name of the feature.
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(kalman): ExtensionAPI isn't really the right place for this function.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SplitDependencyName(const std::string& full_name,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  std::string* feature_type,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  std::string* feature_name);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  class OverrideSharedInstanceForTest {
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   public:
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    explicit OverrideSharedInstanceForTest(ExtensionAPI* testing_api);
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ~OverrideSharedInstanceForTest();
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch   private:
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ExtensionAPI* original_api_;
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a completely clean instance. Configure using RegisterSchema() and
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RegisterDependencyProvider before use.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionAPI();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ExtensionAPI();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Add a (non-generated) API schema resource.
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void RegisterSchemaResource(const std::string& api_name, int resource_id);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Add a FeatureProvider for APIs. The features are used to specify
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // dependencies and constraints on the availability of APIs.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterDependencyProvider(const std::string& name,
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                  const FeatureProvider* provider);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns true if the API item called |api_full_name| and all of its
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // dependencies are available in |context|.
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |api_full_name| can be either a namespace name (like "bookmarks") or a
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // member name (like "bookmarks.create").
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  //
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Depending on the configuration of |api| (in _api_features.json), either
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |extension| or |url| (or both) may determine its availability, but this is
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // up to the configuration of the individual feature.
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TODO(kalman): This is just an unnecessary combination of finding a Feature
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // then calling Feature::IsAvailableToContext(..) on it. Just provide that
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // FindFeature function and let callers compose if they want.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Feature::Availability IsAvailable(const std::string& api_full_name,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const Extension* extension,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    Feature::Context context,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const GURL& url);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Determines whether an API, or any parts of that API, are available in
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // |context|.
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool IsAnyFeatureAvailableToContext(const Feature& api,
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                      const Extension* extension,
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                      Feature::Context context,
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                      const GURL& url);
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns true if |name| is available to |extension| in any untrusted
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // extension context, such as content scripts, iframes, or web pages.
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool IsAvailableInUntrustedContext(const std::string& name,
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                     const Extension* extension);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns true if |name| is available to WebUI contexts on |url|.
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool IsAvailableToWebUI(const std::string& name, const GURL& url);
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Gets the schema for the extension API with namespace |full_name|.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ownership remains with this object.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* GetSchema(const std::string& full_name);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Splits a full name from the extension API into its API and child name
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parts. Some examples:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "bookmarks.create" -> ("bookmarks", "create")
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "experimental.input.ui.cursorUp" -> ("experimental.input.ui", "cursorUp")
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "storage.sync.set" -> ("storage", "sync.get")
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "<unknown-api>.monkey" -> ("", "")
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |child_name| parameter can be be NULL if you don't need that part.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string GetAPINameFromFullName(const std::string& full_name,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     std::string* child_name);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Gets a feature from any dependency provider registered with ExtensionAPI.
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns NULL if the feature could not be found.
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Feature* GetFeatureDependency(const std::string& dependency_name);
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ExtensionAPITest, DefaultConfigurationFeatures);
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ExtensionAPITest, TypesHaveNamespace);
1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  friend struct DefaultSingletonTraits<ExtensionAPI>;
1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitDefaultConfiguration();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  bool default_configuration_initialized_;
1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Loads a schema.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LoadSchema(const std::string& name, const base::StringPiece& schema);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map from each API that hasn't been loaded yet to the schema which defines
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it. Note that there may be multiple APIs per schema.
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef std::map<std::string, int> UnloadedSchemaMap;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UnloadedSchemaMap unloaded_schemas_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schemas for each namespace.
1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  typedef std::map<std::string, linked_ptr<const base::DictionaryValue> >
1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SchemaMap;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchemaMap schemas_;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FeatureProviders used for resolving dependencies.
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  typedef std::map<std::string, const FeatureProvider*> FeatureProviderMap;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FeatureProviderMap dependency_providers_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ExtensionAPI);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}  // namespace extensions
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif  // EXTENSIONS_COMMON_EXTENSION_API_H_
167