Home | History | Annotate | Download | only in web_resource
      1 // Copyright (c) 2012 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/web_resource/json_asynchronous_unpacker.h"
      6 
      7 #include "base/command_line.h"
      8 #include "chrome/browser/web_resource/web_resource_service.h"
      9 #include "chrome/common/chrome_switches.h"
     10 #include "chrome/common/chrome_utility_messages.h"
     11 #include "content/public/browser/browser_thread.h"
     12 #include "content/public/browser/utility_process_host.h"
     13 #include "content/public/browser/utility_process_host_client.h"
     14 
     15 using content::BrowserThread;
     16 using content::UtilityProcessHost;
     17 using content::UtilityProcessHostClient;
     18 
     19 // This class coordinates a web resource unpack and parse task which is run in
     20 // a separate process.  Results are sent back to this class and routed to
     21 // the WebResourceService.
     22 class JSONAsynchronousUnpackerImpl
     23     : public UtilityProcessHostClient,
     24       public JSONAsynchronousUnpacker {
     25  public:
     26   explicit JSONAsynchronousUnpackerImpl(
     27       JSONAsynchronousUnpackerDelegate* delegate)
     28     : JSONAsynchronousUnpacker(delegate),
     29       got_response_(false) {
     30   }
     31 
     32   virtual void Start(const std::string& json_data) OVERRIDE {
     33     AddRef();  // balanced in Cleanup.
     34 
     35     BrowserThread::ID thread_id;
     36     CHECK(BrowserThread::GetCurrentThreadIdentifier(&thread_id));
     37     BrowserThread::PostTask(
     38         BrowserThread::IO, FROM_HERE,
     39         base::Bind(
     40             &JSONAsynchronousUnpackerImpl::StartProcessOnIOThread,
     41             this, thread_id, json_data));
     42   }
     43 
     44  private:
     45   virtual ~JSONAsynchronousUnpackerImpl() {}
     46 
     47   // UtilityProcessHostClient.
     48   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
     49     bool handled = true;
     50     IPC_BEGIN_MESSAGE_MAP(JSONAsynchronousUnpackerImpl, message)
     51       IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackWebResource_Succeeded,
     52                           OnUnpackWebResourceSucceeded)
     53       IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_UnpackWebResource_Failed,
     54                           OnUnpackWebResourceFailed)
     55       IPC_MESSAGE_UNHANDLED(handled = false)
     56     IPC_END_MESSAGE_MAP()
     57     return handled;
     58   }
     59 
     60   virtual void OnProcessCrashed(int exit_code) OVERRIDE {
     61     if (got_response_)
     62       return;
     63 
     64     OnUnpackWebResourceFailed(
     65         "Utility process crashed while trying to retrieve web resources.");
     66   }
     67 
     68   void OnUnpackWebResourceSucceeded(
     69       const base::DictionaryValue& parsed_json) {
     70     if (delegate_)
     71       delegate_->OnUnpackFinished(parsed_json);
     72     Cleanup();
     73   }
     74 
     75   void OnUnpackWebResourceFailed(const std::string& error_message) {
     76     if (delegate_)
     77       delegate_->OnUnpackError(error_message);
     78     Cleanup();
     79   }
     80 
     81   // Release reference and set got_response_.
     82   void Cleanup() {
     83     DCHECK(!got_response_);
     84     got_response_ = true;
     85     Release();
     86   }
     87 
     88   void StartProcessOnIOThread(BrowserThread::ID thread_id,
     89                               const std::string& json_data) {
     90     UtilityProcessHost* host = UtilityProcessHost::Create(
     91         this, BrowserThread::GetMessageLoopProxyForThread(thread_id).get());
     92     // TODO(mrc): get proper file path when we start using web resources
     93     // that need to be unpacked.
     94     host->Send(new ChromeUtilityMsg_UnpackWebResource(json_data));
     95   }
     96 
     97   // True if we got a response from the utility process and have cleaned up
     98   // already.
     99   bool got_response_;
    100 };
    101 
    102 JSONAsynchronousUnpacker* JSONAsynchronousUnpacker::Create(
    103     JSONAsynchronousUnpackerDelegate* delegate) {
    104   return new JSONAsynchronousUnpackerImpl(delegate);
    105 }
    106 
    107