Chromium Code Reviews| 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" |
| 22 #include "chrome/browser/metrics/jumplist_metrics_win.h" | |
| 21 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
| 24 #include "chrome/browser/profiles/profile_avatar_icon_util.h" | |
| 25 #include "chrome/browser/profiles/profile_info_cache.h" | |
| 26 #include "chrome/browser/profiles/profile_manager.h" | |
| 22 #include "chrome/browser/sessions/session_types.h" | 27 #include "chrome/browser/sessions/session_types.h" |
| 23 #include "chrome/browser/sessions/tab_restore_service.h" | 28 #include "chrome/browser/sessions/tab_restore_service.h" |
| 24 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 29 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
| 25 #include "chrome/browser/shell_integration.h" | 30 #include "chrome/browser/shell_integration.h" |
| 26 #include "chrome/common/chrome_constants.h" | 31 #include "chrome/common/chrome_constants.h" |
| 27 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/pref_names.h" | 33 #include "chrome/common/pref_names.h" |
| 29 #include "chrome/common/url_constants.h" | 34 #include "chrome/common/url_constants.h" |
| 30 #include "chrome/grit/generated_resources.h" | 35 #include "chrome/grit/generated_resources.h" |
| 31 #include "components/favicon_base/favicon_types.h" | 36 #include "components/favicon_base/favicon_types.h" |
| 32 #include "components/history/core/browser/page_usage_data.h" | 37 #include "components/history/core/browser/page_usage_data.h" |
| 38 #include "components/signin/core/common/profile_management_switches.h" | |
| 33 #include "content/public/browser/browser_thread.h" | 39 #include "content/public/browser/browser_thread.h" |
| 34 #include "content/public/browser/notification_source.h" | 40 #include "content/public/browser/notification_source.h" |
| 35 #include "ui/base/l10n/l10n_util.h" | 41 #include "ui/base/l10n/l10n_util.h" |
| 36 #include "ui/gfx/codec/png_codec.h" | 42 #include "ui/gfx/codec/png_codec.h" |
| 37 #include "ui/gfx/favicon_size.h" | 43 #include "ui/gfx/favicon_size.h" |
| 38 #include "ui/gfx/icon_util.h" | 44 #include "ui/gfx/icon_util.h" |
| 39 #include "ui/gfx/image/image_family.h" | 45 #include "ui/gfx/image/image_family.h" |
| 40 #include "url/gurl.h" | 46 #include "url/gurl.h" |
| 41 | 47 |
| 42 using content::BrowserThread; | 48 using content::BrowserThread; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 items.push_back(incognito); | 126 items.push_back(incognito); |
| 121 } | 127 } |
| 122 | 128 |
| 123 return jumplist_updater->AddTasks(items); | 129 return jumplist_updater->AddTasks(items); |
| 124 } | 130 } |
| 125 | 131 |
| 126 // Updates the application JumpList. | 132 // Updates the application JumpList. |
| 127 bool UpdateJumpList(const wchar_t* app_id, | 133 bool UpdateJumpList(const wchar_t* app_id, |
| 128 const ShellLinkItemList& most_visited_pages, | 134 const ShellLinkItemList& most_visited_pages, |
| 129 const ShellLinkItemList& recently_closed_pages, | 135 const ShellLinkItemList& recently_closed_pages, |
| 130 IncognitoModePrefs::Availability incognito_availability) { | 136 const ShellLinkItemList& profile_switcher, |
| 137 IncognitoModePrefs::Availability incognito_availability, | |
| 138 bool use_profiles_category) { | |
| 131 // JumpList is implemented only on Windows 7 or later. | 139 // JumpList is implemented only on Windows 7 or later. |
| 132 // So, we should return now when this function is called on earlier versions | 140 // So, we should return now when this function is called on earlier versions |
| 133 // of Windows. | 141 // of Windows. |
| 134 if (!JumpListUpdater::IsEnabled()) | 142 if (!JumpListUpdater::IsEnabled()) |
| 135 return true; | 143 return true; |
| 136 | 144 |
| 137 JumpListUpdater jumplist_updater(app_id); | 145 JumpListUpdater jumplist_updater(app_id); |
| 138 if (!jumplist_updater.BeginUpdate()) | 146 if (!jumplist_updater.BeginUpdate()) |
| 139 return false; | 147 return false; |
| 140 | 148 |
| 141 // We allocate 60% of the given JumpList slots to "most-visited" items | 149 size_t recently_closed_items; |
| 142 // and 40% to "recently-closed" items, respectively. | 150 size_t profiles_or_most_visited_items; |
| 143 // Nevertheless, if there are not so many items in |recently_closed_pages|, | 151 |
| 144 // we give the remaining slots to "most-visited" items. | 152 // Depending on the experiment, we are either showing the "Most-Visited" or |
| 145 const int kMostVisited = 60; | 153 // "People" categories. |
| 146 const int kRecentlyClosed = 40; | 154 if (use_profiles_category) { |
| 147 const int kTotal = kMostVisited + kRecentlyClosed; | 155 // Show at most 8 profiles, and fill the rest of the slots with the |
| 148 size_t most_visited_items = | 156 // "recently-closed" items. |
| 149 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); | 157 const size_t kMaxProfiles = 8; |
| 150 size_t recently_closed_items = | 158 size_t max_displayed_items = std::min(kMaxProfiles, |
| 151 jumplist_updater.user_max_items() - most_visited_items; | 159 jumplist_updater.user_max_items()); |
| 152 if (recently_closed_pages.size() < recently_closed_items) { | 160 profiles_or_most_visited_items = std::min(max_displayed_items, |
| 153 most_visited_items += recently_closed_items - recently_closed_pages.size(); | 161 profile_switcher.size()); |
| 154 recently_closed_items = recently_closed_pages.size(); | 162 recently_closed_items = |
| 163 jumplist_updater.user_max_items() - profiles_or_most_visited_items; | |
| 164 } else { | |
| 165 // We allocate 60% of the given JumpList slots to "most-visited" items | |
| 166 // and 40% to "recently-closed" items, respectively. | |
| 167 // Nevertheless, if there are not so many items in |recently_closed_pages|, | |
| 168 // we give the remaining slots to "most-visited" items. | |
| 169 const int kMostVisited = 60; | |
| 170 const int kRecentlyClosed = 40; | |
| 171 const int kTotal = kMostVisited + kRecentlyClosed; | |
| 172 profiles_or_most_visited_items = | |
| 173 MulDiv(jumplist_updater.user_max_items(), kMostVisited, kTotal); | |
| 174 recently_closed_items = | |
| 175 jumplist_updater.user_max_items() - profiles_or_most_visited_items; | |
| 176 if (recently_closed_pages.size() < recently_closed_items) { | |
| 177 profiles_or_most_visited_items += | |
| 178 recently_closed_items - recently_closed_pages.size(); | |
| 179 recently_closed_items = recently_closed_pages.size(); | |
| 180 } | |
| 155 } | 181 } |
| 156 | 182 |
| 157 // Update the "Most Visited" category of the JumpList. | 183 // Update the "Most Visited" category of the JumpList if it exists. |
| 158 // This update request is applied into the JumpList when we commit this | 184 // This update request is applied into the JumpList when we commit this |
| 159 // transaction. | 185 // transaction. |
| 160 if (!jumplist_updater.AddCustomCategory( | 186 if (!use_profiles_category && !jumplist_updater.AddCustomCategory( |
| 161 base::UTF16ToWide( | 187 base::UTF16ToWide( |
| 162 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED)), | 188 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED)), |
| 163 most_visited_pages, most_visited_items)) { | 189 most_visited_pages, profiles_or_most_visited_items)) { |
| 164 return false; | 190 return false; |
| 165 } | 191 } |
| 166 | 192 |
| 167 // Update the "Recently Closed" category of the JumpList. | 193 // Update the "Recently Closed" category of the JumpList. |
| 168 if (!jumplist_updater.AddCustomCategory( | 194 if (!jumplist_updater.AddCustomCategory( |
| 169 base::UTF16ToWide( | 195 base::UTF16ToWide( |
| 170 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), | 196 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), |
| 171 recently_closed_pages, recently_closed_items)) { | 197 recently_closed_pages, recently_closed_items)) { |
| 172 return false; | 198 return false; |
| 173 } | 199 } |
| 174 | 200 |
| 201 // Update the "People" category of the JumpList if it exists. Only display it | |
| 202 // if there's more than one profile available. | |
| 203 if (use_profiles_category && profile_switcher.size() > 1 && | |
| 204 !jumplist_updater.AddCustomCategory( | |
| 205 l10n_util::GetStringUTF16(IDS_PROFILES_OPTIONS_GROUP_NAME), | |
| 206 profile_switcher, profiles_or_most_visited_items)) { | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 175 // Update the "Tasks" category of the JumpList. | 210 // Update the "Tasks" category of the JumpList. |
| 176 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | 211 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
| 177 return false; | 212 return false; |
| 178 | 213 |
| 179 // Commit this transaction and send the updated JumpList to Windows. | 214 // Commit this transaction and send the updated JumpList to Windows. |
| 180 if (!jumplist_updater.CommitUpdate()) | 215 if (!jumplist_updater.CommitUpdate()) |
| 181 return false; | 216 return false; |
| 182 | 217 |
| 183 return true; | 218 return true; |
| 184 } | 219 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 195 // When we add this object to the observer list, we save the pointer to this | 230 // When we add this object to the observer list, we save the pointer to this |
| 196 // TabRestoreService object. This pointer is used when we remove this object | 231 // TabRestoreService object. This pointer is used when we remove this object |
| 197 // from the observer list. | 232 // from the observer list. |
| 198 TabRestoreService* tab_restore_service = | 233 TabRestoreService* tab_restore_service = |
| 199 TabRestoreServiceFactory::GetForProfile(profile_); | 234 TabRestoreServiceFactory::GetForProfile(profile_); |
| 200 if (!tab_restore_service) | 235 if (!tab_restore_service) |
| 201 return; | 236 return; |
| 202 | 237 |
| 203 app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()); | 238 app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()); |
| 204 icon_dir_ = profile_->GetPath().Append(chrome::kJumpListIconDirname); | 239 icon_dir_ = profile_->GetPath().Append(chrome::kJumpListIconDirname); |
| 240 use_profiles_category_ = switches::HasProfilesJumplistExperiment(); | |
| 241 | |
| 205 history::TopSites* top_sites = profile_->GetTopSites(); | 242 history::TopSites* top_sites = profile_->GetTopSites(); |
| 206 if (top_sites) { | 243 if (top_sites) { |
| 207 // TopSites updates itself after a delay. This is especially noticable when | 244 // TopSites updates itself after a delay. This is especially noticable when |
| 208 // your profile is empty. Ask TopSites to update itself when jumplist is | 245 // your profile is empty. Ask TopSites to update itself when jumplist is |
| 209 // initialized. | 246 // initialized. |
| 210 top_sites->SyncWithHistory(); | 247 top_sites->SyncWithHistory(); |
| 211 registrar_.reset(new content::NotificationRegistrar); | 248 registrar_.reset(new content::NotificationRegistrar); |
| 212 // Register for notification when TopSites changes so that we can update | 249 // Register for notification when TopSites changes so that we can update |
| 213 // ourself. | 250 // ourself. |
| 214 registrar_->Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, | 251 registrar_->Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, |
| 215 content::Source<history::TopSites>(top_sites)); | 252 content::Source<history::TopSites>(top_sites)); |
| 216 // Register for notification when profile is destroyed to ensure that all | 253 // Register for notification when profile is destroyed to ensure that all |
| 217 // observers are detatched at that time. | 254 // observers are detatched at that time. |
| 218 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 255 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 219 content::Source<Profile>(profile_)); | 256 content::Source<Profile>(profile_)); |
| 220 } | 257 } |
| 221 tab_restore_service->AddObserver(this); | 258 tab_restore_service->AddObserver(this); |
| 222 pref_change_registrar_.reset(new PrefChangeRegistrar); | 259 pref_change_registrar_.reset(new PrefChangeRegistrar); |
| 223 pref_change_registrar_->Init(profile_->GetPrefs()); | 260 pref_change_registrar_->Init(profile_->GetPrefs()); |
| 224 pref_change_registrar_->Add( | 261 pref_change_registrar_->Add( |
| 225 prefs::kIncognitoModeAvailability, | 262 prefs::kIncognitoModeAvailability, |
| 226 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); | 263 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); |
| 264 | |
| 265 ProfileManager* profile_manager = g_browser_process->profile_manager(); | |
| 266 DCHECK(profile_manager); | |
|
cpu_(ooo_6.6-7.5)
2014/11/12 23:04:57
move this to CHECK() or don't check at all. Note t
noms (inactive)
2014/11/13 16:59:55
Done.
| |
| 267 avatar_menu_.reset(new AvatarMenu( | |
| 268 &profile_manager->GetProfileInfoCache(), this, NULL)); | |
| 269 avatar_menu_->RebuildMenu(); | |
| 270 UpdateProfileSwitcher(); | |
| 227 } | 271 } |
| 228 | 272 |
| 229 JumpList::~JumpList() { | 273 JumpList::~JumpList() { |
| 230 Terminate(); | 274 Terminate(); |
| 231 } | 275 } |
| 232 | 276 |
| 233 // static | 277 // static |
| 234 bool JumpList::Enabled() { | 278 bool JumpList::Enabled() { |
| 235 return JumpListUpdater::IsEnabled(); | 279 return JumpListUpdater::IsEnabled(); |
| 236 } | 280 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 if (tab_restore_service) | 318 if (tab_restore_service) |
| 275 tab_restore_service->RemoveObserver(this); | 319 tab_restore_service->RemoveObserver(this); |
| 276 registrar_.reset(); | 320 registrar_.reset(); |
| 277 pref_change_registrar_.reset(); | 321 pref_change_registrar_.reset(); |
| 278 } | 322 } |
| 279 profile_ = NULL; | 323 profile_ = NULL; |
| 280 } | 324 } |
| 281 | 325 |
| 282 void JumpList::OnMostVisitedURLsAvailable( | 326 void JumpList::OnMostVisitedURLsAvailable( |
| 283 const history::MostVisitedURLList& data) { | 327 const history::MostVisitedURLList& data) { |
| 284 | |
| 285 // If we have a pending favicon request, cancel it here (it is out of date). | 328 // If we have a pending favicon request, cancel it here (it is out of date). |
| 286 CancelPendingUpdate(); | 329 CancelPendingUpdate(); |
| 287 | 330 |
| 288 { | 331 { |
| 289 base::AutoLock auto_lock(list_lock_); | 332 base::AutoLock auto_lock(list_lock_); |
| 290 most_visited_pages_.clear(); | 333 most_visited_pages_.clear(); |
| 291 for (size_t i = 0; i < data.size(); i++) { | 334 for (size_t i = 0; i < data.size(); i++) { |
| 292 const history::MostVisitedURL& url = data[i]; | 335 const history::MostVisitedURL& url = data[i]; |
| 293 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 336 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
| 294 std::string url_string = url.url.spec(); | 337 std::string url_string = url.url.spec(); |
| 295 std::wstring url_string_wide = base::UTF8ToWide(url_string); | 338 std::wstring url_string_wide = base::UTF8ToWide(url_string); |
| 296 link->GetCommandLine()->AppendArgNative(url_string_wide); | 339 link->GetCommandLine()->AppendArgNative(url_string_wide); |
| 340 link->GetCommandLine()->AppendSwitchASCII( | |
| 341 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); | |
| 297 link->set_title(!url.title.empty()? url.title : url_string_wide); | 342 link->set_title(!url.title.empty()? url.title : url_string_wide); |
| 298 most_visited_pages_.push_back(link); | 343 most_visited_pages_.push_back(link); |
| 299 icon_urls_.push_back(make_pair(url_string, link)); | 344 icon_urls_.push_back(make_pair(url_string, link)); |
| 300 } | 345 } |
| 301 } | 346 } |
| 302 | 347 |
| 303 // Send a query that retrieves the first favicon. | 348 // Send a query that retrieves the first favicon. |
| 304 StartLoadingFavicon(); | 349 StartLoadingFavicon(); |
| 305 } | 350 } |
| 306 | 351 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 recently_closed_pages_ = temp_list; | 388 recently_closed_pages_ = temp_list; |
| 344 } | 389 } |
| 345 | 390 |
| 346 // Send a query that retrieves the first favicon. | 391 // Send a query that retrieves the first favicon. |
| 347 StartLoadingFavicon(); | 392 StartLoadingFavicon(); |
| 348 } | 393 } |
| 349 | 394 |
| 350 void JumpList::TabRestoreServiceDestroyed(TabRestoreService* service) { | 395 void JumpList::TabRestoreServiceDestroyed(TabRestoreService* service) { |
| 351 } | 396 } |
| 352 | 397 |
| 398 void JumpList::OnAvatarMenuChanged(AvatarMenu* avatar_menu) { | |
| 399 UpdateProfileSwitcher(); | |
| 400 PostRunUpdate(); | |
| 401 } | |
| 402 | |
| 353 bool JumpList::AddTab(const TabRestoreService::Tab* tab, | 403 bool JumpList::AddTab(const TabRestoreService::Tab* tab, |
| 354 ShellLinkItemList* list, | 404 ShellLinkItemList* list, |
| 355 size_t max_items) { | 405 size_t max_items) { |
| 356 // This code adds the URL and the title strings of the given tab to the | 406 // This code adds the URL and the title strings of the given tab to the |
| 357 // specified list. | 407 // specified list. |
| 358 if (list->size() >= max_items) | 408 if (list->size() >= max_items) |
| 359 return false; | 409 return false; |
| 360 | 410 |
| 361 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 411 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
| 362 const sessions::SerializedNavigationEntry& current_navigation = | 412 const sessions::SerializedNavigationEntry& current_navigation = |
| 363 tab->navigations.at(tab->current_navigation_index); | 413 tab->navigations.at(tab->current_navigation_index); |
| 364 std::string url = current_navigation.virtual_url().spec(); | 414 std::string url = current_navigation.virtual_url().spec(); |
| 365 link->GetCommandLine()->AppendArgNative(base::UTF8ToWide(url)); | 415 link->GetCommandLine()->AppendArgNative(base::UTF8ToWide(url)); |
| 416 link->GetCommandLine()->AppendSwitchASCII( | |
| 417 switches::kWinJumplistAction, jumplist::kRecentlyClosedCategory); | |
| 366 link->set_title(current_navigation.title()); | 418 link->set_title(current_navigation.title()); |
| 367 list->push_back(link); | 419 list->push_back(link); |
| 368 icon_urls_.push_back(make_pair(url, link)); | 420 icon_urls_.push_back(make_pair(url, link)); |
| 369 return true; | 421 return true; |
| 370 } | 422 } |
| 371 | 423 |
| 372 void JumpList::AddWindow(const TabRestoreService::Window* window, | 424 void JumpList::AddWindow(const TabRestoreService::Window* window, |
| 373 ShellLinkItemList* list, | 425 ShellLinkItemList* list, |
| 374 size_t max_items) { | 426 size_t max_items) { |
| 375 // This code enumerates al the tabs in the given window object and add their | 427 // This code enumerates al the tabs in the given window object and add their |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 390 waiting_for_icons = !icon_urls_.empty(); | 442 waiting_for_icons = !icon_urls_.empty(); |
| 391 if (waiting_for_icons) { | 443 if (waiting_for_icons) { |
| 392 // Ask FaviconService if it has a favicon of a URL. | 444 // Ask FaviconService if it has a favicon of a URL. |
| 393 // When FaviconService has one, it will call OnFaviconDataAvailable(). | 445 // When FaviconService has one, it will call OnFaviconDataAvailable(). |
| 394 url = GURL(icon_urls_.front().first); | 446 url = GURL(icon_urls_.front().first); |
| 395 } | 447 } |
| 396 } | 448 } |
| 397 | 449 |
| 398 if (!waiting_for_icons) { | 450 if (!waiting_for_icons) { |
| 399 // No more favicons are needed by the application JumpList. Schedule a | 451 // No more favicons are needed by the application JumpList. Schedule a |
| 400 // RunUpdate call. | 452 // RunUpdateOnFileThread call. |
| 401 PostRunUpdate(); | 453 PostRunUpdate(); |
| 402 return; | 454 return; |
| 403 } | 455 } |
| 404 | 456 |
| 405 FaviconService* favicon_service = | 457 FaviconService* favicon_service = |
| 406 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); | 458 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
| 407 task_id_ = favicon_service->GetFaviconImageForPageURL( | 459 task_id_ = favicon_service->GetFaviconImageForPageURL( |
| 408 url, | 460 url, |
| 409 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), | 461 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), |
| 410 &cancelable_task_tracker_); | 462 &cancelable_task_tracker_); |
| 411 } | 463 } |
| 412 | 464 |
| 413 void JumpList::OnFaviconDataAvailable( | 465 void JumpList::OnFaviconDataAvailable( |
| 414 const favicon_base::FaviconImageResult& image_result) { | 466 const favicon_base::FaviconImageResult& image_result) { |
| 415 // If there is currently a favicon request in progress, it is now outdated, | 467 // 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. | 468 // as we have received another, so nullify the handle from the old request. |
| 417 task_id_ = base::CancelableTaskTracker::kBadTaskId; | 469 task_id_ = base::CancelableTaskTracker::kBadTaskId; |
| 418 // lock the list to set icon data and pop the url | 470 // Lock the list to set icon data and pop the url. |
| 419 { | 471 { |
| 420 base::AutoLock auto_lock(list_lock_); | 472 base::AutoLock auto_lock(list_lock_); |
| 421 // Attach the received data to the ShellLinkItem object. | 473 // Attach the received data to the ShellLinkItem object. |
| 422 // This data will be decoded by the RunUpdate method. | 474 // This data will be decoded by the RunUpdateOnFileThread method. |
| 423 if (!image_result.image.IsEmpty()) { | 475 if (!image_result.image.IsEmpty()) { |
| 424 if (!icon_urls_.empty() && icon_urls_.front().second) | 476 if (!icon_urls_.empty() && icon_urls_.front().second) |
| 425 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); | 477 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); |
| 426 } | 478 } |
| 427 | 479 |
| 428 if (!icon_urls_.empty()) | 480 if (!icon_urls_.empty()) |
| 429 icon_urls_.pop_front(); | 481 icon_urls_.pop_front(); |
| 430 } | 482 } |
| 431 // Check whether we need to load more favicons. | 483 // Check whether we need to load more favicons. |
| 432 StartLoadingFavicon(); | 484 StartLoadingFavicon(); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 445 } | 497 } |
| 446 | 498 |
| 447 void JumpList::PostRunUpdate() { | 499 void JumpList::PostRunUpdate() { |
| 448 // Check if incognito windows (or normal windows) are disabled by policy. | 500 // Check if incognito windows (or normal windows) are disabled by policy. |
| 449 IncognitoModePrefs::Availability incognito_availability = | 501 IncognitoModePrefs::Availability incognito_availability = |
| 450 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) | 502 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) |
| 451 : IncognitoModePrefs::ENABLED; | 503 : IncognitoModePrefs::ENABLED; |
| 452 | 504 |
| 453 BrowserThread::PostTask( | 505 BrowserThread::PostTask( |
| 454 BrowserThread::FILE, FROM_HERE, | 506 BrowserThread::FILE, FROM_HERE, |
| 455 base::Bind(&JumpList::RunUpdate, this, incognito_availability)); | 507 base::Bind(&JumpList::RunUpdateOnFileThread, |
| 508 this, | |
| 509 incognito_availability)); | |
| 456 } | 510 } |
| 457 | 511 |
| 458 void JumpList::RunUpdate( | 512 void JumpList::RunUpdateOnFileThread( |
| 459 IncognitoModePrefs::Availability incognito_availability) { | 513 IncognitoModePrefs::Availability incognito_availability) { |
| 460 ShellLinkItemList local_most_visited_pages; | 514 ShellLinkItemList local_most_visited_pages; |
| 461 ShellLinkItemList local_recently_closed_pages; | 515 ShellLinkItemList local_recently_closed_pages; |
| 516 ShellLinkItemList local_profile_switcher; | |
| 462 | 517 |
| 463 { | 518 { |
| 464 base::AutoLock auto_lock(list_lock_); | 519 base::AutoLock auto_lock(list_lock_); |
| 465 // Make sure we are not out of date: if icon_urls_ is not empty, then | 520 // Make sure we are not out of date: if icon_urls_ is not empty, then |
| 466 // another notification has been received since we processed this one | 521 // another notification has been received since we processed this one |
| 467 if (!icon_urls_.empty()) | 522 if (!icon_urls_.empty()) |
| 468 return; | 523 return; |
| 469 | 524 |
| 470 // Make local copies of lists so we can release the lock. | 525 // Make local copies of lists so we can release the lock. |
| 471 local_most_visited_pages = most_visited_pages_; | 526 local_most_visited_pages = most_visited_pages_; |
| 472 local_recently_closed_pages = recently_closed_pages_; | 527 local_recently_closed_pages = recently_closed_pages_; |
| 528 local_profile_switcher = profile_switcher_; | |
| 473 } | 529 } |
| 474 | 530 |
| 475 // Delete the directory which contains old icon files, rename the current | 531 // Delete the directory which contains old icon files, rename the current |
| 476 // icon directory, and create a new directory which contains new JumpList | 532 // icon directory, and create a new directory which contains new JumpList |
| 477 // icon files. | 533 // icon files. |
| 478 base::FilePath icon_dir_old(icon_dir_.value() + L"Old"); | 534 base::FilePath icon_dir_old(icon_dir_.value() + L"Old"); |
| 479 if (base::PathExists(icon_dir_old)) | 535 if (base::PathExists(icon_dir_old)) |
| 480 base::DeleteFile(icon_dir_old, true); | 536 base::DeleteFile(icon_dir_old, true); |
| 481 base::Move(icon_dir_, icon_dir_old); | 537 base::Move(icon_dir_, icon_dir_old); |
| 482 base::CreateDirectory(icon_dir_); | 538 base::CreateDirectory(icon_dir_); |
| 483 | 539 |
| 484 // Create temporary icon files for shortcuts in the "Most Visited" category. | 540 // Create temporary icon files for shortcuts in the "Most Visited" category. |
| 485 CreateIconFiles(local_most_visited_pages); | 541 CreateIconFiles(local_most_visited_pages); |
| 486 | 542 |
| 487 // Create temporary icon files for shortcuts in the "Recently Closed" | 543 // Create temporary icon files for shortcuts in the "Recently Closed" |
| 488 // category. | 544 // category. |
| 489 CreateIconFiles(local_recently_closed_pages); | 545 CreateIconFiles(local_recently_closed_pages); |
| 490 | 546 |
| 547 // Create temporary icon files for the profile avatars in the "People" | |
| 548 // category. | |
| 549 CreateIconFiles(local_profile_switcher); | |
| 550 | |
| 491 // We finished collecting all resources needed for updating an application | 551 // We finished collecting all resources needed for updating an application |
| 492 // JumpList. So, create a new JumpList and replace the current JumpList | 552 // JumpList. So, create a new JumpList and replace the current JumpList |
| 493 // with it. | 553 // with it. |
| 494 UpdateJumpList(app_id_.c_str(), local_most_visited_pages, | 554 UpdateJumpList(app_id_.c_str(), |
| 495 local_recently_closed_pages, incognito_availability); | 555 local_most_visited_pages, |
| 556 local_recently_closed_pages, | |
| 557 local_profile_switcher, | |
| 558 incognito_availability, | |
| 559 use_profiles_category_); | |
| 496 } | 560 } |
| 497 | 561 |
| 498 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { | 562 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { |
| 499 for (ShellLinkItemList::const_iterator item = item_list.begin(); | 563 for (ShellLinkItemList::const_iterator item = item_list.begin(); |
| 500 item != item_list.end(); ++item) { | 564 item != item_list.end(); ++item) { |
| 501 base::FilePath icon_path; | 565 base::FilePath icon_path; |
| 502 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) | 566 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) |
| 503 (*item)->set_icon(icon_path.value(), 0); | 567 (*item)->set_icon(icon_path.value(), 0); |
| 504 } | 568 } |
| 505 } | 569 } |
| 570 | |
| 571 void JumpList::UpdateProfileSwitcher() { | |
| 572 ShellLinkItemList new_profile_switcher; | |
| 573 | |
| 574 // Don't display a menu in the single profile case. | |
| 575 if (avatar_menu_->GetNumberOfItems() > 1) { | |
| 576 for (size_t i = 0; i < avatar_menu_->GetNumberOfItems(); ++i) { | |
| 577 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | |
| 578 const AvatarMenu::Item& item = avatar_menu_->GetItemAt(i); | |
| 579 | |
| 580 link->set_title(item.name); | |
| 581 link->GetCommandLine()->AppendSwitchPath( | |
| 582 switches::kProfileDirectory, item.profile_path.BaseName()); | |
| 583 link->GetCommandLine()->AppendSwitch( | |
| 584 switches::kActivateExistingProfileBrowser); | |
| 585 link->GetCommandLine()->AppendSwitchASCII( | |
| 586 switches::kWinJumplistAction, jumplist::kProfilesCategory); | |
| 587 | |
| 588 gfx::Image avatar; | |
| 589 bool is_rectangle; | |
| 590 profiles::GetTransparentBackgroundProfileAvatar( | |
| 591 item.profile_path, &avatar, &is_rectangle); | |
| 592 link->set_icon_data(avatar.AsBitmap()); | |
| 593 new_profile_switcher.push_back(link); | |
| 594 } | |
| 595 } | |
| 596 | |
| 597 { | |
| 598 base::AutoLock auto_lock(list_lock_); | |
| 599 new_profile_switcher.swap(profile_switcher_); | |
| 600 } | |
| 601 } | |
| OLD | NEW |