172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/foreign_session_handler.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 73f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <algorithm> 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string> 93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include <vector> 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_vector.h" 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/string_number_conversions.h" 12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/utf_string_conversions.h" 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/values.h" 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sessions/session_restore.h" 16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/engine/syncapi.h" 17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/sync/profile_sync_service.h" 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/new_tab_ui.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_details.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "chrome/common/url_constants.h" 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace browser_sync { 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Maximum number of session we're going to display on the NTP 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenstatic const int kMaxSessionsToShow = 10; 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Invalid value, used to note that we don't have a tab or window number. 293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstatic const int kInvalidId = -1; 303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenForeignSessionHandler::ForeignSessionHandler() { 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen Init(); 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid ForeignSessionHandler::RegisterMessages() { 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("getForeignSessions", 37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewCallback(this, 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &ForeignSessionHandler::HandleGetForeignSessions)); 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen web_ui_->RegisterMessageCallback("openForeignSession", 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewCallback(this, 413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen &ForeignSessionHandler::HandleOpenForeignSession)); 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid ForeignSessionHandler::Init() { 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen registrar_.Add(this, NotificationType::SYNC_CONFIGURE_DONE, 46731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotificationService::AllSources()); 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen registrar_.Add(this, NotificationType::FOREIGN_SESSION_UPDATED, 48731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotificationService::AllSources()); 49731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick registrar_.Add(this, NotificationType::FOREIGN_SESSION_DISABLED, 50731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NotificationService::AllSources()); 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid ForeignSessionHandler::Observe(NotificationType type, 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const NotificationSource& source, 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const NotificationDetails& details) { 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ListValue list_value; 57731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick switch (type.value) { 58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case NotificationType::SYNC_CONFIGURE_DONE: 59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case NotificationType::FOREIGN_SESSION_UPDATED: 60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick HandleGetForeignSessions(&list_value); 61731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case NotificationType::FOREIGN_SESSION_DISABLED: 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Calling foreignSessions with empty list will automatically hide 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // foreign session section. 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("foreignSessions", list_value); 66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick break; 67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick default: 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick NOTREACHED(); 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSessionModelAssociator* ForeignSessionHandler::GetModelAssociator() { 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ProfileSyncService* service = web_ui_->GetProfile()->GetProfileSyncService(); 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (service == NULL) 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return NULL; 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We only want to set the model associator if there is one, and it is done 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // syncing sessions. 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SessionModelAssociator* model_associator = service-> 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetSessionModelAssociator(); 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (model_associator == NULL || 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen !service->ShouldPushChanges()) { 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return NULL; 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return web_ui_->GetProfile()->GetProfileSyncService()-> 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetSessionModelAssociator(); 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid ForeignSessionHandler::HandleGetForeignSessions(const ListValue* args) { 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SessionModelAssociator* associator = GetModelAssociator(); 903f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::vector<const ForeignSession*> sessions; 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (associator == NULL) { 933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Called before associator created, exit. 943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Note: we don't own the ForeignSessions themselves. 983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!associator->GetAllForeignSessions(&sessions)) { 99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick LOG(ERROR) << "ForeignSessionHandler failed to get session data from" 100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "SessionModelAssociator."; 101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int added_count = 0; 1043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ListValue session_list; 1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen for (std::vector<const ForeignSession*>::const_iterator i = 1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen sessions.begin(); i != sessions.end() && 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen added_count < kMaxSessionsToShow; ++i) { 1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const ForeignSession* foreign_session = *i; 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<ListValue> window_list(new ListValue()); 1103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen for (std::vector<SessionWindow*>::const_iterator it = 1113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen foreign_session->windows.begin(); it != foreign_session->windows.end(); 1123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ++it) { 1133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen SessionWindow* window = *it; 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_ptr<DictionaryValue> window_data(new DictionaryValue()); 1153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (SessionWindowToValue(*window, window_data.get())) { 116731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick window_data->SetString("sessionTag", 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch foreign_session->foreign_session_tag); 118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 119731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Give ownership to |list_value|. 120731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick window_list->Append(window_data.release()); 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen added_count++; 124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Give ownership to |session_list|. 1263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen session_list.Append(window_list.release()); 1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen web_ui_->CallJavascriptFunction("foreignSessions", session_list); 1293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid ForeignSessionHandler::HandleOpenForeignSession( 1323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const ListValue* args) { 1333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen size_t num_args = args->GetSize(); 1343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (num_args > 3U || num_args == 0) { 1353f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "openForeignWindow called with only " << args->GetSize() 1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen << " arguments."; 1373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Extract the machine tag (always provided). 1413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string session_string_value; 1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!args->GetString(0, &session_string_value)) { 1433f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "Failed to extract session tag."; 1443f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Extract window number. 1483f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string window_num_str; 1493f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int window_num = kInvalidId; 1503f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (num_args >= 2 && (!args->GetString(1, &window_num_str) || 1513f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen !base::StringToInt(window_num_str, &window_num))) { 1523f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "Failed to extract window number."; 1533f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1543f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1553f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1563f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Extract tab id. 1573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::string tab_id_str; 1583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen SessionID::id_type tab_id = kInvalidId; 1593f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (num_args == 3 && (!args->GetString(2, &tab_id_str) || 1603f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen !base::StringToInt(tab_id_str, &tab_id))) { 1613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "Failed to extract tab SessionID."; 1623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1633f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1643f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen SessionModelAssociator* associator = GetModelAssociator(); 1663f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1673f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (tab_id != kInvalidId) { 1683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // We don't actually care about |window_num|, this is just a sanity check. 1693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DCHECK_LT(kInvalidId, window_num); 1703f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const SessionTab* tab; 1713f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!associator->GetForeignTab(session_string_value, tab_id, &tab)) { 1723f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "Failed to load foreign tab."; 1733f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionRestore::RestoreForeignSessionTab(web_ui_->GetProfile(), *tab); 1763f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } else { 1773f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::vector<SessionWindow*> windows; 1783f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen // Note: we don't own the ForeignSessions themselves. 1793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (!associator->GetForeignSession(session_string_value, &windows)) { 1803f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen LOG(ERROR) << "ForeignSessionHandler failed to get session data from" 1813f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen "SessionModelAssociator."; 1823f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return; 1833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1843f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::vector<SessionWindow*>::const_iterator iter_begin = windows.begin() + 1853f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ((window_num == kInvalidId) ? 0 : window_num); 1863f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::vector<SessionWindow*>::const_iterator iter_end = 1873f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ((window_num == kInvalidId) ? 1883f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::vector<SessionWindow*>::const_iterator(windows.end()) : 1893f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen iter_begin+1); 19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SessionRestore::RestoreForeignSessionWindows(web_ui_->GetProfile(), 1913f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen iter_begin, 1923f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen iter_end); 1933f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 1943f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 1953f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 1963f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool ForeignSessionHandler::SessionTabToValue( 1973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const SessionTab& tab, 1983f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DictionaryValue* dictionary) { 1993f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (tab.navigations.empty()) 2003f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 2013f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen int selected_index = tab.current_navigation_index; 2023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen selected_index = std::max( 2033f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 0, 2043f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen std::min(selected_index, 2053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen static_cast<int>(tab.navigations.size() - 1))); 2063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const TabNavigation& current_navigation = 2073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen tab.navigations.at(selected_index); 2083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (current_navigation.virtual_url() == GURL(chrome::kChromeUINewTabURL)) 2093f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 2103f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NewTabUI::SetURLTitleAndDirection(dictionary, current_navigation.title(), 2113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen current_navigation.virtual_url()); 2123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen dictionary->SetString("type", "tab"); 21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen dictionary->SetDouble("timestamp", 21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static_cast<double>(tab.timestamp.ToInternalValue())); 2153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen dictionary->SetInteger("sessionId", tab.tab_id.id()); 2163f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return true; 2173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen} 2183f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 2193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbool ForeignSessionHandler::SessionWindowToValue( 2203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const SessionWindow& window, 2213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen DictionaryValue* dictionary) { 2223f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (window.tabs.empty()) { 2233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NOTREACHED(); 2243f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 2253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen } 2263f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen scoped_ptr<ListValue> tab_values(new ListValue()); 2273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen for (size_t i = 0; i < window.tabs.size(); ++i) { 2283f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen scoped_ptr<DictionaryValue> tab_value(new DictionaryValue()); 2293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (SessionTabToValue(*window.tabs[i], tab_value.get())) 2303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen tab_values->Append(tab_value.release()); 231bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 2323f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen if (tab_values->GetSize() == 0) 2333f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return false; 2343f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen dictionary->SetString("type", "window"); 23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen dictionary->SetDouble("timestamp", 23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static_cast<double>(window.timestamp.ToInternalValue())); 2373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen dictionary->SetInteger("sessionId", window.window_id.id()); 2383f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen dictionary->Set("tabs", tab_values.release()); 2393f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen return true; 240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 242bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} // namespace browser_sync 243