| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/webui/foreign_session_handler.h" | 5 #include "chrome/browser/ui/webui/foreign_session_handler.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "ui/base/webui/web_ui_util.h" | 37 #include "ui/base/webui/web_ui_util.h" |
| 38 | 38 |
| 39 namespace browser_sync { | 39 namespace browser_sync { |
| 40 | 40 |
| 41 namespace { | 41 namespace { |
| 42 | 42 |
| 43 // Maximum number of sessions we're going to display on the NTP | 43 // Maximum number of sessions we're going to display on the NTP |
| 44 const size_t kMaxSessionsToShow = 10; | 44 const size_t kMaxSessionsToShow = 10; |
| 45 | 45 |
| 46 // Helper method to create JSON compatible objects from Session objects. | 46 // Helper method to create JSON compatible objects from Session objects. |
| 47 scoped_ptr<base::DictionaryValue> SessionTabToValue( | 47 std::unique_ptr<base::DictionaryValue> SessionTabToValue( |
| 48 const ::sessions::SessionTab& tab) { | 48 const ::sessions::SessionTab& tab) { |
| 49 if (tab.navigations.empty()) | 49 if (tab.navigations.empty()) |
| 50 return nullptr; | 50 return nullptr; |
| 51 | 51 |
| 52 int selected_index = std::min(tab.current_navigation_index, | 52 int selected_index = std::min(tab.current_navigation_index, |
| 53 static_cast<int>(tab.navigations.size() - 1)); | 53 static_cast<int>(tab.navigations.size() - 1)); |
| 54 const ::sessions::SerializedNavigationEntry& current_navigation = | 54 const ::sessions::SerializedNavigationEntry& current_navigation = |
| 55 tab.navigations.at(selected_index); | 55 tab.navigations.at(selected_index); |
| 56 GURL tab_url = current_navigation.virtual_url(); | 56 GURL tab_url = current_navigation.virtual_url(); |
| 57 if (!tab_url.is_valid() || | 57 if (!tab_url.is_valid() || |
| 58 tab_url.spec() == chrome::kChromeUINewTabURL) { | 58 tab_url.spec() == chrome::kChromeUINewTabURL) { |
| 59 return nullptr; | 59 return nullptr; |
| 60 } | 60 } |
| 61 | 61 |
| 62 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); | 62 std::unique_ptr<base::DictionaryValue> dictionary( |
| 63 new base::DictionaryValue()); |
| 63 NewTabUI::SetUrlTitleAndDirection(dictionary.get(), | 64 NewTabUI::SetUrlTitleAndDirection(dictionary.get(), |
| 64 current_navigation.title(), tab_url); | 65 current_navigation.title(), tab_url); |
| 65 dictionary->SetString("type", "tab"); | 66 dictionary->SetString("type", "tab"); |
| 66 dictionary->SetDouble("timestamp", | 67 dictionary->SetDouble("timestamp", |
| 67 static_cast<double>(tab.timestamp.ToInternalValue())); | 68 static_cast<double>(tab.timestamp.ToInternalValue())); |
| 68 // TODO(jeremycho): This should probably be renamed to tabId to avoid | 69 // TODO(jeremycho): This should probably be renamed to tabId to avoid |
| 69 // confusion with the ID corresponding to a session. Investigate all the | 70 // confusion with the ID corresponding to a session. Investigate all the |
| 70 // places (C++ and JS) where this is being used. (http://crbug.com/154865). | 71 // places (C++ and JS) where this is being used. (http://crbug.com/154865). |
| 71 dictionary->SetInteger("sessionId", tab.tab_id.id()); | 72 dictionary->SetInteger("sessionId", tab.tab_id.id()); |
| 72 return dictionary; | 73 return dictionary; |
| 73 } | 74 } |
| 74 | 75 |
| 75 // Helper for initializing a boilerplate SessionWindow JSON compatible object. | 76 // Helper for initializing a boilerplate SessionWindow JSON compatible object. |
| 76 scoped_ptr<base::DictionaryValue> BuildWindowData( | 77 std::unique_ptr<base::DictionaryValue> BuildWindowData( |
| 77 base::Time modification_time, | 78 base::Time modification_time, |
| 78 SessionID::id_type window_id) { | 79 SessionID::id_type window_id) { |
| 79 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue()); | 80 std::unique_ptr<base::DictionaryValue> dictionary( |
| 81 new base::DictionaryValue()); |
| 80 // The items which are to be written into |dictionary| are also described in | 82 // The items which are to be written into |dictionary| are also described in |
| 81 // chrome/browser/resources/ntp4/other_sessions.js in @typedef for WindowData. | 83 // chrome/browser/resources/ntp4/other_sessions.js in @typedef for WindowData. |
| 82 // Please update it whenever you add or remove any keys here. | 84 // Please update it whenever you add or remove any keys here. |
| 83 dictionary->SetString("type", "window"); | 85 dictionary->SetString("type", "window"); |
| 84 dictionary->SetDouble("timestamp", modification_time.ToInternalValue()); | 86 dictionary->SetDouble("timestamp", modification_time.ToInternalValue()); |
| 85 const base::TimeDelta last_synced = base::Time::Now() - modification_time; | 87 const base::TimeDelta last_synced = base::Time::Now() - modification_time; |
| 86 // If clock skew leads to a future time, or we last synced less than a minute | 88 // If clock skew leads to a future time, or we last synced less than a minute |
| 87 // ago, output "Just now". | 89 // ago, output "Just now". |
| 88 dictionary->SetString( | 90 dictionary->SetString( |
| 89 "userVisibleTimestamp", | 91 "userVisibleTimestamp", |
| 90 last_synced < base::TimeDelta::FromMinutes(1) | 92 last_synced < base::TimeDelta::FromMinutes(1) |
| 91 ? l10n_util::GetStringUTF16(IDS_SYNC_TIME_JUST_NOW) | 93 ? l10n_util::GetStringUTF16(IDS_SYNC_TIME_JUST_NOW) |
| 92 : ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, | 94 : ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, |
| 93 ui::TimeFormat::LENGTH_SHORT, last_synced)); | 95 ui::TimeFormat::LENGTH_SHORT, last_synced)); |
| 94 | 96 |
| 95 dictionary->SetInteger("sessionId", window_id); | 97 dictionary->SetInteger("sessionId", window_id); |
| 96 return dictionary; | 98 return dictionary; |
| 97 } | 99 } |
| 98 | 100 |
| 99 // Helper method to create JSON compatible objects from SessionWindow objects. | 101 // Helper method to create JSON compatible objects from SessionWindow objects. |
| 100 scoped_ptr<base::DictionaryValue> SessionWindowToValue( | 102 std::unique_ptr<base::DictionaryValue> SessionWindowToValue( |
| 101 const ::sessions::SessionWindow& window) { | 103 const ::sessions::SessionWindow& window) { |
| 102 if (window.tabs.empty()) | 104 if (window.tabs.empty()) |
| 103 return nullptr; | 105 return nullptr; |
| 104 scoped_ptr<base::ListValue> tab_values(new base::ListValue()); | 106 std::unique_ptr<base::ListValue> tab_values(new base::ListValue()); |
| 105 // Calculate the last |modification_time| for all entries within a window. | 107 // Calculate the last |modification_time| for all entries within a window. |
| 106 base::Time modification_time = window.timestamp; | 108 base::Time modification_time = window.timestamp; |
| 107 for (const ::sessions::SessionTab* tab : window.tabs) { | 109 for (const ::sessions::SessionTab* tab : window.tabs) { |
| 108 scoped_ptr<base::DictionaryValue> tab_value(SessionTabToValue(*tab)); | 110 std::unique_ptr<base::DictionaryValue> tab_value(SessionTabToValue(*tab)); |
| 109 if (tab_value.get()) { | 111 if (tab_value.get()) { |
| 110 modification_time = std::max(modification_time, | 112 modification_time = std::max(modification_time, |
| 111 tab->timestamp); | 113 tab->timestamp); |
| 112 tab_values->Append(tab_value.release()); | 114 tab_values->Append(tab_value.release()); |
| 113 } | 115 } |
| 114 } | 116 } |
| 115 if (tab_values->GetSize() == 0) | 117 if (tab_values->GetSize() == 0) |
| 116 return nullptr; | 118 return nullptr; |
| 117 scoped_ptr<base::DictionaryValue> dictionary( | 119 std::unique_ptr<base::DictionaryValue> dictionary( |
| 118 BuildWindowData(window.timestamp, window.window_id.id())); | 120 BuildWindowData(window.timestamp, window.window_id.id())); |
| 119 dictionary->Set("tabs", tab_values.release()); | 121 dictionary->Set("tabs", tab_values.release()); |
| 120 return dictionary; | 122 return dictionary; |
| 121 } | 123 } |
| 122 | 124 |
| 123 } // namespace | 125 } // namespace |
| 124 | 126 |
| 125 ForeignSessionHandler::ForeignSessionHandler() : scoped_observer_(this) { | 127 ForeignSessionHandler::ForeignSessionHandler() : scoped_observer_(this) { |
| 126 load_attempt_time_ = base::TimeTicks::Now(); | 128 load_attempt_time_ = base::TimeTicks::Now(); |
| 127 } | 129 } |
| 128 | 130 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 base::TimeTicks::Now() - load_attempt_time_); | 263 base::TimeTicks::Now() - load_attempt_time_); |
| 262 load_attempt_time_ = base::TimeTicks(); | 264 load_attempt_time_ = base::TimeTicks(); |
| 263 } | 265 } |
| 264 | 266 |
| 265 // Use a pref to keep track of sessions that were collapsed by the user. | 267 // Use a pref to keep track of sessions that were collapsed by the user. |
| 266 // To prevent the pref from accumulating stale sessions, clear it each time | 268 // To prevent the pref from accumulating stale sessions, clear it each time |
| 267 // and only add back sessions that are still current. | 269 // and only add back sessions that are still current. |
| 268 DictionaryPrefUpdate pref_update(Profile::FromWebUI(web_ui())->GetPrefs(), | 270 DictionaryPrefUpdate pref_update(Profile::FromWebUI(web_ui())->GetPrefs(), |
| 269 prefs::kNtpCollapsedForeignSessions); | 271 prefs::kNtpCollapsedForeignSessions); |
| 270 base::DictionaryValue* current_collapsed_sessions = pref_update.Get(); | 272 base::DictionaryValue* current_collapsed_sessions = pref_update.Get(); |
| 271 scoped_ptr<base::DictionaryValue> collapsed_sessions( | 273 std::unique_ptr<base::DictionaryValue> collapsed_sessions( |
| 272 current_collapsed_sessions->DeepCopy()); | 274 current_collapsed_sessions->DeepCopy()); |
| 273 current_collapsed_sessions->Clear(); | 275 current_collapsed_sessions->Clear(); |
| 274 | 276 |
| 275 // Note: we don't own the SyncedSessions themselves. | 277 // Note: we don't own the SyncedSessions themselves. |
| 276 for (size_t i = 0; i < sessions.size() && i < kMaxSessionsToShow; ++i) { | 278 for (size_t i = 0; i < sessions.size() && i < kMaxSessionsToShow; ++i) { |
| 277 const sync_driver::SyncedSession* session = sessions[i]; | 279 const sync_driver::SyncedSession* session = sessions[i]; |
| 278 const std::string& session_tag = session->session_tag; | 280 const std::string& session_tag = session->session_tag; |
| 279 scoped_ptr<base::DictionaryValue> session_data( | 281 std::unique_ptr<base::DictionaryValue> session_data( |
| 280 new base::DictionaryValue()); | 282 new base::DictionaryValue()); |
| 281 // The items which are to be written into |session_data| are also | 283 // The items which are to be written into |session_data| are also |
| 282 // described in chrome/browser/resources/ntp4/other_sessions.js in | 284 // described in chrome/browser/resources/ntp4/other_sessions.js in |
| 283 // @typedef for SessionData. Please update it whenever you add or remove | 285 // @typedef for SessionData. Please update it whenever you add or remove |
| 284 // any keys here. | 286 // any keys here. |
| 285 session_data->SetString("tag", session_tag); | 287 session_data->SetString("tag", session_tag); |
| 286 session_data->SetString("name", session->session_name); | 288 session_data->SetString("name", session->session_name); |
| 287 session_data->SetString("deviceType", session->DeviceTypeAsString()); | 289 session_data->SetString("deviceType", session->DeviceTypeAsString()); |
| 288 session_data->SetString("modifiedTime", | 290 session_data->SetString("modifiedTime", |
| 289 FormatSessionTime(session->modified_time)); | 291 FormatSessionTime(session->modified_time)); |
| 290 | 292 |
| 291 bool is_collapsed = collapsed_sessions->HasKey(session_tag); | 293 bool is_collapsed = collapsed_sessions->HasKey(session_tag); |
| 292 session_data->SetBoolean("collapsed", is_collapsed); | 294 session_data->SetBoolean("collapsed", is_collapsed); |
| 293 if (is_collapsed) | 295 if (is_collapsed) |
| 294 current_collapsed_sessions->SetBoolean(session_tag, true); | 296 current_collapsed_sessions->SetBoolean(session_tag, true); |
| 295 | 297 |
| 296 scoped_ptr<base::ListValue> window_list(new base::ListValue()); | 298 std::unique_ptr<base::ListValue> window_list(new base::ListValue()); |
| 297 const std::string group_name = | 299 const std::string group_name = |
| 298 base::FieldTrialList::FindFullName("TabSyncByRecency"); | 300 base::FieldTrialList::FindFullName("TabSyncByRecency"); |
| 299 if (group_name != "Enabled") { | 301 if (group_name != "Enabled") { |
| 300 // Order tabs by visual order within window. | 302 // Order tabs by visual order within window. |
| 301 for (auto map_iter : session->windows) { | 303 for (auto map_iter : session->windows) { |
| 302 scoped_ptr<base::DictionaryValue> window_data( | 304 std::unique_ptr<base::DictionaryValue> window_data( |
| 303 SessionWindowToValue(*map_iter.second)); | 305 SessionWindowToValue(*map_iter.second)); |
| 304 if (window_data.get()) | 306 if (window_data.get()) |
| 305 window_list->Append(window_data.release()); | 307 window_list->Append(window_data.release()); |
| 306 } | 308 } |
| 307 } else { | 309 } else { |
| 308 // Order tabs by recency. This involves creating a synthetic singleton | 310 // Order tabs by recency. This involves creating a synthetic singleton |
| 309 // window that contains all the tabs of the session. | 311 // window that contains all the tabs of the session. |
| 310 base::Time modification_time; | 312 base::Time modification_time; |
| 311 std::vector<const ::sessions::SessionTab*> tabs; | 313 std::vector<const ::sessions::SessionTab*> tabs; |
| 312 open_tabs->GetForeignSessionTabs(session_tag, &tabs); | 314 open_tabs->GetForeignSessionTabs(session_tag, &tabs); |
| 313 scoped_ptr<base::ListValue> tab_values(new base::ListValue()); | 315 std::unique_ptr<base::ListValue> tab_values(new base::ListValue()); |
| 314 for (const ::sessions::SessionTab* tab : tabs) { | 316 for (const ::sessions::SessionTab* tab : tabs) { |
| 315 scoped_ptr<base::DictionaryValue> tab_value(SessionTabToValue(*tab)); | 317 std::unique_ptr<base::DictionaryValue> tab_value( |
| 318 SessionTabToValue(*tab)); |
| 316 if (tab_value.get()) { | 319 if (tab_value.get()) { |
| 317 modification_time = std::max(modification_time, tab->timestamp); | 320 modification_time = std::max(modification_time, tab->timestamp); |
| 318 tab_values->Append(tab_value.release()); | 321 tab_values->Append(tab_value.release()); |
| 319 } | 322 } |
| 320 } | 323 } |
| 321 if (tab_values->GetSize() != 0) { | 324 if (tab_values->GetSize() != 0) { |
| 322 scoped_ptr<base::DictionaryValue> window_data( | 325 std::unique_ptr<base::DictionaryValue> window_data( |
| 323 BuildWindowData(modification_time, 1)); | 326 BuildWindowData(modification_time, 1)); |
| 324 window_data->Set("tabs", tab_values.release()); | 327 window_data->Set("tabs", tab_values.release()); |
| 325 window_list->Append(window_data.release()); | 328 window_list->Append(window_data.release()); |
| 326 } | 329 } |
| 327 } | 330 } |
| 328 | 331 |
| 329 session_data->Set("windows", window_list.release()); | 332 session_data->Set("windows", window_list.release()); |
| 330 session_list.Append(session_data.release()); | 333 session_list.Append(session_data.release()); |
| 331 } | 334 } |
| 332 } | 335 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 // collapsed state persists. | 429 // collapsed state persists. |
| 427 PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); | 430 PrefService* prefs = Profile::FromWebUI(web_ui())->GetPrefs(); |
| 428 DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions); | 431 DictionaryPrefUpdate update(prefs, prefs::kNtpCollapsedForeignSessions); |
| 429 if (is_collapsed) | 432 if (is_collapsed) |
| 430 update.Get()->SetBoolean(session_tag, true); | 433 update.Get()->SetBoolean(session_tag, true); |
| 431 else | 434 else |
| 432 update.Get()->Remove(session_tag, NULL); | 435 update.Get()->Remove(session_tag, NULL); |
| 433 } | 436 } |
| 434 | 437 |
| 435 } // namespace browser_sync | 438 } // namespace browser_sync |
| OLD | NEW |