Home | History | Annotate | Download | only in win
      1 // Copyright (c) 2012 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 "remoting/host/setup/win/auth_code_getter.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "base/time/time.h"
      9 #include "base/win/scoped_bstr.h"
     10 #include "base/win/scoped_variant.h"
     11 #include "remoting/host/setup/oauth_helper.h"
     12 
     13 namespace {
     14 const int kUrlPollIntervalMs = 100;
     15 }  // namespace remoting
     16 
     17 namespace remoting {
     18 
     19 AuthCodeGetter::AuthCodeGetter() :
     20     browser_(NULL),
     21     timer_interval_(base::TimeDelta::FromMilliseconds(kUrlPollIntervalMs)) {
     22 }
     23 
     24 AuthCodeGetter::~AuthCodeGetter() {
     25   KillBrowser();
     26 }
     27 
     28 void AuthCodeGetter::GetAuthCode(
     29     base::Callback<void(const std::string&)> on_auth_code) {
     30   if (browser_) {
     31     on_auth_code.Run("");
     32     return;
     33   }
     34   on_auth_code_ = on_auth_code;
     35   HRESULT hr = browser_.CreateInstance(CLSID_InternetExplorer, NULL,
     36                                        CLSCTX_LOCAL_SERVER);
     37   if (FAILED(hr)) {
     38     on_auth_code_.Run("");
     39     return;
     40   }
     41   base::win::ScopedBstr url(base::UTF8ToWide(
     42       GetOauthStartUrl(GetDefaultOauthRedirectUrl())).c_str());
     43   base::win::ScopedVariant empty_variant;
     44   hr = browser_->Navigate(url, empty_variant.AsInput(), empty_variant.AsInput(),
     45                           empty_variant.AsInput(), empty_variant.AsInput());
     46   if (FAILED(hr)) {
     47     KillBrowser();
     48     on_auth_code_.Run("");
     49     return;
     50   }
     51   browser_->put_Visible(VARIANT_TRUE);
     52   StartTimer();
     53 }
     54 
     55 void AuthCodeGetter::StartTimer() {
     56   timer_.Start(FROM_HERE, timer_interval_, this, &AuthCodeGetter::OnTimer);
     57 }
     58 
     59 void AuthCodeGetter::OnTimer() {
     60   std::string auth_code;
     61   if (TestBrowserUrl(&auth_code)) {
     62     on_auth_code_.Run(auth_code);
     63   } else {
     64     StartTimer();
     65   }
     66 }
     67 
     68 bool AuthCodeGetter::TestBrowserUrl(std::string* auth_code) {
     69   *auth_code = "";
     70   if (!browser_) {
     71     return true;
     72   }
     73   base::win::ScopedBstr url;
     74   HRESULT hr = browser_->get_LocationName(url.Receive());
     75   if (!SUCCEEDED(hr)) {
     76     KillBrowser();
     77     return true;
     78   }
     79   *auth_code = GetOauthCodeInUrl(base::WideToUTF8(static_cast<BSTR>(url)),
     80                                  GetDefaultOauthRedirectUrl());
     81   if (!auth_code->empty()) {
     82     KillBrowser();
     83     return true;
     84   }
     85   return false;
     86 }
     87 
     88 void AuthCodeGetter::KillBrowser() {
     89   if (browser_) {
     90     browser_->Quit();
     91     browser_.Release();
     92   }
     93 }
     94 
     95 }  // namespace remoting
     96