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"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/version.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h"
125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/install_tracker.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/webstore_data_fetcher.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_util.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
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";
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kExtensionIsBlacklisted[] = "Extension is blacklisted";
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kInstallInProgressError[] = "An install is already in progress";
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kLaunchInProgressError[] = "A launch is already in progress";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebstoreStandaloneInstaller::WebstoreStandaloneInstaller(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& webstore_item_id,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Callback& callback)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : id_(webstore_item_id),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback_(callback),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_(profile),
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      install_source_(WebstoreInstaller::INSTALL_SOURCE_INLINE),
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      show_user_count_(true),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      average_rating_(0.0),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rating_count_(0) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::BeginInstall() {
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Add a ref to keep this alive for WebstoreDataFetcher.
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // All code paths from here eventually lead to either CompleteInstall or
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // AbortInstall, which both release this ref.
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AddRef();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!crx_file::id_util::IdIsValid(id_)) {
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::INVALID_ID, kInvalidWebstoreItemId);
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webstore_install::Result result = webstore_install::OTHER_ERROR;
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string error;
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!EnsureUniqueInstall(&result, &error)) {
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(result, error);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the requesting page as the referrer both since that is more correct
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (it is the page that caused this request to happen) and so that we can
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // track top sites that trigger inline install requests.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_fetcher_.reset(new WebstoreDataFetcher(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      this,
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_->GetRequestContext(),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetRequestorURL(),
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id_));
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  webstore_data_fetcher_->Start();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Private interface implementation.
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
87116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebstoreStandaloneInstaller::~WebstoreStandaloneInstaller() {
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebstoreStandaloneInstaller::RunCallback(bool success,
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                              const std::string& error,
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                              webstore_install::Result result) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  callback_.Run(success, error, result);
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebstoreStandaloneInstaller::AbortInstall() {
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  callback_.Reset();
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Abort any in-progress fetches.
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (webstore_data_fetcher_) {
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    webstore_data_fetcher_.reset();
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_active_install_.reset();
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    Release();  // Matches the AddRef in BeginInstall.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool WebstoreStandaloneInstaller::EnsureUniqueInstall(
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    webstore_install::Result* reason,
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string* error) {
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InstallTracker* tracker = InstallTracker::Get(profile_);
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK(tracker);
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const ActiveInstallData* existing_install_data =
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      tracker->GetActiveInstall(id_);
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (existing_install_data) {
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (existing_install_data->is_ephemeral) {
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *reason = webstore_install::LAUNCH_IN_PROGRESS;
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *error = kLaunchInProgressError;
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    } else {
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *reason = webstore_install::INSTALL_IN_PROGRESS;
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      *error = kInstallInProgressError;
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ActiveInstallData install_data(id_);
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  InitInstallData(&install_data);
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_active_install_.reset(new ScopedActiveInstall(tracker, install_data));
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebstoreStandaloneInstaller::CompleteInstall(
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    webstore_install::Result result,
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const std::string& error) {
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_active_install_.reset();
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!callback_.is_null())
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback_.Run(result == webstore_install::SUCCESS, error, result);
137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  Release();  // Matches the AddRef in BeginInstall.
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebstoreStandaloneInstaller::ProceedWithInstallPrompt() {
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  install_prompt_ = CreateInstallPrompt();
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (install_prompt_.get()) {
143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ShowInstallUI();
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Control flow finishes up in InstallUIProceed or InstallUIAbort.
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    InstallUIProceed();
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdochscoped_refptr<const Extension>
151116680a4aac90f2aa7413d9095a592090648e557Ben MurdochWebstoreStandaloneInstaller::GetLocalizedExtensionForDisplay() {
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!localized_extension_for_display_.get()) {
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DCHECK(manifest_.get());
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (!manifest_.get())
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return NULL;
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string error;
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    localized_extension_for_display_ =
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ExtensionInstallPrompt::GetLocalizedExtensionForDisplay(
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            manifest_.get(),
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            Extension::REQUIRE_KEY | Extension::FROM_WEBSTORE,
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            id_,
163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            localized_name_,
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            localized_description_,
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            &error);
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return localized_extension_for_display_.get();
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebstoreStandaloneInstaller::InitInstallData(
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ActiveInstallData* install_data) const {
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Default implementation sets no properties.
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid WebstoreStandaloneInstaller::OnManifestParsed() {
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ProceedWithInstallPrompt();
177116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochscoped_ptr<ExtensionInstallPrompt>
180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochWebstoreStandaloneInstaller::CreateInstallUI() {
181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return make_scoped_ptr(new ExtensionInstallPrompt(GetWebContents()));
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_ptr<WebstoreInstaller::Approval>
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)WebstoreStandaloneInstaller::CreateApproval() const {
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WebstoreInstaller::Approval> approval(
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          profile_,
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          id_,
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          scoped_ptr<base::DictionaryValue>(manifest_.get()->DeepCopy()),
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          true));
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  approval->skip_post_install_ui = !ShouldShowPostInstallUI();
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  approval->use_app_installed_bubble = ShouldShowAppInstalledBubble();
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  approval->installing_icon = gfx::ImageSkia::CreateFrom1xBitmap(icon_);
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return approval.Pass();
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebstoreStandaloneInstaller::InstallUIProceed() {
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!CheckRequestorAlive()) {
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    CompleteInstall(webstore_install::ABORTED, std::string());
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<WebstoreInstaller::Approval> approval = CreateApproval();
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExtensionService* extension_service =
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ExtensionSystem::Get(profile_)->extension_service();
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Extension* installed_extension =
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extension_service->GetExtensionById(id_, true /* include disabled */);
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (installed_extension) {
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::string install_message;
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    webstore_install::Result install_result = webstore_install::SUCCESS;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool done = true;
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (ExtensionPrefs::Get(profile_)->IsExtensionBlacklisted(id_)) {
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Don't install a blacklisted extension.
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      install_result = webstore_install::BLACKLISTED;
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      install_message = kExtensionIsBlacklisted;
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (util::IsEphemeralApp(installed_extension->id(), profile_) &&
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               !approval->is_ephemeral) {
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // If the target extension has already been installed ephemerally and is
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // up to date, it can be promoted to a regular installed extension and
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // downloading from the Web Store is not necessary.
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_refptr<const Extension> extension_to_install =
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          GetLocalizedExtensionForDisplay();
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!extension_to_install.get()) {
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CompleteInstall(webstore_install::INVALID_MANIFEST,
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        kInvalidManifestError);
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return;
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (installed_extension->version()->CompareTo(
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              *extension_to_install->version()) < 0) {
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // If the existing extension is out of date, proceed with the install
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // to update the extension.
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        done = false;
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else {
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        install_ui::ShowPostInstallUIForApproval(
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            profile_, *approval, installed_extension);
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        extension_service->PromoteEphemeralApp(installed_extension, false);
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (!extension_service->IsExtensionEnabled(id_)) {
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // If the extension is installed but disabled, and not blacklisted,
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // enable it.
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extension_service->EnableExtension(id_);
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }  // else extension is installed and enabled; no work to be done.
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (done) {
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CompleteInstall(install_result, install_message);
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<WebstoreInstaller> installer = new WebstoreInstaller(
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      profile_,
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this,
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetWebContents(),
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      id_,
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      approval.Pass(),
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      install_source_);
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  installer->Start();
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid WebstoreStandaloneInstaller::InstallUIAbort(bool user_initiated) {
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CompleteInstall(webstore_install::USER_CANCELLED, kUserCancelledError);
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreRequestFailure() {
26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  OnWebStoreDataFetcherDone();
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CompleteInstall(webstore_install::WEBSTORE_REQUEST_ERROR,
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  kWebstoreRequestError);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseSuccess(
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> webstore_data) {
27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  OnWebStoreDataFetcherDone();
27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorAlive()) {
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::ABORTED, std::string());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string error;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckInlineInstallPermitted(*webstore_data, &error)) {
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::NOT_PERMITTED, error);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorPermitted(*webstore_data, &error)) {
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::NOT_PERMITTED, error);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Manifest, number of users, average rating and rating count are required.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!webstore_data->GetString(kManifestKey, &manifest) ||
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(kUsersKey, &localized_user_count_) ||
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetDouble(kAverageRatingKey, &average_rating_) ||
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetInteger(kRatingCountKey, &rating_count_)) {
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE,
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    kInvalidWebstoreResponseError);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
306a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Optional.
307a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  show_user_count_ = true;
308a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  webstore_data->GetBoolean(kShowUserCountKey, &show_user_count_);
309a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (average_rating_ < ExtensionInstallPrompt::kMinExtensionRating ||
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      average_rating_ > ExtensionInstallPrompt::kMaxExtensionRating) {
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE,
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    kInvalidWebstoreResponseError);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Localized name and description are optional.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((webstore_data->HasKey(kLocalizedNameKey) &&
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(kLocalizedNameKey, &localized_name_)) ||
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (webstore_data->HasKey(kLocalizedDescriptionKey) &&
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !webstore_data->GetString(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kLocalizedDescriptionKey, &localized_description_))) {
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE,
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    kInvalidWebstoreResponseError);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Icon URL is optional.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL icon_url;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (webstore_data->HasKey(kIconUrlKey)) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string icon_url_string;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!webstore_data->GetString(kIconUrlKey, &icon_url_string)) {
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE,
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      kInvalidWebstoreResponseError);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_url = GURL(extension_urls::GetWebstoreLaunchURL()).Resolve(
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        icon_url_string);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!icon_url.is_valid()) {
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE,
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      kInvalidWebstoreResponseError);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Assume ownership of webstore_data.
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  webstore_data_ = webstore_data.Pass();
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<WebstoreInstallHelper> helper =
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new WebstoreInstallHelper(this,
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                id_,
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                manifest,
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                std::string(),  // We don't have any icon data.
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                icon_url,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                profile_->GetRequestContext());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The helper will call us back via OnWebstoreParseSucces or
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OnWebstoreParseFailure.
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  helper->Start();
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreResponseParseFailure(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error) {
36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  OnWebStoreDataFetcherDone();
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CompleteInstall(webstore_install::INVALID_WEBSTORE_RESPONSE, error);
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseSuccess(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkBitmap& icon,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::DictionaryValue* manifest) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK_EQ(id_, id);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!CheckRequestorAlive()) {
374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::ABORTED, std::string());
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  manifest_.reset(manifest);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_ = icon;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OnManifestParsed();
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnWebstoreParseFailure(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallHelperResultCode result_code,
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error_message) {
3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webstore_install::Result install_result = webstore_install::OTHER_ERROR;
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (result_code) {
390116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case WebstoreInstallHelper::Delegate::MANIFEST_ERROR:
391116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      install_result = webstore_install::INVALID_MANIFEST;
392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case WebstoreInstallHelper::Delegate::ICON_ERROR:
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      install_result = webstore_install::ICON_ERROR;
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    default:
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
398116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
399116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
400116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CompleteInstall(install_result, error_message);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallSuccess(
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id) {
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(id_, id);
406116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CompleteInstall(webstore_install::SUCCESS, std::string());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WebstoreStandaloneInstaller::OnExtensionInstallFailure(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& error,
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    WebstoreInstaller::FailureReason reason) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(id_, id);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  webstore_install::Result install_result = webstore_install::OTHER_ERROR;
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  switch (reason) {
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case WebstoreInstaller::FAILURE_REASON_CANCELLED:
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      install_result = webstore_install::USER_CANCELLED;
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_FOUND:
421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    case WebstoreInstaller::FAILURE_REASON_DEPENDENCY_NOT_SHARED_MODULE:
422116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      install_result = webstore_install::MISSING_DEPENDENCIES;
423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    default:
425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      break;
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  CompleteInstall(install_result, error);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebstoreStandaloneInstaller::ShowInstallUI() {
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<const Extension> localized_extension =
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetLocalizedExtensionForDisplay();
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!localized_extension.get()) {
435116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CompleteInstall(webstore_install::INVALID_MANIFEST, kInvalidManifestError);
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  install_ui_ = CreateInstallUI();
440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  install_ui_->ConfirmStandaloneInstall(
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this, localized_extension.get(), &icon_, install_prompt_);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void WebstoreStandaloneInstaller::OnWebStoreDataFetcherDone() {
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // An instance of this class is passed in as a delegate for the
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // WebstoreInstallHelper, ExtensionInstallPrompt and WebstoreInstaller, and
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // therefore needs to remain alive until they are done. Clear the webstore
44846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // data fetcher to avoid calling Release in AbortInstall while any of these
44946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // operations are in progress.
45046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  webstore_data_fetcher_.reset();
45146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
45246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
454