| // 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/ui/browser_list.h" |
| #include "chrome/browser/ui/browser_navigator.h" |
| #include "extensions/common/extension.h" |
| #include "google_apis/gaia/gaia_urls.h" |
| #include "net/url_request/url_fetcher.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| |
| namespace { |
| |
| // The URL to the webstore page for a specific app. "_asi=1" instructs webstore |
| // to immediately try to install the app if the referrer is the sign in page. |
| // This is actually the short form of the URL which just redirects to the full |
| // URL. Since "_asi=1" only works on the full url, we need to resolve it first |
| // before navigating the user to it. |
| const char kWebstoreUrlFormat[] = |
| "https://chrome.google.com/webstore/detail/%s?_asi=1"; |
| |
| // The URL for the sign in page, set as the referrer to webstore. |
| const char kAccountsUrl[] = "https://accounts.google.com/ServiceLogin"; |
| |
| // Returns the webstore URL for an app. |
| GURL GetAppInstallUrl(const std::string& app_id) { |
| return GURL(base::StringPrintf(kWebstoreUrlFormat, app_id.c_str())); |
| } |
| |
| void NavigateToUrlWithAccountsReferrer(const GURL& url) { |
| Browser* browser = |
| BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_NATIVE)->get(0); |
| if (!browser) |
| return; |
| |
| chrome::NavigateParams params( |
| browser, url, content::PAGE_TRANSITION_AUTO_TOPLEVEL); |
| params.disposition = NEW_FOREGROUND_TAB; |
| params.window_action = chrome::NavigateParams::SHOW_WINDOW; |
| params.referrer = content::Referrer(); |
| params.referrer.url = GURL(kAccountsUrl); |
| chrome::Navigate(¶ms); |
| } |
| |
| class AppURLFetcher : net::URLFetcherDelegate { |
| public: |
| explicit AppURLFetcher(const std::string& app_id); |
| |
| // net::URLFetcherDelegate OVERRIDES: |
| virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; |
| |
| private: |
| virtual ~AppURLFetcher(); |
| |
| scoped_ptr<net::URLFetcher> url_fetcher_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AppURLFetcher); |
| }; |
| |
| AppURLFetcher::AppURLFetcher(const std::string& app_id) { |
| url_fetcher_.reset(net::URLFetcher::Create( |
| GetAppInstallUrl(app_id), net::URLFetcher::GET, this)); |
| url_fetcher_->SetRequestContext(g_browser_process->system_request_context()); |
| url_fetcher_->SetStopOnRedirect(true); |
| url_fetcher_->Start(); |
| } |
| |
| AppURLFetcher::~AppURLFetcher() { |
| } |
| |
| void AppURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) { |
| if (source->GetResponseCode() == 301) { |
| // Moved permanently. |
| NavigateToUrlWithAccountsReferrer(source->GetURL()); |
| } |
| |
| delete this; |
| } |
| |
| } // namespace |
| |
| namespace install_chrome_app { |
| |
| void InstallChromeApp(const std::string& app_id) { |
| if (!extensions::Extension::IdIsValid(app_id)) |
| return; |
| |
| new AppURLFetcher(app_id); |
| } |
| |
| } // namespace install_chrome_app |