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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider_json.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/string_escape.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_provider.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/automation/automation_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_id.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using automation::Error;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using automation::ErrorCode;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationJSONReply::AutomationJSONReply(AutomationProvider* provider,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         IPC::Message* reply_message)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : provider_(provider),
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_(reply_message) {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationJSONReply::~AutomationJSONReply() {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!message_) << "JSON automation request not replied!";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationJSONReply::SendSuccess(const Value* value) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(message_) << "Resending reply for JSON automation request";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json_string = "{}";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONWriter::Write(value, &json_string);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationMsg_SendJSONRequest::WriteReplyParams(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      message_, json_string, true);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider_->Send(message_);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_ = NULL;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationJSONReply::SendError(const std::string& error_message) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendError(Error(error_message));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationJSONReply::SendErrorCode(ErrorCode code) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SendError(Error(code));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutomationJSONReply::SendError(const Error& error) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(message_) << "Resending reply for JSON automation request";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue dict;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict.SetString("error", error.message());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  dict.SetInteger("code", error.code());
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(&dict, &json);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationMsg_SendJSONRequest::WriteReplyParams(message_, json, false);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  provider_->Send(message_);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_ = NULL;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetBrowserFromJSONArgs(
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* args,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser** browser,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args->HasKey("auto_id")) {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationId id;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetAutomationIdFromJSONArgs(args, "auto_id", &id, error))
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* tab;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_util::GetTabForId(id, &tab)) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "'auto_id' does not refer to an open tab";
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* container = automation_util::GetBrowserForTab(tab);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!container) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "tab does not belong to an open browser";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *browser = container;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_index;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!args->GetInteger("windex", &browser_index)) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "'windex' missing or invalid";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *browser = automation_util::GetBrowserAt(browser_index);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!*browser) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "Cannot locate browser from given index";
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetTabFromJSONArgs(
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* args,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents** tab,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args->HasKey("auto_id")) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationId id;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetAutomationIdFromJSONArgs(args, "auto_id", &id, error))
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_util::GetTabForId(id, tab)) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "'auto_id' does not refer to an open tab";
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_index, tab_index;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!args->GetInteger("windex", &browser_index)) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "'windex' missing or invalid";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!args->GetInteger("tab_index", &tab_index)) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "'tab_index' missing or invalid";
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *tab = automation_util::GetWebContentsAt(browser_index, tab_index);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!*tab) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "Cannot locate tab from given indices";
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetBrowserAndTabFromJSONArgs(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* args,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser** browser,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents** tab,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetBrowserFromJSONArgs(args, browser, error) &&
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         GetTabFromJSONArgs(args, tab, error);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetAutomationIdFromJSONArgs(
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* args,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationId* id,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* id_value;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!args->Get(key, &id_value)) {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = base::StringPrintf("Missing parameter '%s'", key.c_str());
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return AutomationId::FromValue(id_value, id, error);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetRenderViewFromJSONArgs(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* args,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderViewHost** rvh,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* id_value;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (args->Get("auto_id", &id_value)) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationId id;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!AutomationId::FromValue(id_value, &id, error))
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation_util::GetRenderViewForId(id, profile, rvh)) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = "ID does not correspond to an open view";
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the render view id is not specified, check for browser/tab indices.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebContents* tab = NULL;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetTabFromJSONArgs(args, &tab, error))
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *rvh = tab->GetRenderViewHost();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetExtensionFromJSONArgsHelper(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* args,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool include_disabled,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension** extension,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!args->GetString(key, &id)) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = base::StringPrintf("Missing or invalid key: %s", key.c_str());
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionService* service = extensions::ExtensionSystem::Get(profile)->
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      extension_service();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!service) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = "No extensions service.";
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!service->GetInstalledExtension(id)) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The extension ID does not correspond to any extension, whether crashed
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // or not.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = base::StringPrintf("Extension %s is not installed.",
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                id.c_str());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const extensions::Extension* installed_extension =
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service->GetExtensionById(id, include_disabled);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!installed_extension) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = "Extension is disabled or has crashed.";
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *extension = installed_extension;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetExtensionFromJSONArgs(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* args,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension** extension,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetExtensionFromJSONArgsHelper(
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      args, key, profile, true /* include_disabled */, extension, error);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetEnabledExtensionFromJSONArgs(
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* args,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& key,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension** extension,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string* error) {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetExtensionFromJSONArgsHelper(
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      args, key, profile, false /* include_disabled */, extension, error);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
237