webstore_standalone_installer.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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 "chrome/common/extensions/extension.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "googleurl/src/gurl.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kManifestKey[] = "manifest";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIconUrlKey[] = "icon_url";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLocalizedNameKey[] = "localized_name";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLocalizedDescriptionKey[] = "localized_description";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUsersKey[] = "users";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAverageRatingKey[] = "average_rating";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRatingCountKey[] = "rating_count";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRedirectUrlKey[] = "redirect_url";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidWebstoreItemId[] = "Invalid Chrome Web Store item ID";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kWebstoreRequestError[] =
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Could not fetch data from the Chrome Web Store";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidWebstoreResponseError[] = "Invalid Chrome Web Store reponse";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidManifestError[] = "Invalid manifest";
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserCancelledError[] = "User cancelled install";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebstoreStandaloneInstaller::WebstoreStandaloneInstaller(
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& webstore_item_id,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Callback& callback)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(webstore_item_id),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_(callback),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_(profile),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      average_rating_(0.0),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rating_count_(0) {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(!callback_.is_null());
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {}
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Private interface implementation.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::BeginInstall() {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddRef();  // Balanced in CompleteInstall or WebContentsDestroyed.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!Extension::IdIsValid(id_)) {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall(kInvalidWebstoreItemId);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the requesting page as the referrer both since that is more correct
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (it is the page that caused this request to happen) and so that we can
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // track top sites that trigger inline install requests.
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_fetcher_.reset(new WebstoreDataFetcher(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetRequestContext(),
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetRequestorURL(),
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id_));
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_fetcher_->Start();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CompleteInstall(kWebstoreRequestError);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* webstore_data) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorAlive()) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall("");
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckInlineInstallPermitted(*webstore_data, &error)) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteInstall(error);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorPermitted(*webstore_data, &error)) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteInstall(error);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Manifest, number of users, average rating and rating count are required.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webstore_data->GetString(kManifestKey, &manifest) ||
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(kUsersKey, &localized_user_count_) ||
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) ||
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall(kInvalidWebstoreResponseError);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating ||
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall(kInvalidWebstoreResponseError);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Localized name and description are optional.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((webstore_data->HasKey(kLocalizedNameKey) &&
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) ||
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (webstore_data->HasKey(kLocalizedDescriptionKey) &&
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kLocalizedDescriptionKey, &localized_description_))) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall(kInvalidWebstoreResponseError);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Icon URL is optional.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (webstore_data->HasKey(kIconUrlKey)) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string icon_url_string;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CompleteInstall(kInvalidWebstoreResponseError);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon_url_string);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!icon_url.is_valid()) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CompleteInstall(kInvalidWebstoreResponseError);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Assume ownership of webstore_data.
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_.reset(webstore_data);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<WebstoreInstallHelper> helper = new WebstoreInstallHelper(
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      id_,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      manifest,
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "",  // We don't have any icon data.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      icon_url,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetRequestContext());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The helper will call us back via OnWebstoreParseSucces or
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OnWebstoreParseFailure.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->Start();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure(
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteInstall(error);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseSuccess(
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkBitmap& icon,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* manifest) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(id_, id);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorAlive()) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall("");
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest_.reset(manifest);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_ = icon;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  install_prompt_ = CreateInstallPrompt();
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (install_prompt_) {
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateInstallUI();
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Control flow finishes up in InstallUIProceed or InstallUIAbort.
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InstallUIProceed();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseFailure(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallHelperResultCode result_code,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error_message) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteInstall(error_message);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::InstallUIProceed() {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorAlive()) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CompleteInstall("");
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebstoreInstaller::Approval> approval(
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          profile_,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          id_,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy())));
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  approval->skip_post_install_ui = !ShouldShowPostInstallUI();
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  approval->use_app_installed_bubble = ShouldShowAppInstalledBubble();
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller(
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &(GetWebContents()->GetController()),
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id_,
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      approval.Pass(),
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      WebstoreInstaller::FLAG_INLINE_INSTALL);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  installer->Start();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteInstall(kUserCancelledError);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallSuccess(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(id_, id);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteInstall("");
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallFailure(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WebstoreInstaller::FailureReason cancelled) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(id_, id);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CompleteInstall(error);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreStandaloneInstaller::AbortInstall() {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback_.Reset();
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Abort any in-progress fetches.
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (webstore_data_fetcher_.get()) {
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    webstore_data_fetcher_.reset();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Release();  // Matches the AddRef in BeginInstall.
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::CompleteInstall(const std::string& error) {
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clear webstore_data_fetcher_ so that WebContentsDestroyed will no longer
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // call Release in case the WebContents is destroyed before this object.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WebstoreDataFetcher> webstore_data_fetcher(
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      webstore_data_fetcher_.Pass());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!callback_.is_null())
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_.Run(error.empty(), error);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Release();  // Matches the AddRef in BeginInstall.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WebstoreStandaloneInstaller::CreateInstallUI() {
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  localized_extension_for_display_ =
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          manifest_.get(),
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE,
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          id_,
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          localized_name_,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          localized_description_,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &error);
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!localized_extension_for_display_) {
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CompleteInstall(kInvalidManifestError);
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  install_ui_.reset(new ExtensionInstallPrompt(GetWebContents()));
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  install_ui_->ConfirmStandaloneInstall(this,
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        localized_extension_for_display_,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        &icon_,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        *install_prompt_);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
277