| 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/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 15 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
| 16 #include "chrome/browser/favicon/favicon_service.h" | 17 #include "chrome/browser/favicon/favicon_service.h" |
| 17 #include "chrome/browser/favicon/favicon_service_factory.h" | 18 #include "chrome/browser/favicon/favicon_service_factory.h" |
| 18 #include "chrome/browser/history/history_service.h" | 19 #include "chrome/browser/history/history_service.h" |
| 19 #include "chrome/browser/history/top_sites.h" | 20 #include "chrome/browser/history/top_sites.h" |
| 20 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/sessions/session_types.h" | 22 #include "chrome/browser/sessions/session_types.h" |
| 22 #include "chrome/browser/sessions/tab_restore_service.h" | 23 #include "chrome/browser/sessions/tab_restore_service.h" |
| 23 #include "chrome/browser/sessions/tab_restore_service_factory.h" | 24 #include "chrome/browser/sessions/tab_restore_service_factory.h" |
| 24 #include "chrome/browser/shell_integration.h" | 25 #include "chrome/browser/shell_integration.h" |
| 25 #include "chrome/common/chrome_constants.h" | 26 #include "chrome/common/chrome_constants.h" |
| 26 #include "chrome/common/chrome_switches.h" | 27 #include "chrome/common/chrome_switches.h" |
| 28 #include "chrome/common/pref_names.h" |
| 27 #include "chrome/common/url_constants.h" | 29 #include "chrome/common/url_constants.h" |
| 28 #include "chrome/grit/generated_resources.h" | 30 #include "chrome/grit/generated_resources.h" |
| 29 #include "components/favicon_base/favicon_types.h" | 31 #include "components/favicon_base/favicon_types.h" |
| 30 #include "components/history/core/browser/page_usage_data.h" | 32 #include "components/history/core/browser/page_usage_data.h" |
| 31 #include "content/public/browser/browser_thread.h" | 33 #include "content/public/browser/browser_thread.h" |
| 32 #include "content/public/browser/notification_source.h" | 34 #include "content/public/browser/notification_source.h" |
| 33 #include "ui/base/l10n/l10n_util.h" | 35 #include "ui/base/l10n/l10n_util.h" |
| 34 #include "ui/gfx/codec/png_codec.h" | 36 #include "ui/gfx/codec/png_codec.h" |
| 35 #include "ui/gfx/favicon_size.h" | 37 #include "ui/gfx/favicon_size.h" |
| 36 #include "ui/gfx/icon_util.h" | 38 #include "ui/gfx/icon_util.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 if (!IconUtil::CreateIconFileFromImageFamily(image_family, path)) | 77 if (!IconUtil::CreateIconFileFromImageFamily(image_family, path)) |
| 76 return false; | 78 return false; |
| 77 | 79 |
| 78 // Add this icon file to the list and return its absolute path. | 80 // Add this icon file to the list and return its absolute path. |
| 79 // The IShellLink::SetIcon() function needs the absolute path to an icon. | 81 // The IShellLink::SetIcon() function needs the absolute path to an icon. |
| 80 *icon_path = path; | 82 *icon_path = path; |
| 81 return true; | 83 return true; |
| 82 } | 84 } |
| 83 | 85 |
| 84 // Updates the "Tasks" category of the JumpList. | 86 // Updates the "Tasks" category of the JumpList. |
| 85 bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) { | 87 bool UpdateTaskCategory( |
| 88 JumpListUpdater* jumplist_updater, |
| 89 IncognitoModePrefs::Availability incognito_availability) { |
| 86 base::FilePath chrome_path; | 90 base::FilePath chrome_path; |
| 87 if (!PathService::Get(base::FILE_EXE, &chrome_path)) | 91 if (!PathService::Get(base::FILE_EXE, &chrome_path)) |
| 88 return false; | 92 return false; |
| 89 | 93 |
| 90 ShellLinkItemList items; | 94 ShellLinkItemList items; |
| 91 | 95 |
| 92 // Create an IShellLink object which launches Chrome, and add it to the | 96 // Create an IShellLink object which launches Chrome, and add it to the |
| 93 // collection. We use our application icon as the icon for this item. | 97 // collection. We use our application icon as the icon for this item. |
| 94 // We remove '&' characters from this string so we can share it with our | 98 // We remove '&' characters from this string so we can share it with our |
| 95 // system menu. | 99 // system menu. |
| 96 scoped_refptr<ShellLinkItem> chrome = CreateShellLink(); | 100 if (incognito_availability != IncognitoModePrefs::FORCED) { |
| 97 base::string16 chrome_title = l10n_util::GetStringUTF16(IDS_NEW_WINDOW); | 101 scoped_refptr<ShellLinkItem> chrome = CreateShellLink(); |
| 98 ReplaceSubstringsAfterOffset(&chrome_title, 0, L"&", L""); | 102 base::string16 chrome_title = l10n_util::GetStringUTF16(IDS_NEW_WINDOW); |
| 99 chrome->set_title(chrome_title); | 103 ReplaceSubstringsAfterOffset(&chrome_title, 0, L"&", L""); |
| 100 chrome->set_icon(chrome_path.value(), 0); | 104 chrome->set_title(chrome_title); |
| 101 items.push_back(chrome); | 105 chrome->set_icon(chrome_path.value(), 0); |
| 106 items.push_back(chrome); |
| 107 } |
| 102 | 108 |
| 103 // Create an IShellLink object which launches Chrome in incognito mode, and | 109 // Create an IShellLink object which launches Chrome in incognito mode, and |
| 104 // add it to the collection. We use our application icon as the icon for | 110 // add it to the collection. We use our application icon as the icon for |
| 105 // this item. | 111 // this item. |
| 106 scoped_refptr<ShellLinkItem> incognito = CreateShellLink(); | 112 if (incognito_availability != IncognitoModePrefs::DISABLED) { |
| 107 incognito->GetCommandLine()->AppendSwitch(switches::kIncognito); | 113 scoped_refptr<ShellLinkItem> incognito = CreateShellLink(); |
| 108 base::string16 incognito_title = | 114 incognito->GetCommandLine()->AppendSwitch(switches::kIncognito); |
| 109 l10n_util::GetStringUTF16(IDS_NEW_INCOGNITO_WINDOW); | 115 base::string16 incognito_title = |
| 110 ReplaceSubstringsAfterOffset(&incognito_title, 0, L"&", L""); | 116 l10n_util::GetStringUTF16(IDS_NEW_INCOGNITO_WINDOW); |
| 111 incognito->set_title(incognito_title); | 117 ReplaceSubstringsAfterOffset(&incognito_title, 0, L"&", L""); |
| 112 incognito->set_icon(chrome_path.value(), 0); | 118 incognito->set_title(incognito_title); |
| 113 items.push_back(incognito); | 119 incognito->set_icon(chrome_path.value(), 0); |
| 120 items.push_back(incognito); |
| 121 } |
| 114 | 122 |
| 115 return jumplist_updater->AddTasks(items); | 123 return jumplist_updater->AddTasks(items); |
| 116 } | 124 } |
| 117 | 125 |
| 118 // Updates the application JumpList. | 126 // Updates the application JumpList. |
| 119 bool UpdateJumpList(const wchar_t* app_id, | 127 bool UpdateJumpList(const wchar_t* app_id, |
| 120 const ShellLinkItemList& most_visited_pages, | 128 const ShellLinkItemList& most_visited_pages, |
| 121 const ShellLinkItemList& recently_closed_pages) { | 129 const ShellLinkItemList& recently_closed_pages, |
| 130 IncognitoModePrefs::Availability incognito_availability) { |
| 122 // JumpList is implemented only on Windows 7 or later. | 131 // JumpList is implemented only on Windows 7 or later. |
| 123 // So, we should return now when this function is called on earlier versions | 132 // So, we should return now when this function is called on earlier versions |
| 124 // of Windows. | 133 // of Windows. |
| 125 if (!JumpListUpdater::IsEnabled()) | 134 if (!JumpListUpdater::IsEnabled()) |
| 126 return true; | 135 return true; |
| 127 | 136 |
| 128 JumpListUpdater jumplist_updater(app_id); | 137 JumpListUpdater jumplist_updater(app_id); |
| 129 if (!jumplist_updater.BeginUpdate()) | 138 if (!jumplist_updater.BeginUpdate()) |
| 130 return false; | 139 return false; |
| 131 | 140 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 157 | 166 |
| 158 // Update the "Recently Closed" category of the JumpList. | 167 // Update the "Recently Closed" category of the JumpList. |
| 159 if (!jumplist_updater.AddCustomCategory( | 168 if (!jumplist_updater.AddCustomCategory( |
| 160 base::UTF16ToWide( | 169 base::UTF16ToWide( |
| 161 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), | 170 l10n_util::GetStringUTF16(IDS_NEW_TAB_RECENTLY_CLOSED)), |
| 162 recently_closed_pages, recently_closed_items)) { | 171 recently_closed_pages, recently_closed_items)) { |
| 163 return false; | 172 return false; |
| 164 } | 173 } |
| 165 | 174 |
| 166 // Update the "Tasks" category of the JumpList. | 175 // Update the "Tasks" category of the JumpList. |
| 167 if (!UpdateTaskCategory(&jumplist_updater)) | 176 if (!UpdateTaskCategory(&jumplist_updater, incognito_availability)) |
| 168 return false; | 177 return false; |
| 169 | 178 |
| 170 // Commit this transaction and send the updated JumpList to Windows. | 179 // Commit this transaction and send the updated JumpList to Windows. |
| 171 if (!jumplist_updater.CommitUpdate()) | 180 if (!jumplist_updater.CommitUpdate()) |
| 172 return false; | 181 return false; |
| 173 | 182 |
| 174 return true; | 183 return true; |
| 175 } | 184 } |
| 176 | 185 |
| 177 } // namespace | 186 } // namespace |
| 178 | 187 |
| 179 JumpList::JumpList() | 188 JumpList::JumpList(Profile* profile) |
| 180 : weak_ptr_factory_(this), | 189 : weak_ptr_factory_(this), |
| 181 profile_(NULL), | 190 profile_(profile), |
| 182 task_id_(base::CancelableTaskTracker::kBadTaskId) {} | 191 task_id_(base::CancelableTaskTracker::kBadTaskId) { |
| 183 | 192 DCHECK(Enabled()); |
| 184 JumpList::~JumpList() { | |
| 185 Terminate(); | |
| 186 } | |
| 187 | |
| 188 // static | |
| 189 bool JumpList::Enabled() { | |
| 190 return JumpListUpdater::IsEnabled(); | |
| 191 } | |
| 192 | |
| 193 bool JumpList::AddObserver(Profile* profile) { | |
| 194 // To update JumpList when a tab is added or removed, we add this object to | 193 // To update JumpList when a tab is added or removed, we add this object to |
| 195 // the observer list of the TabRestoreService class. | 194 // the observer list of the TabRestoreService class. |
| 196 // When we add this object to the observer list, we save the pointer to this | 195 // When we add this object to the observer list, we save the pointer to this |
| 197 // TabRestoreService object. This pointer is used when we remove this object | 196 // TabRestoreService object. This pointer is used when we remove this object |
| 198 // from the observer list. | 197 // from the observer list. |
| 199 if (!JumpListUpdater::IsEnabled() || !profile) | 198 TabRestoreService* tab_restore_service = |
| 200 return false; | 199 TabRestoreServiceFactory::GetForProfile(profile_); |
| 200 if (!tab_restore_service) |
| 201 return; |
| 201 | 202 |
| 202 TabRestoreService* tab_restore_service = | 203 app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath()); |
| 203 TabRestoreServiceFactory::GetForProfile(profile); | 204 icon_dir_ = profile_->GetPath().Append(chrome::kJumpListIconDirname); |
| 204 if (!tab_restore_service) | |
| 205 return false; | |
| 206 | |
| 207 app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile->GetPath()); | |
| 208 icon_dir_ = profile->GetPath().Append(chrome::kJumpListIconDirname); | |
| 209 profile_ = profile; | |
| 210 history::TopSites* top_sites = profile_->GetTopSites(); | 205 history::TopSites* top_sites = profile_->GetTopSites(); |
| 211 if (top_sites) { | 206 if (top_sites) { |
| 212 // TopSites updates itself after a delay. This is especially noticable when | 207 // TopSites updates itself after a delay. This is especially noticable when |
| 213 // your profile is empty. Ask TopSites to update itself when jumplist is | 208 // your profile is empty. Ask TopSites to update itself when jumplist is |
| 214 // initialized. | 209 // initialized. |
| 215 top_sites->SyncWithHistory(); | 210 top_sites->SyncWithHistory(); |
| 216 registrar_.reset(new content::NotificationRegistrar); | 211 registrar_.reset(new content::NotificationRegistrar); |
| 217 // Register for notification when TopSites changes so that we can update | 212 // Register for notification when TopSites changes so that we can update |
| 218 // ourself. | 213 // ourself. |
| 219 registrar_->Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, | 214 registrar_->Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED, |
| 220 content::Source<history::TopSites>(top_sites)); | 215 content::Source<history::TopSites>(top_sites)); |
| 221 // Register for notification when profile is destroyed to ensure that all | 216 // Register for notification when profile is destroyed to ensure that all |
| 222 // observers are detatched at that time. | 217 // observers are detatched at that time. |
| 223 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 218 registrar_->Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 224 content::Source<Profile>(profile_)); | 219 content::Source<Profile>(profile_)); |
| 225 } | 220 } |
| 226 tab_restore_service->AddObserver(this); | 221 tab_restore_service->AddObserver(this); |
| 227 return true; | 222 pref_change_registrar_.reset(new PrefChangeRegistrar); |
| 223 pref_change_registrar_->Init(profile_->GetPrefs()); |
| 224 pref_change_registrar_->Add( |
| 225 prefs::kIncognitoModeAvailability, |
| 226 base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this)); |
| 227 } |
| 228 |
| 229 JumpList::~JumpList() { |
| 230 Terminate(); |
| 231 } |
| 232 |
| 233 // static |
| 234 bool JumpList::Enabled() { |
| 235 return JumpListUpdater::IsEnabled(); |
| 228 } | 236 } |
| 229 | 237 |
| 230 void JumpList::Observe(int type, | 238 void JumpList::Observe(int type, |
| 231 const content::NotificationSource& source, | 239 const content::NotificationSource& source, |
| 232 const content::NotificationDetails& details) { | 240 const content::NotificationDetails& details) { |
| 233 switch (type) { | 241 switch (type) { |
| 234 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { | 242 case chrome::NOTIFICATION_TOP_SITES_CHANGED: { |
| 235 // Most visited urls changed, query again. | 243 // Most visited urls changed, query again. |
| 236 history::TopSites* top_sites = profile_->GetTopSites(); | 244 history::TopSites* top_sites = profile_->GetTopSites(); |
| 237 if (top_sites) { | 245 if (top_sites) { |
| 238 top_sites->GetMostVisitedURLs( | 246 top_sites->GetMostVisitedURLs( |
| 239 base::Bind(&JumpList::OnMostVisitedURLsAvailable, | 247 base::Bind(&JumpList::OnMostVisitedURLsAvailable, |
| 240 weak_ptr_factory_.GetWeakPtr()), false); | 248 weak_ptr_factory_.GetWeakPtr()), false); |
| 241 } | 249 } |
| 242 break; | 250 break; |
| 243 } | 251 } |
| 244 case chrome::NOTIFICATION_PROFILE_DESTROYED: { | 252 case chrome::NOTIFICATION_PROFILE_DESTROYED: { |
| 245 // Profile was destroyed, do clean-up. | 253 // Profile was destroyed, do clean-up. |
| 246 Terminate(); | 254 Terminate(); |
| 247 break; | 255 break; |
| 248 } | 256 } |
| 249 default: | 257 default: |
| 250 NOTREACHED() << "Unexpected notification type."; | 258 NOTREACHED() << "Unexpected notification type."; |
| 251 } | 259 } |
| 252 } | 260 } |
| 253 | 261 |
| 254 void JumpList::RemoveObserver() { | |
| 255 if (profile_) { | |
| 256 TabRestoreService* tab_restore_service = | |
| 257 TabRestoreServiceFactory::GetForProfile(profile_); | |
| 258 if (tab_restore_service) | |
| 259 tab_restore_service->RemoveObserver(this); | |
| 260 registrar_.reset(); | |
| 261 } | |
| 262 profile_ = NULL; | |
| 263 } | |
| 264 | |
| 265 void JumpList::CancelPendingUpdate() { | 262 void JumpList::CancelPendingUpdate() { |
| 266 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { | 263 if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { |
| 267 cancelable_task_tracker_.TryCancel(task_id_); | 264 cancelable_task_tracker_.TryCancel(task_id_); |
| 268 task_id_ = base::CancelableTaskTracker::kBadTaskId; | 265 task_id_ = base::CancelableTaskTracker::kBadTaskId; |
| 269 } | 266 } |
| 270 } | 267 } |
| 271 | 268 |
| 272 void JumpList::Terminate() { | 269 void JumpList::Terminate() { |
| 273 CancelPendingUpdate(); | 270 CancelPendingUpdate(); |
| 274 RemoveObserver(); | 271 if (profile_) { |
| 272 TabRestoreService* tab_restore_service = |
| 273 TabRestoreServiceFactory::GetForProfile(profile_); |
| 274 if (tab_restore_service) |
| 275 tab_restore_service->RemoveObserver(this); |
| 276 registrar_.reset(); |
| 277 pref_change_registrar_.reset(); |
| 278 } |
| 279 profile_ = NULL; |
| 275 } | 280 } |
| 276 | 281 |
| 277 void JumpList::OnMostVisitedURLsAvailable( | 282 void JumpList::OnMostVisitedURLsAvailable( |
| 278 const history::MostVisitedURLList& data) { | 283 const history::MostVisitedURLList& data) { |
| 279 | 284 |
| 280 // If we have a pending favicon request, cancel it here (it is out of date). | 285 // If we have a pending favicon request, cancel it here (it is out of date). |
| 281 CancelPendingUpdate(); | 286 CancelPendingUpdate(); |
| 282 | 287 |
| 283 { | 288 { |
| 284 base::AutoLock auto_lock(list_lock_); | 289 base::AutoLock auto_lock(list_lock_); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 DCHECK(!window->tabs.empty()); | 377 DCHECK(!window->tabs.empty()); |
| 373 | 378 |
| 374 for (size_t i = 0; i < window->tabs.size(); ++i) { | 379 for (size_t i = 0; i < window->tabs.size(); ++i) { |
| 375 if (!AddTab(&window->tabs[i], list, max_items)) | 380 if (!AddTab(&window->tabs[i], list, max_items)) |
| 376 return; | 381 return; |
| 377 } | 382 } |
| 378 } | 383 } |
| 379 | 384 |
| 380 void JumpList::StartLoadingFavicon() { | 385 void JumpList::StartLoadingFavicon() { |
| 381 GURL url; | 386 GURL url; |
| 387 bool waiting_for_icons = true; |
| 382 { | 388 { |
| 383 base::AutoLock auto_lock(list_lock_); | 389 base::AutoLock auto_lock(list_lock_); |
| 384 if (icon_urls_.empty()) { | 390 waiting_for_icons = !icon_urls_.empty(); |
| 385 // No more favicons are needed by the application JumpList. Schedule a | 391 if (waiting_for_icons) { |
| 386 // RunUpdate call. | 392 // Ask FaviconService if it has a favicon of a URL. |
| 387 BrowserThread::PostTask( | 393 // When FaviconService has one, it will call OnFaviconDataAvailable(). |
| 388 BrowserThread::FILE, FROM_HERE, | 394 url = GURL(icon_urls_.front().first); |
| 389 base::Bind(&JumpList::RunUpdate, this)); | |
| 390 return; | |
| 391 } | 395 } |
| 392 // Ask FaviconService if it has a favicon of a URL. | |
| 393 // When FaviconService has one, it will call OnFaviconDataAvailable(). | |
| 394 url = GURL(icon_urls_.front().first); | |
| 395 } | 396 } |
| 397 |
| 398 if (!waiting_for_icons) { |
| 399 // No more favicons are needed by the application JumpList. Schedule a |
| 400 // RunUpdate call. |
| 401 PostRunUpdate(); |
| 402 return; |
| 403 } |
| 404 |
| 396 FaviconService* favicon_service = | 405 FaviconService* favicon_service = |
| 397 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); | 406 FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); |
| 398 task_id_ = favicon_service->GetFaviconImageForPageURL( | 407 task_id_ = favicon_service->GetFaviconImageForPageURL( |
| 399 url, | 408 url, |
| 400 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), | 409 base::Bind(&JumpList::OnFaviconDataAvailable, base::Unretained(this)), |
| 401 &cancelable_task_tracker_); | 410 &cancelable_task_tracker_); |
| 402 } | 411 } |
| 403 | 412 |
| 404 void JumpList::OnFaviconDataAvailable( | 413 void JumpList::OnFaviconDataAvailable( |
| 405 const favicon_base::FaviconImageResult& image_result) { | 414 const favicon_base::FaviconImageResult& image_result) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 416 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); | 425 icon_urls_.front().second->set_icon_data(image_result.image.AsBitmap()); |
| 417 } | 426 } |
| 418 | 427 |
| 419 if (!icon_urls_.empty()) | 428 if (!icon_urls_.empty()) |
| 420 icon_urls_.pop_front(); | 429 icon_urls_.pop_front(); |
| 421 } | 430 } |
| 422 // Check whether we need to load more favicons. | 431 // Check whether we need to load more favicons. |
| 423 StartLoadingFavicon(); | 432 StartLoadingFavicon(); |
| 424 } | 433 } |
| 425 | 434 |
| 426 void JumpList::RunUpdate() { | 435 void JumpList::OnIncognitoAvailabilityChanged() { |
| 436 bool waiting_for_icons = true; |
| 437 { |
| 438 base::AutoLock auto_lock(list_lock_); |
| 439 waiting_for_icons = !icon_urls_.empty(); |
| 440 } |
| 441 if (!waiting_for_icons) |
| 442 PostRunUpdate(); |
| 443 // If |icon_urls_| isn't empty then OnFaviconDataAvailable will eventually |
| 444 // call PostRunUpdate(). |
| 445 } |
| 446 |
| 447 void JumpList::PostRunUpdate() { |
| 448 // Check if incognito windows (or normal windows) are disabled by policy. |
| 449 IncognitoModePrefs::Availability incognito_availability = |
| 450 profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) |
| 451 : IncognitoModePrefs::ENABLED; |
| 452 |
| 453 BrowserThread::PostTask( |
| 454 BrowserThread::FILE, FROM_HERE, |
| 455 base::Bind(&JumpList::RunUpdate, this, incognito_availability)); |
| 456 } |
| 457 |
| 458 void JumpList::RunUpdate( |
| 459 IncognitoModePrefs::Availability incognito_availability) { |
| 427 ShellLinkItemList local_most_visited_pages; | 460 ShellLinkItemList local_most_visited_pages; |
| 428 ShellLinkItemList local_recently_closed_pages; | 461 ShellLinkItemList local_recently_closed_pages; |
| 429 | 462 |
| 430 { | 463 { |
| 431 base::AutoLock auto_lock(list_lock_); | 464 base::AutoLock auto_lock(list_lock_); |
| 432 // Make sure we are not out of date: if icon_urls_ is not empty, then | 465 // Make sure we are not out of date: if icon_urls_ is not empty, then |
| 433 // another notification has been received since we processed this one | 466 // another notification has been received since we processed this one |
| 434 if (!icon_urls_.empty()) | 467 if (!icon_urls_.empty()) |
| 435 return; | 468 return; |
| 436 | 469 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 448 base::Move(icon_dir_, icon_dir_old); | 481 base::Move(icon_dir_, icon_dir_old); |
| 449 base::CreateDirectory(icon_dir_); | 482 base::CreateDirectory(icon_dir_); |
| 450 | 483 |
| 451 // Create temporary icon files for shortcuts in the "Most Visited" category. | 484 // Create temporary icon files for shortcuts in the "Most Visited" category. |
| 452 CreateIconFiles(local_most_visited_pages); | 485 CreateIconFiles(local_most_visited_pages); |
| 453 | 486 |
| 454 // Create temporary icon files for shortcuts in the "Recently Closed" | 487 // Create temporary icon files for shortcuts in the "Recently Closed" |
| 455 // category. | 488 // category. |
| 456 CreateIconFiles(local_recently_closed_pages); | 489 CreateIconFiles(local_recently_closed_pages); |
| 457 | 490 |
| 458 // We finished collecting all resources needed for updating an appliation | 491 // We finished collecting all resources needed for updating an application |
| 459 // JumpList. So, create a new JumpList and replace the current JumpList | 492 // JumpList. So, create a new JumpList and replace the current JumpList |
| 460 // with it. | 493 // with it. |
| 461 UpdateJumpList(app_id_.c_str(), local_most_visited_pages, | 494 UpdateJumpList(app_id_.c_str(), local_most_visited_pages, |
| 462 local_recently_closed_pages); | 495 local_recently_closed_pages, incognito_availability); |
| 463 } | 496 } |
| 464 | 497 |
| 465 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { | 498 void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { |
| 466 for (ShellLinkItemList::const_iterator item = item_list.begin(); | 499 for (ShellLinkItemList::const_iterator item = item_list.begin(); |
| 467 item != item_list.end(); ++item) { | 500 item != item_list.end(); ++item) { |
| 468 base::FilePath icon_path; | 501 base::FilePath icon_path; |
| 469 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) | 502 if (CreateIconFile((*item)->icon_data(), icon_dir_, &icon_path)) |
| 470 (*item)->set_icon(icon_path.value(), 0); | 503 (*item)->set_icon(icon_path.value(), 0); |
| 471 } | 504 } |
| 472 } | 505 } |
| OLD | NEW |