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
AuthCodeGetter()19 AuthCodeGetter::AuthCodeGetter() :
20 browser_(NULL),
21 timer_interval_(base::TimeDelta::FromMilliseconds(kUrlPollIntervalMs)) {
22 }
23
~AuthCodeGetter()24 AuthCodeGetter::~AuthCodeGetter() {
25 KillBrowser();
26 }
27
GetAuthCode(base::Callback<void (const std::string &)> on_auth_code)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
StartTimer()55 void AuthCodeGetter::StartTimer() {
56 timer_.Start(FROM_HERE, timer_interval_, this, &AuthCodeGetter::OnTimer);
57 }
58
OnTimer()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
TestBrowserUrl(std::string * auth_code)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
KillBrowser()88 void AuthCodeGetter::KillBrowser() {
89 if (browser_) {
90 browser_->Quit();
91 browser_.Release();
92 }
93 }
94
95 } // namespace remoting
96