blob: 0b4823e43b883d686650e034e7c2e90d77a37c22 [file] [log] [blame]
// Copyright 2013 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 "components/safe_json/safe_json_parser_impl.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/thread_task_runner_handle.h"
#include "base/tuple.h"
#include "base/values.h"
#include "components/safe_json/safe_json_parser_messages.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/utility_process_host.h"
#include "grit/components_strings.h"
#include "ipc/ipc_message_macros.h"
#include "ui/base/l10n/l10n_util.h"
using content::BrowserThread;
using content::UtilityProcessHost;
namespace safe_json {
SafeJsonParserImpl::SafeJsonParserImpl(const std::string& unsafe_json,
const SuccessCallback& success_callback,
const ErrorCallback& error_callback)
: unsafe_json_(unsafe_json),
success_callback_(success_callback),
error_callback_(error_callback) {}
SafeJsonParserImpl::~SafeJsonParserImpl() {
}
void SafeJsonParserImpl::StartWorkOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
UtilityProcessHost* host = UtilityProcessHost::Create(
this, base::ThreadTaskRunnerHandle::Get().get());
host->SetName(
l10n_util::GetStringUTF16(IDS_UTILITY_PROCESS_JSON_PARSER_NAME));
host->Send(new SafeJsonParserMsg_ParseJSON(unsafe_json_));
}
void SafeJsonParserImpl::OnJSONParseSucceeded(const base::ListValue& wrapper) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
const base::Value* value = NULL;
CHECK(wrapper.Get(0, &value));
parsed_json_.reset(value->DeepCopy());
ReportResults();
}
void SafeJsonParserImpl::OnJSONParseFailed(const std::string& error_message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
error_ = error_message;
ReportResults();
}
void SafeJsonParserImpl::ReportResults() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
caller_task_runner_->PostTask(
FROM_HERE,
base::Bind(&SafeJsonParserImpl::ReportResultsOnOriginThread, this));
}
void SafeJsonParserImpl::ReportResultsOnOriginThread() {
DCHECK(caller_task_runner_->RunsTasksOnCurrentThread());
if (error_.empty() && parsed_json_) {
if (!success_callback_.is_null())
success_callback_.Run(parsed_json_.Pass());
} else {
if (!error_callback_.is_null())
error_callback_.Run(error_);
}
}
bool SafeJsonParserImpl::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(SafeJsonParserImpl, message)
IPC_MESSAGE_HANDLER(SafeJsonParserHostMsg_ParseJSON_Succeeded,
OnJSONParseSucceeded)
IPC_MESSAGE_HANDLER(SafeJsonParserHostMsg_ParseJSON_Failed,
OnJSONParseFailed)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void SafeJsonParserImpl::Start() {
caller_task_runner_ = base::ThreadTaskRunnerHandle::Get();
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::Bind(&SafeJsonParserImpl::StartWorkOnIOThread, this));
}
} // namespace safe_json