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 "chrome/common/extensions/features/chrome_channel_feature_filter.h" 6 7#include <map> 8#include <string> 9 10#include "base/lazy_instance.h" 11#include "base/strings/stringprintf.h" 12#include "chrome/common/extensions/features/feature_channel.h" 13#include "extensions/common/features/simple_feature.h" 14 15namespace extensions { 16 17namespace { 18 19static const char kFeatureChannelKey[] = "channel"; 20 21struct Mappings { 22 Mappings() { 23 channels["trunk"] = chrome::VersionInfo::CHANNEL_UNKNOWN; 24 channels["canary"] = chrome::VersionInfo::CHANNEL_CANARY; 25 channels["dev"] = chrome::VersionInfo::CHANNEL_DEV; 26 channels["beta"] = chrome::VersionInfo::CHANNEL_BETA; 27 channels["stable"] = chrome::VersionInfo::CHANNEL_STABLE; 28 } 29 30 std::map<std::string, chrome::VersionInfo::Channel> channels; 31}; 32 33base::LazyInstance<Mappings> g_mappings = LAZY_INSTANCE_INITIALIZER; 34 35std::string GetChannelName(chrome::VersionInfo::Channel channel) { 36 typedef std::map<std::string, chrome::VersionInfo::Channel> ChannelsMap; 37 ChannelsMap channels = g_mappings.Get().channels; 38 for (ChannelsMap::iterator i = channels.begin(); i != channels.end(); ++i) { 39 if (i->second == channel) 40 return i->first; 41 } 42 NOTREACHED(); 43 return "unknown"; 44} 45 46chrome::VersionInfo::Channel GetChannelValue(const std::string& name) { 47 typedef std::map<std::string, chrome::VersionInfo::Channel> ChannelsMap; 48 ChannelsMap channels = g_mappings.Get().channels; 49 ChannelsMap::const_iterator iter = channels.find(name); 50 CHECK(iter != channels.end()); 51 return iter->second; 52} 53 54} // namespace 55 56ChromeChannelFeatureFilter::ChromeChannelFeatureFilter(SimpleFeature* feature) 57 : SimpleFeatureFilter(feature), 58 channel_has_been_set_(false), 59 channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) { 60} 61 62ChromeChannelFeatureFilter::~ChromeChannelFeatureFilter() {} 63 64std::string ChromeChannelFeatureFilter::Parse( 65 const base::DictionaryValue* value) { 66 std::string channel_name; 67 if (value->GetString(kFeatureChannelKey, &channel_name)) { 68 channel_ = GetChannelValue(channel_name); 69 } 70 71 // The "trunk" channel uses VersionInfo::CHANNEL_UNKNOWN, so we need to keep 72 // track of whether the channel has been set or not separately. 73 channel_has_been_set_ |= value->HasKey(kFeatureChannelKey); 74 75 if (!channel_has_been_set_ && !feature()->HasDependencies()) { 76 return feature()->name() + 77 ": Must supply a value for channel or dependencies."; 78 } 79 80 return std::string(); 81} 82 83Feature::Availability ChromeChannelFeatureFilter::IsAvailableToManifest( 84 const std::string& extension_id, 85 Manifest::Type type, 86 Manifest::Location location, 87 int manifest_version, 88 Feature::Platform platfortm) const { 89 if (channel_has_been_set_ && channel_ < GetCurrentChannel()) { 90 return Feature::CreateAvailability( 91 Feature::UNSUPPORTED_CHANNEL, 92 base::StringPrintf( 93 "'%s' requires Google Chrome %s channel or newer, but this is the " 94 "%s channel.", 95 feature()->name().c_str(), 96 GetChannelName(channel_).c_str(), 97 GetChannelName(GetCurrentChannel()).c_str())); 98 } 99 return Feature::CreateAvailability(Feature::IS_AVAILABLE, std::string()); 100} 101 102} // namespace extensions 103