Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync / glue / typed_url_change_processor.cc
index a5a2be8..51539c9 100644 (file)
@@ -14,6 +14,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/glue/typed_url_model_associator.h"
 #include "chrome/browser/sync/profile_sync_service.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/browser/notification_service.h"
 #include "sync/internal_api/public/change_record.h"
 #include "sync/internal_api/public/read_node.h"
@@ -38,8 +39,8 @@ TypedUrlChangeProcessor::TypedUrlChangeProcessor(
     Profile* profile,
     TypedUrlModelAssociator* model_associator,
     history::HistoryBackend* history_backend,
-    DataTypeErrorHandler* error_handler)
-    : ChangeProcessor(error_handler),
+    sync_driver::DataTypeErrorHandler* error_handler)
+    : sync_driver::ChangeProcessor(error_handler),
       profile_(profile),
       model_associator_(model_associator),
       history_backend_(history_backend),
@@ -57,6 +58,8 @@ TypedUrlChangeProcessor::TypedUrlChangeProcessor(
 
 TypedUrlChangeProcessor::~TypedUrlChangeProcessor() {
   DCHECK(backend_loop_ == base::MessageLoop::current());
+  DCHECK(history_backend_);
+  history_backend_->RemoveObserver(this);
 }
 
 void TypedUrlChangeProcessor::Observe(
@@ -76,10 +79,27 @@ void TypedUrlChangeProcessor::Observe(
   } else if (type == chrome::NOTIFICATION_HISTORY_URLS_DELETED) {
     HandleURLsDeleted(
         content::Details<history::URLsDeletedDetails>(details).ptr());
-  } else {
-    DCHECK_EQ(chrome::NOTIFICATION_HISTORY_URL_VISITED, type);
-    HandleURLsVisited(
-        content::Details<history::URLVisitedDetails>(details).ptr());
+  }
+  UMA_HISTOGRAM_PERCENTAGE("Sync.TypedUrlChangeProcessorErrors",
+                           model_associator_->GetErrorPercentage());
+}
+
+void TypedUrlChangeProcessor::OnURLVisited(
+    history::HistoryBackend* history_backend,
+    ui::PageTransition transition,
+    const history::URLRow& row,
+    const history::RedirectList& redirects,
+    base::Time visit_time) {
+  DCHECK(backend_loop_ == base::MessageLoop::current());
+
+  base::AutoLock al(disconnect_lock_);
+  if (disconnected_)
+    return;
+
+  DVLOG(1) << "Observed typed_url change.";
+  if (ShouldSyncVisit(row.typed_count(), transition)) {
+    syncer::WriteTransaction trans(FROM_HERE, share_handle());
+    CreateOrUpdateSyncNode(row, &trans);
   }
   UMA_HISTOGRAM_PERCENTAGE("Sync.TypedUrlChangeProcessorErrors",
                            model_associator_->GetErrorPercentage());
@@ -110,11 +130,13 @@ bool TypedUrlChangeProcessor::CreateOrUpdateSyncNode(
   }
 
   syncer::ReadNode typed_url_root(trans);
-  if (typed_url_root.InitByTagLookup(kTypedUrlTag) !=
+  if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
           syncer::BaseNode::INIT_OK) {
-    error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-        "Server did not create the top-level typed_url node. We "
-         "might be running against an out-of-date server.");
+    syncer::SyncError error(FROM_HERE,
+                            syncer::SyncError::DATATYPE_ERROR,
+                            "No top level folder",
+                            syncer::TYPED_URLS);
+    error_handler()->OnSingleDataTypeUnrecoverableError(error);
     return false;
   }
 
@@ -129,51 +151,28 @@ bool TypedUrlChangeProcessor::CreateOrUpdateSyncNode(
   if (result == syncer::BaseNode::INIT_OK) {
     model_associator_->WriteToSyncNode(url, visit_vector, &update_node);
   } else if (result == syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY) {
-    // TODO(tim): Investigating bug 121587.
-    syncer::Cryptographer* crypto = trans->GetCryptographer();
-    syncer::ModelTypeSet encrypted_types(trans->GetEncryptedTypes());
-    const sync_pb::EntitySpecifics& specifics =
-        update_node.GetEntry()->GetSpecifics();
-    CHECK(specifics.has_encrypted());
-    const bool can_decrypt = crypto->CanDecrypt(specifics.encrypted());
-    const bool agreement = encrypted_types.Has(syncer::TYPED_URLS);
-    if (!agreement && !can_decrypt) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "Could not InitByIdLookup in CreateOrUpdateSyncNode, "
-          " Cryptographer thinks typed urls not encrypted, and CanDecrypt"
-          " failed.");
-      LOG(ERROR) << "Case 1.";
-    } else if (agreement && can_decrypt) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
-          " Cryptographer thinks typed urls are encrypted, and CanDecrypt"
-          " succeeded (?!), but DecryptIfNecessary failed.");
-      LOG(ERROR) << "Case 2.";
-    } else if (agreement) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
-          " Cryptographer thinks typed urls are encrypted, but CanDecrypt"
-          " failed.");
-      LOG(ERROR) << "Case 3.";
-    } else {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "Could not InitByIdLookup on CreateOrUpdateSyncNode, "
-          " Cryptographer thinks typed urls not encrypted, but CanDecrypt"
-          " succeeded (super weird, btw)");
-      LOG(ERROR) << "Case 4.";
-    }
+    syncer::SyncError error(FROM_HERE,
+                            syncer::SyncError::DATATYPE_ERROR,
+                            "Failed to decrypt.",
+                            syncer::TYPED_URLS);
+    error_handler()->OnSingleDataTypeUnrecoverableError(error);
+    return false;
   } else {
     syncer::WriteNode create_node(trans);
     syncer::WriteNode::InitUniqueByCreationResult result =
         create_node.InitUniqueByCreation(syncer::TYPED_URLS,
                                          typed_url_root, tag);
     if (result != syncer::WriteNode::INIT_SUCCESS) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "Failed to create typed_url sync node.");
