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::SizeTToString(changes_size) + " changes");
     70   }
     71   details.Set("changes", changes_value);
     72   HandleJsEvent(FROM_HERE, "onChangesApplied", JsEventDetails(&details));
     73 }
     74 
     75 void JsMutationEventObserver::OnChangesComplete(ModelType model_type) {
     76   if (!event_handler_.IsInitialized()) {
     77     return;
     78   }
     79   base::DictionaryValue details;
     80   details.SetString("modelType", ModelTypeToString(model_type));
     81   HandleJsEvent(FROM_HERE, "onChangesComplete", JsEventDetails(&details));
     82 }
     83 
     84 void JsMutationEventObserver::OnTransactionWrite(
     85     const syncable::ImmutableWriteTransactionInfo& write_transaction_info,
     86     ModelTypeSet models_with_changes) {
     87   DCHECK(CalledOnValidThread());
     88   if (!event_handler_.IsInitialized()) {
     89     return;
     90   }
     91   base::DictionaryValue details;
     92   details.Set("writeTransactionInfo",
     93               write_transaction_info.Get().ToValue(kChangeLimit));
     94   details.Set("modelsWithChanges",
     95               ModelTypeSetToValue(models_with_changes));
     96   HandleJsEvent(FROM_HERE, "onTransactionWrite", JsEventDetails(&details));
     97 }
     98 
     99 void JsMutationEventObserver::HandleJsEvent(
    100     const tracked_objects::Location& from_here,
    101     const std::string& name, const JsEventDetails& details) {
    102   if (!event_handler_.IsInitialized()) {
    103     NOTREACHED();
    104     return;
    105   }
    106   event_handler_.Call(from_here,
    107                       &JsEventHandler::HandleJsEvent, name, details);
    108 }
    109 
    110 }  // namespace syncer
    111