Home | History | Annotate | Download | only in internal_api
      1 // Copyright (c) 2012 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 "sync/internal_api/js_mutation_event_observer.h"
      6 
      7 #include <string>
      8 
      9 #include "base/location.h"
     10 #include "base/logging.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/values.h"
     13 #include "sync/js/js_event_details.h"
     14 #include "sync/js/js_event_handler.h"
     15 
     16 namespace syncer {
     17 
     18 JsMutationEventObserver::JsMutationEventObserver()
     19     : weak_ptr_factory_(this) {}
     20 
     21 JsMutationEventObserver::~JsMutationEventObserver() {
     22   DCHECK(CalledOnValidThread());
     23 }
     24 
     25 base::WeakPtr<JsMutationEventObserver> JsMutationEventObserver::AsWeakPtr() {
     26   return weak_ptr_factory_.GetWeakPtr();
     27 }
     28 
     29 void JsMutationEventObserver::InvalidateWeakPtrs() {
     30   weak_ptr_factory_.InvalidateWeakPtrs();
     31 }
     32 
     33 void JsMutationEventObserver::SetJsEventHandler(
     34     const WeakHandle<JsEventHandler>& event_handler) {
     35   event_handler_ = event_handler;
     36 }
     37 
     38 namespace {
     39 
     40 // Max number of changes we attempt to convert to values (to avoid
     41 // running out of memory).
     42 const size_t kChangeLimit = 100;
     43 
     44 }  // namespace
     45 
     46 void JsMutationEventObserver::OnChangesApplied(
     47     ModelType model_type,
     48     int64 write_transaction_id,
     49     const ImmutableChangeRecordList& changes) {
     50   if (!event_handler_.IsInitialized()) {
     51     return;
     52   }
     53   base::DictionaryValue details;
     54   details.SetString("modelType", ModelTypeToString(model_type));
     55   details.SetString("writeTransactionId",
     56                     base::Int64ToString(write_transaction_id));
     57   base::Value* changes_value = NULL;
     58   const size_t changes_size = changes.Get().size();
     59   if (changes_size <= kChangeLimit) {
     60     base::ListValue* changes_list = new base::ListValue();
     61     for (ChangeRecordList::const_iterator it =
     62              changes.Get().begin(); it != changes.Get().end(); ++it) {
     63       changes_list->Append(it->ToValue());
     64     }
     65     changes_value = changes_list;
     66   } else {
     67     changes_value =
     68         new base::StringValue(
     69             base::Uint64ToString(static_cast<uint64>(changes_size)) +
     70             " changes");
     71   }
     72   details.Set("changes", changes_value);
     73   HandleJsEvent(FROM_HERE, "onChangesApplied", JsEventDetails(&details));
     74 }
     75 
     76 void JsMutationEventObserver::OnChangesComplete(ModelType model_type) {
     77   if (!event_handler_.IsInitialized()) {
     78     return;
     79   }
     80   base::DictionaryValue details;
     81   details.SetString("modelType", ModelTypeToString(model_type));
     82   HandleJsEvent(FROM_HERE, "onChangesComplete", JsEventDetails(&details));
     83 }
     84 
     85 void JsMutationEventObserver::OnTransactionWrite(
     86     const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
     87     ModelTypeSet models_with_changes) {
     88   DCHECK(CalledOnValidThread());
     89   if (!event_handler_.IsInitialized()) {
     90     return;
     91   }
     92   base::DictionaryValue details;
     93   details.Set("writeTransactionInfo",
     94               write_transaction_info.Get().ToValue(kChangeLimit));
     95   details.Set("modelsWithChanges",
     96               ModelTypeSetToValue(models_with_changes));
     97   HandleJsEvent(FROM_HERE, "onTransactionWrite", JsEventDetails(&details));
     98 }
     99 
    100 void JsMutationEventObserver::HandleJsEvent(
    101     const tracked_objects::Location& from_here,
    102     const std::string& name, const JsEventDetails& details) {
    103   if (!event_handler_.IsInitialized()) {
    104     NOTREACHED();
    105     return;
    106   }
    107   event_handler_.Call(from_here,
    108                       &JsEventHandler::HandleJsEvent, name, details);
    109 }
    110 
    111 }  // namespace syncer
    112