webstore_standalone_installer.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/webstore_standalone_installer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID"; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kWebstoreRequestError[] = 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not fetch data from the Chrome Web Store"; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse"; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidManifestError[] = "Invalid manifest"; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserCancelledError[] = "User cancelled install"; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kExtensionIsBlacklisted[] = "Extension is blacklisted"; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebstoreStandaloneInstaller::WebstoreStandaloneInstaller( 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& webstore_item_id, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Profile* profile, 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Callback& callback) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : id_(webstore_item_id), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback), 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_(profile), 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE), 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) show_user_count_(true), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) average_rating_(0.0), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rating_count_(0) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Private interface implementation. 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::BeginInstall() { 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Add a ref to keep this alive for WebstoreDataFetcher. 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // All code paths from here eventually lead to either CompleteInstall or 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // AbortInstall, which both release this ref. 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddRef(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Extension::IdIsValid(id_)) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreItemId); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the requesting page as the referrer both since that is more correct 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (it is the page that caused this request to happen) and so that we can 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // track top sites that trigger inline install requests. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_data_fetcher_.reset(new WebstoreDataFetcher( 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_->GetRequestContext(), 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRequestorURL(), 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id_)); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_data_fetcher_->Start(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool WebstoreStandaloneInstaller::CheckInstallValid( 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::DictionaryValue& manifest, 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string* error) { 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return true; 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<ExtensionInstallPrompt> 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochWebstoreStandaloneInstaller::CreateInstallUI() { 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents())); 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<WebstoreInstaller::Approval> 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebstoreStandaloneInstaller::CreateApproval() const { 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<WebstoreInstaller::Approval> approval( 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WebstoreInstaller::Approval::CreateWithNoInstallPrompt( 88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) profile_, 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) id_, 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()), 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) true)); 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) approval->skip_post_install_ui = !ShouldShowPostInstallUI(); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) approval->use_app_installed_bubble = ShouldShowAppInstalledBubble(); 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_); 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return approval.Pass(); 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompleteInstall(kWebstoreRequestError); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess( 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::DictionaryValue> webstore_data) { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckRequestorAlive()) { 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteInstall(std::string()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckInlineInstallPermitted(*webstore_data, &error)) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompleteInstall(error); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckRequestorPermitted(*webstore_data, &error)) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompleteInstall(error); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Manifest, number of users, average rating and rating count are required. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string manifest; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!webstore_data->GetString(kManifestKey, &manifest) || 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !webstore_data->GetString(kUsersKey, &localized_user_count_) || 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) || 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreResponseError); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Optional. 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) show_user_count_ = true; 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_); 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating || 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreResponseError); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Localized name and description are optional. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((webstore_data->HasKey(kLocalizedNameKey) && 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) || 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (webstore_data->HasKey(kLocalizedDescriptionKey) && 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !webstore_data->GetString( 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kLocalizedDescriptionKey, &localized_description_))) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreResponseError); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Icon URL is optional. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL icon_url; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (webstore_data->HasKey(kIconUrlKey)) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string icon_url_string; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreResponseError); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_url_string); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!icon_url.is_valid()) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kInvalidWebstoreResponseError); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Assume ownership of webstore_data. 168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webstore_data_ = webstore_data.Pass(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<WebstoreInstallHelper> helper = 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new WebstoreInstallHelper(this, 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) id_, 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) manifest, 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), // We don't have any icon data. 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) icon_url, 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetRequestContext()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The helper will call us back via OnWebstoreParseSucces or 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnWebstoreParseFailure. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper->Start(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure( 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(error); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseSuccess( 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& icon, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* manifest) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK_EQ(id_, id); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckRequestorAlive()) { 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteInstall(std::string()); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manifest_.reset(manifest); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_ = icon; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string error; 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!CheckInstallValid(*manifest, &error)) { 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!error.empty()); 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CompleteInstall(error); 205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) install_prompt_ = CreateInstallPrompt(); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (install_prompt_) { 210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ShowInstallUI(); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Control flow finishes up in InstallUIProceed or InstallUIAbort. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Balanced in InstallUIAbort or indirectly in InstallUIProceed via 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // OnExtensionInstallSuccess or OnExtensionInstallFailure. 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddRef(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InstallUIProceed(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseFailure( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InstallHelperResultCode result_code, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_message) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(error_message); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::InstallUIProceed() { 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!CheckRequestorAlive()) { 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteInstall(std::string()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionService* extension_service = 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem::Get(profile_)->extension_service(); 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_service->GetExtensionById(id_, true /* include disabled */); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (extension) { 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string install_result; // Empty string for install success. 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extension_service->IsExtensionEnabled(id_)) { 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) { 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the extension is installed but disabled, and not blacklisted, 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // enable it. 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_service->EnableExtension(id_); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { // Don't install a blacklisted extension. 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) install_result = kExtensionIsBlacklisted; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } // else extension is installed and enabled; no work to be done. 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CompleteInstall(install_result); 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller( 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_, 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetWebContents(), 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id_, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) approval.Pass(), 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) install_source_); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->Start(); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(kUserCancelledError); 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Release(); // Balanced in ShowInstallUI. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallSuccess( 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(id_, id); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteInstall(std::string()); 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Release(); // Balanced in ShowInstallUI. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallFailure( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebstoreInstaller::FailureReason cancelled) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(id_, id); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteInstall(error); 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Release(); // Balanced in ShowInstallUI. 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreStandaloneInstaller::AbortInstall() { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_.Reset(); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Abort any in-progress fetches. 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (webstore_data_fetcher_) { 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webstore_data_fetcher_.reset(); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Release(); // Matches the AddRef in BeginInstall. 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebstoreStandaloneInstaller::InvokeCallback(const std::string& error) { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback_.is_null()) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(error.empty(), error); 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WebstoreStandaloneInstaller::CompleteInstall(const std::string& error) { 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) InvokeCallback(error); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Release(); // Matches the AddRef in BeginInstall. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochWebstoreStandaloneInstaller::ShowInstallUI() { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string error; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) localized_extension_for_display_ = 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExtensionInstallPrompt::GetLocalizedExtensionForDisplay( 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) manifest_.get(), 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE, 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id_, 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) localized_name_, 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) localized_description_, 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &error); 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!localized_extension_for_display_.get()) { 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CompleteInstall(kInvalidManifestError); 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Keep this alive as long as the install prompt lives. 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Balanced in InstallUIAbort or indirectly in InstallUIProceed via 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // OnExtensionInstallSuccess or OnExtensionInstallFailure. 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddRef(); 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch install_ui_ = CreateInstallUI(); 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) install_ui_->ConfirmStandaloneInstall( 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, localized_extension_for_display_.get(), &icon_, *install_prompt_); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 331