| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/sync/engine_impl/attachments/attachment_uploader_impl.h" | 5 #include "components/sync/engine_impl/attachments/attachment_uploader_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 const char kContentType[] = "application/octet-stream"; | 34 const char kContentType[] = "application/octet-stream"; |
| 35 const char kAttachments[] = "attachments/"; | 35 const char kAttachments[] = "attachments/"; |
| 36 const char kSyncStoreBirthday[] = "X-Sync-Store-Birthday"; | 36 const char kSyncStoreBirthday[] = "X-Sync-Store-Birthday"; |
| 37 const char kSyncDataTypeId[] = "X-Sync-Data-Type-Id"; | 37 const char kSyncDataTypeId[] = "X-Sync-Data-Type-Id"; |
| 38 | 38 |
| 39 } // namespace | 39 } // namespace |
| 40 | 40 |
| 41 namespace syncer { | 41 namespace syncer { |
| 42 | 42 |
| 43 // Encapsulates all the state associated with a single upload. | 43 // Encapsulates all the state associated with a single upload. |
| 44 class AttachmentUploaderImpl::UploadState : public net::URLFetcherDelegate, | 44 class AttachmentUploaderImpl::UploadState |
| 45 public OAuth2TokenService::Consumer, | 45 : public net::URLFetcherDelegate, |
| 46 public base::NonThreadSafe { | 46 public OAuth2TokenService::Consumer { |
| 47 public: | 47 public: |
| 48 // Construct an UploadState. | 48 // Construct an UploadState. |
| 49 // | 49 // |
| 50 // UploadState encapsulates the state associated with a single upload. When | 50 // UploadState encapsulates the state associated with a single upload. When |
| 51 // the upload completes, the UploadState object becomes "stopped". | 51 // the upload completes, the UploadState object becomes "stopped". |
| 52 // | 52 // |
| 53 // |owner| is a pointer to the object that owns this UploadState. Upon | 53 // |owner| is a pointer to the object that owns this UploadState. Upon |
| 54 // completion this object will PostTask to owner's OnUploadStateStopped | 54 // completion this object will PostTask to owner's OnUploadStateStopped |
| 55 // method. | 55 // method. |
| 56 UploadState( | 56 UploadState( |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 std::string account_id_; | 110 std::string account_id_; |
| 111 OAuth2TokenService::ScopeSet scopes_; | 111 OAuth2TokenService::ScopeSet scopes_; |
| 112 std::string access_token_; | 112 std::string access_token_; |
| 113 std::string raw_store_birthday_; | 113 std::string raw_store_birthday_; |
| 114 OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider_; | 114 OAuth2TokenServiceRequest::TokenServiceProvider* token_service_provider_; |
| 115 // Pointer to the AttachmentUploaderImpl that owns this object. | 115 // Pointer to the AttachmentUploaderImpl that owns this object. |
| 116 base::WeakPtr<AttachmentUploaderImpl> owner_; | 116 base::WeakPtr<AttachmentUploaderImpl> owner_; |
| 117 std::unique_ptr<OAuth2TokenServiceRequest> access_token_request_; | 117 std::unique_ptr<OAuth2TokenServiceRequest> access_token_request_; |
| 118 ModelType model_type_; | 118 ModelType model_type_; |
| 119 | 119 |
| 120 SEQUENCE_CHECKER(sequence_checker_); |
| 121 |
| 120 DISALLOW_COPY_AND_ASSIGN(UploadState); | 122 DISALLOW_COPY_AND_ASSIGN(UploadState); |
| 121 }; | 123 }; |
| 122 | 124 |
| 123 AttachmentUploaderImpl::UploadState::UploadState( | 125 AttachmentUploaderImpl::UploadState::UploadState( |
| 124 const GURL& upload_url, | 126 const GURL& upload_url, |
| 125 const scoped_refptr<net::URLRequestContextGetter>& | 127 const scoped_refptr<net::URLRequestContextGetter>& |
| 126 url_request_context_getter, | 128 url_request_context_getter, |
| 127 const Attachment& attachment, | 129 const Attachment& attachment, |
| 128 const UploadCallback& user_callback, | 130 const UploadCallback& user_callback, |
| 129 const std::string& account_id, | 131 const std::string& account_id, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 149 DCHECK(!account_id_.empty()); | 151 DCHECK(!account_id_.empty()); |
| 150 DCHECK(!scopes_.empty()); | 152 DCHECK(!scopes_.empty()); |
| 151 DCHECK(token_service_provider_); | 153 DCHECK(token_service_provider_); |
| 152 DCHECK(!raw_store_birthday_.empty()); | 154 DCHECK(!raw_store_birthday_.empty()); |
| 153 GetToken(); | 155 GetToken(); |
| 154 } | 156 } |
| 155 | 157 |
| 156 AttachmentUploaderImpl::UploadState::~UploadState() {} | 158 AttachmentUploaderImpl::UploadState::~UploadState() {} |
| 157 | 159 |
| 158 bool AttachmentUploaderImpl::UploadState::IsStopped() const { | 160 bool AttachmentUploaderImpl::UploadState::IsStopped() const { |
| 159 DCHECK(CalledOnValidThread()); | 161 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 160 return is_stopped_; | 162 return is_stopped_; |
| 161 } | 163 } |
| 162 | 164 |
| 163 void AttachmentUploaderImpl::UploadState::AddUserCallback( | 165 void AttachmentUploaderImpl::UploadState::AddUserCallback( |
| 164 const UploadCallback& user_callback) { | 166 const UploadCallback& user_callback) { |
| 165 DCHECK(CalledOnValidThread()); | 167 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 166 DCHECK(!is_stopped_); | 168 DCHECK(!is_stopped_); |
| 167 user_callbacks_.push_back(user_callback); | 169 user_callbacks_.push_back(user_callback); |
| 168 } | 170 } |
| 169 | 171 |
| 170 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() { | 172 const Attachment& AttachmentUploaderImpl::UploadState::GetAttachment() { |
| 171 DCHECK(CalledOnValidThread()); | 173 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 172 return attachment_; | 174 return attachment_; |
| 173 } | 175 } |
| 174 | 176 |
| 175 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete( | 177 void AttachmentUploaderImpl::UploadState::OnURLFetchComplete( |
| 176 const net::URLFetcher* source) { | 178 const net::URLFetcher* source) { |
| 177 DCHECK(CalledOnValidThread()); | 179 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 178 if (is_stopped_) { | 180 if (is_stopped_) { |
| 179 return; | 181 return; |
| 180 } | 182 } |
| 181 | 183 |
| 182 UploadResult result = UPLOAD_TRANSIENT_ERROR; | 184 UploadResult result = UPLOAD_TRANSIENT_ERROR; |
| 183 AttachmentId attachment_id = attachment_.GetId(); | 185 AttachmentId attachment_id = attachment_.GetId(); |
| 184 net::URLRequestStatus status = source->GetStatus(); | 186 net::URLRequestStatus status = source->GetStatus(); |
| 185 const int response_code = source->GetResponseCode(); | 187 const int response_code = source->GetResponseCode(); |
| 186 UMA_HISTOGRAM_SPARSE_SLOWLY( | 188 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 187 "Sync.Attachments.UploadResponseCode", | 189 "Sync.Attachments.UploadResponseCode", |
| (...skipping 12 matching lines...) Expand all Loading... |
| 200 } else if (response_code == net::URLFetcher::RESPONSE_CODE_INVALID) { | 202 } else if (response_code == net::URLFetcher::RESPONSE_CODE_INVALID) { |
| 201 result = UPLOAD_TRANSIENT_ERROR; | 203 result = UPLOAD_TRANSIENT_ERROR; |
| 202 } | 204 } |
| 203 StopAndReportResult(result, attachment_id); | 205 StopAndReportResult(result, attachment_id); |
| 204 } | 206 } |
| 205 | 207 |
| 206 void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess( | 208 void AttachmentUploaderImpl::UploadState::OnGetTokenSuccess( |
| 207 const OAuth2TokenService::Request* request, | 209 const OAuth2TokenService::Request* request, |
| 208 const std::string& access_token, | 210 const std::string& access_token, |
| 209 const base::Time& expiration_time) { | 211 const base::Time& expiration_time) { |
| 210 DCHECK(CalledOnValidThread()); | 212 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 211 if (is_stopped_) { | 213 if (is_stopped_) { |
| 212 return; | 214 return; |
| 213 } | 215 } |
| 214 | 216 |
| 215 DCHECK_EQ(access_token_request_.get(), request); | 217 DCHECK_EQ(access_token_request_.get(), request); |
| 216 access_token_request_.reset(); | 218 access_token_request_.reset(); |
| 217 access_token_ = access_token; | 219 access_token_ = access_token; |
| 218 net::NetworkTrafficAnnotationTag traffic_annotation = | 220 net::NetworkTrafficAnnotationTag traffic_annotation = |
| 219 net::DefineNetworkTrafficAnnotation("sync_attachment_uploader", R"( | 221 net::DefineNetworkTrafficAnnotation("sync_attachment_uploader", R"( |
| 220 semantics { | 222 semantics { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData(); | 261 scoped_refptr<base::RefCountedMemory> memory = attachment_.GetData(); |
| 260 const std::string upload_content(memory->front_as<char>(), memory->size()); | 262 const std::string upload_content(memory->front_as<char>(), memory->size()); |
| 261 fetcher_->SetUploadData(kContentType, upload_content); | 263 fetcher_->SetUploadData(kContentType, upload_content); |
| 262 | 264 |
| 263 fetcher_->Start(); | 265 fetcher_->Start(); |
| 264 } | 266 } |
| 265 | 267 |
| 266 void AttachmentUploaderImpl::UploadState::OnGetTokenFailure( | 268 void AttachmentUploaderImpl::UploadState::OnGetTokenFailure( |
| 267 const OAuth2TokenService::Request* request, | 269 const OAuth2TokenService::Request* request, |
| 268 const GoogleServiceAuthError& error) { | 270 const GoogleServiceAuthError& error) { |
| 269 DCHECK(CalledOnValidThread()); | 271 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 270 if (is_stopped_) { | 272 if (is_stopped_) { |
| 271 return; | 273 return; |
| 272 } | 274 } |
| 273 | 275 |
| 274 DCHECK_EQ(access_token_request_.get(), request); | 276 DCHECK_EQ(access_token_request_.get(), request); |
| 275 access_token_request_.reset(); | 277 access_token_request_.reset(); |
| 276 // TODO(maniscalco): We treat this as a transient error, but it may in fact be | 278 // TODO(maniscalco): We treat this as a transient error, but it may in fact be |
| 277 // a very long lived error and require user action. Consider differentiating | 279 // a very long lived error and require user action. Consider differentiating |
| 278 // between the causes of GetToken failure and act accordingly. Think about | 280 // between the causes of GetToken failure and act accordingly. Think about |
| 279 // the causes of GetToken failure. Are there (bug 412802). | 281 // the causes of GetToken failure. Are there (bug 412802). |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 const std::string& store_birthday, | 314 const std::string& store_birthday, |
| 313 ModelType model_type) | 315 ModelType model_type) |
| 314 : sync_service_url_(sync_service_url), | 316 : sync_service_url_(sync_service_url), |
| 315 url_request_context_getter_(url_request_context_getter), | 317 url_request_context_getter_(url_request_context_getter), |
| 316 account_id_(account_id), | 318 account_id_(account_id), |
| 317 scopes_(scopes), | 319 scopes_(scopes), |
| 318 token_service_provider_(token_service_provider), | 320 token_service_provider_(token_service_provider), |
| 319 raw_store_birthday_(store_birthday), | 321 raw_store_birthday_(store_birthday), |
| 320 model_type_(model_type), | 322 model_type_(model_type), |
| 321 weak_ptr_factory_(this) { | 323 weak_ptr_factory_(this) { |
| 322 DCHECK(CalledOnValidThread()); | 324 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 323 DCHECK(!account_id.empty()); | 325 DCHECK(!account_id.empty()); |
| 324 DCHECK(!scopes.empty()); | 326 DCHECK(!scopes.empty()); |
| 325 DCHECK(token_service_provider_.get()); | 327 DCHECK(token_service_provider_.get()); |
| 326 DCHECK(!raw_store_birthday_.empty()); | 328 DCHECK(!raw_store_birthday_.empty()); |
| 327 } | 329 } |
| 328 | 330 |
| 329 AttachmentUploaderImpl::~AttachmentUploaderImpl() { | 331 AttachmentUploaderImpl::~AttachmentUploaderImpl() { |
| 330 DCHECK(CalledOnValidThread()); | 332 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 331 } | 333 } |
| 332 | 334 |
| 333 void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment, | 335 void AttachmentUploaderImpl::UploadAttachment(const Attachment& attachment, |
| 334 const UploadCallback& callback) { | 336 const UploadCallback& callback) { |
| 335 DCHECK(CalledOnValidThread()); | 337 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 336 const AttachmentId attachment_id = attachment.GetId(); | 338 const AttachmentId attachment_id = attachment.GetId(); |
| 337 const std::string unique_id = attachment_id.GetProto().unique_id(); | 339 const std::string unique_id = attachment_id.GetProto().unique_id(); |
| 338 DCHECK(!unique_id.empty()); | 340 DCHECK(!unique_id.empty()); |
| 339 StateMap::iterator iter = state_map_.find(unique_id); | 341 StateMap::iterator iter = state_map_.find(unique_id); |
| 340 if (iter != state_map_.end()) { | 342 if (iter != state_map_.end()) { |
| 341 // We have an old upload request for this attachment... | 343 // We have an old upload request for this attachment... |
| 342 if (!iter->second->IsStopped()) { | 344 if (!iter->second->IsStopped()) { |
| 343 // "join" to it. | 345 // "join" to it. |
| 344 DCHECK(attachment.GetData()->Equals( | 346 DCHECK(attachment.GetData()->Equals( |
| 345 iter->second->GetAttachment().GetData())); | 347 iter->second->GetAttachment().GetData())); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 "%s: %s", kSyncStoreBirthday, encoded_store_birthday.c_str())); | 422 "%s: %s", kSyncStoreBirthday, encoded_store_birthday.c_str())); |
| 421 | 423 |
| 422 // Use field number to pass ModelType because it's stable and we have server | 424 // Use field number to pass ModelType because it's stable and we have server |
| 423 // code to decode it. | 425 // code to decode it. |
| 424 const int field_number = GetSpecificsFieldNumberFromModelType(model_type); | 426 const int field_number = GetSpecificsFieldNumberFromModelType(model_type); |
| 425 fetcher->AddExtraRequestHeader( | 427 fetcher->AddExtraRequestHeader( |
| 426 base::StringPrintf("%s: %d", kSyncDataTypeId, field_number)); | 428 base::StringPrintf("%s: %d", kSyncDataTypeId, field_number)); |
| 427 } | 429 } |
| 428 | 430 |
| 429 } // namespace syncer | 431 } // namespace syncer |
| OLD | NEW |