Delay sending TabDetachedAt and TabClosingAt observer notifications.

Previously, the notifications were sent during the tab-close-loop [if multiple
tabs were being closed]. This made reentrancy particularly dangerous.

The logic in Browser::TabDetachedAt and Browser::TabInsertedAt relied on the
|index| parameter to determine whether the index of the active tab has changed
[for which there is no notification]. This CL changes those methods to always
call SessionService::SetSelectedTabInWindow, and modifies
SessionService::SetSelectedTabInWindow to be idempotent.

Bug: 842194
Change-Id: I2fc54749e495ab9c925bdba89ef857c4ea3537d9
Reviewed-on: https://chromium-review.googlesource.com/1055732
Reviewed-by: Scott Violet <[email protected]>
Commit-Queue: Erik Chen <[email protected]>
Cr-Commit-Position: refs/heads/master@{#558530}
diff --git a/chrome/browser/sessions/session_service.h b/chrome/browser/sessions/session_service.h
index 169c527..3c42ba4e 100644
--- a/chrome/browser/sessions/session_service.h
+++ b/chrome/browser/sessions/session_service.h
@@ -384,6 +384,10 @@
   // Force session commands to be rebuild before next save event.
   bool rebuild_on_next_save_;
 
+  // Don't send duplicate SetSelectedTabInWindow commands when the selected
+  // tab's index hasn't changed.
+  std::map<SessionID, int> last_selected_tab_in_window_;
+
   base::WeakPtrFactory<SessionService> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(SessionService);