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 13namespace { 14const int kUrlPollIntervalMs = 100; 15} // namespace remoting 16 17namespace remoting { 18 19AuthCodeGetter::AuthCodeGetter() : 20 browser_(NULL), 21 timer_interval_(base::TimeDelta::FromMilliseconds(kUrlPollIntervalMs)) { 22} 23 24AuthCodeGetter::~AuthCodeGetter() { 25 KillBrowser(); 26} 27 28void 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 55void AuthCodeGetter::StartTimer() { 56 timer_.Start(FROM_HERE, timer_interval_, this, &AuthCodeGetter::OnTimer); 57} 58 59void 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 68bool 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 88void AuthCodeGetter::KillBrowser() { 89 if (browser_) { 90 browser_->Quit(); 91 browser_.Release(); 92 } 93} 94 95} // namespace remoting 96