1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/webstore_install_helper.h"
#include "base/bind.h"
#include "base/values.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/safe_json_parser.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_request.h"
using content::BrowserThread;
namespace {
const char kImageDecodeError[] = "Image decode failed";
} // namespace
namespace extensions {
WebstoreInstallHelper::WebstoreInstallHelper(
Delegate* delegate,
const std::string& id,
const std::string& manifest,
const GURL& icon_url,
net::URLRequestContextGetter* context_getter)
: delegate_(delegate),
id_(id),
manifest_(manifest),
icon_url_(icon_url),
context_getter_(context_getter),
icon_decode_complete_(false),
manifest_parse_complete_(false),
parse_error_(Delegate::UNKNOWN_ERROR) {
}
WebstoreInstallHelper::~WebstoreInstallHelper() {}
void WebstoreInstallHelper::Start() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// No existing |json_parser_| to avoid unbalanced AddRef().
CHECK(!json_parser_.get());
AddRef(); // Balanced in OnJSONParseSucceeded()/OnJSONParseFailed().
// Use base::Unretained so that base::Bind won't AddRef() on us. Otherwise,
// we'll have two callbacks holding references to us, only one of which will
// ever be called.
json_parser_ = new SafeJsonParser(
manifest_,
base::Bind(&WebstoreInstallHelper::OnJSONParseSucceeded,
base::Unretained(this)),
base::Bind(&WebstoreInstallHelper::OnJSONParseFailed,
base::Unretained(this)));
json_parser_->Start();
if (icon_url_.is_empty()) {
icon_decode_complete_ = true;
} else {
// No existing |icon_fetcher_| to avoid unbalanced AddRef().
CHECK(!icon_fetcher_.get());
AddRef(); // Balanced in OnFetchComplete().
icon_fetcher_.reset(new chrome::BitmapFetcher(icon_url_, this));
icon_fetcher_->Start(
context_getter_, std::string(),
net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE,
net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES);
}
}
void WebstoreInstallHelper::OnFetchComplete(const GURL& url,
const SkBitmap* image) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// OnFetchComplete should only be called as icon_fetcher_ delegate to avoid
// unbalanced Release().
CHECK(icon_fetcher_.get());
if (image)
icon_ = *image;
icon_decode_complete_ = true;
if (icon_.empty()) {
error_ = kImageDecodeError;
parse_error_ = Delegate::ICON_ERROR;
}
icon_fetcher_.reset();
ReportResultsIfComplete();
Release(); // Balanced in Start().
}
void WebstoreInstallHelper::OnJSONParseSucceeded(
scoped_ptr<base::Value> result) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
manifest_parse_complete_ = true;
const base::DictionaryValue* value;
if (result->GetAsDictionary(&value))
parsed_manifest_.reset(value->DeepCopy());
else
parse_error_ = Delegate::MANIFEST_ERROR;
ReportResultsIfComplete();
Release(); // Balanced in Start().
}
void WebstoreInstallHelper::OnJSONParseFailed(
const std::string& error_message) {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
manifest_parse_complete_ = true;
error_ = error_message;
parse_error_ = Delegate::MANIFEST_ERROR;
ReportResultsIfComplete();
Release(); // Balanced in Start().
}
void WebstoreInstallHelper::ReportResultsIfComplete() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!icon_decode_complete_ || !manifest_parse_complete_)
return;
if (error_.empty() && parsed_manifest_)
delegate_->OnWebstoreParseSuccess(id_, icon_, parsed_manifest_.release());
else
delegate_->OnWebstoreParseFailure(id_, parse_error_, error_);
}
} // namespace extensions
|