- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / web_resource / json_asynchronous_unpacker.cc
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 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     host->EnableZygote();
93     // TODO(mrc): get proper file path when we start using web resources
94     // that need to be unpacked.
95     host->Send(new ChromeUtilityMsg_UnpackWebResource(json_data));
96   }
97
98   // True if we got a response from the utility process and have cleaned up
99   // already.
100   bool got_response_;
101 };
102
103 JSONAsynchronousUnpacker* JSONAsynchronousUnpacker::Create(
104     JSONAsynchronousUnpackerDelegate* delegate) {
105   return new JSONAsynchronousUnpackerImpl(delegate);
106 }
107