summaryrefslogtreecommitdiffstats
path: root/chrome/common/extensions/simple_feature_provider.cc
blob: 08bed3131f5592d8f6779edbc0a3c40599b6810e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/extensions/simple_feature_provider.h"

#include "base/json/json_reader.h"
#include "base/lazy_instance.h"
#include "chrome/common/extensions/manifest_feature.h"
#include "chrome/common/extensions/permission_feature.h"
#include "grit/common_resources.h"
#include "ui/base/resource/resource_bundle.h"

namespace extensions {

namespace {

template<class FeatureClass>
Feature* CreateFeature() {
  return new FeatureClass();
}

struct Static {
  Static()
      : manifest_features(
            LoadProvider("manifest",
                         &CreateFeature<ManifestFeature>,
                         IDR_EXTENSION_MANIFEST_FEATURES)),
        permission_features(
            LoadProvider("permissions",
                         &CreateFeature<PermissionFeature>,
                         IDR_EXTENSION_PERMISSION_FEATURES)) {
  }

  scoped_ptr<SimpleFeatureProvider> manifest_features;
  scoped_ptr<SimpleFeatureProvider> permission_features;

 private:
  scoped_ptr<SimpleFeatureProvider> LoadProvider(
      const std::string& debug_string,
      SimpleFeatureProvider::FeatureFactory factory,
      int resource_id) {
    std::string manifest_features =
        ResourceBundle::GetSharedInstance().GetRawDataResource(
            resource_id).as_string();
    int error_code = 0;
    std::string error_message;
    Value* value = base::JSONReader::ReadAndReturnError(
        manifest_features, base::JSON_PARSE_RFC,
        &error_code, &error_message);
    CHECK(value) << "Could not load features: " << debug_string << " "
                 << error_message;
    CHECK(value->IsType(Value::TYPE_DICTIONARY)) << debug_string;
    scoped_ptr<DictionaryValue> dictionary_value(
        static_cast<DictionaryValue*>(value));
    return scoped_ptr<SimpleFeatureProvider>(
        new SimpleFeatureProvider(dictionary_value.get(), factory));
  }
};

base::LazyInstance<Static> g_static = LAZY_INSTANCE_INITIALIZER;

}  // namespace

SimpleFeatureProvider::SimpleFeatureProvider(DictionaryValue* root,
                                             FeatureFactory factory)
    : factory_(factory ? factory :
               static_cast<FeatureFactory>(&CreateFeature<Feature>)) {
  for (DictionaryValue::Iterator iter(*root); iter.HasNext(); iter.Advance()) {
    if (iter.value().GetType() != Value::TYPE_DICTIONARY) {
      LOG(ERROR) << iter.key() << ": Feature description must be dictionary.";
      continue;
    }

    linked_ptr<Feature> feature((*factory_)());
    feature->set_name(iter.key());
    feature->Parse(static_cast<const DictionaryValue*>(&iter.value()));

    if (feature->extension_types()->empty()) {
      LOG(ERROR) << iter.key() << ": Simple features must specify atleast one "
                 << "value for extension_types.";
      continue;
    }

    if (!feature->contexts()->empty()) {
      LOG(ERROR) << iter.key() << ": Simple features do not support contexts.";
      continue;
    }

    features_[iter.key()] = feature;
  }
}

SimpleFeatureProvider::~SimpleFeatureProvider() {
}

// static
SimpleFeatureProvider* SimpleFeatureProvider::GetManifestFeatures() {
  return g_static.Get().manifest_features.get();
}

// static
SimpleFeatureProvider* SimpleFeatureProvider::GetPermissionFeatures() {
  return g_static.Get().permission_features.get();
}

std::set<std::string> SimpleFeatureProvider::GetAllFeatureNames() const {
  std::set<std::string> result;
  for (FeatureMap::const_iterator iter = features_.begin();
       iter != features_.end(); ++iter) {
    result.insert(iter->first);
  }
  return result;
}

Feature* SimpleFeatureProvider::GetFeature(const std::string& name) {
  FeatureMap::iterator iter = features_.find(name);
  if (iter != features_.end())
    return iter->second.get();
  else
    return NULL;
}

}  // namespace