+
+      syncer::SyncError error(FROM_HERE,
+                              syncer::SyncError::DATATYPE_ERROR,
+                              "Failed to create sync node",
+                              syncer::TYPED_URLS);
+      error_handler()->OnSingleDataTypeUnrecoverableError(error);
       return false;
     }
 
-    create_node.SetTitle(UTF8ToWide(tag));
+    create_node.SetTitle(tag);
     model_associator_->WriteToSyncNode(url, visit_vector, &create_node);
   }
   return true;
@@ -188,13 +187,16 @@ void TypedUrlChangeProcessor::HandleURLsDeleted(
   // a bad clock setting won't go on an archival rampage and delete all
   // history from every client). The server will gracefully age out the sync DB
   // entries when they've been idle for long enough.
-  if (details->archived)
+  if (details->expired)
     return;
 
   if (details->all_history) {
     if (!model_associator_->DeleteAllNodes(&trans)) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          std::string());
+      syncer::SyncError error(FROM_HERE,
+                              syncer::SyncError::DATATYPE_ERROR,
+                              "Failed to delete local nodes.",
+                              syncer::TYPED_URLS);
+      error_handler()->OnSingleDataTypeUnrecoverableError(error);
       return;
     }
   } else {
@@ -212,21 +214,8 @@ void TypedUrlChangeProcessor::HandleURLsDeleted(
   }
 }
 
