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
3 // found in the LICENSE file.
5 #include "chrome/browser/sync/sync_stopped_reporter.h"
7 #include "base/location.h"
8 #include "base/logging.h"
9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/timer/timer.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/sync/glue/local_device_info_provider_impl.h"
15 #include "chrome/common/chrome_version_info.h"
16 #include "net/base/load_flags.h"
17 #include "net/http/http_status_code.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_request_context_getter.h"
20 #include "sync/protocol/sync.pb.h"
24 const char kEventEndpoint
[] = "event";
26 // The request is tiny, so even on poor connections 10 seconds should be
27 // plenty of time. Since sync is off when this request is started, we don't
28 // want anything sync-related hanging around for very long from a human
29 // perspective either. This seems like a good compromise.
30 const base::TimeDelta kRequestTimeout
= base::TimeDelta::FromSeconds(10);
32 std::string
GetUserAgent() {
33 chrome::VersionInfo version_info
;
34 return browser_sync::LocalDeviceInfoProviderImpl::MakeUserAgentForSyncApi(
40 namespace browser_sync
{
42 SyncStoppedReporter::SyncStoppedReporter(
43 const GURL
& sync_service_url
,
44 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
,
45 const ResultCallback
& callback
)
46 : sync_event_url_(GetSyncEventURL(sync_service_url
)),
47 user_agent_(GetUserAgent()),
48 request_context_(request_context
),
50 DCHECK(!sync_service_url
.is_empty());
51 DCHECK(!user_agent_
.empty());
52 DCHECK(request_context
);
55 SyncStoppedReporter::~SyncStoppedReporter() {}
57 void SyncStoppedReporter::ReportSyncStopped(const std::string
& access_token
,
58 const std::string
& cache_guid
,
59 const std::string
& birthday
) {
60 DCHECK(!access_token
.empty());
61 DCHECK(!cache_guid
.empty());
62 DCHECK(!birthday
.empty());
64 // Make the request proto with the GUID identifying this client.
65 sync_pb::EventRequest event_request
;
66 sync_pb::SyncDisabledEvent
* sync_disabled_event
=
67 event_request
.mutable_sync_disabled();
68 sync_disabled_event
->set_cache_guid(cache_guid
);
69 sync_disabled_event
->set_store_birthday(birthday
);
72 event_request
.SerializeToString(&msg
);
75 net::URLFetcher::Create(sync_event_url_
, net::URLFetcher::POST
, this);
76 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
77 "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization
,
78 access_token
.c_str()));
79 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
80 "%s: %s", net::HttpRequestHeaders::kUserAgent
, user_agent_
.c_str()));
81 fetcher_
->SetRequestContext(request_context_
.get());
82 fetcher_
->SetUploadData("application/octet-stream", msg
);
83 fetcher_
->SetLoadFlags(net::LOAD_BYPASS_CACHE
|
84 net::LOAD_DISABLE_CACHE
|
85 net::LOAD_DO_NOT_SAVE_COOKIES
|
86 net::LOAD_DO_NOT_SEND_COOKIES
);
88 timer_
.Start(FROM_HERE
, kRequestTimeout
, this,
89 &SyncStoppedReporter::OnTimeout
);
92 void SyncStoppedReporter::OnURLFetchComplete(const net::URLFetcher
* source
) {
93 Result result
= source
->GetResponseCode() == net::HTTP_OK
94 ? RESULT_SUCCESS
: RESULT_ERROR
;
97 if (!callback_
.is_null()) {
98 base::ThreadTaskRunnerHandle::Get()->PostTask(
99 FROM_HERE
, base::Bind(callback_
, result
));
103 void SyncStoppedReporter::OnTimeout() {
105 if (!callback_
.is_null()) {
106 base::ThreadTaskRunnerHandle::Get()->PostTask(
107 FROM_HERE
, base::Bind(callback_
, RESULT_TIMEOUT
));
112 GURL
SyncStoppedReporter::GetSyncEventURL(const GURL
& sync_service_url
) {
113 std::string path
= sync_service_url
.path();
114 if (path
.empty() || *path
.rbegin() != '/') {
117 path
+= kEventEndpoint
;
118 GURL::Replacements replacements
;
119 replacements
.SetPathStr(path
);
120 return sync_service_url
.ReplaceComponents(replacements
);
123 void SyncStoppedReporter::SetTimerTaskRunnerForTest(
124 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
) {
125 timer_
.SetTaskRunner(task_runner
);
128 } // namespace browser_sync