Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_install_helper.cc
blob7fd097413e4bffcbb74c1bd93ec945f1c388cfd0
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.
5 #include "chrome/browser/extensions/webstore_install_helper.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/values.h"
11 #include "chrome/common/chrome_utility_messages.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/utility_process_host.h"
14 #include "net/base/load_flags.h"
15 #include "net/url_request/url_fetcher.h"
16 #include "net/url_request/url_request_context_getter.h"
17 #include "net/url_request/url_request_status.h"
19 using content::BrowserThread;
20 using content::UtilityProcessHost;
22 namespace {
24 const char kImageDecodeError[] = "Image decode failed";
26 } // namespace
28 namespace extensions {
30 WebstoreInstallHelper::WebstoreInstallHelper(
31 Delegate* delegate,
32 const std::string& id,
33 const std::string& manifest,
34 const std::string& icon_data,
35 const GURL& icon_url,
36 net::URLRequestContextGetter* context_getter)
37 : delegate_(delegate),
38 id_(id),
39 manifest_(manifest),
40 icon_base64_data_(icon_data),
41 icon_url_(icon_url),
42 context_getter_(context_getter),
43 icon_decode_complete_(false),
44 manifest_parse_complete_(false),
45 parse_error_(Delegate::UNKNOWN_ERROR) {}
47 WebstoreInstallHelper::~WebstoreInstallHelper() {}
49 void WebstoreInstallHelper::Start() {
50 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
51 CHECK(icon_base64_data_.empty() || icon_url_.is_empty());
53 if (icon_base64_data_.empty() && icon_url_.is_empty())
54 icon_decode_complete_ = true;
56 BrowserThread::PostTask(
57 BrowserThread::IO,
58 FROM_HERE,
59 base::Bind(&WebstoreInstallHelper::StartWorkOnIOThread, this));
61 if (!icon_url_.is_empty()) {
62 CHECK(context_getter_);
63 url_fetcher_.reset(net::URLFetcher::Create(
64 icon_url_, net::URLFetcher::GET, this));
65 url_fetcher_->SetRequestContext(context_getter_);
66 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
67 net::LOAD_DO_NOT_SEND_COOKIES);
69 url_fetcher_->Start();
70 // We'll get called back in OnURLFetchComplete.
74 void WebstoreInstallHelper::StartWorkOnIOThread() {
75 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
76 utility_host_ = UtilityProcessHost::Create(
77 this, base::MessageLoopProxy::current().get())->AsWeakPtr();
78 utility_host_->StartBatchMode();
80 if (!icon_base64_data_.empty())
81 utility_host_->Send(
82 new ChromeUtilityMsg_DecodeImageBase64(icon_base64_data_));
84 utility_host_->Send(new ChromeUtilityMsg_ParseJSON(manifest_));
87 void WebstoreInstallHelper::OnURLFetchComplete(
88 const net::URLFetcher* source) {
89 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
90 CHECK(source == url_fetcher_.get());
91 if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS ||
92 source->GetResponseCode() != 200) {
93 BrowserThread::PostTask(
94 BrowserThread::IO,
95 FROM_HERE,
96 base::Bind(&WebstoreInstallHelper::OnDecodeImageFailed, this));
97 } else {
98 std::string response_data;
99 source->GetResponseAsString(&response_data);
100 fetched_icon_data_.insert(fetched_icon_data_.begin(),
101 response_data.begin(),
102 response_data.end());
103 BrowserThread::PostTask(
104 BrowserThread::IO,
105 FROM_HERE,
106 base::Bind(&WebstoreInstallHelper::StartFetchedImageDecode, this));
108 url_fetcher_.reset();
111 void WebstoreInstallHelper::StartFetchedImageDecode() {
112 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
113 CHECK(utility_host_.get());
114 utility_host_->Send(new ChromeUtilityMsg_DecodeImage(fetched_icon_data_));
118 bool WebstoreInstallHelper::OnMessageReceived(const IPC::Message& message) {
119 bool handled = true;
120 IPC_BEGIN_MESSAGE_MAP(WebstoreInstallHelper, message)
121 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Succeeded,
122 OnDecodeImageSucceeded)
123 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DecodeImage_Failed,
124 OnDecodeImageFailed)
125 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded,
126 OnJSONParseSucceeded)
127 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed,
128 OnJSONParseFailed)
129 IPC_MESSAGE_UNHANDLED(handled = false)
130 IPC_END_MESSAGE_MAP()
131 return handled;
135 void WebstoreInstallHelper::OnDecodeImageSucceeded(
136 const SkBitmap& decoded_image) {
137 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
138 icon_ = decoded_image;
139 icon_decode_complete_ = true;
140 ReportResultsIfComplete();
143 void WebstoreInstallHelper::OnDecodeImageFailed() {
144 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
145 icon_decode_complete_ = true;
146 error_ = kImageDecodeError;
147 parse_error_ = Delegate::ICON_ERROR;
148 ReportResultsIfComplete();
151 void WebstoreInstallHelper::OnJSONParseSucceeded(
152 const base::ListValue& wrapper) {
153 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
154 manifest_parse_complete_ = true;
155 const base::Value* value = NULL;
156 CHECK(wrapper.Get(0, &value));
157 if (value->IsType(base::Value::TYPE_DICTIONARY)) {
158 parsed_manifest_.reset(
159 static_cast<const base::DictionaryValue*>(value)->DeepCopy());
160 } else {
161 parse_error_ = Delegate::MANIFEST_ERROR;
163 ReportResultsIfComplete();
166 void WebstoreInstallHelper::OnJSONParseFailed(
167 const std::string& error_message) {
168 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
169 manifest_parse_complete_ = true;
170 error_ = error_message;
171 parse_error_ = Delegate::MANIFEST_ERROR;
172 ReportResultsIfComplete();
175 void WebstoreInstallHelper::ReportResultsIfComplete() {
176 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
178 if (!icon_decode_complete_ || !manifest_parse_complete_)
179 return;
181 // The utility_host_ will take care of deleting itself after this call.
182 if (utility_host_.get()) {
183 utility_host_->EndBatchMode();
184 utility_host_.reset();
187 BrowserThread::PostTask(
188 BrowserThread::UI,
189 FROM_HERE,
190 base::Bind(&WebstoreInstallHelper::ReportResultFromUIThread, this));
193 void WebstoreInstallHelper::ReportResultFromUIThread() {
194 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 if (error_.empty() && parsed_manifest_)
196 delegate_->OnWebstoreParseSuccess(id_, icon_, parsed_manifest_.release());
197 else
198 delegate_->OnWebstoreParseFailure(id_, parse_error_, error_);
201 } // namespace extensions