Home | History | Annotate | Download | only in browser
      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/browser/safe_json_parser.h"
      6 
      7 #include "chrome/common/chrome_utility_messages.h"
      8 #include "content/public/browser/browser_thread.h"
      9 #include "content/public/browser/utility_process_host.h"
     10 
     11 using content::BrowserThread;
     12 using content::UtilityProcessHost;
     13 
     14 SafeJsonParser::SafeJsonParser(const std::string& unsafe_json,
     15                                const SuccessCallback& success_callback,
     16                                const ErrorCallback& error_callback)
     17     : unsafe_json_(unsafe_json),
     18       success_callback_(success_callback),
     19       error_callback_(error_callback) {}
     20 
     21 void SafeJsonParser::Start() {
     22   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     23   BrowserThread::PostTask(
     24       BrowserThread::IO,
     25       FROM_HERE,
     26       base::Bind(&SafeJsonParser::StartWorkOnIOThread, this));
     27 }
     28 
     29 SafeJsonParser::~SafeJsonParser() {}
     30 
     31 void SafeJsonParser::StartWorkOnIOThread() {
     32   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     33   UtilityProcessHost* host =
     34       UtilityProcessHost::Create(this, base::MessageLoopProxy::current().get());
     35   host->Send(new ChromeUtilityMsg_ParseJSON(unsafe_json_));
     36 }
     37 
     38 void SafeJsonParser::OnJSONParseSucceeded(const base::ListValue& wrapper) {
     39   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     40   const Value* value = NULL;
     41   CHECK(wrapper.Get(0, &value));
     42 
     43   parsed_json_.reset(value->DeepCopy());
     44   ReportResults();
     45 }
     46 
     47 void SafeJsonParser::OnJSONParseFailed(const std::string& error_message) {
     48   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     49   error_ = error_message;
     50   ReportResults();
     51 }
     52 
     53 void SafeJsonParser::ReportResults() {
     54   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
     55 
     56   BrowserThread::PostTask(
     57       BrowserThread::UI,
     58       FROM_HERE,
     59       base::Bind(&SafeJsonParser::ReportResultOnUIThread, this));
     60 }
     61 
     62 void SafeJsonParser::ReportResultOnUIThread() {
     63   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     64   if (error_.empty() && parsed_json_) {
     65     if (!success_callback_.is_null())
     66       success_callback_.Run(parsed_json_.Pass());
     67   } else {
     68     if (!error_callback_.is_null())
     69       error_callback_.Run(error_);
     70   }
     71 }
     72 
     73 bool SafeJsonParser::OnMessageReceived(const IPC::Message& message) {
     74   bool handled = true;
     75   IPC_BEGIN_MESSAGE_MAP(SafeJsonParser, message)
     76     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
     77                         OnJSONParseSucceeded)
     78     IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
     79                         OnJSONParseFailed)
     80     IPC_MESSAGE_UNHANDLED(handled = false)
     81   IPC_END_MESSAGE_MAP()
     82   return handled;
     83 }
     84