Home | History | Annotate | Download | only in invalidation
      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