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 "net/base/load_flags.h"
16 #include "net/http/http_status_code.h"
17 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_request_context_getter.h"
19 #include "sync/protocol/sync.pb.h"
23 const char kEventEndpoint
[] = "event";
25 // The request is tiny, so even on poor connections 10 seconds should be
26 // plenty of time. Since sync is off when this request is started, we don't
27 // want anything sync-related hanging around for very long from a human
28 // perspective either. This seems like a good compromise.
29 const int kRequestTimeoutSeconds
= 10;
31 std::string
GetUserAgent() {
32 return browser_sync::LocalDeviceInfoProviderImpl::MakeUserAgentForSyncApi();
37 namespace browser_sync
{
39 SyncStoppedReporter::SyncStoppedReporter(
40 const GURL
& sync_service_url
,
41 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
,
42 const ResultCallback
& callback
)
43 : sync_event_url_(GetSyncEventURL(sync_service_url
)),
44 user_agent_(GetUserAgent()),
45 request_context_(request_context
),
47 DCHECK(!sync_service_url
.is_empty());
48 DCHECK(!user_agent_
.empty());
49 DCHECK(request_context
);
52 SyncStoppedReporter::~SyncStoppedReporter() {}
54 void SyncStoppedReporter::ReportSyncStopped(const std::string
& access_token
,
55 const std::string
& cache_guid
,
56 const std::string
& birthday
) {
57 DCHECK(!access_token
.empty());
58 DCHECK(!cache_guid
.empty());
59 DCHECK(!birthday
.empty());
61 // Make the request proto with the GUID identifying this client.
62 sync_pb::EventRequest event_request
;
63 sync_pb::SyncDisabledEvent
* sync_disabled_event
=
64 event_request
.mutable_sync_disabled();
65 sync_disabled_event
->set_cache_guid(cache_guid
);
66 sync_disabled_event
->set_store_birthday(birthday
);
69 event_request
.SerializeToString(&msg
);
72 net::URLFetcher::Create(sync_event_url_
, net::URLFetcher::POST
, this);
73 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
74 "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization
,
75 access_token
.c_str()));
76 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
77 "%s: %s", net::HttpRequestHeaders::kUserAgent
, user_agent_
.c_str()));
78 fetcher_
->SetRequestContext(request_context_
.get());
79 fetcher_
->SetUploadData("application/octet-stream", msg
);
80 fetcher_
->SetLoadFlags(net::LOAD_BYPASS_CACHE
|
81 net::LOAD_DISABLE_CACHE
|
82 net::LOAD_DO_NOT_SAVE_COOKIES
|
83 net::LOAD_DO_NOT_SEND_COOKIES
);
85 timer_
.Start(FROM_HERE
, base::TimeDelta::FromSeconds(kRequestTimeoutSeconds
),
86 this, &SyncStoppedReporter::OnTimeout
);
89 void SyncStoppedReporter::OnURLFetchComplete(const net::URLFetcher
* source
) {
90 Result result
= source
->GetResponseCode() == net::HTTP_OK
91 ? RESULT_SUCCESS
: RESULT_ERROR
;
94 if (!callback_
.is_null()) {
95 base::ThreadTaskRunnerHandle::Get()->PostTask(
96 FROM_HERE
, base::Bind(callback_
, result
));
100 void SyncStoppedReporter::OnTimeout() {
102 if (!callback_
.is_null()) {
103 base::ThreadTaskRunnerHandle::Get()->PostTask(
104 FROM_HERE
, base::Bind(callback_
, RESULT_TIMEOUT
));
109 GURL
SyncStoppedReporter::GetSyncEventURL(const GURL
& sync_service_url
) {
110 std::string path
= sync_service_url
.path();
111 if (path
.empty() || *path
.rbegin() != '/') {
114 path
+= kEventEndpoint
;
115 GURL::Replacements replacements
;
116 replacements
.SetPathStr(path
);
117 return sync_service_url
.ReplaceComponents(replacements
);
120 void SyncStoppedReporter::SetTimerTaskRunnerForTest(
121 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
) {
122 timer_
.SetTaskRunner(task_runner
);
125 } // namespace browser_sync