-void TypedUrlChangeProcessor::HandleURLsVisited(
-    history::URLVisitedDetails* details) {
-  if (!ShouldSyncVisit(details))
-    return;
-
-  syncer::WriteTransaction trans(FROM_HERE, share_handle());
-  CreateOrUpdateSyncNode(details->row, &trans);
-}
-
-bool TypedUrlChangeProcessor::ShouldSyncVisit(
-    history::URLVisitedDetails* details) {
-  int typed_count = details->row.typed_count();
-  content::PageTransition transition = static_cast<content::PageTransition>(
-      details->transition & content::PAGE_TRANSITION_CORE_MASK);
-
+bool TypedUrlChangeProcessor::ShouldSyncVisit(int typed_count,
+                                              ui::PageTransition transition) {
   // Just use an ad-hoc criteria to determine whether to ignore this
   // notification. For most users, the distribution of visits is roughly a bell
   // curve with a long tail - there are lots of URLs with < 5 visits so we want
@@ -234,7 +223,7 @@ bool TypedUrlChangeProcessor::ShouldSyncVisit(
   // suggestions. But there are relatively few URLs with > 10 visits, and those
   // tend to be more broadly distributed such that there's no need to sync up
   // every visit to preserve their relative ordering.
-  return (transition == content::PAGE_TRANSITION_TYPED &&
+  return (ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) &&
           typed_count > 0 &&
           (typed_count < kTypedUrlVisitThrottleThreshold ||
            (typed_count % kTypedUrlVisitThrottleMultiple) == 0));
@@ -251,10 +240,13 @@ void TypedUrlChangeProcessor::ApplyChangesFromSyncModel(
     return;
 
   syncer::ReadNode typed_url_root(trans);
-  if (typed_url_root.InitByTagLookup(kTypedUrlTag) !=
+  if (typed_url_root.InitTypeRoot(syncer::TYPED_URLS) !=
           syncer::BaseNode::INIT_OK) {
-    error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-        "TypedUrl root node lookup failed.");
+    syncer::SyncError error(FROM_HERE,
+                            syncer::SyncError::DATATYPE_ERROR,
+                            "Failed to init type root.",
+                            syncer::TYPED_URLS);
+    error_handler()->OnSingleDataTypeUnrecoverableError(error);
     return;
   }
 
@@ -275,8 +267,11 @@ void TypedUrlChangeProcessor::ApplyChangesFromSyncModel(
 
     syncer::ReadNode sync_node(trans);
     if (sync_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) {
-      error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE,
-          "TypedUrl node lookup failed.");
+      syncer::SyncError error(FROM_HERE,
+                              syncer::SyncError::DATATYPE_ERROR,
+                              "Failed to init sync node.",
+                              syncer::TYPED_URLS);
+      error_handler()->OnSingleDataTypeUnrecoverableError(error);
       return;
     }
 
@@ -335,9 +330,8 @@ void TypedUrlChangeProcessor::Disconnect() {
   disconnected_ = true;
 }
 
-void TypedUrlChangeProcessor::StartImpl(Profile* profile) {
+void TypedUrlChangeProcessor::StartImpl() {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  DCHECK_EQ(profile, profile_);
   DCHECK(history_backend_);
   DCHECK(backend_loop_);
   backend_loop_->PostTask(FROM_HERE,
@@ -347,6 +341,7 @@ void TypedUrlChangeProcessor::StartImpl(Profile* profile) {
 
 void TypedUrlChangeProcessor::StartObserving() {
   DCHECK(backend_loop_ == base::MessageLoop::current());
+  DCHECK(history_backend_);
   DCHECK(profile_);
   notification_registrar_.Add(
       this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
@@ -354,13 +349,12 @@ void TypedUrlChangeProcessor::StartObserving() {
   notification_registrar_.Add(
       this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
       content::Source<Profile>(profile_));
-  notification_registrar_.Add(
-      this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
-      content::Source<Profile>(profile_));
+  history_backend_->AddObserver(this);
 }
 
 void TypedUrlChangeProcessor::StopObserving() {
   DCHECK(backend_loop_ == base::MessageLoop::current());
+  DCHECK(history_backend_);
   DCHECK(profile_);
   notification_registrar_.Remove(
       this, chrome::NOTIFICATION_HISTORY_URLS_MODIFIED,
@@ -368,9 +362,7 @@ void TypedUrlChangeProcessor::StopObserving() {
   notification_registrar_.Remove(
       this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
       content::Source<Profile>(profile_));
-  notification_registrar_.Remove(
-      this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
-      content::Source<Profile>(profile_));
+  history_backend_->RemoveObserver(this);
 }
 
 }  // namespace browser_sync