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