OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/gcd_rest_client.h" | 5 #include "remoting/host/gcd_rest_client.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
| 9 #include <utility> |
| 10 |
9 #include "base/bind.h" | 11 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
11 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
12 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
13 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
14 #include "base/time/default_clock.h" | 16 #include "base/time/default_clock.h" |
15 #include "base/values.h" | 17 #include "base/values.h" |
16 #include "net/url_request/url_fetcher.h" | 18 #include "net/url_request/url_fetcher.h" |
17 #include "remoting/base/logging.h" | 19 #include "remoting/base/logging.h" |
18 | 20 |
19 namespace remoting { | 21 namespace remoting { |
20 | 22 |
21 GcdRestClient::GcdRestClient(const std::string& gcd_base_url, | 23 GcdRestClient::GcdRestClient(const std::string& gcd_base_url, |
22 const std::string& gcd_device_id, | 24 const std::string& gcd_device_id, |
23 const scoped_refptr<net::URLRequestContextGetter>& | 25 const scoped_refptr<net::URLRequestContextGetter>& |
24 url_request_context_getter, | 26 url_request_context_getter, |
25 OAuthTokenGetter* token_getter) | 27 OAuthTokenGetter* token_getter) |
26 : gcd_base_url_(gcd_base_url), | 28 : gcd_base_url_(gcd_base_url), |
27 gcd_device_id_(gcd_device_id), | 29 gcd_device_id_(gcd_device_id), |
28 url_request_context_getter_(url_request_context_getter), | 30 url_request_context_getter_(url_request_context_getter), |
29 token_getter_(token_getter), | 31 token_getter_(token_getter), |
30 clock_(new base::DefaultClock) { | 32 clock_(new base::DefaultClock) {} |
31 } | |
32 | 33 |
33 GcdRestClient::~GcdRestClient() { | 34 GcdRestClient::~GcdRestClient() {} |
34 } | |
35 | 35 |
36 void GcdRestClient::PatchState( | 36 void GcdRestClient::PatchState( |
37 scoped_ptr<base::DictionaryValue> patch_details, | 37 scoped_ptr<base::DictionaryValue> patch_details, |
38 const GcdRestClient::ResultCallback& callback) { | 38 const GcdRestClient::ResultCallback& callback) { |
39 DCHECK(!HasPendingRequest()); | 39 DCHECK(!HasPendingRequest()); |
40 | 40 |
41 // Construct a status update message in the format GCD expects. The | 41 // Construct a status update message in the format GCD expects. The |
42 // message looks like this, where "..." is filled in from | 42 // message looks like this, where "..." is filled in from |
43 // |patch_details|: | 43 // |patch_details|: |
44 // | 44 // |
45 // { | 45 // { |
46 // requestTimeMs: T, | 46 // requestTimeMs: T, |
47 // patches: [{ | 47 // patches: [{ |
48 // timeMs: T, | 48 // timeMs: T, |
49 // patch: {...} | 49 // patch: {...} |
50 // }] | 50 // }] |
51 // } | 51 // } |
52 // | 52 // |
53 // Note that |now| is deliberately using a double to hold an integer | 53 // Note that |now| is deliberately using a double to hold an integer |
54 // value because |DictionaryValue| doesn't support int64_t values, and | 54 // value because |DictionaryValue| doesn't support int64_t values, and |
55 // GCD doesn't accept fractional values. | 55 // GCD doesn't accept fractional values. |
56 double now = clock_->Now().ToJavaTime(); | 56 double now = clock_->Now().ToJavaTime(); |
57 scoped_ptr<base::DictionaryValue> patch_dict(new base::DictionaryValue); | 57 scoped_ptr<base::DictionaryValue> patch_dict(new base::DictionaryValue); |
58 patch_dict->SetDouble("requestTimeMs", now); | 58 patch_dict->SetDouble("requestTimeMs", now); |
59 scoped_ptr<base::ListValue> patch_list(new base::ListValue); | 59 scoped_ptr<base::ListValue> patch_list(new base::ListValue); |
60 base::DictionaryValue* patch_item = new base::DictionaryValue; | 60 base::DictionaryValue* patch_item = new base::DictionaryValue; |
61 patch_list->Append(patch_item); | 61 patch_list->Append(patch_item); |
62 patch_item->Set("patch", patch_details.Pass()); | 62 patch_item->Set("patch", std::move(patch_details)); |
63 patch_item->SetDouble("timeMs", now); | 63 patch_item->SetDouble("timeMs", now); |
64 patch_dict->Set("patches", patch_list.Pass()); | 64 patch_dict->Set("patches", std::move(patch_list)); |
65 | 65 |
66 // Stringify the message. | 66 // Stringify the message. |
67 std::string patch_string; | 67 std::string patch_string; |
68 if (!base::JSONWriter::Write(*patch_dict, &patch_string)) { | 68 if (!base::JSONWriter::Write(*patch_dict, &patch_string)) { |
69 LOG(ERROR) << "Error building GCD device state patch."; | 69 LOG(ERROR) << "Error building GCD device state patch."; |
70 callback.Run(OTHER_ERROR); | 70 callback.Run(OTHER_ERROR); |
71 return; | 71 return; |
72 } | 72 } |
73 DLOG(INFO) << "sending state patch: " << patch_string; | 73 DLOG(INFO) << "sending state patch: " << patch_string; |
74 | 74 |
75 std::string url = | 75 std::string url = |
76 gcd_base_url_ + "/devices/" + gcd_device_id_ + "/patchState"; | 76 gcd_base_url_ + "/devices/" + gcd_device_id_ + "/patchState"; |
77 | 77 |
78 // Prepare an HTTP request to issue once an auth token is available. | 78 // Prepare an HTTP request to issue once an auth token is available. |
79 callback_ = callback; | 79 callback_ = callback; |
80 url_fetcher_ = | 80 url_fetcher_ = |
81 net::URLFetcher::Create(GURL(url), net::URLFetcher::POST, this); | 81 net::URLFetcher::Create(GURL(url), net::URLFetcher::POST, this); |
82 url_fetcher_->SetUploadData("application/json", patch_string); | 82 url_fetcher_->SetUploadData("application/json", patch_string); |
83 if (url_request_context_getter_) { | 83 if (url_request_context_getter_) { |
84 url_fetcher_->SetRequestContext(url_request_context_getter_.get()); | 84 url_fetcher_->SetRequestContext(url_request_context_getter_.get()); |
85 } | 85 } |
86 | 86 |
87 token_getter_->CallWithToken( | 87 token_getter_->CallWithToken( |
88 base::Bind(&GcdRestClient::OnTokenReceived, base::Unretained(this))); | 88 base::Bind(&GcdRestClient::OnTokenReceived, base::Unretained(this))); |
89 } | 89 } |
90 | 90 |
| 91 void GcdRestClient::SetClockForTest(scoped_ptr<base::Clock> clock) { |
| 92 clock_ = std::move(clock); |
| 93 } |
| 94 |
91 void GcdRestClient::OnTokenReceived(OAuthTokenGetter::Status status, | 95 void GcdRestClient::OnTokenReceived(OAuthTokenGetter::Status status, |
92 const std::string& user_email, | 96 const std::string& user_email, |
93 const std::string& access_token) { | 97 const std::string& access_token) { |
94 DCHECK(HasPendingRequest()); | 98 DCHECK(HasPendingRequest()); |
95 | 99 |
96 if (status != OAuthTokenGetter::SUCCESS) { | 100 if (status != OAuthTokenGetter::SUCCESS) { |
97 LOG(ERROR) << "Error getting OAuth token for GCD request: " | 101 LOG(ERROR) << "Error getting OAuth token for GCD request: " |
98 << url_fetcher_->GetOriginalURL(); | 102 << url_fetcher_->GetOriginalURL(); |
99 if (status == OAuthTokenGetter::NETWORK_ERROR) { | 103 if (status == OAuthTokenGetter::NETWORK_ERROR) { |
100 FinishCurrentRequest(NETWORK_ERROR); | 104 FinishCurrentRequest(NETWORK_ERROR); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 << ") fetching URL: " << request_url; | 137 << ") fetching URL: " << request_url; |
134 status = NETWORK_ERROR; | 138 status = NETWORK_ERROR; |
135 } else { | 139 } else { |
136 LOG(ERROR) << "Error (" << response << ") fetching URL: " << request_url; | 140 LOG(ERROR) << "Error (" << response << ") fetching URL: " << request_url; |
137 } | 141 } |
138 | 142 |
139 FinishCurrentRequest(status); | 143 FinishCurrentRequest(status); |
140 } | 144 } |
141 | 145 |
142 } // namespace remoting | 146 } // namespace remoting |
OLD | NEW |