1// Copyright (c) 2012 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/api/extension_action/script_badge_handler.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/strings/utf_string_conversions.h"
9#include "base/values.h"
10#include "chrome/common/extensions/extension.h"
11#include "chrome/common/extensions/extension_constants.h"
12#include "chrome/common/extensions/extension_manifest_constants.h"
13#include "chrome/common/extensions/feature_switch.h"
14#include "chrome/common/extensions/manifest.h"
15#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
16#include "extensions/common/install_warning.h"
17
18namespace errors = extension_manifest_errors;
19namespace keys = extension_manifest_keys;
20
21namespace extensions {
22
23ScriptBadgeHandler::ScriptBadgeHandler() {
24}
25
26ScriptBadgeHandler::~ScriptBadgeHandler() {
27}
28
29const std::vector<std::string> ScriptBadgeHandler::PrerequisiteKeys() const {
30  return SingleKey(keys::kIcons);
31}
32
33bool ScriptBadgeHandler::Parse(Extension* extension, string16* error) {
34  scoped_ptr<ActionInfo> action_info(new ActionInfo);
35
36  // Provide a default script badge if one isn't declared in the manifest.
37  if (!extension->manifest()->HasKey(keys::kScriptBadge)) {
38    SetActionInfoDefaults(extension, action_info.get());
39    ActionInfo::SetScriptBadgeInfo(extension, action_info.release());
40    return true;
41  }
42
43  // So as to not confuse developers if they specify a script badge section
44  // in the manifest, show a warning if the script badge declaration isn't
45  // going to have any effect.
46  if (!FeatureSwitch::script_badges()->IsEnabled()) {
47    extension->AddInstallWarning(
48        InstallWarning(InstallWarning::FORMAT_TEXT,
49                       errors::kScriptBadgeRequiresFlag));
50  }
51
52  const base::DictionaryValue* dict = NULL;
53  if (!extension->manifest()->GetDictionary(keys::kScriptBadge, &dict)) {
54    *error = ASCIIToUTF16(errors::kInvalidScriptBadge);
55    return false;
56  }
57
58  action_info = ActionInfo::Load(extension, dict, error);
59
60  if (!action_info.get())
61    return false;  // Failed to parse script badge definition.
62
63  // Script badges always use their extension's title and icon so users can rely
64  // on the visual appearance to know which extension is running.  This isn't
65  // bulletproof since an malicious extension could use a different 16x16 icon
66  // that matches the icon of a trusted extension, and users wouldn't be warned
67  // during installation.
68
69  if (!action_info->default_title.empty()) {
70    extension->AddInstallWarning(
71        InstallWarning(InstallWarning::FORMAT_TEXT,
72                       errors::kScriptBadgeTitleIgnored));
73  }
74
75  if (!action_info->default_icon.empty()) {
76    extension->AddInstallWarning(
77        InstallWarning(InstallWarning::FORMAT_TEXT,
78                       errors::kScriptBadgeIconIgnored));
79  }
80
81  SetActionInfoDefaults(extension, action_info.get());
82  ActionInfo::SetScriptBadgeInfo(extension, action_info.release());
83  return true;
84}
85
86bool ScriptBadgeHandler::AlwaysParseForType(Manifest::Type type) const {
87  return type == Manifest::TYPE_EXTENSION;
88}
89
90void ScriptBadgeHandler::SetActionInfoDefaults(const Extension* extension,
91                                               ActionInfo* info) {
92  info->default_title = extension->name();
93  info->default_icon.Clear();
94  for (size_t i = 0; i < extension_misc::kNumScriptBadgeIconSizes; ++i) {
95    std::string path = IconsInfo::GetIcons(extension).Get(
96        extension_misc::kScriptBadgeIconSizes[i],
97        ExtensionIconSet::MATCH_BIGGER);
98    if (!path.empty()) {
99      info->default_icon.Add(
100          extension_misc::kScriptBadgeIconSizes[i], path);
101    }
102  }
103}
104
105const std::vector<std::string> ScriptBadgeHandler::Keys() const {
106  return SingleKey(keys::kScriptBadge);
107}
108
109}  // namespace extensions
110