summaryrefslogtreecommitdiffstats
path: root/chrome/browser/apps/install_chrome_app.cc
blob: 525f31eef5329828bae0d113aa8a5963b331e448 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// 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/install_chrome_app.h"

#include "base/basictypes.h"
#include "base/command_line.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:
  virtual ~WebstoreInstallWithPromptAppsOnly() {}

  // extensions::WebstoreStandaloneInstaller overrides:
  virtual 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(chrome::HOST_DESKTOP_TYPE_NATIVE)->get(0);
  DCHECK(browser);

  content::OpenURLParams params(GetAppInstallUrl(app_id),
                                content::Referrer(),
                                NEW_FOREGROUND_TAB,
                                content::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