| // 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/apps/platform_apps/install_chrome_app.h" |
| |
| #include "base/command_line.h" |
| #include "base/macros.h" |
| #include "base/strings/stringprintf.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/extensions/webstore_install_with_prompt.h" |
| #include "chrome/browser/extensions/webstore_standalone_installer.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_window.h" |
| #include "chrome/common/extensions/webstore_install_result.h" |
| #include "components/crx_file/id_util.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/common/manifest_constants.h" |
| |
| using extensions::ExtensionRegistry; |
| |
| namespace { |
| |
| // The URL to the webstore page for a specific app. |
| const char kWebstoreUrlFormat[] = |
| "https://chrome.google.com/webstore/detail/%s"; |
| |
| // Error given when the extension is not an app. |
| const char kInstallChromeAppErrorNotAnApp[] = |
| "--install-chrome-app can only be used to install apps."; |
| |
| // Returns the webstore URL for an app. |
| GURL GetAppInstallUrl(const std::string& app_id) { |
| return GURL(base::StringPrintf(kWebstoreUrlFormat, app_id.c_str())); |
| } |
| |
| // Checks the manifest and completes the installation with NOT_PERMITTED if the |
| // extension is not an app. |
| class WebstoreInstallWithPromptAppsOnly |
| : public extensions::WebstoreInstallWithPrompt { |
| public: |
| WebstoreInstallWithPromptAppsOnly(const std::string& app_id, |
| Profile* profile, |
| gfx::NativeWindow parent_window) |
| : WebstoreInstallWithPrompt( |
| app_id, |
| profile, |
| parent_window, |
| extensions::WebstoreStandaloneInstaller::Callback()) {} |
| |
| private: |
| ~WebstoreInstallWithPromptAppsOnly() override {} |
| |
| // extensions::WebstoreStandaloneInstaller overrides: |
| void OnManifestParsed() override; |
| |
| DISALLOW_COPY_AND_ASSIGN(WebstoreInstallWithPromptAppsOnly); |
| }; |
| |
| void WebstoreInstallWithPromptAppsOnly::OnManifestParsed() { |
| if (!manifest()->HasKey(extensions::manifest_keys::kApp)) { |
| CompleteInstall(extensions::webstore_install::NOT_PERMITTED, |
| kInstallChromeAppErrorNotAnApp); |
| return; |
| } |
| |
| ProceedWithInstallPrompt(); |
| } |
| |
| } // namespace |
| |
| namespace install_chrome_app { |
| |
| void InstallChromeApp(const std::string& app_id) { |
| if (!crx_file::id_util::IdIsValid(app_id)) |
| return; |
| |
| // At the moment InstallChromeApp() is called immediately after handling |
| // startup URLs, so a browser is guaranteed to be created. If that changes we |
| // may need to start a browser or browser session here. |
| Browser* browser = BrowserList::GetInstance()->get(0); |
| DCHECK(browser); |
| |
| content::OpenURLParams params(GetAppInstallUrl(app_id), content::Referrer(), |
| WindowOpenDisposition::NEW_FOREGROUND_TAB, |
| ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false); |
| browser->OpenURL(params); |
| |
| ExtensionRegistry* registry = ExtensionRegistry::Get(browser->profile()); |
| // Skip if this app is already installed or blacklisted. For disabled or |
| // or terminated apps, going through the installation flow should re-enable |
| // them. |
| const extensions::Extension* installed_extension = registry->GetExtensionById( |
| app_id, ExtensionRegistry::ENABLED | ExtensionRegistry::BLACKLISTED); |
| // TODO(jackhou): For installed apps, maybe we should do something better, |
| // e.g. show the app list (and re-add it to the taskbar). |
| if (installed_extension) |
| return; |
| |
| WebstoreInstallWithPromptAppsOnly* installer = |
| new WebstoreInstallWithPromptAppsOnly( |
| app_id, browser->profile(), browser->window()->GetNativeWindow()); |
| installer->BeginInstall(); |
| } |
| |
| } // namespace install_chrome_app |