OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/win/jumplist.h" | 5 #include "chrome/browser/win/jumplist.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 } | 180 } |
181 | 181 |
182 return jumplist_updater->AddTasks(items); | 182 return jumplist_updater->AddTasks(items); |
183 } | 183 } |
184 | 184 |
185 // Updates the application JumpList, which consists of 1) delete old icon files; | 185 // Updates the application JumpList, which consists of 1) delete old icon files; |
186 // 2) create new icon files; 3) notify the OS. | 186 // 2) create new icon files; 3) notify the OS. |
187 // Note that any timeout error along the way results in the old jumplist being | 187 // Note that any timeout error along the way results in the old jumplist being |
188 // left as-is, while any non-timeout error results in the old jumplist being | 188 // left as-is, while any non-timeout error results in the old jumplist being |
189 // left as-is, but without icon files. | 189 // left as-is, but without icon files. |
190 void UpdateJumpList(const wchar_t* app_id, | 190 bool UpdateJumpList(const wchar_t* app_id, |
191 const base::FilePath& icon_dir, | 191 const base::FilePath& icon_dir, |
192 const ShellLinkItemList& most_visited_pages, | 192 const ShellLinkItemList& most_visited_pages, |
193 const ShellLinkItemList& recently_closed_pages, | 193 const ShellLinkItemList& recently_closed_pages, |
| 194 bool most_visited_pages_have_updates, |
| 195 bool recently_closed_pages_have_updates, |
194 IncognitoModePrefs::Availability incognito_availability) { | 196 IncognitoModePrefs::Availability incognito_availability) { |
195 if (!JumpListUpdater::IsEnabled()) | 197 if (!JumpListUpdater::IsEnabled()) |
196 return; | 198 return true; |
197 | 199 |
198 // Records the time cost of starting a JumpListUpdater. | 200 // Records the time cost of starting a JumpListUpdater. |
199 base::ElapsedTimer begin_update_timer; | 201 base::ElapsedTimer begin_update_timer; |
200 | 202 |
201 JumpListUpdater jumplist_updater(app_id); | 203 JumpListUpdater jumplist_updater(app_id); |
202 if (!jumplist_updater.BeginUpdate()) | 204 if (!jumplist_updater.BeginUpdate()) |
203 return; | 205 return false; |
204 | 206 |
205 // Stops jumplist update if JumpListUpdater's start times out, as it's very | 207 // Stops jumplist update if JumpListUpdater's start times out, as it's very |
206 // likely the following update steps will also take a long time. | 208 // likely the following update steps will also take a long time. |
207 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate) | 209 if (begin_update_timer.Elapsed() >= kTimeOutForJumplistUpdate) |
208 return; | 210 return false; |
209 | 211 |
210 // The default maximum number of items to display in JumpList is 10. | 212 // The default maximum number of items to display in JumpList is 10. |
211 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx | 213 // https://msdn.microsoft.com/library/windows/desktop/dd378398.aspx |
212 // The "Most visited" category title always takes 1 of the JumpList slots if | 214 // The "Most visited" category title always takes 1 of the JumpList slots if |
213 // |most_visited_pages| isn't empty. | 215 // |most_visited_pages| isn't empty. |
214 // The "Recently closed" category title will also take 1 if | 216 // The "Recently closed" category title will also take 1 if |
215 // |recently_closed_pages| isn't empty. | 217 // |recently_closed_pages| isn't empty. |
216 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories | 218 // For the remaining slots, we allocate 5/8 (i.e., 5 slots if both categories |
217 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories | 219 // present) to "most-visited" items and 3/8 (i.e., 3 slots if both categories |
218 // present) to "recently-closed" items, respectively. | 220 // present) to "recently-closed" items, respectively. |
| 221 // Nevertheless, if there are not so many items in |recently_closed_pages|, |
| 222 // we give the remaining slots to "most-visited" items. |
219 | 223 |
220 const int kMostVisited = 50; | 224 const int kMostVisited = 50; |
221 const int kRecentlyClosed = 30; | 225 const int kRecentlyClosed = 30; |
222 const int kTotal = kMostVisited + kRecentlyClosed; | 226 const int kTotal = kMostVisited + kRecentlyClosed; |
223 | 227 |
224 // Adjust the available jumplist slots to account for the category titles. | 228 // Adjust the available jumplist slots to account for the category titles. |
225 size_t user_max_items_adjusted = jumplist_updater.user_max_items(); | 229 size_t user_max_items_adjusted = jumplist_updater.user_max_items(); |
226 if (!most_visited_pages.empty()) | 230 if (!most_visited_pages.empty()) |
227 --user_max_items_adjusted; | 231 --user_max_items_adjusted; |
228 if (!recently_closed_pages.empty()) | 232 if (!recently_closed_pages.empty()) |
229 --user_max_items_adjusted; | 233 --user_max_items_adjusted; |
230 | 234 |
231 size_t most_visited_items = | 235 size_t most_visited_items = |
232 MulDiv(user_max_items_adjusted, kMostVisited, kTotal); | 236 MulDiv(user_max_items_adjusted, kMostVisited, kTotal); |
233 size_t recently_closed_items = user_max_items_adjusted - most_visited_items; | 237 size_t recently_closed_items = user_max_items_adjusted - most_visited_items; |
234 if (recently_closed_pages.size() < recently_closed_items) { | 238 if (recently_closed_pages.size() < recently_closed_items) { |
235 most_visited_items += recently_closed_items - recently_closed_pages.size(); | 239 most_visited_items += recently_closed_items - recently_closed_pages.size(); |
236 recently_closed_items = recently_closed_pages.size(); | 240 recently_closed_items = recently_closed_pages.size(); |
237 } | 241 } |
238 | 242 |
239 // Delete the content in JumpListIcons folder and log the results to UMA. | 243 if (most_visited_pages_have_updates) { |
240 DeleteDirectoryContentAndLogResults(icon_dir, kFileDeleteLimit); | 244 // Delete the content in JumpListIconsMostVisited folder and log the results |
| 245 // to UMA. |
| 246 base::FilePath icon_dir_most_visited = icon_dir.DirName().Append( |
| 247 icon_dir.BaseName().value() + FILE_PATH_LITERAL("MostVisited")); |
241 | 248 |
242 // If JumpListIcons directory doesn't exist (we have tried to create it | 249 DeleteDirectoryContentAndLogResults(icon_dir_most_visited, |
243 // already) or is not empty, skip updating the jumplist icons. The jumplist | 250 kFileDeleteLimit); |
244 // links should be updated anyway, as it doesn't involve disk IO. In this | |
245 // case, Chrome's icon will be used for the new links. | |
246 | 251 |
247 bool should_create_icons = | 252 // If the directory doesn't exist (we have tried to create it in |
248 base::DirectoryExists(icon_dir) && base::IsDirectoryEmpty(icon_dir); | 253 // DeleteDirectoryContentAndLogResults) or is not empty, skip updating the |
| 254 // jumplist icons. The jumplist links should be updated anyway, as it |
| 255 // doesn't involve disk IO. In this case, Chrome's icon will be used for the |
| 256 // new links. |
| 257 if (base::DirectoryExists(icon_dir_most_visited) && |
| 258 base::IsDirectoryEmpty(icon_dir_most_visited)) { |
| 259 // Create icon files for shortcuts in the "Most Visited" category. |
| 260 CreateIconFiles(icon_dir_most_visited, most_visited_pages, |
| 261 most_visited_items); |
| 262 } |
| 263 } |
249 | 264 |
250 // Create icon files for shortcuts in the "Most Visited" category. | 265 if (recently_closed_pages_have_updates) { |
251 if (should_create_icons) | 266 // Delete the content in JumpListIconsRecentClosed folder and log the |
252 CreateIconFiles(icon_dir, most_visited_pages, most_visited_items); | 267 // results to UMA. |
| 268 base::FilePath icon_dir_recent_closed = icon_dir.DirName().Append( |
| 269 icon_dir.BaseName().value() + FILE_PATH_LITERAL("RecentClosed")); |
| 270 |
| 271 DeleteDirectoryContentAndLogResults(icon_dir_recent_closed, |
| 272 kFileDeleteLimit); |
| 273 |
| 274 if (base::DirectoryExists(icon_dir_recent_closed) && |
| 275 base::IsDirectoryEmpty(icon_dir_recent_closed)) { |
| 276 // Create icon files for shortcuts in the "Recently Closed" category. |
| 277 CreateIconFiles(icon_dir_recent_closed, recently_closed_pages, |
| 278 recently_closed_items); |
| 279 } |
| 280 } |
| 281 |
| 282 // TODO(chengx): Remove the UMA histogram after fixing http://crbug.com/40407. |
| 283 SCOPED_UMA_HISTOGRAM_TIMER("WinJumplist.UpdateJumpListDuration"); |
253 | 284 |
254 // Update the "Most Visited" category of the JumpList if it exists. | 285 // Update the "Most Visited" category of the JumpList if it exists. |
255 // This update request is applied into the JumpList when we commit this | 286 // This update request is applied into the JumpList when we commit this |
256 // transaction. | 287 // transaction. |
257 if (!jumplist_updater.AddCustomCategory( | 288 if (!jumplist_updater.AddCustomCategory( |
258 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), | 289 l10n_util::GetStringUTF16(IDS_NEW_TAB_MOST_VISITED), |
259 most_visited_pages, most_visited_items)) { | 290 most_visited_pages, most_visited_items)) { |
260 return; | 291 return false; |
261 } | 292 } |
262 | 293 |
263 // Create icon files for shortcuts in the "Recently Closed" category. | |
264 if (should_create_icons) | |
265 CreateIconFiles(icon_dir, recently_closed_pages, recently_closed_items); | |
266 | |
267 // Update the "Recently Closed" category of the JumpList. | 294 // Update the "Recently Closed" category of the JumpList. |
268 if (!jumplist_updater.AddCustomCategory( | 295 if (!jumplist_updater.AddCustomCategory( |
269 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), | 296 l10n_util::GetStringUTF16(IDS_RECENTLY_CLOSED), |
270 recently_closed_pages, recently_closed_items)) { | 297 recently_closed_pages, recently_closed_items)) { |
271 return; | 298 return false; |
272 } | 299 } |
273 | 300 |
274 // Update the "Tasks" category of the JumpList. | 301 // Update the "Tasks" category of the JumpList. |
275 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) | 302 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
276 return; | 303 return false; |
277 | 304 |
278 // Commit this transaction and send the updated JumpList to Windows. | 305 // Commit this transaction and send the updated JumpList to Windows. |
279 jumplist_updater.CommitUpdate(); | 306 return jumplist_updater.CommitUpdate(); |
280 } | 307 } |
281 | 308 |
282 // Updates the jumplist, once all the data has been fetched. | 309 // Updates the jumplist, once all the data has been fetched. |
283 void RunUpdateJumpList(IncognitoModePrefs::Availability incognito_availability, | 310 void RunUpdateJumpList(IncognitoModePrefs::Availability incognito_availability, |
284 const std::wstring& app_id, | 311 const std::wstring& app_id, |
285 const base::FilePath& icon_dir, | 312 const base::FilePath& icon_dir, |
286 base::RefCountedData<JumpListData>* ref_counted_data) { | 313 base::RefCountedData<JumpListData>* ref_counted_data) { |
287 JumpListData* data = &ref_counted_data->data; | 314 JumpListData* data = &ref_counted_data->data; |
288 ShellLinkItemList local_most_visited_pages; | 315 ShellLinkItemList local_most_visited_pages; |
289 ShellLinkItemList local_recently_closed_pages; | 316 ShellLinkItemList local_recently_closed_pages; |
| 317 bool most_visited_pages_have_updates; |
| 318 bool recently_closed_pages_have_updates; |
290 | 319 |
291 { | 320 { |
292 base::AutoLock auto_lock(data->list_lock_); | 321 base::AutoLock auto_lock(data->list_lock_); |
293 // Make sure we are not out of date: if icon_urls_ is not empty, then | 322 // Make sure we are not out of date: if icon_urls_ is not empty, then |
294 // another notification has been received since we processed this one | 323 // another notification has been received since we processed this one |
295 if (!data->icon_urls_.empty()) | 324 if (!data->icon_urls_.empty()) |
296 return; | 325 return; |
297 | 326 |
298 // Make local copies of lists so we can release the lock. | 327 // Make local copies of lists and flags so we can release the lock. |
299 local_most_visited_pages = data->most_visited_pages_; | 328 local_most_visited_pages = data->most_visited_pages_; |
300 local_recently_closed_pages = data->recently_closed_pages_; | 329 local_recently_closed_pages = data->recently_closed_pages_; |
| 330 |
| 331 most_visited_pages_have_updates = data->most_visited_pages_have_updates_; |
| 332 recently_closed_pages_have_updates = |
| 333 data->recently_closed_pages_have_updates_; |
| 334 |
| 335 // Clear the flags to reflect that we'll take actions on these updates. |
| 336 data->most_visited_pages_have_updates_ = false; |
| 337 data->recently_closed_pages_have_updates_ = false; |
301 } | 338 } |
302 | 339 |
303 // Updates the application JumpList. | 340 if (!most_visited_pages_have_updates && !recently_closed_pages_have_updates) |
304 UpdateJumpList(app_id.c_str(), icon_dir, local_most_visited_pages, | 341 return; |
305 local_recently_closed_pages, incognito_availability); | 342 |
| 343 // Updates the application JumpList. If it fails, reset the flags to true if |
| 344 // they were so that the corresponding JumpList categories will be tried to |
| 345 // update again in the next run. |
| 346 if (!UpdateJumpList( |
| 347 app_id.c_str(), icon_dir, local_most_visited_pages, |
| 348 local_recently_closed_pages, most_visited_pages_have_updates, |
| 349 recently_closed_pages_have_updates, incognito_availability)) { |
| 350 base::AutoLock auto_lock(data->list_lock_); |
| 351 if (most_visited_pages_have_updates) |
| 352 data->most_visited_pages_have_updates_ = true; |
| 353 if (recently_closed_pages_have_updates) |
| 354 data->recently_closed_pages_have_updates_ = true; |
| 355 } |
306 } | 356 } |
307 | 357 |
308 } // namespace | 358 } // namespace |
309 | 359 |
310 JumpList::JumpListData::JumpListData() {} | 360 JumpList::JumpListData::JumpListData() {} |
311 | 361 |
312 JumpList::JumpListData::~JumpListData() {} | 362 JumpList::JumpListData::~JumpListData() {} |
313 | 363 |
314 JumpList::JumpList(Profile* profile) | 364 JumpList::JumpList(Profile* profile) |
315 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread( | 365 : RefcountedKeyedService(content::BrowserThread::GetTaskRunnerForThread( |
316 content::BrowserThread::UI)), | 366 content::BrowserThread::UI)), |
317 profile_(profile), | 367 profile_(profile), |
318 jumplist_data_(new base::RefCountedData<JumpListData>), | 368 jumplist_data_(new base::RefCountedData<JumpListData>), |
319 task_id_(base::CancelableTaskTracker::kBadTaskId), | 369 task_id_(base::CancelableTaskTracker::kBadTaskId), |
320 update_jumplisticons_task_runner_(base::CreateCOMSTATaskRunnerWithTraits( | 370 update_jumplist_task_runner_(base::CreateCOMSTATaskRunnerWithTraits( |
321 base::TaskTraits() | 371 base::TaskTraits() |
322 .WithPriority(base::TaskPriority::USER_VISIBLE) | 372 .WithPriority(base::TaskPriority::USER_VISIBLE) |
323 .WithShutdownBehavior( | 373 .WithShutdownBehavior( |
324 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | 374 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
325 .MayBlock())), | 375 .MayBlock())), |
326 delete_jumplisticonsold_task_runner_( | 376 delete_jumplisticons_task_runner_( |
327 base::CreateSequencedTaskRunnerWithTraits( | 377 base::CreateSequencedTaskRunnerWithTraits( |
328 base::TaskTraits() | 378 base::TaskTraits() |
329 .WithPriority(base::TaskPriority::BACKGROUND) | 379 .WithPriority(base::TaskPriority::BACKGROUND) |
330 .WithShutdownBehavior( | 380 .WithShutdownBehavior( |
331 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) | 381 base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) |
332 .MayBlock())), | 382 .MayBlock())), |
333 weak_ptr_factory_(this) { | 383 weak_ptr_factory_(this) { |
334 DCHECK(Enabled()); | 384 DCHECK(Enabled()); |
335 // To update JumpList when a tab is added or removed, we add this object to | 385 // To update JumpList when a tab is added or removed, we add this object to |
336 // the observer list of the TabRestoreService class. | 386 // the observer list of the TabRestoreService class. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 for (size_t i = 0; i < urls.size(); i++) { | 468 for (size_t i = 0; i < urls.size(); i++) { |
419 const history::MostVisitedURL& url = urls[i]; | 469 const history::MostVisitedURL& url = urls[i]; |
420 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 470 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
421 std::string url_string = url.url.spec(); | 471 std::string url_string = url.url.spec(); |
422 std::wstring url_string_wide = base::UTF8ToWide(url_string); | 472 std::wstring url_string_wide = base::UTF8ToWide(url_string); |
423 link->GetCommandLine()->AppendArgNative(url_string_wide); | 473 link->GetCommandLine()->AppendArgNative(url_string_wide); |
424 link->GetCommandLine()->AppendSwitchASCII( | 474 link->GetCommandLine()->AppendSwitchASCII( |
425 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); | 475 switches::kWinJumplistAction, jumplist::kMostVisitedCategory); |
426 link->set_title(!url.title.empty() ? url.title : url_string_wide); | 476 link->set_title(!url.title.empty() ? url.title : url_string_wide); |
427 data->most_visited_pages_.push_back(link); | 477 data->most_visited_pages_.push_back(link); |
428 data->icon_urls_.push_back(make_pair(url_string, link)); | 478 data->icon_urls_.push_back(std::make_pair(url_string, link)); |
429 } | 479 } |
| 480 data->most_visited_pages_have_updates_ = true; |
430 } | 481 } |
431 | 482 |
432 // Send a query that retrieves the first favicon. | 483 // Send a query that retrieves the first favicon. |
433 StartLoadingFavicon(); | 484 StartLoadingFavicon(); |
434 } | 485 } |
435 | 486 |
436 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) { | 487 void JumpList::TabRestoreServiceChanged(sessions::TabRestoreService* service) { |
437 DCHECK(CalledOnValidThread()); | 488 DCHECK(CalledOnValidThread()); |
438 // if we have a pending handle request, cancel it here (it is out of date). | 489 // if we have a pending favicon request, cancel it here (it is out of date). |
439 CancelPendingUpdate(); | 490 CancelPendingUpdate(); |
440 | 491 |
441 // local list to pass to methods | |
442 ShellLinkItemList temp_list; | |
443 | |
444 // Create a list of ShellLinkItems from the "Recently Closed" pages. | 492 // Create a list of ShellLinkItems from the "Recently Closed" pages. |
445 // As noted above, we create a ShellLinkItem objects with the following | 493 // As noted above, we create a ShellLinkItem objects with the following |
446 // parameters. | 494 // parameters. |
447 // * arguments | 495 // * arguments |
448 // The last URL of the tab object. | 496 // The last URL of the tab object. |
449 // * title | 497 // * title |
450 // The title of the last URL. | 498 // The title of the last URL. |
451 // * icon | 499 // * icon |
452 // An empty string. This value is to be updated in OnFaviconDataAvailable(). | 500 // An empty string. This value is to be updated in OnFaviconDataAvailable(). |
453 // This code is copied from | 501 // This code is copied from |
454 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. | 502 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. |
455 const int kRecentlyClosedCount = 3; | 503 const int kRecentlyClosedCount = 3; |
456 sessions::TabRestoreService* tab_restore_service = | 504 sessions::TabRestoreService* tab_restore_service = |
457 TabRestoreServiceFactory::GetForProfile(profile_); | 505 TabRestoreServiceFactory::GetForProfile(profile_); |
458 for (const auto& entry : tab_restore_service->entries()) { | 506 |
459 switch (entry->type) { | |
460 case sessions::TabRestoreService::TAB: | |
461 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), | |
462 &temp_list, kRecentlyClosedCount); | |
463 break; | |
464 case sessions::TabRestoreService::WINDOW: | |
465 AddWindow( | |
466 static_cast<const sessions::TabRestoreService::Window&>(*entry), | |
467 &temp_list, kRecentlyClosedCount); | |
468 break; | |
469 } | |
470 } | |
471 // Lock recently_closed_pages and copy temp_list into it. | |
472 { | 507 { |
473 JumpListData* data = &jumplist_data_->data; | 508 JumpListData* data = &jumplist_data_->data; |
474 base::AutoLock auto_lock(data->list_lock_); | 509 base::AutoLock auto_lock(data->list_lock_); |
475 data->recently_closed_pages_ = temp_list; | 510 data->recently_closed_pages_.clear(); |
| 511 |
| 512 for (const auto& entry : tab_restore_service->entries()) { |
| 513 switch (entry->type) { |
| 514 case sessions::TabRestoreService::TAB: |
| 515 AddTab(static_cast<const sessions::TabRestoreService::Tab&>(*entry), |
| 516 kRecentlyClosedCount, data); |
| 517 break; |
| 518 case sessions::TabRestoreService::WINDOW: |
| 519 AddWindow( |
| 520 static_cast<const sessions::TabRestoreService::Window&>(*entry), |
| 521 kRecentlyClosedCount, data); |
| 522 break; |
| 523 } |
| 524 } |
| 525 |
| 526 data->recently_closed_pages_have_updates_ = true; |
476 } | 527 } |
477 | 528 |
478 // Send a query that retrieves the first favicon. | 529 // Send a query that retrieves the first favicon. |
479 StartLoadingFavicon(); | 530 StartLoadingFavicon(); |
480 } | 531 } |
481 | 532 |
482 void JumpList::TabRestoreServiceDestroyed( | 533 void JumpList::TabRestoreServiceDestroyed( |
483 sessions::TabRestoreService* service) {} | 534 sessions::TabRestoreService* service) {} |
484 | 535 |
485 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab, | 536 bool JumpList::AddTab(const sessions::TabRestoreService::Tab& tab, |
486 ShellLinkItemList* list, | 537 size_t max_items, |
487 size_t max_items) { | 538 JumpListData* data) { |
488 DCHECK(CalledOnValidThread()); | 539 DCHECK(CalledOnValidThread()); |
| 540 data->list_lock_.AssertAcquired(); |
489 | 541 |
490 // This code adds the URL and the title strings of the given tab to the | 542 // This code adds the URL and the title strings of the given tab to |data|. |
491 // specified list. | 543 if (data->recently_closed_pages_.size() >= max_items) |
492 if (list->size() >= max_items) | |
493 return false; | 544 return false; |
494 | 545 |
495 scoped_refptr<ShellLinkItem> link = CreateShellLink(); | 546 scoped_refptr<ShellLinkItem> link = CreateShellLink(); |
496 const sessions::SerializedNavigationEntry& current_navigation = | 547 const sessions::SerializedNavigationEntry& current_navigation = |
497 tab.navigations.at(tab.current_navigation_index); | 548 tab.navigations.at(tab.current_navigation_index); |
498 std::string url = current_navigation.virtual_url().spec(); | 549 std::string url = current_navigation.virtual_url().spec(); |
499 link->GetCommandLine()->AppendArgNative(base::UTF8ToWide(url)); | 550 link->GetCommandLine()->AppendArgNative(base::UTF8ToWide(url)); |
500 link->GetCommandLine()->AppendSwitchASCII( | 551 link->GetCommandLine()->AppendSwitchASCII(switches::kWinJumplistAction, |
501 switches::kWinJumplistAction, jumplist::kRecentlyClosedCategory); | 552 jumplist::kRecentlyClosedCategory); |
502 link->set_title(current_navigation.title()); | 553 link->set_title(current_navigation.title()); |
503 list->push_back(link); | 554 data->recently_closed_pages_.push_back(link); |
504 { | 555 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link))); |
505 JumpListData* data = &jumplist_data_->data; | 556 |
506 base::AutoLock auto_lock(data->list_lock_); | |
507 data->icon_urls_.push_back(std::make_pair(std::move(url), std::move(link))); | |
508 } | |
509 return true; | 557 return true; |
510 } | 558 } |
511 | 559 |
512 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window, | 560 void JumpList::AddWindow(const sessions::TabRestoreService::Window& window, |
513 ShellLinkItemList* list, | 561 size_t max_items, |
514 size_t max_items) { | 562 JumpListData* data) { |
515 DCHECK(CalledOnValidThread()); | 563 DCHECK(CalledOnValidThread()); |
| 564 data->list_lock_.AssertAcquired(); |
516 | 565 |
517 // This code enumerates al the tabs in the given window object and add their | 566 // This code enumerates all the tabs in the given window object and add their |
518 // URLs and titles to the list. | 567 // URLs and titles to |data|. |
519 DCHECK(!window.tabs.empty()); | 568 DCHECK(!window.tabs.empty()); |
520 | 569 |
521 for (const auto& tab : window.tabs) { | 570 for (const auto& tab : window.tabs) { |
522 if (!AddTab(*tab, list, max_items)) | 571 if (!AddTab(*tab, max_items, data)) |
523 return; | 572 return; |
524 } | 573 } |
525 } | 574 } |
526 | 575 |
527 void JumpList::StartLoadingFavicon() { | 576 void JumpList::StartLoadingFavicon() { |
528 DCHECK(CalledOnValidThread()); | 577 DCHECK(CalledOnValidThread()); |
529 | 578 |
530 GURL url; | 579 GURL url; |
531 bool waiting_for_icons = true; | 580 bool waiting_for_icons = true; |
532 { | 581 { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 | 636 |
588 void JumpList::OnIncognitoAvailabilityChanged() { | 637 void JumpList::OnIncognitoAvailabilityChanged() { |
589 DCHECK(CalledOnValidThread()); | 638 DCHECK(CalledOnValidThread()); |
590 | 639 |
591 bool waiting_for_icons = true; | 640 bool waiting_for_icons = true; |
592 { | 641 { |
593 JumpListData* data = &jumplist_data_->data; | 642 JumpListData* data = &jumplist_data_->data; |
594 base::AutoLock auto_lock(data->list_lock_); | 643 base::AutoLock auto_lock(data->list_lock_); |
595 waiting_for_icons = !data->icon_urls_.empty(); | 644 waiting_for_icons = !data->icon_urls_.empty(); |
596 } | 645 } |
| 646 |
| 647 // Since neither the "Most Visited" category nor the "Recently Closed" |
| 648 // category changes, mark the flags so that icon files for those categories |
| 649 // won't be updated later on. |
597 if (!waiting_for_icons) | 650 if (!waiting_for_icons) |
598 PostRunUpdate(); | 651 PostRunUpdate(); |
599 // If |icon_urls_| isn't empty then OnFaviconDataAvailable will eventually | |
600 // call PostRunUpdate(). | |
601 } | 652 } |
602 | 653 |
603 void JumpList::PostRunUpdate() { | 654 void JumpList::PostRunUpdate() { |
604 DCHECK(CalledOnValidThread()); | 655 DCHECK(CalledOnValidThread()); |
605 | 656 |
606 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); | 657 TRACE_EVENT0("browser", "JumpList::PostRunUpdate"); |
607 // Initialize the one-shot timer to update the jumplists in a while. | 658 // Initialize the one-shot timer to update the jumplists in a while. |
608 // If there is already a request queued then cancel it and post the new | 659 // If there is already a request queued then cancel it and post the new |
609 // request. This ensures that JumpListUpdates won't happen until there has | 660 // request. This ensures that JumpListUpdates won't happen until there has |
610 // been a brief quiet period, thus avoiding update storms. | 661 // been a brief quiet period, thus avoiding update storms. |
611 if (timer_.IsRunning()) { | 662 if (timer_.IsRunning()) { |
612 timer_.Reset(); | 663 timer_.Reset(); |
613 } else { | 664 } else { |
614 timer_.Start(FROM_HERE, kDelayForJumplistUpdate, this, | 665 timer_.Start(FROM_HERE, kDelayForJumplistUpdate, this, |
615 &JumpList::DeferredRunUpdate); | 666 &JumpList::DeferredRunUpdate); |
616 } | 667 } |
617 } | 668 } |
618 | 669 |
619 void JumpList::DeferredRunUpdate() { | 670 void JumpList::DeferredRunUpdate() { |
620 DCHECK(CalledOnValidThread()); | 671 DCHECK(CalledOnValidThread()); |
621 | 672 |
622 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); | 673 TRACE_EVENT0("browser", "JumpList::DeferredRunUpdate"); |
623 // Check if incognito windows (or normal windows) are disabled by policy. | 674 // Check if incognito windows (or normal windows) are disabled by policy. |
624 IncognitoModePrefs::Availability incognito_availability = | 675 IncognitoModePrefs::Availability incognito_availability = |
625 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) | 676 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) |
626 : IncognitoModePrefs::ENABLED; | 677 : IncognitoModePrefs::ENABLED; |
627 | 678 |
628 // Post a task to update the jumplist in JumpListIcons folder, which consists | 679 // Post a task to update the JumpList, which consists of 1) delete old icons, |
629 // of 1) delete old icons, 2) create new icons, 3) notify the OS. | 680 // 2) create new icons, 3) notify the OS. |
630 update_jumplisticons_task_runner_->PostTask( | 681 update_jumplist_task_runner_->PostTask( |
631 FROM_HERE, base::Bind(&RunUpdateJumpList, incognito_availability, app_id_, | 682 FROM_HERE, base::Bind(&RunUpdateJumpList, incognito_availability, app_id_, |
632 icon_dir_, base::RetainedRef(jumplist_data_))); | 683 icon_dir_, base::RetainedRef(jumplist_data_))); |
633 | 684 |
634 // Post a task to delete JumpListIconsOld folder and log the results to UMA. | 685 // Post a task to delete JumpListIcons folder as it's no longer needed. |
| 686 // Now we have JumpListIconsMostVisited folder and JumpListIconsRecentClosed |
| 687 // folder instead. |
| 688 delete_jumplisticons_task_runner_->PostTask( |
| 689 FROM_HERE, |
| 690 base::Bind(&DeleteDirectoryAndLogResults, icon_dir_, kFileDeleteLimit)); |
| 691 |
| 692 // Post a task to delete JumpListIconsOld folder as it's no longer needed. |
635 base::FilePath icon_dir_old = icon_dir_.DirName().Append( | 693 base::FilePath icon_dir_old = icon_dir_.DirName().Append( |
636 icon_dir_.BaseName().value() + FILE_PATH_LITERAL("Old")); | 694 icon_dir_.BaseName().value() + FILE_PATH_LITERAL("Old")); |
637 | 695 |
638 delete_jumplisticonsold_task_runner_->PostTask( | 696 delete_jumplisticons_task_runner_->PostTask( |
639 FROM_HERE, base::Bind(&DeleteDirectoryAndLogResults, | 697 FROM_HERE, base::Bind(&DeleteDirectoryAndLogResults, |
640 std::move(icon_dir_old), kFileDeleteLimit)); | 698 std::move(icon_dir_old), kFileDeleteLimit)); |
641 } | 699 } |
642 | 700 |
643 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { | 701 void JumpList::TopSitesLoaded(history::TopSites* top_sites) { |
644 } | 702 } |
645 | 703 |
646 void JumpList::TopSitesChanged(history::TopSites* top_sites, | 704 void JumpList::TopSitesChanged(history::TopSites* top_sites, |
647 ChangeReason change_reason) { | 705 ChangeReason change_reason) { |
648 top_sites->GetMostVisitedURLs( | 706 top_sites->GetMostVisitedURLs( |
649 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 707 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
650 weak_ptr_factory_.GetWeakPtr()), | 708 weak_ptr_factory_.GetWeakPtr()), |
651 false); | 709 false); |
652 } | 710 } |
OLD | NEW |