15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/context_menus/context_menus_api.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/api/context_menus/context_menus_api_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/menu_manager.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/api/context_menus.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/error_utils.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "extensions/common/url_pattern_set.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::ErrorUtils;
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace helpers = extensions::context_menus_api_helpers;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIdRequiredError[] = "Extensions using event pages must pass an "
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "id parameter to chrome.contextMenus.create";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Create = api::context_menus::Create;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Remove = api::context_menus::Remove;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace Update = api::context_menus::Update;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ContextMenusCreateFunction::RunSync() {
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MenuItem::Id id(GetProfile()->IsOffTheRecord(),
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  MenuItem::ExtensionKey(extension_id()));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Create::Params> params(Create::Params::Create(*args_));
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params->create_properties.id.get()) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id.string_uid = *params->create_properties.id;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (BackgroundInfo::HasLazyBackgroundPage(extension())) {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_ = kIdRequiredError;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The Generated Id is added by context_menus_custom_bindings.js.
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::DictionaryValue* properties = NULL;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &properties));
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXTENSION_FUNCTION_VALIDATE(
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        properties->GetInteger(helpers::kGeneratedIdKey, &id.uid));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return helpers::CreateMenuItem(
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      params->create_properties, GetProfile(), extension(), id, &error_);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ContextMenusUpdateFunction::RunSync() {
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MenuItem::Id item_id(GetProfile()->IsOffTheRecord(),
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       MenuItem::ExtensionKey(extension_id()));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Update::Params> params(Update::Params::Create(*args_));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->id.as_string)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    item_id.string_uid = *params->id.as_string;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (params->id.as_integer)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    item_id.uid = *params->id.as_integer;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return helpers::UpdateMenuItem(
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      params->update_properties, GetProfile(), extension(), item_id, &error_);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ContextMenusRemoveFunction::RunSync() {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Remove::Params> params(Remove::Params::Create(*args_));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTENSION_FUNCTION_VALIDATE(params.get());
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MenuManager* manager = MenuManager::Get(GetProfile());
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MenuItem::Id id(GetProfile()->IsOffTheRecord(),
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  MenuItem::ExtensionKey(extension_id()));
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (params->menu_item_id.as_string)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id.string_uid = *params->menu_item_id.as_string;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else if (params->menu_item_id.as_integer)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    id.uid = *params->menu_item_id.as_integer;
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MenuItem* item = manager->GetItemById(id);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure one extension can't remove another's menu items.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!item || item->extension_id() != extension_id()) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    error_ = ErrorUtils::FormatErrorMessage(
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        helpers::kCannotFindItemError, helpers::GetIDString(id));
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!manager->RemoveContextMenuItem(id))
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  manager->WriteToStorage(extension(), id.extension_key);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool ContextMenusRemoveAllFunction::RunSync() {
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  MenuManager* manager = MenuManager::Get(GetProfile());
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  manager->RemoveAllContextItems(MenuItem::ExtensionKey(extension()->id()));
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  manager->WriteToStorage(extension(),
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          MenuItem::ExtensionKey(extension()->id()));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
115