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. 32 GURL GetAppInstallUrl(const std::string& app_id) { 33 return GURL(base::StringPrintf(kWebstoreUrlFormat, app_id.c_str())); 34 } 35 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(¶ms); 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 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 74 AppURLFetcher::~AppURLFetcher() { 75 } 76 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 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