Commit 453ac12c authored by tmdiep@chromium.org's avatar tmdiep@chromium.org

Show post-install UI when ephemeral apps are promoted to installed apps

Installing an ephemeral app bypasses download of the CRX from the
webstore and thus also bypasses post-install UI. This patch ensures
that post-install UI is shown, such as showing the app launcher with
the app highlighted.

BUG=394997
TEST=See bug

Review URL: https://codereview.chromium.org/407483002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@285859 0039d316-1c4b-4281-b951-d872f2087c98
parent aca48d3e
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_install_ui_util.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_tracker.h" #include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/webstore_installer.h" #include "chrome/browser/extensions/webstore_installer.h"
...@@ -553,6 +554,9 @@ bool WebstorePrivateCompleteInstallFunction::RunAsync() { ...@@ -553,6 +554,9 @@ bool WebstorePrivateCompleteInstallFunction::RunAsync() {
util::IsEphemeralApp(extension->id(), GetProfile()) && util::IsEphemeralApp(extension->id(), GetProfile()) &&
extension->version()->CompareTo( extension->version()->CompareTo(
*approval_->dummy_extension->version()) >= 0) { *approval_->dummy_extension->version()) >= 0) {
install_ui::ShowPostInstallUIForApproval(
GetProfile(), *approval_, extension);
ExtensionService* extension_service = ExtensionService* extension_service =
ExtensionSystem::Get(GetProfile())->extension_service(); ExtensionSystem::Get(GetProfile())->extension_service();
extension_service->PromoteEphemeralApp(extension, false); extension_service->PromoteEphemeralApp(extension, false);
......
...@@ -30,7 +30,7 @@ class ExtensionInstallUI { ...@@ -30,7 +30,7 @@ class ExtensionInstallUI {
// Called when an extension was installed. // Called when an extension was installed.
virtual void OnInstallSuccess(const extensions::Extension* extension, virtual void OnInstallSuccess(const extensions::Extension* extension,
SkBitmap* icon) = 0; const SkBitmap* icon) = 0;
// Called when an extension failed to install. // Called when an extension failed to install.
virtual void OnInstallFailure(const extensions::CrxInstallerError& error) = 0; virtual void OnInstallFailure(const extensions::CrxInstallerError& error) = 0;
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/extension_install_ui_util.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/extension_install_ui.h"
namespace extensions {
namespace install_ui {
void ShowPostInstallUIForApproval(Profile* profile,
const WebstoreInstaller::Approval& approval,
const Extension* extension) {
scoped_ptr<ExtensionInstallUI> install_ui(
ExtensionInstallUI::Create(profile));
install_ui->SetUseAppInstalledBubble(approval.use_app_installed_bubble);
install_ui->set_skip_post_install_ui(approval.skip_post_install_ui);
install_ui->OnInstallSuccess(extension, approval.installing_icon.bitmap());
}
} // namespace install_ui
} // namespace extensions
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_UTIL_H_
#define CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_UTIL_H_
#include "chrome/browser/extensions/webstore_installer.h"
class Profile;
namespace extensions {
namespace install_ui {
// Creates an ExtensionInstallUI and copies properties from an approval. Calls
// ExtensionInstallUI::OnInstallSuccess() to show the post-install UI for an
// extension.
void ShowPostInstallUIForApproval(Profile* profile,
const WebstoreInstaller::Approval& approval,
const Extension* extension);
} // namespace install_ui
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_INSTALL_UI_UTIL_H_
...@@ -24,6 +24,13 @@ ...@@ -24,6 +24,13 @@
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
#include "ipc/ipc_message.h" #include "ipc/ipc_message.h"
#if defined(OS_WIN)
#include "apps/app_window.h"
#include "apps/app_window_registry.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#endif
using content::BrowserThread; using content::BrowserThread;
namespace { namespace {
...@@ -32,6 +39,39 @@ void PrintPackExtensionMessage(const std::string& message) { ...@@ -32,6 +39,39 @@ void PrintPackExtensionMessage(const std::string& message) {
VLOG(1) << message; VLOG(1) << message;
} }
// On Windows, the jumplist action for installing an ephemeral app has to use
// the --install-from-webstore command line arg to initiate an install.
scoped_refptr<extensions::WebstoreStandaloneInstaller>
CreateEphemeralAppInstaller(
Profile* profile,
const std::string& app_id,
extensions::WebstoreStandaloneInstaller::Callback callback) {
scoped_refptr<extensions::WebstoreStandaloneInstaller> installer;
#if defined(OS_WIN)
using extensions::ExtensionRegistry;
ExtensionRegistry* registry = ExtensionRegistry::Get(profile);
DCHECK(registry);
if (!registry->GetExtensionById(app_id, ExtensionRegistry::EVERYTHING) ||
!extensions::util::IsEphemeralApp(app_id, profile)) {
return installer;
}
apps::AppWindowRegistry* app_window_registry =
apps::AppWindowRegistry::Get(profile);
DCHECK(app_window_registry);
apps::AppWindow* app_window =
app_window_registry->GetCurrentAppWindowForApp(app_id);
if (!app_window)
return installer;
installer = new extensions::WebstoreInstallWithPrompt(
app_id, profile, app_window->GetNativeWindow(), callback);
#endif
return installer;
}
} // namespace } // namespace
namespace extensions { namespace extensions {
...@@ -245,11 +285,12 @@ void AppInstallHelper::BeginInstall( ...@@ -245,11 +285,12 @@ void AppInstallHelper::BeginInstall(
WebstoreStandaloneInstaller::Callback callback = WebstoreStandaloneInstaller::Callback callback =
base::Bind(&AppInstallHelper::OnAppInstallComplete, base::Bind(&AppInstallHelper::OnAppInstallComplete,
base::Unretained(this)); base::Unretained(this));
installer_ = new WebstoreStartupInstaller(
id, installer_ = CreateEphemeralAppInstaller(profile, id, callback);
profile, if (!installer_.get()) {
show_prompt, installer_ =
callback); new WebstoreStartupInstaller(id, profile, show_prompt, callback);
}
installer_->BeginInstall(); installer_->BeginInstall();
} }
......
...@@ -19,6 +19,7 @@ WebstoreInstallWithPrompt::WebstoreInstallWithPrompt( ...@@ -19,6 +19,7 @@ WebstoreInstallWithPrompt::WebstoreInstallWithPrompt(
Profile* profile, Profile* profile,
const Callback& callback) const Callback& callback)
: WebstoreStandaloneInstaller(webstore_item_id, profile, callback), : WebstoreStandaloneInstaller(webstore_item_id, profile, callback),
show_post_install_ui_(true),
dummy_web_contents_( dummy_web_contents_(
WebContents::Create(WebContents::CreateParams(profile))), WebContents::Create(WebContents::CreateParams(profile))),
parent_window_(NULL) { parent_window_(NULL) {
...@@ -31,6 +32,7 @@ WebstoreInstallWithPrompt::WebstoreInstallWithPrompt( ...@@ -31,6 +32,7 @@ WebstoreInstallWithPrompt::WebstoreInstallWithPrompt(
gfx::NativeWindow parent_window, gfx::NativeWindow parent_window,
const Callback& callback) const Callback& callback)
: WebstoreStandaloneInstaller(webstore_item_id, profile, callback), : WebstoreStandaloneInstaller(webstore_item_id, profile, callback),
show_post_install_ui_(true),
dummy_web_contents_( dummy_web_contents_(
WebContents::Create(WebContents::CreateParams(profile))), WebContents::Create(WebContents::CreateParams(profile))),
parent_window_(parent_window) { parent_window_(parent_window) {
...@@ -65,7 +67,7 @@ WebstoreInstallWithPrompt::CreateInstallUI() { ...@@ -65,7 +67,7 @@ WebstoreInstallWithPrompt::CreateInstallUI() {
} }
bool WebstoreInstallWithPrompt::ShouldShowPostInstallUI() const { bool WebstoreInstallWithPrompt::ShouldShowPostInstallUI() const {
return false; return show_post_install_ui_;
} }
bool WebstoreInstallWithPrompt::ShouldShowAppInstalledBubble() const { bool WebstoreInstallWithPrompt::ShouldShowAppInstalledBubble() const {
......
...@@ -48,6 +48,8 @@ class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller, ...@@ -48,6 +48,8 @@ class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller,
friend class base::RefCountedThreadSafe<WebstoreInstallWithPrompt>; friend class base::RefCountedThreadSafe<WebstoreInstallWithPrompt>;
virtual ~WebstoreInstallWithPrompt(); virtual ~WebstoreInstallWithPrompt();
void set_show_post_install_ui(bool show) { show_post_install_ui_ = show; }
// extensions::WebstoreStandaloneInstaller overrides: // extensions::WebstoreStandaloneInstaller overrides:
virtual bool CheckRequestorAlive() const OVERRIDE; virtual bool CheckRequestorAlive() const OVERRIDE;
virtual const GURL& GetRequestorURL() const OVERRIDE; virtual const GURL& GetRequestorURL() const OVERRIDE;
...@@ -69,6 +71,8 @@ class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller, ...@@ -69,6 +71,8 @@ class WebstoreInstallWithPrompt : public WebstoreStandaloneInstaller,
const content::OpenURLParams& params) OVERRIDE; const content::OpenURLParams& params) OVERRIDE;
private: private:
bool show_post_install_ui_;
GURL dummy_requestor_url_; GURL dummy_requestor_url_;
// A non-visible WebContents used to download data from the webstore. // A non-visible WebContents used to download data from the webstore.
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_install_prompt.h"
#include "chrome/browser/extensions/extension_install_ui.h" #include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/browser/extensions/extension_install_ui_util.h"
#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/install_tracker.h" #include "chrome/browser/extensions/install_tracker.h"
#include "chrome/browser/extensions/webstore_data_fetcher.h" #include "chrome/browser/extensions/webstore_data_fetcher.h"
...@@ -360,6 +361,8 @@ void WebstoreStandaloneInstaller::InstallUIProceed() { ...@@ -360,6 +361,8 @@ void WebstoreStandaloneInstaller::InstallUIProceed() {
// to update the extension. // to update the extension.
done = false; done = false;
} else { } else {
install_ui::ShowPostInstallUIForApproval(
profile_, *approval, installed_extension);
extension_service->PromoteEphemeralApp(installed_extension, false); extension_service->PromoteEphemeralApp(installed_extension, false);
} }
} else if (!extension_service->IsExtensionEnabled(id_)) { } else if (!extension_service->IsExtensionEnabled(id_)) {
......
...@@ -14,6 +14,7 @@ WebstoreStartupInstaller::WebstoreStartupInstaller( ...@@ -14,6 +14,7 @@ WebstoreStartupInstaller::WebstoreStartupInstaller(
: WebstoreInstallWithPrompt(webstore_item_id, profile, callback), : WebstoreInstallWithPrompt(webstore_item_id, profile, callback),
show_prompt_(show_prompt) { show_prompt_(show_prompt) {
set_install_source(WebstoreInstaller::INSTALL_SOURCE_INLINE); set_install_source(WebstoreInstaller::INSTALL_SOURCE_INLINE);
set_show_post_install_ui(false);
} }
WebstoreStartupInstaller::~WebstoreStartupInstaller() {} WebstoreStartupInstaller::~WebstoreStartupInstaller() {}
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
void ExtensionInstallUIAndroid::OnInstallSuccess( void ExtensionInstallUIAndroid::OnInstallSuccess(
const extensions::Extension* extension, const extensions::Extension* extension,
SkBitmap* icon) { const SkBitmap* icon) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
......
...@@ -16,7 +16,7 @@ class ExtensionInstallUIAndroid : public ExtensionInstallUI { ...@@ -16,7 +16,7 @@ class ExtensionInstallUIAndroid : public ExtensionInstallUI {
// ExtensionInstallUI: // ExtensionInstallUI:
virtual void OnInstallSuccess(const extensions::Extension* extension, virtual void OnInstallSuccess(const extensions::Extension* extension,
SkBitmap* icon) OVERRIDE; const SkBitmap* icon) OVERRIDE;
virtual void OnInstallFailure( virtual void OnInstallFailure(
const extensions::CrxInstallerError& error) OVERRIDE; const extensions::CrxInstallerError& error) OVERRIDE;
......
...@@ -16,6 +16,7 @@ WebstoreInstaller::WebstoreInstaller(const std::string& webstore_item_id, ...@@ -16,6 +16,7 @@ WebstoreInstaller::WebstoreInstaller(const std::string& webstore_item_id,
callback) { callback) {
set_install_source( set_install_source(
extensions::WebstoreInstaller::INSTALL_SOURCE_APP_LAUNCHER); extensions::WebstoreInstaller::INSTALL_SOURCE_APP_LAUNCHER);
set_show_post_install_ui(false);
} }
WebstoreInstaller::~WebstoreInstaller() {} WebstoreInstaller::~WebstoreInstaller() {}
......
...@@ -219,7 +219,7 @@ ExtensionInstallUIDefault::ExtensionInstallUIDefault(Profile* profile) ...@@ -219,7 +219,7 @@ ExtensionInstallUIDefault::ExtensionInstallUIDefault(Profile* profile)
ExtensionInstallUIDefault::~ExtensionInstallUIDefault() {} ExtensionInstallUIDefault::~ExtensionInstallUIDefault() {}
void ExtensionInstallUIDefault::OnInstallSuccess(const Extension* extension, void ExtensionInstallUIDefault::OnInstallSuccess(const Extension* extension,
SkBitmap* icon) { const SkBitmap* icon) {
if (skip_post_install_ui()) if (skip_post_install_ui())
return; return;
......
...@@ -18,7 +18,7 @@ class ExtensionInstallUIDefault : public ExtensionInstallUI { ...@@ -18,7 +18,7 @@ class ExtensionInstallUIDefault : public ExtensionInstallUI {
// ExtensionInstallUI: // ExtensionInstallUI:
virtual void OnInstallSuccess(const extensions::Extension* extension, virtual void OnInstallSuccess(const extensions::Extension* extension,
SkBitmap* icon) OVERRIDE; const SkBitmap* icon) OVERRIDE;
virtual void OnInstallFailure( virtual void OnInstallFailure(
const extensions::CrxInstallerError& error) OVERRIDE; const extensions::CrxInstallerError& error) OVERRIDE;
virtual void SetUseAppInstalledBubble(bool use_bubble) OVERRIDE; virtual void SetUseAppInstalledBubble(bool use_bubble) OVERRIDE;
......
...@@ -869,6 +869,8 @@ ...@@ -869,6 +869,8 @@
'browser/extensions/extension_infobar_delegate.h', 'browser/extensions/extension_infobar_delegate.h',
'browser/extensions/extension_install_ui.cc', 'browser/extensions/extension_install_ui.cc',
'browser/extensions/extension_install_ui.h', 'browser/extensions/extension_install_ui.h',
'browser/extensions/extension_install_ui_util.cc',
'browser/extensions/extension_install_ui_util.h',
'browser/extensions/extension_tab_util.cc', 'browser/extensions/extension_tab_util.cc',
'browser/extensions/extension_tab_util.h', 'browser/extensions/extension_tab_util.h',
'browser/extensions/menu_manager.cc', 'browser/extensions/menu_manager.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment