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