| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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.h" | 5 #include "chrome/browser/jumplist.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <shobjidl.h> | 8 #include <shobjidl.h> |
| 9 #include <propkey.h> | 9 #include <propkey.h> |
| 10 #include <propvarutil.h> | 10 #include <propvarutil.h> |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 #include "chrome/browser/history/history.h" | 27 #include "chrome/browser/history/history.h" |
| 28 #include "chrome/browser/history/page_usage_data.h" | 28 #include "chrome/browser/history/page_usage_data.h" |
| 29 #include "chrome/browser/profile.h" | 29 #include "chrome/browser/profile.h" |
| 30 #include "chrome/browser/sessions/tab_restore_service.h" | 30 #include "chrome/browser/sessions/tab_restore_service.h" |
| 31 #include "chrome/common/chrome_constants.h" | 31 #include "chrome/common/chrome_constants.h" |
| 32 #include "chrome/common/chrome_switches.h" | 32 #include "chrome/common/chrome_switches.h" |
| 33 #include "chrome/common/url_constants.h" | 33 #include "chrome/common/url_constants.h" |
| 34 #include "googleurl/src/gurl.h" | 34 #include "googleurl/src/gurl.h" |
| 35 #include "third_party/skia/include/core/SkBitmap.h" | 35 #include "third_party/skia/include/core/SkBitmap.h" |
| 36 | 36 |
| 37 #include "grit/chromium_strings.h" |
| 37 #include "grit/generated_resources.h" | 38 #include "grit/generated_resources.h" |
| 38 | 39 |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 // COM interfaces used in this file. | 42 // COM interfaces used in this file. |
| 42 // These interface declarations are copied from Windows SDK 7.0. | 43 // These interface declarations are copied from Windows SDK 7.0. |
| 43 // TODO(hbono): Bug 16903: to be deleted them when we use Windows SDK 7.0. | 44 // TODO(hbono): Bug 16903: to be deleted them when we use Windows SDK 7.0. |
| 44 #ifndef __IObjectArray_INTERFACE_DEFINED__ | 45 #ifndef __IObjectArray_INTERFACE_DEFINED__ |
| 45 #define __IObjectArray_INTERFACE_DEFINED__ | 46 #define __IObjectArray_INTERFACE_DEFINED__ |
| 46 | 47 |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 // * switches (std::wstring) | 274 // * switches (std::wstring) |
| 274 // Command-lien switches for the application. This string is to be added | 275 // Command-lien switches for the application. This string is to be added |
| 275 // before the arguments of each ShellLinkItem object. If there aren't any | 276 // before the arguments of each ShellLinkItem object. If there aren't any |
| 276 // switches, use an empty string. | 277 // switches, use an empty string. |
| 277 // * data (ShellLinkItemList) | 278 // * data (ShellLinkItemList) |
| 278 // A list of ShellLinkItem objects to be added under the specified category. | 279 // A list of ShellLinkItem objects to be added under the specified category. |
| 279 HRESULT UpdateCategory(ScopedComPtr<ICustomDestinationList> list, | 280 HRESULT UpdateCategory(ScopedComPtr<ICustomDestinationList> list, |
| 280 int category_id, | 281 int category_id, |
| 281 const std::wstring& application, | 282 const std::wstring& application, |
| 282 const std::wstring& switches, | 283 const std::wstring& switches, |
| 283 const ShellLinkItemList& data) { | 284 const ShellLinkItemList& data, |
| 285 int max_slots) { |
| 284 // Exit this function when the given vector does not contain any items | 286 // Exit this function when the given vector does not contain any items |
| 285 // because an ICustomDestinationList::AppendCategory() call fails in this | 287 // because an ICustomDestinationList::AppendCategory() call fails in this |
| 286 // case. | 288 // case. |
| 287 if (data.empty()) | 289 if (data.empty() || !max_slots) |
| 288 return S_OK; | 290 return S_OK; |
| 289 | 291 |
| 290 std::wstring category = l10n_util::GetString(category_id); | 292 std::wstring category = l10n_util::GetString(category_id); |
| 291 | 293 |
| 292 // Create an EnumerableObjectCollection object. | 294 // Create an EnumerableObjectCollection object. |
| 293 // We once add the given items to this collection object and add this | 295 // We once add the given items to this collection object and add this |
| 294 // collection to the JumpList. | 296 // collection to the JumpList. |
| 295 ScopedComPtr<IObjectCollection> collection; | 297 ScopedComPtr<IObjectCollection> collection; |
| 296 HRESULT result = collection.CreateInstance(CLSID_EnumerableObjectCollection, | 298 HRESULT result = collection.CreateInstance(CLSID_EnumerableObjectCollection, |
| 297 NULL, CLSCTX_INPROC_SERVER); | 299 NULL, CLSCTX_INPROC_SERVER); |
| 298 if (FAILED(result)) | 300 if (FAILED(result)) |
| 299 return false; | 301 return false; |
| 300 | 302 |
| 301 for (ShellLinkItemList::const_iterator item = data.begin(); | 303 for (ShellLinkItemList::const_iterator item = data.begin(); |
| 302 item != data.end(); ++item) { | 304 item != data.end() && max_slots > 0; ++item, --max_slots) { |
| 303 scoped_refptr<ShellLinkItem> link(*item); | 305 scoped_refptr<ShellLinkItem> link(*item); |
| 304 AddShellLink(collection, application, switches, link); | 306 AddShellLink(collection, application, switches, link); |
| 305 } | 307 } |
| 306 | 308 |
| 307 // We can now add the new list to the JumpList. | 309 // We can now add the new list to the JumpList. |
| 308 // The ICustomDestinationList::AppendCategory() function needs the | 310 // The ICustomDestinationList::AppendCategory() function needs the |
| 309 // IObjectArray interface to retrieve each item in the list. So, we retrive | 311 // IObjectArray interface to retrieve each item in the list. So, we retrive |
| 310 // the IObjectArray interface from the IEnumeratableObjectCollection object | 312 // the IObjectArray interface from the IEnumeratableObjectCollection object |
| 311 // and use it. | 313 // and use it. |
| 312 // It seems the ICustomDestinationList::AppendCategory() function just | 314 // It seems the ICustomDestinationList::AppendCategory() function just |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 if (win_util::GetWinVersion() < win_util::WINVERSION_WIN7) | 388 if (win_util::GetWinVersion() < win_util::WINVERSION_WIN7) |
| 387 return true; | 389 return true; |
| 388 | 390 |
| 389 // Create an ICustomDestinationList object and attach it to our application. | 391 // Create an ICustomDestinationList object and attach it to our application. |
| 390 ScopedComPtr<ICustomDestinationList> destination_list; | 392 ScopedComPtr<ICustomDestinationList> destination_list; |
| 391 HRESULT result = destination_list.CreateInstance(CLSID_DestinationList, NULL, | 393 HRESULT result = destination_list.CreateInstance(CLSID_DestinationList, NULL, |
| 392 CLSCTX_INPROC_SERVER); | 394 CLSCTX_INPROC_SERVER); |
| 393 if (FAILED(result)) | 395 if (FAILED(result)) |
| 394 return false; | 396 return false; |
| 395 | 397 |
| 398 // Set the App ID for this JumpList. |
| 399 destination_list->SetAppID(l10n_util::GetString(IDS_PRODUCT_NAME).c_str()); |
| 400 |
| 396 // Start a transaction that updates the JumpList of this application. | 401 // Start a transaction that updates the JumpList of this application. |
| 397 // This implementation just replaces the all items in this JumpList, so | 402 // This implementation just replaces the all items in this JumpList, so |
| 398 // we don't have to use the IObjectArray object returned from this call. | 403 // we don't have to use the IObjectArray object returned from this call. |
| 399 // It seems Windows 7 RC (Build 7100) automatically checks the items in this | 404 // It seems Windows 7 RC (Build 7100) automatically checks the items in this |
| 400 // removed list and prevent us from adding the same item. | 405 // removed list and prevent us from adding the same item. |
| 401 UINT max_slots; | 406 UINT max_slots; |
| 402 ScopedComPtr<IObjectArray> removed; | 407 ScopedComPtr<IObjectArray> removed; |
| 403 result = destination_list->BeginList(&max_slots, __uuidof(*removed), | 408 result = destination_list->BeginList(&max_slots, __uuidof(*removed), |
| 404 reinterpret_cast<void**>(&removed)); | 409 reinterpret_cast<void**>(&removed)); |
| 405 if (FAILED(result)) | 410 if (FAILED(result)) |
| 406 return false; | 411 return false; |
| 407 | 412 |
| 408 // Retrieve the absolute path to "chrome.exe". | 413 // Retrieve the absolute path to "chrome.exe". |
| 409 std::wstring chrome_path; | 414 std::wstring chrome_path; |
| 410 if (!PathService::Get(base::FILE_EXE, &chrome_path)) | 415 if (!PathService::Get(base::FILE_EXE, &chrome_path)) |
| 411 return false; | 416 return false; |
| 412 | 417 |
| 413 // Retrieve the command-line switches of this process. | 418 // Retrieve the command-line switches of this process. |
| 414 std::wstring chrome_switches; | 419 std::wstring chrome_switches; |
| 415 | 420 |
| 421 // We allocate 60% of the given JumpList slots to "most-visited" items |
| 422 // and 40% to "recently-closed" items, respectively. |
| 423 // Nevertheless, if there are not so many items in |recently_closed_pages|, |
| 424 // we give the remaining slots to "most-visited" items. |
| 425 const int kMostVisited = 60; |
| 426 const int kRecentlyClosed = 40; |
| 427 const int kTotal = kMostVisited + kRecentlyClosed; |
| 428 size_t most_visited_items = MulDiv(max_slots, kMostVisited, kTotal); |
| 429 size_t recently_closed_items = max_slots - most_visited_items; |
| 430 if (recently_closed_pages.size() < recently_closed_items) { |
| 431 most_visited_items += recently_closed_items - recently_closed_pages.size(); |
| 432 recently_closed_items = recently_closed_pages.size(); |
| 433 } |
| 434 |
| 416 // Update the "Most Visited" category of the JumpList. | 435 // Update the "Most Visited" category of the JumpList. |
| 417 // This update request is applied into the JumpList when we commit this | 436 // This update request is applied into the JumpList when we commit this |
| 418 // transaction. | 437 // transaction. |
| 419 result = UpdateCategory(destination_list, IDS_NEW_TAB_MOST_VISITED, | 438 result = UpdateCategory(destination_list, IDS_NEW_TAB_MOST_VISITED, |
| 420 chrome_path, chrome_switches, most_visited_pages); | 439 chrome_path, chrome_switches, most_visited_pages, |
| 440 most_visited_items); |
| 421 if (FAILED(result)) | 441 if (FAILED(result)) |
| 422 return false; | 442 return false; |
| 423 | 443 |
| 424 // Update the "Recently Closed" category of the JumpList. | 444 // Update the "Recently Closed" category of the JumpList. |
| 425 result = UpdateCategory(destination_list, IDS_NEW_TAB_RECENTLY_CLOSED, | 445 result = UpdateCategory(destination_list, IDS_NEW_TAB_RECENTLY_CLOSED, |
| 426 chrome_path, chrome_switches, recently_closed_pages); | 446 chrome_path, chrome_switches, recently_closed_pages, |
| 447 recently_closed_items); |
| 427 if (FAILED(result)) | 448 if (FAILED(result)) |
| 428 return false; | 449 return false; |
| 429 | 450 |
| 430 // Update the "Tasks" category of the JumpList. | 451 // Update the "Tasks" category of the JumpList. |
| 431 result = UpdateTaskCategory(destination_list, chrome_path, chrome_switches); | 452 result = UpdateTaskCategory(destination_list, chrome_path, chrome_switches); |
| 432 if (FAILED(result)) | 453 if (FAILED(result)) |
| 433 return false; | 454 return false; |
| 434 | 455 |
| 435 // Commit this transaction and send the updated JumpList to Windows. | 456 // Commit this transaction and send the updated JumpList to Windows. |
| 436 result = destination_list->CommitList(); | 457 result = destination_list->CommitList(); |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 // As noted above, we create a ShellLinkItem objects with the following | 704 // As noted above, we create a ShellLinkItem objects with the following |
| 684 // parameters. | 705 // parameters. |
| 685 // * arguments | 706 // * arguments |
| 686 // The last URL of the tab object. | 707 // The last URL of the tab object. |
| 687 // * title | 708 // * title |
| 688 // The title of the last URL. | 709 // The title of the last URL. |
| 689 // * icon | 710 // * icon |
| 690 // An empty string. This value is to be updated in OnFavIconDataAvailable(). | 711 // An empty string. This value is to be updated in OnFavIconDataAvailable(). |
| 691 // This code is copied from | 712 // This code is copied from |
| 692 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. | 713 // RecentlyClosedTabsHandler::TabRestoreServiceChanged() to emulate it. |
| 714 const int kRecentlyClosedCount = 4; |
| 693 recently_closed_pages_.clear(); | 715 recently_closed_pages_.clear(); |
| 694 TabRestoreService* tab_restore_service = profile_->GetTabRestoreService(); | 716 TabRestoreService* tab_restore_service = profile_->GetTabRestoreService(); |
| 695 const TabRestoreService::Entries& entries = tab_restore_service->entries(); | 717 const TabRestoreService::Entries& entries = tab_restore_service->entries(); |
| 696 for (TabRestoreService::Entries::const_iterator it = entries.begin(); | 718 for (TabRestoreService::Entries::const_iterator it = entries.begin(); |
| 697 it != entries.end(); ++it) { | 719 it != entries.end(); ++it) { |
| 698 const TabRestoreService::Entry* entry = *it; | 720 const TabRestoreService::Entry* entry = *it; |
| 699 if (entry->type == TabRestoreService::TAB) { | 721 if (entry->type == TabRestoreService::TAB) { |
| 700 AddTab(static_cast<const TabRestoreService::Tab*>(entry), | 722 AddTab(static_cast<const TabRestoreService::Tab*>(entry), |
| 701 &recently_closed_pages_, 3); | 723 &recently_closed_pages_, kRecentlyClosedCount); |
| 702 } else if (entry->type == TabRestoreService::WINDOW) { | 724 } else if (entry->type == TabRestoreService::WINDOW) { |
| 703 AddWindow(static_cast<const TabRestoreService::Window*>(entry), | 725 AddWindow(static_cast<const TabRestoreService::Window*>(entry), |
| 704 &recently_closed_pages_, 3); | 726 &recently_closed_pages_, kRecentlyClosedCount); |
| 705 } | 727 } |
| 706 } | 728 } |
| 707 | 729 |
| 708 // Send a query that retrieves the first fav icon. | 730 // Send a query that retrieves the first fav icon. |
| 709 StartLoadingFavIcon(); | 731 StartLoadingFavIcon(); |
| 710 } | 732 } |
| 711 | 733 |
| 712 void JumpList::OnFavIconDataAvailable( | 734 void JumpList::OnFavIconDataAvailable( |
| 713 FaviconService::Handle handle, | 735 FaviconService::Handle handle, |
| 714 bool know_favicon, | 736 bool know_favicon, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 733 // the file thread. | 755 // the file thread. |
| 734 ChromeThread::PostTask( | 756 ChromeThread::PostTask( |
| 735 ChromeThread::FILE, FROM_HERE, | 757 ChromeThread::FILE, FROM_HERE, |
| 736 new JumpListUpdateTask( | 758 new JumpListUpdateTask( |
| 737 icon_dir_, most_visited_pages_, recently_closed_pages_)); | 759 icon_dir_, most_visited_pages_, recently_closed_pages_)); |
| 738 | 760 |
| 739 // Delete all items in these lists since we don't need these lists any longer. | 761 // Delete all items in these lists since we don't need these lists any longer. |
| 740 most_visited_pages_.clear(); | 762 most_visited_pages_.clear(); |
| 741 recently_closed_pages_.clear(); | 763 recently_closed_pages_.clear(); |
| 742 } | 764 } |
| OLD | NEW |