13551c9c881056c480085172ff9840cab31610854Torne (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) 53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#ifndef EXTENSIONS_COMMON_MANIFEST_H_ 63551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#define EXTENSIONS_COMMON_MANIFEST_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct InstallWarning; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wraps the DictionaryValue form of extension's manifest. Enforces access to 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// properties of the manifest using ManifestFeatureProvider. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Manifest { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // What an extension was loaded from. 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NOTE: These values are stored as integers in the preferences and used 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in histograms so don't remove or reorder existing items. Just append 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the end. 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Location { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INVALID_LOCATION, 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) INTERNAL, // A crx file from the internal Extensions directory. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTERNAL_PREF, // A crx file from an external directory (via prefs). 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTERNAL_REGISTRY, // A crx file from an external directory (via eg the 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // registry on Windows). 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UNPACKED, // From loading an unpacked extension from the 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extensions settings page. 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COMPONENT, // An integral component of Chrome itself, which 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // happens to be implemented as an extension. We don't 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // show these in the management UI. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTERNAL_PREF_DOWNLOAD, // A crx file from an external directory (via 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // prefs), installed from an update URL. 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXTERNAL_POLICY_DOWNLOAD, // A crx file from an external directory (via 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // admin policies), installed from an update URL. 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) COMMAND_LINE, // --load-extension. 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXTERNAL_POLICY, // A crx file from an external directory (via admin 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // policies), cached locally and installed from the 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // cache. 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXTERNAL_COMPONENT, // Similar to COMPONENT in that it's considered an 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // internal implementation detail of chrome, but 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // installed from an update URL like the *DOWNLOAD ones. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // New enum values must go above here. 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NUM_LOCATIONS 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do not change the order of entries or remove entries in this list 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // as this is used in UMA_HISTOGRAM_ENUMERATIONs about extensions. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum Type { 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_UNKNOWN = 0, 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_EXTENSION, 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_THEME, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_USER_SCRIPT, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_HOSTED_APP, 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is marked legacy because platform apps are preferred. For 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // backwards compatibility, we can't remove support for packaged apps 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TYPE_LEGACY_PACKAGED_APP, 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TYPE_PLATFORM_APP, 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TYPE_SHARED_MODULE, 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // New enum values must go above here. 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) NUM_LOAD_TYPES 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Given two install sources, return the one which should take priority 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // over the other. If an extension is installed from two sources A and B, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // its install source should be set to GetHigherPriorityLocation(A, B). 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static Location GetHigherPriorityLocation(Location loc1, Location loc2); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether the |location| is external or not. 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static inline bool IsExternalLocation(Location location) { 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return location == EXTERNAL_PREF || 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location == EXTERNAL_REGISTRY || 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) location == EXTERNAL_PREF_DOWNLOAD || 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) location == EXTERNAL_POLICY || 830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) location == EXTERNAL_POLICY_DOWNLOAD || 840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) location == EXTERNAL_COMPONENT; 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether the |location| is unpacked (no CRX) or not. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static inline bool IsUnpackedLocation(Location location) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return location == UNPACKED || location == COMMAND_LINE; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Whether extensions with |location| are auto-updatable or not. 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static inline bool IsAutoUpdateableLocation(Location location) { 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only internal and external extensions can be autoupdated. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return location == INTERNAL || 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IsExternalLocation(location); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Whether the |location| is a source of extensions force-installed through 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // policy. 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static inline bool IsPolicyLocation(Location location) { 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return location == EXTERNAL_POLICY || 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) location == EXTERNAL_POLICY_DOWNLOAD; 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Whether the |location| is an extension intended to be an internal part of 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Chrome. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static inline bool IsComponentLocation(Location location) { 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return location == COMPONENT || location == EXTERNAL_COMPONENT; 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unpacked extensions start off with file access since they are a developer 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // feature. 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static inline bool ShouldAlwaysAllowFileAccess(Location location) { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IsUnpackedLocation(location); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Manifest(Location location, scoped_ptr<base::DictionaryValue> value); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Manifest(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id() const { return extension_id_; } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_extension_id(const std::string& id) { extension_id_ = id; } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Location location() const { return location_; } 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns false and |error| will be non-empty if the manifest is malformed. 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |warnings| will be populated if there are keys in the manifest that cannot 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be specified by the extension type. 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ValidateManifest(std::string* error, 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<InstallWarning>* warnings) const; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The version of this extension's manifest. We increase the manifest 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // version when making breaking changes to the extension system. If the 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest contains no explicit manifest version, this returns the current 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system default. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetManifestVersion() const; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the manifest type. 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type type() const { return type_; } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_theme() const { return type_ == TYPE_THEME; } 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_app() const { 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_legacy_packaged_app() || is_hosted_app() || is_platform_app(); 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_platform_app() const { return type_ == TYPE_PLATFORM_APP; } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_hosted_app() const { return type_ == TYPE_HOSTED_APP; } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_legacy_packaged_app() const { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return type_ == TYPE_LEGACY_PACKAGED_APP; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_extension() const { return type_ == TYPE_EXTENSION; } 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_shared_module() const { return type_ == TYPE_SHARED_MODULE; } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These access the wrapped manifest value, returning false when the property 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // does not exist or if the manifest type can't access it. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasKey(const std::string& key) const; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasPath(const std::string& path) const; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Get(const std::string& path, const base::Value** out_value) const; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetBoolean(const std::string& path, bool* out_value) const; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetInteger(const std::string& path, int* out_value) const; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetString(const std::string& path, std::string* out_value) const; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool GetString(const std::string& path, base::string16* out_value) const; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GetDictionary(const std::string& path, 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue** out_value) const; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool GetList(const std::string& path, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::ListValue** out_value) const; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a new Manifest equal to this one, passing ownership to 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the caller. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Manifest* DeepCopy() const; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if this equals the |other| manifest. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Equals(const Manifest* other) const; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Gets the underlying DictionaryValue representing the manifest. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: only use this when you KNOW you don't need the validation. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::DictionaryValue* value() const { return value_.get(); } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the extension can specify the given |path|. 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanAccessPath(const std::string& path) const; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanAccessKey(const std::string& key) const; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A persistent, globally unique ID. An extension's ID is used in things 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // like directory structures and URLs, and is expected to not change across 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // versions. It is generated as a SHA-256 hash of the extension's public 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // key, or as a hash of the path in the case of unpacked extensions. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string extension_id_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The location the extension was loaded from. 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Location location_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The underlying dictionary representation of the manifest. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::DictionaryValue> value_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Type type_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Manifest); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif // EXTENSIONS_COMMON_MANIFEST_H_ 203