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