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 3 // found in the LICENSE file. 4 5 #include "components/invalidation/invalidation.h" 6 7 #include <cstddef> 8 9 #include "base/bind.h" 10 #include "base/json/json_string_value_serializer.h" 11 #include "base/location.h" 12 #include "base/rand_util.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/values.h" 15 #include "components/invalidation/ack_handler.h" 16 #include "components/invalidation/invalidation_util.h" 17 18 namespace syncer { 19 20 namespace { 21 const char kObjectIdKey[] = "objectId"; 22 const char kIsUnknownVersionKey[] = "isUnknownVersion"; 23 const char kVersionKey[] = "version"; 24 const char kPayloadKey[] = "payload"; 25 const int64 kInvalidVersion = -1; 26 } 27 28 Invalidation Invalidation::Init(const invalidation::ObjectId& id, 29 int64 version, 30 const std::string& payload) { 31 return Invalidation(id, false, version, payload, AckHandle::CreateUnique()); 32 } 33 34 Invalidation Invalidation::InitUnknownVersion( 35 const invalidation::ObjectId& id) { 36 return Invalidation( 37 id, true, kInvalidVersion, std::string(), AckHandle::CreateUnique()); 38 } 39 40 Invalidation Invalidation::InitFromDroppedInvalidation( 41 const Invalidation& dropped) { 42 return Invalidation( 43 dropped.id_, true, kInvalidVersion, std::string(), dropped.ack_handle_); 44 } 45 46 scoped_ptr<Invalidation> Invalidation::InitFromValue( 47 const base::DictionaryValue& value) { 48 invalidation::ObjectId id; 49 50 const base::DictionaryValue* object_id_dict; 51 if (!value.GetDictionary(kObjectIdKey, &object_id_dict) || 52 !ObjectIdFromValue(*object_id_dict, &id)) { 53 DLOG(WARNING) << "Failed to parse id"; 54 return scoped_ptr<Invalidation>(); 55 } 56 bool is_unknown_version; 57 if (!value.GetBoolean(kIsUnknownVersionKey, &is_unknown_version)) { 58 DLOG(WARNING) << "Failed to parse is_unknown_version flag"; 59 return scoped_ptr<Invalidation>(); 60 } 61 if (is_unknown_version) { 62 return scoped_ptr<Invalidation>(new Invalidation( 63 id, 64 true, 65 kInvalidVersion, 66 std::string(), 67 AckHandle::CreateUnique())); 68 } 69 int64 version = 0; 70 std::string version_as_string; 71 if (!value.GetString(kVersionKey, &version_as_string) 72 || !base::StringToInt64(version_as_string, &version)) { 73 DLOG(WARNING) << "Failed to parse version"; 74 return scoped_ptr<Invalidation>(); 75 } 76 std::string payload; 77 if (!value.GetString(kPayloadKey, &payload)) { 78 DLOG(WARNING) << "Failed to parse payload"; 79 return scoped_ptr<Invalidation>(); 80 } 81 return scoped_ptr<Invalidation>(new Invalidation( 82 id, 83 false, 84 version, 85 payload, 86 AckHandle::CreateUnique())); 87 } 88 89 Invalidation::~Invalidation() { 90 } 91 92 invalidation::ObjectId Invalidation::object_id() const { 93 return id_; 94 } 95 96 bool Invalidation::is_unknown_version() const { 97 return is_unknown_version_; 98 } 99 100 int64 Invalidation::version() const { 101 DCHECK(!is_unknown_version_); 102 return version_; 103 } 104 105 const std::string& Invalidation::payload() const { 106 DCHECK(!is_unknown_version_); 107 return payload_; 108 } 109 110 const AckHandle& Invalidation::ack_handle() const { 111 return ack_handle_; 112 } 113 114 void Invalidation::SetAckHandler( 115 base::WeakPtr<AckHandler> handler, 116 scoped_refptr<base::SequencedTaskRunner> handler_task_runner) { 117 ack_handler_ = handler; 118 ack_handler_task_runner_ = handler_task_runner; 119 } 120 121 bool Invalidation::SupportsAcknowledgement() const { 122 return !!ack_handler_task_runner_.get(); 123 } 124 125 void Invalidation::Acknowledge() const { 126 if (SupportsAcknowledgement()) { 127 ack_handler_task_runner_->PostTask( 128 FROM_HERE, 129 base::Bind(&AckHandler::Acknowledge, ack_handler_, id_, ack_handle_)); 130 } 131 } 132 133 void Invalidation::Drop() { 134 if (SupportsAcknowledgement()) { 135 ack_handler_task_runner_->PostTask( 136 FROM_HERE, 137 base::Bind(&AckHandler::Drop, ack_handler_, id_, ack_handle_)); 138 } 139 } 140 141 bool Invalidation::Equals(const Invalidation& other) const { 142 return id_ == other.id_ && is_unknown_version_ == other.is_unknown_version_ && 143 version_ == other.version_ && payload_ == other.payload_; 144 } 145 146 scoped_ptr<base::DictionaryValue> Invalidation::ToValue() const { 147 scoped_ptr<base::DictionaryValue> value(new base::DictionaryValue()); 148 value->Set(kObjectIdKey, ObjectIdToValue(id_).release()); 149 if (is_unknown_version_) { 150 value->SetBoolean(kIsUnknownVersionKey, true); 151 } else { 152 value->SetBoolean(kIsUnknownVersionKey, false); 153 value->SetString(kVersionKey, base::Int64ToString(version_)); 154 value->SetString(kPayloadKey, payload_); 155 } 156 return value.Pass(); 157 } 158 159 std::string Invalidation::ToString() const { 160 std::string output; 161 JSONStringValueSerializer serializer(&output); 162 serializer.set_pretty_print(true); 163 serializer.Serialize(*ToValue().get()); 164 return output; 165 } 166 167 Invalidation::Invalidation(const invalidation::ObjectId& id, 168 bool is_unknown_version, 169 int64 version, 170 const std::string& payload, 171 AckHandle ack_handle) 172 : id_(id), 173 is_unknown_version_(is_unknown_version), 174 version_(version), 175 payload_(payload), 176 ack_handle_(ack_handle) { 177 } 178 179 } // namespace syncer 180