• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 namespace {
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.
25 const 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.
29 const char kAccountsUrl[] = "https://accounts.google.com/ServiceLogin";
30 
31 // Returns the webstore URL for an app.
GetAppInstallUrl(const std::string & app_id)32 GURL GetAppInstallUrl(const std::string& app_id) {
33   return GURL(base::StringPrintf(kWebstoreUrlFormat, app_id.c_str()));
34 }
35 
NavigateToUrlWithAccountsReferrer(const GURL & url)36 void 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 
51 class 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 
AppURLFetcher(const std::string & app_id)66 AppURLFetcher::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 
~AppURLFetcher()74 AppURLFetcher::~AppURLFetcher() {
75 }
76 
OnURLFetchComplete(const net::URLFetcher * source)77 void 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 
88 namespace install_chrome_app {
89 
InstallChromeApp(const std::string & app_id)90 void 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