Index: delta_performer.cc |
diff --git a/delta_performer.cc b/delta_performer.cc |
index 6143ec5ae6556f405144ef91a135fc9fb9a6a47c..92d4733d02fbc2269f722e47fe206f42958f73a5 100644 |
--- a/delta_performer.cc |
+++ b/delta_performer.cc |
@@ -222,7 +222,7 @@ ssize_t DeltaPerformer::Write(const void* bytes, size_t count) { |
// that if the operation gets interrupted, we don't try to resume the |
// update. |
if (!IsIdempotentOperation(op)) { |
- ResetUpdateProgress(); |
+ ResetUpdateProgress(prefs_); |
} |
if (op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE || |
op.type() == DeltaArchiveManifest_InstallOperation_Type_REPLACE_BZ) { |
@@ -512,19 +512,57 @@ void DeltaPerformer::DiscardBufferHeadBytes(size_t count, bool do_hash) { |
buffer_.erase(buffer_.begin(), buffer_.begin() + count); |
} |
-bool DeltaPerformer::ResetUpdateProgress() { |
- TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation, |
- kUpdateStateOperationInvalid)); |
+bool DeltaPerformer::CanResumeUpdate(PrefsInterface* prefs, |
+ string update_check_response_hash) { |
+ int64_t next_operation = kUpdateStateOperationInvalid; |
+ TEST_AND_RETURN_FALSE(prefs->GetInt64(kPrefsUpdateStateNextOperation, |
+ &next_operation) && |
+ next_operation != kUpdateStateOperationInvalid && |
+ next_operation > 0); |
+ |
+ string interrupted_hash; |
+ TEST_AND_RETURN_FALSE(prefs->GetString(kPrefsUpdateCheckResponseHash, |
+ &interrupted_hash) && |
+ !interrupted_hash.empty() && |
+ interrupted_hash == update_check_response_hash); |
+ |
+ // Sanity check the rest. |
+ int64_t next_data_offset = -1; |
+ TEST_AND_RETURN_FALSE(prefs->GetInt64(kPrefsUpdateStateNextDataOffset, |
+ &next_data_offset) && |
+ next_data_offset >= 0); |
+ |
+ string signed_sha256_context; |
+ TEST_AND_RETURN_FALSE( |
+ prefs->GetString(kPrefsUpdateStateSignedSHA256Context, |
+ &signed_sha256_context) && |
+ !signed_sha256_context.empty()); |
+ |
+ int64_t manifest_metadata_size = 0; |
+ TEST_AND_RETURN_FALSE(prefs->GetInt64(kPrefsManifestMetadataSize, |
+ &manifest_metadata_size) && |
+ manifest_metadata_size > 0); |
+ |
+ return true; |
+} |
+ |
+bool DeltaPerformer::ResetUpdateProgress(PrefsInterface* prefs) { |
+ TEST_AND_RETURN_FALSE(prefs->SetInt64(kPrefsUpdateStateNextOperation, |
+ kUpdateStateOperationInvalid)); |
return true; |
} |
bool DeltaPerformer::CheckpointUpdateProgress() { |
// First reset the progress in case we die in the middle of the state update. |
- ResetUpdateProgress(); |
- TEST_AND_RETURN_FALSE(prefs_->SetString(kPrefsUpdateStateSignedSHA256Context, |
- hash_calculator_.GetContext())); |
- TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset, |
- buffer_offset_)); |
+ ResetUpdateProgress(prefs_); |
+ if (last_updated_buffer_offset_ != buffer_offset_) { |
+ TEST_AND_RETURN_FALSE( |
+ prefs_->SetString(kPrefsUpdateStateSignedSHA256Context, |
+ hash_calculator_.GetContext())); |
+ TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextDataOffset, |
+ buffer_offset_)); |
+ last_updated_buffer_offset_ = buffer_offset_; |
+ } |
TEST_AND_RETURN_FALSE(prefs_->SetInt64(kPrefsUpdateStateNextOperation, |
next_operation_num_)); |
return true; |