1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/apps/install_chrome_app.h"
7 #include "base/basictypes.h"
8 #include "base/command_line.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/extensions/webstore_install_with_prompt.h"
12 #include "chrome/browser/extensions/webstore_standalone_installer.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/common/extensions/webstore_install_result.h"
18 #include "components/crx_file/id_util.h"
19 #include "extensions/browser/extension_registry.h"
20 #include "extensions/common/manifest_constants.h"
22 using extensions::ExtensionRegistry
;
26 // The URL to the webstore page for a specific app.
27 const char kWebstoreUrlFormat
[] =
28 "https://chrome.google.com/webstore/detail/%s";
30 // Error given when the extension is not an app.
31 const char kInstallChromeAppErrorNotAnApp
[] =
32 "--install-chrome-app can only be used to install apps.";
34 // Returns the webstore URL for an app.
35 GURL
GetAppInstallUrl(const std::string
& app_id
) {
36 return GURL(base::StringPrintf(kWebstoreUrlFormat
, app_id
.c_str()));
39 // Checks the manifest and completes the installation with NOT_PERMITTED if the
40 // extension is not an app.
41 class WebstoreInstallWithPromptAppsOnly
42 : public extensions::WebstoreInstallWithPrompt
{
44 WebstoreInstallWithPromptAppsOnly(const std::string
& app_id
,
46 gfx::NativeWindow parent_window
)
47 : WebstoreInstallWithPrompt(
51 extensions::WebstoreStandaloneInstaller::Callback()) {}
54 ~WebstoreInstallWithPromptAppsOnly() override
{}
56 // extensions::WebstoreStandaloneInstaller overrides:
57 void OnManifestParsed() override
;
59 DISALLOW_COPY_AND_ASSIGN(WebstoreInstallWithPromptAppsOnly
);
62 void WebstoreInstallWithPromptAppsOnly::OnManifestParsed() {
63 if (!manifest()->HasKey(extensions::manifest_keys::kApp
)) {
64 CompleteInstall(extensions::webstore_install::NOT_PERMITTED
,
65 kInstallChromeAppErrorNotAnApp
);
69 ProceedWithInstallPrompt();
74 namespace install_chrome_app
{
76 void InstallChromeApp(const std::string
& app_id
) {
77 if (!crx_file::id_util::IdIsValid(app_id
))
80 // At the moment InstallChromeApp() is called immediately after handling
81 // startup URLs, so a browser is guaranteed to be created. If that changes we
82 // may need to start a browser or browser session here.
84 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE
)->get(0);
87 content::OpenURLParams
params(GetAppInstallUrl(app_id
),
90 ui::PAGE_TRANSITION_AUTO_TOPLEVEL
,
92 browser
->OpenURL(params
);
94 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser
->profile());
95 // Skip if this app is already installed or blacklisted. For disabled or
96 // or terminated apps, going through the installation flow should re-enable
98 const extensions::Extension
* installed_extension
= registry
->GetExtensionById(
99 app_id
, ExtensionRegistry::ENABLED
| ExtensionRegistry::BLACKLISTED
);
100 // TODO(jackhou): For installed apps, maybe we should do something better,
101 // e.g. show the app list (and re-add it to the taskbar).
102 if (installed_extension
)
105 WebstoreInstallWithPromptAppsOnly
* installer
=
106 new WebstoreInstallWithPromptAppsOnly(
107 app_id
, browser
->profile(), browser
->window()->GetNativeWindow());
108 installer
->BeginInstall();
111 } // namespace install_chrome_app