install_chrome_app.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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.
4
5#include "chrome/browser/apps/install_chrome_app.h"
6
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/ui/browser_list.h"
12#include "chrome/browser/ui/browser_navigator.h"
13#include "extensions/common/extension.h"
14#include "google_apis/gaia/gaia_urls.h"
15#include "net/url_request/url_fetcher.h"
16#include "net/url_request/url_fetcher_delegate.h"
17
18namespace {
19
20// The URL to the webstore page for a specific app. "_asi=1" instructs webstore
21// to immediately try to install the app if the referrer is the sign in page.
22// This is actually the short form of the URL which just redirects to the full
23// URL. Since "_asi=1" only works on the full url, we need to resolve it first
24// before navigating the user to it.
25const char kWebstoreUrlFormat[] =
26    "https://chrome.google.com/webstore/detail/%s?_asi=1";
27
28// The URL for the sign in page, set as the referrer to webstore.
29const char kAccountsUrl[] = "https://accounts.google.com/ServiceLogin";
30
31// Returns the webstore URL for an app.
32GURL GetAppInstallUrl(const std::string& app_id) {
33  return GURL(base::StringPrintf(kWebstoreUrlFormat, app_id.c_str()));
34}
35
36void NavigateToUrlWithAccountsReferrer(const GURL& url) {
37  Browser* browser =
38      BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->get(0);
39  if (!browser)
40    return;
41
42  chrome::NavigateParams params(
43      browser, url, content::PAGE_TRANSITION_AUTO_TOPLEVEL);
44  params.disposition = NEW_FOREGROUND_TAB;
45  params.window_action = chrome::NavigateParams::SHOW_WINDOW;
46  params.referrer = content::Referrer();
47  params.referrer.url = GURL(kAccountsUrl);
48  chrome::Navigate(&params);
49}
50
51class AppURLFetcher : net::URLFetcherDelegate {
52 public:
53  explicit AppURLFetcher(const std::string& app_id);
54
55  // net::URLFetcherDelegate OVERRIDES:
56  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
57
58 private:
59  virtual ~AppURLFetcher();
60
61  scoped_ptr<net::URLFetcher> url_fetcher_;
62
63  DISALLOW_COPY_AND_ASSIGN(AppURLFetcher);
64};
65
66AppURLFetcher::AppURLFetcher(const std::string& app_id) {
67  url_fetcher_.reset(net::URLFetcher::Create(
68      GetAppInstallUrl(app_id), net::URLFetcher::GET, this));
69  url_fetcher_->SetRequestContext(g_browser_process->system_request_context());
70  url_fetcher_->SetStopOnRedirect(true);
71  url_fetcher_->Start();
72}
73
74AppURLFetcher::~AppURLFetcher() {
75}
76
77void AppURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
78  if (source->GetResponseCode() == 301) {
79    // Moved permanently.
80    NavigateToUrlWithAccountsReferrer(source->GetURL());
81  }
82
83  delete this;
84}
85
86}  // namespace
87
88namespace install_chrome_app {
89
90void InstallChromeApp(const std::string& app_id) {
91  if (!extensions::Extension::IdIsValid(app_id))
92    return;
93
94  new AppURLFetcher(app_id);
95}
96
97}  // namespace install_chrome_app
98