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;
33 namespace browser_sync
{
35 SyncStoppedReporter::SyncStoppedReporter(
36 const GURL
& sync_service_url
,
37 const std::string
& user_agent
,
38 const scoped_refptr
<net::URLRequestContextGetter
>& request_context
,
39 const ResultCallback
& callback
)
40 : sync_event_url_(GetSyncEventURL(sync_service_url
)),
41 user_agent_(user_agent
),
42 request_context_(request_context
),
44 DCHECK(!sync_service_url
.is_empty());
45 DCHECK(!user_agent_
.empty());
46 DCHECK(request_context
);
49 SyncStoppedReporter::~SyncStoppedReporter() {}
51 void SyncStoppedReporter::ReportSyncStopped(const std::string
& access_token
,
52 const std::string
& cache_guid
,
53 const std::string
& birthday
) {
54 DCHECK(!access_token
.empty());
55 DCHECK(!cache_guid
.empty());
56 DCHECK(!birthday
.empty());
58 // Make the request proto with the GUID identifying this client.
59 sync_pb::EventRequest event_request
;
60 sync_pb::SyncDisabledEvent
* sync_disabled_event
=
61 event_request
.mutable_sync_disabled();
62 sync_disabled_event
->set_cache_guid(cache_guid
);
63 sync_disabled_event
->set_store_birthday(birthday
);
66 event_request
.SerializeToString(&msg
);
69 net::URLFetcher::Create(sync_event_url_
, net::URLFetcher::POST
, this);
70 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
71 "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization
,
72 access_token
.c_str()));
73 fetcher_
->AddExtraRequestHeader(base::StringPrintf(
74 "%s: %s", net::HttpRequestHeaders::kUserAgent
, user_agent_
.c_str()));
75 fetcher_
->SetRequestContext(request_context_
.get());
76 fetcher_
->SetUploadData("application/octet-stream", msg
);
77 fetcher_
->SetLoadFlags(net::LOAD_BYPASS_CACHE
|
78 net::LOAD_DISABLE_CACHE
|
79 net::LOAD_DO_NOT_SAVE_COOKIES
|
80 net::LOAD_DO_NOT_SEND_COOKIES
);
82 timer_
.Start(FROM_HERE
, base::TimeDelta::FromSeconds(kRequestTimeoutSeconds
),
83 this, &SyncStoppedReporter::OnTimeout
);
86 void SyncStoppedReporter::OnURLFetchComplete(const net::URLFetcher
* source
) {
87 Result result
= source
->GetResponseCode() == net::HTTP_OK
88 ? RESULT_SUCCESS
: RESULT_ERROR
;
91 if (!callback_
.is_null()) {
92 base::ThreadTaskRunnerHandle::Get()->PostTask(
93 FROM_HERE
, base::Bind(callback_
, result
));
97 void SyncStoppedReporter::OnTimeout() {
99 if (!callback_
.is_null()) {
100 base::ThreadTaskRunnerHandle::Get()->PostTask(
101 FROM_HERE
, base::Bind(callback_
, RESULT_TIMEOUT
));
106 GURL
SyncStoppedReporter::GetSyncEventURL(const GURL
& sync_service_url
) {
107 std::string path
= sync_service_url
.path();
108 if (path
.empty() || *path
.rbegin() != '/') {
111 path
+= kEventEndpoint
;
112 GURL::Replacements replacements
;
113 replacements
.SetPathStr(path
);
114 return sync_service_url
.ReplaceComponents(replacements
);
117 void SyncStoppedReporter::SetTimerTaskRunnerForTest(
118 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
) {
119 timer_
.SetTaskRunner(task_runner
);
122 } // namespace browser_sync