Add logging to debug nullptr in TabWebContentsDelegateAndroid.addNewContents

Adds logging which verifies that the |delegate_| used by WebContentsImpl for
WebContentsCreated is the same used for AddNewContents. A failure will result
in a crash on Android.

Helps debug by providing the following info:
- If delegate is null at WebContentsCreated and non-null at AddNewContents,
there is a race between WebContentsCreated and delegate assignment.
- If delegate is non-null in both cases, but different, it means we're
updating the delegate between the two, which is also not safe.
- If no log messages are fired and we still crash, it means AddNewContents
was called twice.

Bug: 758186
Change-Id: I103cd77c148af25adb1c7002354bb3b853c913b5
Reviewed-on: https://chromium-review.googlesource.com/c/1407269
Commit-Queue: Eric Karl <[email protected]>
Reviewed-by: Bo <[email protected]>
Cr-Commit-Position: refs/heads/master@{#622232}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index a5db2e1..4bdfeba 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2779,6 +2779,9 @@
     AddDestructionObserver(new_contents_impl);
   }
 
+  // Track the delegate on which WebContentsCreated may be called.
+  // TODO(ericrk): Remove this once debugging complete. https://crbug.com/758186
+  web_contents_created_delegate_ = delegate_;
   if (delegate_) {
     delegate_->WebContentsCreated(this, render_process_id,
                                   opener->GetRoutingID(), params.frame_name,
@@ -2910,6 +2913,14 @@
 
   // The delegate can be null in tests, so we must check for it :(.
   if (delegate) {
+    // TODO(ericrk): Remove this once debugging complete.
+    // https://crbug.com/758186
+    if (web_contents_created_delegate_ != delegate_) {
+      LOG(ERROR) << "AddNewContents called on different delegate from "
+                    "WebContentsCreated. "
+                 << delegate_ << " vs " << web_contents_created_delegate_;
+    }
+
     // Mark the web contents as pending resume, then immediately do
     // the resume if the delegate wants it.
     created->is_resume_pending_ = true;
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 2c1b30e..3e652d8 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1835,6 +1835,10 @@
   // WebContents can be found by using GetOuterWebContents().
   Portal* portal_ = nullptr;
 
+  // TODO(ericrk): Variable to debug https://crbug.com/758186. Remove when
+  // debugging concluded.
+  WebContentsDelegate* web_contents_created_delegate_ = nullptr;
+
   base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_;
   base::WeakPtrFactory<WebContentsImpl> weak_factory_;