Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/dom_ui/foreign_session_handler.h" | 5 #include "chrome/browser/dom_ui/foreign_session_handler.h" |
| 6 | 6 |
| 7 #include <algorithm> | |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 #include <vector> |
| 9 #include "base/scoped_vector.h" | 10 #include "base/scoped_vector.h" |
| 11 #include "base/string_number_conversions.h" | |
| 10 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/browser/dom_ui/value_helper.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/dom_ui/new_tab_ui.h" | |
| 12 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/sessions/session_restore.h" | 16 #include "chrome/browser/sessions/session_restore.h" |
| 14 #include "chrome/browser/sessions/tab_restore_service.h" | |
| 15 #include "chrome/browser/sync/engine/syncapi.h" | 17 #include "chrome/browser/sync/engine/syncapi.h" |
| 16 #include "chrome/browser/sync/profile_sync_service.h" | 18 #include "chrome/browser/sync/profile_sync_service.h" |
| 17 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
| 18 #include "chrome/common/notification_details.h" | 20 #include "chrome/common/notification_details.h" |
| 19 #include "chrome/common/notification_service.h" | 21 #include "chrome/common/notification_service.h" |
| 22 #include "chrome/common/url_constants.h" | |
| 20 | 23 |
| 21 namespace browser_sync { | 24 namespace browser_sync { |
| 22 | 25 |
| 23 static const int kMaxSessionsToShow = 10; | 26 static const int kMaxSessionsToShow = 10; |
| 24 | 27 |
| 25 ForeignSessionHandler::ForeignSessionHandler() { | 28 ForeignSessionHandler::ForeignSessionHandler() { |
| 26 Init(); | 29 Init(); |
| 27 } | 30 } |
| 28 | 31 |
| 29 void ForeignSessionHandler::RegisterMessages() { | 32 void ForeignSessionHandler::RegisterMessages() { |
| 30 dom_ui_->RegisterMessageCallback("getForeignSessions", | 33 dom_ui_->RegisterMessageCallback("getForeignSessions", |
| 31 NewCallback(this, | 34 NewCallback(this, |
| 32 &ForeignSessionHandler::HandleGetForeignSessions)); | 35 &ForeignSessionHandler::HandleGetForeignSessions)); |
| 33 dom_ui_->RegisterMessageCallback("reopenForeignSession", | 36 dom_ui_->RegisterMessageCallback("openForeignSession", |
| 34 NewCallback(this, | 37 NewCallback(this, |
| 35 &ForeignSessionHandler::HandleReopenForeignSession)); | 38 &ForeignSessionHandler::HandleOpenForeignSession)); |
| 36 } | 39 } |
| 37 | 40 |
| 38 void ForeignSessionHandler::Init() { | 41 void ForeignSessionHandler::Init() { |
| 39 registrar_.Add(this, NotificationType::SYNC_CONFIGURE_DONE, | 42 registrar_.Add(this, NotificationType::SYNC_CONFIGURE_DONE, |
| 40 NotificationService::AllSources()); | 43 NotificationService::AllSources()); |
| 41 registrar_.Add(this, NotificationType::FOREIGN_SESSION_UPDATED, | 44 registrar_.Add(this, NotificationType::FOREIGN_SESSION_UPDATED, |
| 42 NotificationService::AllSources()); | 45 NotificationService::AllSources()); |
| 43 registrar_.Add(this, NotificationType::FOREIGN_SESSION_DISABLED, | 46 registrar_.Add(this, NotificationType::FOREIGN_SESSION_DISABLED, |
| 44 NotificationService::AllSources()); | 47 NotificationService::AllSources()); |
| 45 } | 48 } |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 74 if (model_associator == NULL || | 77 if (model_associator == NULL || |
| 75 !service->ShouldPushChanges()) { | 78 !service->ShouldPushChanges()) { |
| 76 return NULL; | 79 return NULL; |
| 77 } | 80 } |
| 78 return dom_ui_->GetProfile()->GetProfileSyncService()-> | 81 return dom_ui_->GetProfile()->GetProfileSyncService()-> |
| 79 GetSessionModelAssociator(); | 82 GetSessionModelAssociator(); |
| 80 } | 83 } |
| 81 | 84 |
| 82 void ForeignSessionHandler::HandleGetForeignSessions(const ListValue* args) { | 85 void ForeignSessionHandler::HandleGetForeignSessions(const ListValue* args) { |
| 83 SessionModelAssociator* associator = GetModelAssociator(); | 86 SessionModelAssociator* associator = GetModelAssociator(); |
| 84 if (associator) | 87 std::vector<const ForeignSession*> sessions; |
| 85 GetForeignSessions(associator); | |
| 86 } | |
| 87 | 88 |
| 88 void ForeignSessionHandler::HandleReopenForeignSession( | 89 if (associator == NULL) { |
| 89 const ListValue* args) { | 90 // Called before associator created, exit. |
| 90 // Extract the machine tag and use it to obtain the id for the node we are | 91 return; |
| 91 // looking for. Send it along with a valid associator to OpenForeignSessions. | |
| 92 std::string session_string_value = WideToUTF8(ExtractStringValue(args)); | |
| 93 SessionModelAssociator* associator = GetModelAssociator(); | |
| 94 if (associator && !session_string_value.empty()) { | |
| 95 int64 id = associator->GetSyncIdFromChromeId(session_string_value); | |
| 96 OpenForeignSession(associator, id); | |
| 97 } | 92 } |
| 98 } | |
| 99 | 93 |
| 100 void ForeignSessionHandler::OpenForeignSession( | 94 // Note: we don't own the ForeignSessions themselves. |
| 101 SessionModelAssociator* associator, int64 id) { | 95 if (!associator->GetAllForeignSessions(&sessions)) { |
| 102 // Obtain the session windows for the foreign session. | |
| 103 // We don't have a ForeignSessionHandler in off the record mode, so we | |
| 104 // expect the ProfileSyncService to exist. | |
| 105 sync_api::ReadTransaction trans(dom_ui_->GetProfile()-> | |
| 106 GetProfileSyncService()->backend()->GetUserShareHandle()); | |
| 107 ScopedVector<ForeignSession> session; | |
| 108 associator->AppendForeignSessionWithID(id, &session.get(), &trans); | |
| 109 | |
| 110 DCHECK_EQ(1U, session.size()); | |
| 111 std::vector<SessionWindow*> windows = (*session.begin())->windows; | |
| 112 SessionRestore::RestoreForeignSessionWindows(dom_ui_->GetProfile(), &windows); | |
| 113 } | |
| 114 | |
| 115 void ForeignSessionHandler::GetForeignSessions( | |
| 116 SessionModelAssociator* associator) { | |
| 117 ScopedVector<ForeignSession> clients; | |
| 118 if (!associator->GetSessionData(&clients.get())) { | |
| 119 LOG(ERROR) << "ForeignSessionHandler failed to get session data from" | 96 LOG(ERROR) << "ForeignSessionHandler failed to get session data from" |
| 120 "SessionModelAssociator."; | 97 "SessionModelAssociator."; |
| 121 return; | 98 return; |
| 122 } | 99 } |
| 123 int added_count = 0; | 100 int added_count = 0; |
| 124 ListValue client_list; | 101 ListValue session_list; |
| 125 for (std::vector<ForeignSession*>::const_iterator i = | 102 for (std::vector<const ForeignSession*>::const_iterator i = |
| 126 clients->begin(); i != clients->end() && | 103 sessions.begin(); i != sessions.end() && |
| 127 added_count < kMaxSessionsToShow; ++i) { | 104 added_count < kMaxSessionsToShow; ++i) { |
| 128 ForeignSession* foreign_session = *i; | 105 const ForeignSession* foreign_session = *i; |
| 129 std::vector<TabRestoreService::Entry*> entries; | |
| 130 dom_ui_->GetProfile()->GetTabRestoreService()->CreateEntriesFromWindows( | |
| 131 &foreign_session->windows, &entries); | |
| 132 scoped_ptr<ListValue> window_list(new ListValue()); | 106 scoped_ptr<ListValue> window_list(new ListValue()); |
| 133 for (std::vector<TabRestoreService::Entry*>::const_iterator it = | 107 for (std::vector<SessionWindow*>::const_iterator it = |
| 134 entries.begin(); it != entries.end(); ++it) { | 108 foreign_session->windows.begin(); it != foreign_session->windows.end(); |
| 135 TabRestoreService::Entry* entry = *it; | 109 ++it) { |
| 110 SessionWindow* window = *it; | |
| 136 scoped_ptr<DictionaryValue> window_data(new DictionaryValue()); | 111 scoped_ptr<DictionaryValue> window_data(new DictionaryValue()); |
| 137 if (entry->type == TabRestoreService::WINDOW && | 112 if (SessionWindowToValue(*window, window_data.get())) { |
| 138 ValueHelper::WindowToValue( | |
| 139 *static_cast<TabRestoreService::Window*>(entry), | |
| 140 window_data.get())) { | |
| 141 // The javascript checks if the session id is a valid session id, | |
| 142 // when rendering session information to the new tab page, and it | |
| 143 // sends the sessionTag back when we need to restore a session. | |
| 144 | |
| 145 // TODO(zea): sessionTag is per client, it might be better per window. | |
| 146 window_data->SetString("sessionTag", | 113 window_data->SetString("sessionTag", |
| 147 foreign_session->foreign_session_tag); | 114 foreign_session->foreign_session_tag); |
| 148 window_data->SetInteger("sessionId", entry->id); | |
| 149 | 115 |
| 150 // Give ownership to |list_value|. | 116 // Give ownership to |list_value|. |
| 151 window_list->Append(window_data.release()); | 117 window_list->Append(window_data.release()); |
| 152 } | 118 } |
| 153 } | 119 } |
| 154 added_count++; | 120 added_count++; |
| 155 | 121 |
| 156 // Give ownership to |client_list| | 122 // Give ownership to |session_list| |
| 157 client_list.Append(window_list.release()); | 123 session_list.Append(window_list.release()); |
| 158 } | 124 } |
| 159 dom_ui_->CallJavascriptFunction(L"foreignSessions", client_list); | 125 dom_ui_->CallJavascriptFunction(L"foreignSessions", session_list); |
| 126 } | |
| 127 | |
| 128 void ForeignSessionHandler::HandleOpenForeignSession( | |
| 129 const ListValue* args) { | |
| 130 size_t num_args = args->GetSize(); | |
| 131 if (num_args > 3U || num_args == 0) { | |
| 132 LOG(ERROR) << "openForeignWindow called with only " << args->GetSize() | |
| 133 << " arguments."; | |
| 134 return; | |
| 135 } | |
| 136 | |
| 137 // Extract the machine tag (always provided) | |
| 138 std::string session_string_value; | |
| 139 if (!args->GetString(0, &session_string_value)) { | |
| 140 LOG(ERROR) << "Failed to extract session tag."; | |
| 141 return; | |
| 142 } | |
| 143 | |
| 144 // Extract window number. | |
| 145 std::string window_num_str; | |
| 146 int window_num = -1; | |
| 147 if (num_args >= 2 && (!args->GetString(1, &window_num_str) || | |
| 148 !base::StringToInt(window_num_str, &window_num))) { | |
| 149 LOG(ERROR) << "Failed to extract window number."; | |
| 150 return; | |
| 151 } | |
| 152 | |
| 153 // Extract tab id. | |
| 154 std::string tab_id_str; | |
| 155 SessionID::id_type tab_id = -1; | |
| 156 if (num_args == 3 && (!args->GetString(2, &tab_id_str) || | |
| 157 !base::StringToInt(tab_id_str, &tab_id))) { | |
| 158 LOG(ERROR) << "Failed to extract tab SessionID."; | |
| 159 return; | |
| 160 } | |
| 161 | |
| 162 SessionModelAssociator* associator = GetModelAssociator(); | |
| 163 | |
| 164 if (tab_id != -1) { | |
|
tim (not reviewing)
2010/12/15 21:14:00
what's '-1'? Can we get a named constant? (to use
Nicolas Zea
2010/12/16 18:09:18
Done.
| |
| 165 // We don't actually care about |window_num|, this is just a sanity check. | |
| 166 DCHECK_LT(-1, window_num); | |
| 167 const SessionTab* tab; | |
| 168 if (!associator->GetForeignTab(session_string_value, tab_id, &tab)) { | |
| 169 LOG(ERROR) << "Failed to load foreign tab."; | |
| 170 return; | |
| 171 } | |
| 172 SessionRestore::RestoreForeignSessionTab(dom_ui_->GetProfile(), *tab); | |
| 173 } else { | |
| 174 std::vector<SessionWindow*> windows; | |
| 175 // Note: we don't own the ForeignSessions themselves. | |
| 176 if (!associator->GetForeignSession(session_string_value, &windows)) { | |
| 177 LOG(ERROR) << "ForeignSessionHandler failed to get session data from" | |
| 178 "SessionModelAssociator."; | |
| 179 return; | |
| 180 } | |
| 181 std::vector<SessionWindow*>::const_iterator iter_begin = windows.begin() + | |
| 182 ((window_num == -1) ? 0 : window_num); | |
| 183 std::vector<SessionWindow*>::const_iterator iter_end = ((window_num == -1) ? | |
| 184 std::vector<SessionWindow*>::const_iterator(windows.end()) : | |
| 185 iter_begin+1); | |
| 186 SessionRestore::RestoreForeignSessionWindows(dom_ui_->GetProfile(), | |
| 187 iter_begin, | |
| 188 iter_end); | |
| 189 } | |
| 190 } | |
| 191 | |
| 192 bool ForeignSessionHandler::SessionTabToValue( | |
| 193 const SessionTab& tab, | |
| 194 DictionaryValue* dictionary) { | |
| 195 if (tab.navigations.empty()) | |
| 196 return false; | |
| 197 int selected_index = tab.current_navigation_index; | |
| 198 selected_index = std::max( | |
| 199 0, | |
| 200 std::min(selected_index, | |
| 201 static_cast<int>(tab.navigations.size() - 1))); | |
| 202 const TabNavigation& current_navigation = | |
| 203 tab.navigations.at(selected_index); | |
| 204 if (current_navigation.virtual_url() == GURL(chrome::kChromeUINewTabURL)) | |
| 205 return false; | |
| 206 NewTabUI::SetURLTitleAndDirection(dictionary, current_navigation.title(), | |
| 207 current_navigation.virtual_url()); | |
| 208 dictionary->SetString("type", "tab"); | |
| 209 dictionary->SetReal("timestamp", | |
| 210 static_cast<double>(tab.timestamp.ToInternalValue())); | |
| 211 dictionary->SetInteger("sessionId", tab.tab_id.id()); | |
| 212 return true; | |
| 213 } | |
| 214 | |
| 215 bool ForeignSessionHandler::SessionWindowToValue( | |
| 216 const SessionWindow& window, | |
| 217 DictionaryValue* dictionary) { | |
| 218 if (window.tabs.empty()) { | |
| 219 NOTREACHED(); | |
| 220 return false; | |
| 221 } | |
| 222 scoped_ptr<ListValue> tab_values(new ListValue()); | |
| 223 for (size_t i = 0; i < window.tabs.size(); ++i) { | |
| 224 scoped_ptr<DictionaryValue> tab_value(new DictionaryValue()); | |
| 225 if (SessionTabToValue(*window.tabs[i], tab_value.get())) | |
| 226 tab_values->Append(tab_value.release()); | |
| 227 } | |
| 228 if (tab_values->GetSize() == 0) | |
| 229 return false; | |
| 230 dictionary->SetString("type", "window"); | |
| 231 dictionary->SetReal("timestamp", | |
| 232 static_cast<double>(window.timestamp.ToInternalValue())); | |
| 233 dictionary->SetInteger("sessionId", window.window_id.id()); | |
| 234 dictionary->Set("tabs", tab_values.release()); | |
| 235 return true; | |
| 160 } | 236 } |
| 161 | 237 |
| 162 } // namespace browser_sync | 238 } // namespace browser_sync |
| OLD | NEW |