Remove unused field from extension_sorting.cc
[chromium-blink-merge.git] / chrome / browser / extensions / webstore_standalone_installer.cc
blob8508281ab0a75851010de1e4b4ff129f05a9cf33
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_standalone_installer.h"
7 #include "base/values.h"
8 #include "chrome/browser/extensions/crx_installer.h"
9 #include "chrome/browser/extensions/extension_install_prompt.h"
10 #include "chrome/browser/extensions/extension_install_ui.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/webstore_data_fetcher.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/common/extensions/extension.h"
15 #include "content/public/browser/web_contents.h"
16 #include "googleurl/src/gurl.h"
18 using content::WebContents;
20 namespace extensions {
22 const char kManifestKey[] = "manifest";
23 const char kIconUrlKey[] = "icon_url";
24 const char kLocalizedNameKey[] = "localized_name";
25 const char kLocalizedDescriptionKey[] = "localized_description";
26 const char kUsersKey[] = "users";
27 const char kAverageRatingKey[] = "average_rating";
28 const char kRatingCountKey[] = "rating_count";
29 const char kRedirectUrlKey[] = "redirect_url";
31 const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID";
32 const char kWebstoreRequestError[] =
33 "Could not fetch data from the Chrome Web Store";
34 const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse";
35 const char kInvalidManifestError[] = "Invalid manifest";
36 const char kUserCancelledError[] = "User cancelled install";
39 WebstoreStandaloneInstaller::WebstoreStandaloneInstaller(
40 const std::string& webstore_item_id,
41 Profile* profile,
42 const Callback& callback)
43 : id_(webstore_item_id),
44 callback_(callback),
45 profile_(profile),
46 average_rating_(0.0),
47 rating_count_(0) {
48 CHECK(!callback_.is_null());
51 WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {}
54 // Private interface implementation.
57 void WebstoreStandaloneInstaller::BeginInstall() {
58 AddRef(); // Balanced in CompleteInstall or WebContentsDestroyed.
60 if (!Extension::IdIsValid(id_)) {
61 CompleteInstall(kInvalidWebstoreItemId);
62 return;
65 // Use the requesting page as the referrer both since that is more correct
66 // (it is the page that caused this request to happen) and so that we can
67 // track top sites that trigger inline install requests.
68 webstore_data_fetcher_.reset(new WebstoreDataFetcher(
69 this,
70 profile_->GetRequestContext(),
71 GetRequestorURL(),
72 id_));
73 webstore_data_fetcher_->Start();
76 void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() {
77 CompleteInstall(kWebstoreRequestError);
80 void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess(
81 DictionaryValue* webstore_data) {
82 if (!CheckRequestorAlive()) {
83 CompleteInstall(std::string());
84 return;
87 std::string error;
89 if (!CheckInlineInstallPermitted(*webstore_data, &error)) {
90 CompleteInstall(error);
91 return;
94 if (!CheckRequestorPermitted(*webstore_data, &error)) {
95 CompleteInstall(error);
96 return;
99 // Manifest, number of users, average rating and rating count are required.
100 std::string manifest;
101 if (!webstore_data->GetString(kManifestKey, &manifest) ||
102 !webstore_data->GetString(kUsersKey, &localized_user_count_) ||
103 !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) ||
104 !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) {
105 CompleteInstall(kInvalidWebstoreResponseError);
106 return;
109 if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating ||
110 average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) {
111 CompleteInstall(kInvalidWebstoreResponseError);
112 return;
115 // Localized name and description are optional.
116 if ((webstore_data->HasKey(kLocalizedNameKey) &&
117 !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) ||
118 (webstore_data->HasKey(kLocalizedDescriptionKey) &&
119 !webstore_data->GetString(
120 kLocalizedDescriptionKey, &localized_description_))) {
121 CompleteInstall(kInvalidWebstoreResponseError);
122 return;
125 // Icon URL is optional.
126 GURL icon_url;
127 if (webstore_data->HasKey(kIconUrlKey)) {
128 std::string icon_url_string;
129 if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) {
130 CompleteInstall(kInvalidWebstoreResponseError);
131 return;
133 icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve(
134 icon_url_string);
135 if (!icon_url.is_valid()) {
136 CompleteInstall(kInvalidWebstoreResponseError);
137 return;
141 // Assume ownership of webstore_data.
142 webstore_data_.reset(webstore_data);
144 scoped_refptr<WebstoreInstallHelper> helper =
145 new WebstoreInstallHelper(this,
146 id_,
147 manifest,
148 std::string(), // We don't have any icon data.
149 icon_url,
150 profile_->GetRequestContext());
151 // The helper will call us back via OnWebstoreParseSucces or
152 // OnWebstoreParseFailure.
153 helper->Start();
156 void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure(
157 const std::string& error) {
158 CompleteInstall(error);
161 void WebstoreStandaloneInstaller::OnWebstoreParseSuccess(
162 const std::string& id,
163 const SkBitmap& icon,
164 base::DictionaryValue* manifest) {
165 CHECK_EQ(id_, id);
167 if (!CheckRequestorAlive()) {
168 CompleteInstall(std::string());
169 return;
172 manifest_.reset(manifest);
173 icon_ = icon;
175 install_prompt_ = CreateInstallPrompt();
176 if (install_prompt_) {
177 CreateInstallUI();
178 // Control flow finishes up in InstallUIProceed or InstallUIAbort.
179 } else {
180 InstallUIProceed();
184 void WebstoreStandaloneInstaller::OnWebstoreParseFailure(
185 const std::string& id,
186 InstallHelperResultCode result_code,
187 const std::string& error_message) {
188 CompleteInstall(error_message);
191 void WebstoreStandaloneInstaller::InstallUIProceed() {
192 if (!CheckRequestorAlive()) {
193 CompleteInstall(std::string());
194 return;
197 scoped_ptr<WebstoreInstaller::Approval> approval(
198 WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
199 profile_,
200 id_,
201 scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy())));
202 approval->skip_post_install_ui = !ShouldShowPostInstallUI();
203 approval->use_app_installed_bubble = ShouldShowAppInstalledBubble();
205 scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller(
206 profile_,
207 this,
208 &(GetWebContents()->GetController()),
209 id_,
210 approval.Pass(),
211 WebstoreInstaller::FLAG_INLINE_INSTALL);
212 installer->Start();
215 void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) {
216 CompleteInstall(kUserCancelledError);
219 void WebstoreStandaloneInstaller::OnExtensionInstallSuccess(
220 const std::string& id) {
221 CHECK_EQ(id_, id);
222 CompleteInstall(std::string());
225 void WebstoreStandaloneInstaller::OnExtensionInstallFailure(
226 const std::string& id,
227 const std::string& error,
228 WebstoreInstaller::FailureReason cancelled) {
229 CHECK_EQ(id_, id);
230 CompleteInstall(error);
233 void WebstoreStandaloneInstaller::AbortInstall() {
234 callback_.Reset();
235 // Abort any in-progress fetches.
236 if (webstore_data_fetcher_) {
237 webstore_data_fetcher_.reset();
238 Release(); // Matches the AddRef in BeginInstall.
242 void WebstoreStandaloneInstaller::CompleteInstall(const std::string& error) {
243 // Clear webstore_data_fetcher_ so that WebContentsDestroyed will no longer
244 // call Release in case the WebContents is destroyed before this object.
245 scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher(
246 webstore_data_fetcher_.Pass());
247 if (!callback_.is_null())
248 callback_.Run(error.empty(), error);
250 Release(); // Matches the AddRef in BeginInstall.
253 void
254 WebstoreStandaloneInstaller::CreateInstallUI() {
255 std::string error;
256 localized_extension_for_display_ =
257 ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
258 manifest_.get(),
259 Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE,
260 id_,
261 localized_name_,
262 localized_description_,
263 &error);
264 if (!localized_extension_for_display_.get()) {
265 CompleteInstall(kInvalidManifestError);
266 return;
269 install_ui_.reset(new ExtensionInstallPrompt(GetWebContents()));
270 install_ui_->ConfirmStandaloneInstall(
271 this, localized_extension_for_display_.get(), &icon_, *install_prompt_);
274 } // namespace extensions