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 "chrome/common/extensions/api/media_galleries_private/media_galleries_handler.h"
6
7#include "base/logging.h"
8#include "base/strings/string_number_conversions.h"
9#include "base/strings/string_util.h"
10#include "base/strings/utf_string_conversions.h"
11#include "base/values.h"
12#include "chrome/common/extensions/extension_constants.h"
13#include "chrome/common/extensions/extension_manifest_constants.h"
14#include "chrome/common/extensions/manifest.h"
15#include "extensions/common/error_utils.h"
16
17namespace keys = extension_manifest_keys;
18namespace errors = extension_manifest_errors;
19
20namespace {
21
22// Stored on the Extension.
23struct MediaGalleriesHandlerInfo : public extensions::Extension::ManifestData {
24  MediaGalleriesHandler::List media_galleries_handlers;
25
26  MediaGalleriesHandlerInfo();
27  virtual ~MediaGalleriesHandlerInfo();
28};
29
30MediaGalleriesHandlerInfo::MediaGalleriesHandlerInfo() {
31}
32
33MediaGalleriesHandlerInfo::~MediaGalleriesHandlerInfo() {
34}
35
36MediaGalleriesHandler* LoadMediaGalleriesHandler(
37    const std::string& extension_id,
38    const DictionaryValue* media_galleries_handler,
39    string16* error) {
40  scoped_ptr<MediaGalleriesHandler> result(new MediaGalleriesHandler());
41  result->set_extension_id(extension_id);
42
43  std::string handler_id;
44  // Read the file action |id| (mandatory).
45  if (!media_galleries_handler->HasKey(keys::kPageActionId) ||
46      !media_galleries_handler->GetString(keys::kPageActionId, &handler_id)) {
47    *error = ASCIIToUTF16(errors::kInvalidPageActionId);
48    return NULL;
49  }
50  result->set_id(handler_id);
51
52  // Read the page action title from |default_title| (mandatory).
53  std::string title;
54  if (!media_galleries_handler->HasKey(keys::kPageActionDefaultTitle) ||
55      !media_galleries_handler->GetString(keys::kPageActionDefaultTitle,
56                                          &title)) {
57    *error = ASCIIToUTF16(errors::kInvalidPageActionDefaultTitle);
58    return NULL;
59  }
60  result->set_title(title);
61
62  std::string default_icon;
63  // Read the media galleries action |default_icon| (optional).
64  if (media_galleries_handler->HasKey(keys::kPageActionDefaultIcon)) {
65    if (!media_galleries_handler->GetString(
66            keys::kPageActionDefaultIcon, &default_icon) ||
67        default_icon.empty()) {
68      *error = ASCIIToUTF16(errors::kInvalidPageActionIconPath);
69      return NULL;
70    }
71    result->set_icon_path(default_icon);
72  }
73
74  return result.release();
75}
76
77// Loads MediaGalleriesHandlers from |extension_actions| into a list in
78// |result|.
79bool LoadMediaGalleriesHandlers(
80    const std::string& extension_id,
81    const base::ListValue* extension_actions,
82    MediaGalleriesHandler::List* result,
83    string16* error) {
84  for (base::ListValue::const_iterator iter = extension_actions->begin();
85       iter != extension_actions->end();
86       ++iter) {
87    if (!(*iter)->IsType(Value::TYPE_DICTIONARY)) {
88      *error = ASCIIToUTF16(errors::kInvalidMediaGalleriesHandler);
89      return false;
90    }
91    scoped_ptr<MediaGalleriesHandler> action(
92        LoadMediaGalleriesHandler(
93            extension_id, reinterpret_cast<DictionaryValue*>(*iter), error));
94    if (!action)
95      return false;  // Failed to parse media galleries action definition.
96    result->push_back(linked_ptr<MediaGalleriesHandler>(action.release()));
97  }
98  return true;
99}
100
101}  // namespace
102
103MediaGalleriesHandler::MediaGalleriesHandler() {
104}
105
106MediaGalleriesHandler::~MediaGalleriesHandler() {
107}
108
109// static
110MediaGalleriesHandler::List*
111MediaGalleriesHandler::GetHandlers(const extensions::Extension* extension) {
112  MediaGalleriesHandlerInfo* info = static_cast<MediaGalleriesHandlerInfo*>(
113      extension->GetManifestData(keys::kMediaGalleriesHandlers));
114  if (info)
115    return &info->media_galleries_handlers;
116  return NULL;
117}
118
119MediaGalleriesHandlerParser::MediaGalleriesHandlerParser() {
120}
121
122MediaGalleriesHandlerParser::~MediaGalleriesHandlerParser() {
123}
124
125bool MediaGalleriesHandlerParser::Parse(extensions::Extension* extension,
126                                        string16* error) {
127  const base::ListValue* media_galleries_handlers_value = NULL;
128  if (!extension->manifest()->GetList(keys::kMediaGalleriesHandlers,
129                                      &media_galleries_handlers_value)) {
130    *error = ASCIIToUTF16(errors::kInvalidMediaGalleriesHandler);
131    return false;
132  }
133  scoped_ptr<MediaGalleriesHandlerInfo> info(new MediaGalleriesHandlerInfo);
134  if (!LoadMediaGalleriesHandlers(extension->id(),
135                                  media_galleries_handlers_value,
136                                  &info->media_galleries_handlers,
137                                  error)) {
138    return false;  // Failed to parse media galleries actions definition.
139  }
140
141  extension->SetManifestData(keys::kMediaGalleriesHandlers, info.release());
142  return true;
143}
144
145const std::vector<std::string> MediaGalleriesHandlerParser::Keys() const {
146  return SingleKey(keys::kMediaGalleriesHandlers);
147}
148