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#include "extensions/shell/common/shell_extensions_client.h"
6
7#include "base/lazy_instance.h"
8#include "base/logging.h"
9#include "extensions/common/api/generated_schemas.h"
10#include "extensions/common/common_manifest_handlers.h"
11#include "extensions/common/extension_urls.h"
12#include "extensions/common/features/api_feature.h"
13#include "extensions/common/features/base_feature_provider.h"
14#include "extensions/common/features/json_feature_provider_source.h"
15#include "extensions/common/features/manifest_feature.h"
16#include "extensions/common/features/permission_feature.h"
17#include "extensions/common/features/simple_feature.h"
18#include "extensions/common/manifest_handler.h"
19#include "extensions/common/permissions/permission_message_provider.h"
20#include "extensions/common/permissions/permissions_info.h"
21#include "extensions/common/permissions/permissions_provider.h"
22#include "extensions/common/url_pattern_set.h"
23#include "grit/extensions_resources.h"
24
25namespace extensions {
26
27namespace {
28
29template <class FeatureClass>
30SimpleFeature* CreateFeature() {
31  return new FeatureClass;
32}
33
34// TODO(jamescook): Refactor ChromePermissionsMessageProvider so we can share
35// code. For now, this implementation does nothing.
36class ShellPermissionMessageProvider : public PermissionMessageProvider {
37 public:
38  ShellPermissionMessageProvider() {}
39  virtual ~ShellPermissionMessageProvider() {}
40
41  // PermissionMessageProvider implementation.
42  virtual PermissionMessages GetPermissionMessages(
43      const PermissionSet* permissions,
44      Manifest::Type extension_type) const OVERRIDE {
45    return PermissionMessages();
46  }
47
48  virtual std::vector<base::string16> GetWarningMessages(
49      const PermissionSet* permissions,
50      Manifest::Type extension_type) const OVERRIDE {
51    return std::vector<base::string16>();
52  }
53
54  virtual std::vector<base::string16> GetWarningMessagesDetails(
55      const PermissionSet* permissions,
56      Manifest::Type extension_type) const OVERRIDE {
57    return std::vector<base::string16>();
58  }
59
60  virtual bool IsPrivilegeIncrease(
61      const PermissionSet* old_permissions,
62      const PermissionSet* new_permissions,
63      Manifest::Type extension_type) const OVERRIDE {
64    // Ensure we implement this before shipping.
65    CHECK(false);
66    return false;
67  }
68
69 private:
70  DISALLOW_COPY_AND_ASSIGN(ShellPermissionMessageProvider);
71};
72
73base::LazyInstance<ShellPermissionMessageProvider>
74    g_permission_message_provider = LAZY_INSTANCE_INITIALIZER;
75
76}  // namespace
77
78ShellExtensionsClient::ShellExtensionsClient()
79    : extensions_api_permissions_(ExtensionsAPIPermissions()) {
80}
81
82ShellExtensionsClient::~ShellExtensionsClient() {
83}
84
85void ShellExtensionsClient::Initialize() {
86  RegisterCommonManifestHandlers();
87  ManifestHandler::FinalizeRegistration();
88  // TODO(jamescook): Do we need to whitelist any extensions?
89
90  PermissionsInfo::GetInstance()->AddProvider(extensions_api_permissions_);
91}
92
93const PermissionMessageProvider&
94ShellExtensionsClient::GetPermissionMessageProvider() const {
95  NOTIMPLEMENTED();
96  return g_permission_message_provider.Get();
97}
98
99const std::string ShellExtensionsClient::GetProductName() {
100  return "app_shell";
101}
102
103scoped_ptr<FeatureProvider> ShellExtensionsClient::CreateFeatureProvider(
104    const std::string& name) const {
105  scoped_ptr<FeatureProvider> provider;
106  scoped_ptr<JSONFeatureProviderSource> source(
107      CreateFeatureProviderSource(name));
108  if (name == "api") {
109    provider.reset(new BaseFeatureProvider(source->dictionary(),
110                                           CreateFeature<APIFeature>));
111  } else if (name == "manifest") {
112    provider.reset(new BaseFeatureProvider(source->dictionary(),
113                                           CreateFeature<ManifestFeature>));
114  } else if (name == "permission") {
115    provider.reset(new BaseFeatureProvider(source->dictionary(),
116                                           CreateFeature<PermissionFeature>));
117  } else {
118    NOTREACHED();
119  }
120  return provider.Pass();
121}
122
123scoped_ptr<JSONFeatureProviderSource>
124ShellExtensionsClient::CreateFeatureProviderSource(
125    const std::string& name) const {
126  scoped_ptr<JSONFeatureProviderSource> source(
127      new JSONFeatureProviderSource(name));
128  if (name == "api") {
129    source->LoadJSON(IDR_EXTENSION_API_FEATURES);
130  } else if (name == "manifest") {
131    source->LoadJSON(IDR_EXTENSION_MANIFEST_FEATURES);
132  } else if (name == "permission") {
133    source->LoadJSON(IDR_EXTENSION_PERMISSION_FEATURES);
134  } else {
135    NOTREACHED();
136    source.reset();
137  }
138  return source.Pass();
139}
140
141void ShellExtensionsClient::FilterHostPermissions(
142    const URLPatternSet& hosts,
143    URLPatternSet* new_hosts,
144    std::set<PermissionMessage>* messages) const {
145  NOTIMPLEMENTED();
146}
147
148void ShellExtensionsClient::SetScriptingWhitelist(
149    const ScriptingWhitelist& whitelist) {
150  scripting_whitelist_ = whitelist;
151}
152
153const ExtensionsClient::ScriptingWhitelist&
154ShellExtensionsClient::GetScriptingWhitelist() const {
155  // TODO(jamescook): Real whitelist.
156  return scripting_whitelist_;
157}
158
159URLPatternSet ShellExtensionsClient::GetPermittedChromeSchemeHosts(
160    const Extension* extension,
161    const APIPermissionSet& api_permissions) const {
162  NOTIMPLEMENTED();
163  return URLPatternSet();
164}
165
166bool ShellExtensionsClient::IsScriptableURL(const GURL& url,
167                                            std::string* error) const {
168  NOTIMPLEMENTED();
169  return true;
170}
171
172bool ShellExtensionsClient::IsAPISchemaGenerated(
173    const std::string& name) const {
174  return core_api::GeneratedSchemas::IsGenerated(name);
175}
176
177base::StringPiece ShellExtensionsClient::GetAPISchema(
178    const std::string& name) const {
179  return core_api::GeneratedSchemas::Get(name);
180}
181
182void ShellExtensionsClient::RegisterAPISchemaResources(
183    ExtensionAPI* api) const {
184}
185
186bool ShellExtensionsClient::ShouldSuppressFatalErrors() const {
187  return true;
188}
189
190std::string ShellExtensionsClient::GetWebstoreBaseURL() const {
191  return extension_urls::kChromeWebstoreBaseURL;
192}
193
194std::string ShellExtensionsClient::GetWebstoreUpdateURL() const {
195  return extension_urls::kChromeWebstoreUpdateURL;
196}
197
198bool ShellExtensionsClient::IsBlacklistUpdateURL(const GURL& url) const {
199  // TODO(rockot): Maybe we want to do something else here. For now we accept
200  // any URL as a blacklist URL because we don't really care.
201  return true;
202}
203
204}  // namespace extensions
205