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/jumplist_win.h" | 5 #include "chrome/browser/jumplist_win.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
12 #include "base/prefs/pref_change_registrar.h" | 12 #include "base/prefs/pref_change_registrar.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
16 #include "chrome/browser/browser_process.h" | |
16 #include "chrome/browser/chrome_notification_types.h" | 17 #include "chrome/browser/chrome_notification_types.h" |
17 #include "chrome/browser/favicon/favicon_service.h" | 18 #include "chrome/browser/favicon/favicon_service.h" |
18 #include "chrome/browser/favicon/favicon_service_factory.h" | 19 #include "chrome/browser/favicon/favicon_service_factory.h" |
19 #include "chrome/browser/history/history_service.h" | 20 #include "chrome/browser/history/history_service.h" |
20 #include "chrome/browser/history/top_sites.h" | 21 #include "chrome/browser/history/top_sites.h" |
21 #include "chrome/browser/profiles/profile.h" | 22 #include "chrome/browser/profiles/profile.h" |
23 #include "chrome/browser/profiles/profile_avatar_icon_util.h" | |
24 #include "chrome/browser/profiles/profile_info_cache.h" | |
25 #include "chrome/browser/profiles/profile_manager.h" | |
22 #include "chrome/browser/sessions/session_types.h" | 26 #include "chrome/browser/sessions/session_types.h" |
23 #include "chrome/browser/sessions/tab_restore_service.h" | 27 #include "chrome/browser/sessions/tab_restore_service.h" |
24 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 28 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
25 #include "chrome/browser/shell_integration.h" | 29 #include "chrome/browser/shell_integration.h" |
26 #include "chrome/common/chrome_constants.h" | 30 #include "chrome/common/chrome_constants.h" |
27 #include "chrome/common/chrome_switches.h" | 31 #include "chrome/common/chrome_switches.h" |
28 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
29 #include "chrome/common/url_constants.h" | 33 #include "chrome/common/url_constants.h" |
30 #include "chrome/grit/generated_resources.h" | 34 #include "chrome/grit/generated_resources.h" |
31 #include "components/favicon_base/favicon_types.h" | 35 #include "components/favicon_base/favicon_types.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 l10n_util::GetStringUTF16(IDS_NEW_INCOGNITO_WINDOW); | 120 l10n_util::GetStringUTF16(IDS_NEW_INCOGNITO_WINDOW); |
117 ReplaceSubstringsAfterOffset(&incognito_title, 0, L"&", L""); | 121 ReplaceSubstringsAfterOffset(&incognito_title, 0, L"&", L""); |
118 incognito->set_title(incognito_title); | 122 incognito->set_title(incognito_title); |
119 incognito->set_icon(chrome_path.value(), 0); | 123 incognito->set_icon(chrome_path.value(), 0); |
120 items.push_back(incognito); | 124 items.push_back(incognito); |
121 } | 125 } |
122 | 126 |
123 return jumplist_updater->AddTasks(items); | 127 return jumplist_updater->AddTasks(items); |
124 } | 128 } |
125 | 129 |
130 bool UpdateProfilesCategory(JumpListUpdater* jumplist_updater, | |
131 AvatarMenu* avatar_menu, | |
132 const std::vector<gfx::Image>& profile_avatars, | |
133 const base::FilePath& icon_dir) { | |
134 base::FilePath chrome_path; | |
135 if (!PathService::Get(base::FILE_EXE, &chrome_path)) | |
136 return false; | |
137 | |
138 ShellLinkItemList profile_items; | |
139 | |
140 for (size_t i = 0; i < avatar_menu->GetNumberOfItems(); ++i) { | |
141 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | |
142 const AvatarMenu::Item& item = avatar_menu->GetItemAt(i); | |
143 | |
144 link->set_title(base::UTF16ToWide(item.name)); | |
tapted
2014/11/03 23:57:06
is the UTF16ToWide needed? (pretty sure std::wstri
noms (inactive)
2014/11/04 20:03:08
Done.
| |
145 link->GetCommandLine()->AppendSwitchPath( | |
146 switches::kProfileDirectory, item.profile_path.BaseName()); | |
147 link->GetCommandLine()->AppendSwitch( | |
148 switches::kReuseExistingProfileBrowser); | |
149 | |
150 // Icons need to be saved on disk to be used by a ShellLinkItem. | |
151 base::FilePath icon_path; | |
152 if (CreateIconFile(profile_avatars[i].AsBitmap(), icon_dir, &icon_path)) | |
153 link->set_icon(icon_path.value(), 0); | |
154 | |
155 profile_items.push_back(link); | |
156 } | |
157 | |
158 return jumplist_updater->AddCustomCategory( | |
159 base::UTF16ToWide( | |
tapted
2014/11/03 23:57:05
remove UTF16ToWide?
noms (inactive)
2014/11/04 20:03:08
Done.
| |
160 l10n_util::GetStringUTF16(IDS_PROFILES_OPTIONS_GROUP_NAME)), | |
161 profile_items, profile_items.size()); | |
162 } | |
163 | |
126 // Updates the application JumpList. | 164 // Updates the application JumpList. |
127 bool UpdateJumpList(const wchar_t* app_id, | 165 bool UpdateJumpList(const wchar_t* app_id, |
128 const ShellLinkItemList& most_visited_pages, | 166 const ShellLinkItemList& most_visited_pages, |
129 const ShellLinkItemList& recently_closed_pages, | 167 const ShellLinkItemList& recently_closed_pages, |
130 IncognitoModePrefs::Availability incognito_availability) { | 168 IncognitoModePrefs::Availability incognito_availability, |
169 AvatarMenu* avatar_menu, | |
170 const std::vector<gfx::Image>& profile_avatars, | |
171 const base::FilePath& icon_dir) { | |
131 // JumpList is implemented only on Windows 7 or later. | 172 // JumpList is implemented only on Windows 7 or later. |
132 // So, we should return now when this function is called on earlier versions | 173 // So, we should return now when this function is called on earlier versions |
133 // of Windows. | 174 // of Windows. |
134 if (!JumpListUpdater::IsEnabled()) | 175 if (!JumpListUpdater::IsEnabled()) |
135 return true; | 176 return true; |
136 | 177 |
137 JumpListUpdater jumplist_updater(app_id); | 178 JumpListUpdater jumplist_updater(app_id); |
138 if (!jumplist_updater.BeginUpdate()) | 179 if (!jumplist_updater.BeginUpdate()) |
139 return false; | 180 return false; |
140 | 181 |
(...skipping 24 matching lines...) Expand all Loading... | |
165 } | 206 } |
166 | 207 |
167 // Update the "Recently Closed" category of the JumpList. | 208 // Update the "Recently Closed" category of the JumpList. |
168 if (!jumplist_updater.AddCustomCategory( | 209 if (!jumplist_updater.AddCustomCategory( |
169 base::UTF16ToWide( | 210 base::UTF16ToWide( |
170 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), | 211 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), |
171 recently_closed_pages, recently_closed_items)) { | 212 recently_closed_pages, recently_closed_items)) { |
172 return false; | 213 return false; |
173 } | 214 } |
174 | 215 |
216 // Update the "Profiles" category of the JumpList. | |
217 if (!UpdateProfilesCategory(&jumplist_updater, avatar_menu, | |
218 profile_avatars, icon_dir)) { | |
219 return false; | |
220 } | |
221 | |
175 // Update the "Tasks" category of the JumpList. | 222 // Update the "Tasks" category of the JumpList. |
176 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | 223 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
177 return false; | 224 return false; |
178 | 225 |
179 // Commit this transaction and send the updated JumpList to Windows. | 226 // Commit this transaction and send the updated JumpList to Windows. |
180 if (!jumplist_updater.CommitUpdate()) | 227 if (!jumplist_updater.CommitUpdate()) |
181 return false; | 228 return false; |
182 | 229 |
183 return true; | 230 return true; |
184 } | 231 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 // observers are detatched at that time. | 264 // observers are detatched at that time. |
218 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 265 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
219 content::Source<Profile>(profile_)); | 266 content::Source<Profile>(profile_)); |
220 } | 267 } |
221 tab_restore_service->AddObserver(this); | 268 tab_restore_service->AddObserver(this); |
222 pref_change_registrar_.reset(new PrefChangeRegistrar); | 269 pref_change_registrar_.reset(new PrefChangeRegistrar); |
223 pref_change_registrar_->Init(profile_->GetPrefs()); | 270 pref_change_registrar_->Init(profile_->GetPrefs()); |
224 pref_change_registrar_->Add( | 271 pref_change_registrar_->Add( |
225 prefs::kIncognitoModeAvailability, | 272 prefs::kIncognitoModeAvailability, |
226 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); | 273 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); |
274 | |
275 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
276 DCHECK(profile_manager); | |
277 avatar_menu_.reset(new AvatarMenu( | |
278 &profile_manager->GetProfileInfoCache(), this, NULL)); | |
279 avatar_menu_->RebuildMenu(); | |
280 UpdateProfileAvatars(); | |
227 } | 281 } |
228 | 282 |
229 JumpList::~JumpList() { | 283 JumpList::~JumpList() { |
230 Terminate(); | 284 Terminate(); |
231 } | 285 } |
232 | 286 |
233 // static | 287 // static |
234 bool JumpList::Enabled() { | 288 bool JumpList::Enabled() { |
235 return JumpListUpdater::IsEnabled(); | 289 return JumpListUpdater::IsEnabled(); |
236 } | 290 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 recently_closed_pages_ = temp_list; | 397 recently_closed_pages_ = temp_list; |
344 } | 398 } |
345 | 399 |
346 // Send a query that retrieves the first favicon. | 400 // Send a query that retrieves the first favicon. |
347 StartLoadingFavicon(); | 401 StartLoadingFavicon(); |
348 } | 402 } |
349 | 403 |
350 void JumpList::TabRestoreServiceDestroyed(TabRestoreService* service) { | 404 void JumpList::TabRestoreServiceDestroyed(TabRestoreService* service) { |
351 } | 405 } |
352 | 406 |
407 void JumpList::OnAvatarMenuChanged(AvatarMenu* avatar_menu) { | |
408 UpdateProfileAvatars(); | |
409 PostRunUpdate(); | |
410 } | |
411 | |
353 bool JumpList::AddTab(const TabRestoreService::Tab* tab, | 412 bool JumpList::AddTab(const TabRestoreService::Tab* tab, |
354 ShellLinkItemList* list, | 413 ShellLinkItemList* list, |
355 size_t max_items) { | 414 size_t max_items) { |
356 // This code adds the URL and the title strings of the given tab to the | 415 // This code adds the URL and the title strings of the given tab to the |
357 // specified list. | 416 // specified list. |
358 if (list->size() >= max_items) | 417 if (list->size() >= max_items) |
359 return false; | 418 return false; |
360 | 419 |
361 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 420 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
362 const sessions::SerializedNavigationEntry& current_navigation = | 421 const sessions::SerializedNavigationEntry& current_navigation = |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
408 url, | 467 url, |
409 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), | 468 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), |
410 &cancelable_task_tracker_); | 469 &cancelable_task_tracker_); |
411 } | 470 } |
412 | 471 |
413 void JumpList::OnFaviconDataAvailable( | 472 void JumpList::OnFaviconDataAvailable( |
414 const favicon_base::FaviconImageResult& image_result) { | 473 const favicon_base::FaviconImageResult& image_result) { |
415 // If there is currently a favicon request in progress, it is now outdated, | 474 // If there is currently a favicon request in progress, it is now outdated, |
416 // as we have received another, so nullify the handle from the old request. | 475 // as we have received another, so nullify the handle from the old request. |
417 task_id_ = base::CancelableTaskTracker::kBadTaskId; | 476 task_id_ = base::CancelableTaskTracker::kBadTaskId; |
418 // lock the list to set icon data and pop the url | 477 // Lock the list to set icon data and pop the url. |
419 { | 478 { |
420 base::AutoLock auto_lock(list_lock_); | 479 base::AutoLock auto_lock(list_lock_); |
421 // Attach the received data to the ShellLinkItem object. | 480 // Attach the received data to the ShellLinkItem object. |
422 // This data will be decoded by the RunUpdate method. | 481 // This data will be decoded by the RunUpdate method. |
423 if (!image_result.image.IsEmpty()) { | 482 if (!image_result.image.IsEmpty()) { |
424 if (!icon_urls_.empty() && icon_urls_.front().second) | 483 if (!icon_urls_.empty() && icon_urls_.front().second) |
425 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); | 484 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); |
426 } | 485 } |
427 | 486 |
428 if (!icon_urls_.empty()) | 487 if (!icon_urls_.empty()) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 CreateIconFiles(local_most_visited_pages); | 544 CreateIconFiles(local_most_visited_pages); |
486 | 545 |
487 // Create temporary icon files for shortcuts in the "Recently Closed" | 546 // Create temporary icon files for shortcuts in the "Recently Closed" |
488 // category. | 547 // category. |
489 CreateIconFiles(local_recently_closed_pages); | 548 CreateIconFiles(local_recently_closed_pages); |
490 | 549 |
491 // We finished collecting all resources needed for updating an application | 550 // We finished collecting all resources needed for updating an application |
492 // JumpList. So, create a new JumpList and replace the current JumpList | 551 // JumpList. So, create a new JumpList and replace the current JumpList |
493 // with it. | 552 // with it. |
494 UpdateJumpList(app_id_.c_str(), local_most_visited_pages, | 553 UpdateJumpList(app_id_.c_str(), local_most_visited_pages, |
495 local_recently_closed_pages, incognito_availability); | 554 local_recently_closed_pages, incognito_availability, |
555 avatar_menu_.get(), profile_avatars_, icon_dir_); | |
tapted
2014/11/03 23:57:05
RunUpdate runs on the FILE thread, so accessing |a
noms (inactive)
2014/11/04 20:03:08
Done.
| |
496 } | 556 } |
497 | 557 |
498 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { | 558 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { |
499 for (ShellLinkItemList::const_iterator item = item_list.begin(); | 559 for (ShellLinkItemList::const_iterator item = item_list.begin(); |
500 item != item_list.end(); ++item) { | 560 item != item_list.end(); ++item) { |
501 base::FilePath icon_path; | 561 base::FilePath icon_path; |
502 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) | 562 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) |
503 (*item)->set_icon(icon_path.value(), 0); | 563 (*item)->set_icon(icon_path.value(), 0); |
504 } | 564 } |
505 } | 565 } |
566 | |
567 void JumpList::UpdateProfileAvatars() { | |
568 profile_avatars_.clear(); | |
569 for (size_t i = 0; i < avatar_menu_->GetNumberOfItems(); ++i) { | |
570 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(i); | |
571 gfx::Image avatar; | |
572 bool is_rectangle; | |
573 profiles::GetTransparentBackgroundProfileAvatar( | |
574 item.profile_path, &avatar, &is_rectangle); | |
575 profile_avatars_.push_back(avatar); | |
576 } | |
577 } | |
OLD | NEW |