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"
10 #include "base/values.h"
11 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
12 #include "chrome/common/chrome_utility_messages.h"
13 #include "chrome/common/extensions/chrome_utility_extensions_messages.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/utility_process_host.h"
16 #include "net/base/load_flags.h"
17 #include "net/url_request/url_request.h"
19 using content::BrowserThread
;
20 using content::UtilityProcessHost
;
24 const char kImageDecodeError
[] = "Image decode failed";
28 namespace extensions
{
30 WebstoreInstallHelper::WebstoreInstallHelper(
32 const std::string
& id
,
33 const std::string
& manifest
,
35 net::URLRequestContextGetter
* context_getter
)
36 : delegate_(delegate
),
40 context_getter_(context_getter
),
41 icon_decode_complete_(false),
42 manifest_parse_complete_(false),
43 parse_error_(Delegate::UNKNOWN_ERROR
) {
46 WebstoreInstallHelper::~WebstoreInstallHelper() {}
48 void WebstoreInstallHelper::Start() {
49 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
51 if (icon_url_
.is_empty()) {
52 icon_decode_complete_
= true;
54 icon_fetcher_
.reset(new chrome::BitmapFetcher(icon_url_
, this));
56 context_getter_
, std::string(),
57 net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE
,
58 net::LOAD_DO_NOT_SAVE_COOKIES
| net::LOAD_DO_NOT_SEND_COOKIES
);
61 BrowserThread::PostTask(
64 base::Bind(&WebstoreInstallHelper::StartWorkOnIOThread
, this));
67 void WebstoreInstallHelper::StartWorkOnIOThread() {
68 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
69 utility_host_
= UtilityProcessHost::Create(
70 this, base::MessageLoopProxy::current().get())->AsWeakPtr();
71 utility_host_
->StartBatchMode();
73 utility_host_
->Send(new ChromeUtilityMsg_ParseJSON(manifest_
));
76 bool WebstoreInstallHelper::OnMessageReceived(const IPC::Message
& message
) {
78 IPC_BEGIN_MESSAGE_MAP(WebstoreInstallHelper
, message
)
79 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Succeeded
,
81 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_ParseJSON_Failed
,
83 IPC_MESSAGE_UNHANDLED(handled
= false)
88 void WebstoreInstallHelper::OnFetchComplete(const GURL
& url
,
89 const SkBitmap
* image
) {
90 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
93 icon_decode_complete_
= true;
95 error_
= kImageDecodeError
;
96 parse_error_
= Delegate::ICON_ERROR
;
98 icon_fetcher_
.reset();
99 BrowserThread::PostTask(
102 base::Bind(&WebstoreInstallHelper::ReportResultsIfComplete
, this));
105 void WebstoreInstallHelper::OnJSONParseSucceeded(
106 const base::ListValue
& wrapper
) {
107 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
108 manifest_parse_complete_
= true;
109 const base::Value
* value
= NULL
;
110 CHECK(wrapper
.Get(0, &value
));
111 if (value
->IsType(base::Value::TYPE_DICTIONARY
)) {
112 parsed_manifest_
.reset(
113 static_cast<const base::DictionaryValue
*>(value
)->DeepCopy());
115 parse_error_
= Delegate::MANIFEST_ERROR
;
117 ReportResultsIfComplete();
120 void WebstoreInstallHelper::OnJSONParseFailed(
121 const std::string
& error_message
) {
122 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
123 manifest_parse_complete_
= true;
124 error_
= error_message
;
125 parse_error_
= Delegate::MANIFEST_ERROR
;
126 ReportResultsIfComplete();
129 void WebstoreInstallHelper::ReportResultsIfComplete() {
130 CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
132 if (!icon_decode_complete_
|| !manifest_parse_complete_
)
135 // The utility_host_ will take care of deleting itself after this call.
136 if (utility_host_
.get()) {
137 utility_host_
->EndBatchMode();
138 utility_host_
.reset();
141 BrowserThread::PostTask(
144 base::Bind(&WebstoreInstallHelper::ReportResultFromUIThread
, this));
147 void WebstoreInstallHelper::ReportResultFromUIThread() {
148 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
149 if (error_
.empty() && parsed_manifest_
)
150 delegate_
->OnWebstoreParseSuccess(id_
, icon_
, parsed_manifest_
.release());
152 delegate_
->OnWebstoreParseFailure(id_
, parse_error_
, error_
);
155 } // namespace extensions