Commit b943d1c8 authored by joaodasilva's avatar joaodasilva Committed by Commit bot

Hide "New incognito window" from jump list if disabled by policy.

BUG=148392

Review URL: https://codereview.chromium.org/549953003

Cr-Commit-Position: refs/heads/master@{#293850}
parent 87d125f0
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/prefs/pref_change_registrar.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
#include "chrome/browser/shell_integration.h" #include "chrome/browser/shell_integration.h"
#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/favicon_base/favicon_types.h" #include "components/favicon_base/favicon_types.h"
...@@ -82,7 +84,9 @@ bool CreateIconFile(const SkBitmap& bitmap, ...@@ -82,7 +84,9 @@ bool CreateIconFile(const SkBitmap& bitmap,
} }
// Updates the "Tasks" category of the JumpList. // Updates the "Tasks" category of the JumpList.
bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) { bool UpdateTaskCategory(
JumpListUpdater* jumplist_updater,
IncognitoModePrefs::Availability incognito_availability) {
base::FilePath chrome_path; base::FilePath chrome_path;
if (!PathService::Get(base::FILE_EXE, &chrome_path)) if (!PathService::Get(base::FILE_EXE, &chrome_path))
return false; return false;
...@@ -93,16 +97,19 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) { ...@@ -93,16 +97,19 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) {
// collection. We use our application icon as the icon for this item. // collection. We use our application icon as the icon for this item.
// We remove '&' characters from this string so we can share it with our // We remove '&' characters from this string so we can share it with our
// system menu. // system menu.
if (incognito_availability != IncognitoModePrefs::FORCED) {
scoped_refptr<ShellLinkItem> chrome = CreateShellLink(); scoped_refptr<ShellLinkItem> chrome = CreateShellLink();
base::string16 chrome_title = l10n_util::GetStringUTF16(IDS_NEW_WINDOW); base::string16 chrome_title = l10n_util::GetStringUTF16(IDS_NEW_WINDOW);
ReplaceSubstringsAfterOffset(&chrome_title, 0, L"&", L""); ReplaceSubstringsAfterOffset(&chrome_title, 0, L"&", L"");
chrome->set_title(chrome_title); chrome->set_title(chrome_title);
chrome->set_icon(chrome_path.value(), 0); chrome->set_icon(chrome_path.value(), 0);
items.push_back(chrome); items.push_back(chrome);
}
// Create an IShellLink object which launches Chrome in incognito mode, and // Create an IShellLink object which launches Chrome in incognito mode, and
// add it to the collection. We use our application icon as the icon for // add it to the collection. We use our application icon as the icon for
// this item. // this item.
if (incognito_availability != IncognitoModePrefs::DISABLED) {
scoped_refptr<ShellLinkItem> incognito = CreateShellLink(); scoped_refptr<ShellLinkItem> incognito = CreateShellLink();
incognito->GetCommandLine()->AppendSwitch(switches::kIncognito); incognito->GetCommandLine()->AppendSwitch(switches::kIncognito);
base::string16 incognito_title = base::string16 incognito_title =
...@@ -111,6 +118,7 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) { ...@@ -111,6 +118,7 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) {
incognito->set_title(incognito_title); incognito->set_title(incognito_title);
incognito->set_icon(chrome_path.value(), 0); incognito->set_icon(chrome_path.value(), 0);
items.push_back(incognito); items.push_back(incognito);
}
return jumplist_updater->AddTasks(items); return jumplist_updater->AddTasks(items);
} }
...@@ -118,7 +126,8 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) { ...@@ -118,7 +126,8 @@ bool UpdateTaskCategory(JumpListUpdater* jumplist_updater) {
// Updates the application JumpList. // Updates the application JumpList.
bool UpdateJumpList(const wchar_t* app_id, bool UpdateJumpList(const wchar_t* app_id,
const ShellLinkItemList& most_visited_pages, const ShellLinkItemList& most_visited_pages,
const ShellLinkItemList& recently_closed_pages) { const ShellLinkItemList& recently_closed_pages,
IncognitoModePrefs::Availability incognito_availability) {
// JumpList is implemented only on Windows 7 or later. // JumpList is implemented only on Windows 7 or later.
// So, we should return now when this function is called on earlier versions // So, we should return now when this function is called on earlier versions
// of Windows. // of Windows.
...@@ -164,7 +173,7 @@ bool UpdateJumpList(const wchar_t* app_id, ...@@ -164,7 +173,7 @@ bool UpdateJumpList(const wchar_t* app_id,
} }
// Update the "Tasks" category of the JumpList. // Update the "Tasks" category of the JumpList.
if (!UpdateTaskCategory(&jumplist_updater)) if (!UpdateTaskCategory(&jumplist_updater, incognito_availability))
return false; return false;
// Commit this transaction and send the updated JumpList to Windows. // Commit this transaction and send the updated JumpList to Windows.
...@@ -176,37 +185,23 @@ bool UpdateJumpList(const wchar_t* app_id, ...@@ -176,37 +185,23 @@ bool UpdateJumpList(const wchar_t* app_id,
} // namespace } // namespace
JumpList::JumpList() JumpList::JumpList(Profile* profile)
: weak_ptr_factory_(this), : weak_ptr_factory_(this),
profile_(NULL), profile_(profile),
task_id_(base::CancelableTaskTracker::kBadTaskId) {} task_id_(base::CancelableTaskTracker::kBadTaskId) {
DCHECK(Enabled());
JumpList::~JumpList() {
Terminate();
}
// static
bool JumpList::Enabled() {
return JumpListUpdater::IsEnabled();
}
bool JumpList::AddObserver(Profile* profile) {
// To update JumpList when a tab is added or removed, we add this object to // To update JumpList when a tab is added or removed, we add this object to
// the observer list of the TabRestoreService class. // the observer list of the TabRestoreService class.
// When we add this object to the observer list, we save the pointer to this // When we add this object to the observer list, we save the pointer to this
// TabRestoreService object. This pointer is used when we remove this object // TabRestoreService object. This pointer is used when we remove this object
// from the observer list. // from the observer list.
if (!JumpListUpdater::IsEnabled() || !profile)
return false;
TabRestoreService* tab_restore_service = TabRestoreService* tab_restore_service =
TabRestoreServiceFactory::GetForProfile(profile); TabRestoreServiceFactory::GetForProfile(profile_);
if (!tab_restore_service) if (!tab_restore_service)
return false; return;
app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile->GetPath()); app_id_ = ShellIntegration::GetChromiumModelIdForProfile(profile_->GetPath());
icon_dir_ = profile->GetPath().Append(chrome::kJumpListIconDirname); icon_dir_ = profile_->GetPath().Append(chrome::kJumpListIconDirname);
profile_ = profile;
history::TopSites* top_sites = profile_->GetTopSites(); history::TopSites* top_sites = profile_->GetTopSites();
if (top_sites) { if (top_sites) {
// TopSites updates itself after a delay. This is especially noticable when // TopSites updates itself after a delay. This is especially noticable when
...@@ -224,7 +219,20 @@ bool JumpList::AddObserver(Profile* profile) { ...@@ -224,7 +219,20 @@ bool JumpList::AddObserver(Profile* profile) {
content::Source<Profile>(profile_)); content::Source<Profile>(profile_));
} }
tab_restore_service->AddObserver(this); tab_restore_service->AddObserver(this);
return true; pref_change_registrar_.reset(new PrefChangeRegistrar);
pref_change_registrar_->Init(profile_->GetPrefs());
pref_change_registrar_->Add(
prefs::kIncognitoModeAvailability,
base::Bind(&JumpList::OnIncognitoAvailabilityChanged, this));
}
JumpList::~JumpList() {
Terminate();
}
// static
bool JumpList::Enabled() {
return JumpListUpdater::IsEnabled();
} }
void JumpList::Observe(int type, void JumpList::Observe(int type,
...@@ -251,17 +259,6 @@ void JumpList::Observe(int type, ...@@ -251,17 +259,6 @@ void JumpList::Observe(int type,
} }
} }
void JumpList::RemoveObserver() {
if (profile_) {
TabRestoreService* tab_restore_service =
TabRestoreServiceFactory::GetForProfile(profile_);
if (tab_restore_service)
tab_restore_service->RemoveObserver(this);
registrar_.reset();
}
profile_ = NULL;
}
void JumpList::CancelPendingUpdate() { void JumpList::CancelPendingUpdate() {
if (task_id_ != base::CancelableTaskTracker::kBadTaskId) { if (task_id_ != base::CancelableTaskTracker::kBadTaskId) {
cancelable_task_tracker_.TryCancel(task_id_); cancelable_task_tracker_.TryCancel(task_id_);
...@@ -271,7 +268,15 @@ void JumpList::CancelPendingUpdate() { ...@@ -271,7 +268,15 @@ void JumpList::CancelPendingUpdate() {
void JumpList::Terminate() { void JumpList::Terminate() {
CancelPendingUpdate(); CancelPendingUpdate();
RemoveObserver(); if (profile_) {
TabRestoreService* tab_restore_service =
TabRestoreServiceFactory::GetForProfile(profile_);
if (tab_restore_service)
tab_restore_service->RemoveObserver(this);
registrar_.reset();
pref_change_registrar_.reset();
}
profile_ = NULL;
} }
void JumpList::OnMostVisitedURLsAvailable( void JumpList::OnMostVisitedURLsAvailable(
...@@ -379,20 +384,24 @@ void JumpList::AddWindow(const TabRestoreService::Window* window, ...@@ -379,20 +384,24 @@ void JumpList::AddWindow(const TabRestoreService::Window* window,
void JumpList::StartLoadingFavicon() { void JumpList::StartLoadingFavicon() {
GURL url; GURL url;
bool waiting_for_icons = true;
{ {
base::AutoLock auto_lock(list_lock_); base::AutoLock auto_lock(list_lock_);
if (icon_urls_.empty()) { waiting_for_icons = !icon_urls_.empty();
// No more favicons are needed by the application JumpList. Schedule a if (waiting_for_icons) {
// RunUpdate call.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&JumpList::RunUpdate, this));
return;
}
// Ask FaviconService if it has a favicon of a URL. // Ask FaviconService if it has a favicon of a URL.
// When FaviconService has one, it will call OnFaviconDataAvailable(). // When FaviconService has one, it will call OnFaviconDataAvailable().
url = GURL(icon_urls_.front().first); url = GURL(icon_urls_.front().first);
} }
}
if (!waiting_for_icons) {
// No more favicons are needed by the application JumpList. Schedule a
// RunUpdate call.
PostRunUpdate();
return;
}
FaviconService* favicon_service = FaviconService* favicon_service =
FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS); FaviconServiceFactory::GetForProfile(profile_, Profile::EXPLICIT_ACCESS);
task_id_ = favicon_service->GetFaviconImageForPageURL( task_id_ = favicon_service->GetFaviconImageForPageURL(
...@@ -423,7 +432,31 @@ void JumpList::OnFaviconDataAvailable( ...@@ -423,7 +432,31 @@ void JumpList::OnFaviconDataAvailable(
StartLoadingFavicon(); StartLoadingFavicon();
} }
void JumpList::RunUpdate() { void JumpList::OnIncognitoAvailabilityChanged() {
bool waiting_for_icons = true;
{
base::AutoLock auto_lock(list_lock_);
waiting_for_icons = !icon_urls_.empty();
}
if (!waiting_for_icons)
PostRunUpdate();
// If |icon_urls_| isn't empty then OnFaviconDataAvailable will eventually
// call PostRunUpdate().
}
void JumpList::PostRunUpdate() {
// Check if incognito windows (or normal windows) are disabled by policy.
IncognitoModePrefs::Availability incognito_availability =
profile_ ? IncognitoModePrefs::GetAvailability(profile_->GetPrefs())
: IncognitoModePrefs::ENABLED;
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&JumpList::RunUpdate, this, incognito_availability));
}
void JumpList::RunUpdate(
IncognitoModePrefs::Availability incognito_availability) {
ShellLinkItemList local_most_visited_pages; ShellLinkItemList local_most_visited_pages;
ShellLinkItemList local_recently_closed_pages; ShellLinkItemList local_recently_closed_pages;
...@@ -455,11 +488,11 @@ void JumpList::RunUpdate() { ...@@ -455,11 +488,11 @@ void JumpList::RunUpdate() {
// category. // category.
CreateIconFiles(local_recently_closed_pages); CreateIconFiles(local_recently_closed_pages);
// We finished collecting all resources needed for updating an appliation // We finished collecting all resources needed for updating an application
// JumpList. So, create a new JumpList and replace the current JumpList // JumpList. So, create a new JumpList and replace the current JumpList
// with it. // with it.
UpdateJumpList(app_id_.c_str(), local_most_visited_pages, UpdateJumpList(app_id_.c_str(), local_most_visited_pages,
local_recently_closed_pages); local_recently_closed_pages, incognito_availability);
} }
void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) { void JumpList::CreateIconFiles(const ShellLinkItemList& item_list) {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "chrome/browser/history/history_service.h" #include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_types.h" #include "chrome/browser/history/history_types.h"
#include "chrome/browser/jumplist_updater_win.h" #include "chrome/browser/jumplist_updater_win.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/sessions/tab_restore_service_observer.h" #include "chrome/browser/sessions/tab_restore_service_observer.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -29,20 +30,20 @@ namespace content { ...@@ -29,20 +30,20 @@ namespace content {
class NotificationRegistrar; class NotificationRegistrar;
} }
class Profile;
class PageUsageData; class PageUsageData;
class PrefChangeRegistrar;
class Profile;
// A class which implements an application JumpList. // A class which implements an application JumpList.
// This class encapsulates operations required for updating an application // This class encapsulates operations required for updating an application
// JumpList: // JumpList:
// * Retrieving "Most Visited" pages from HistoryService; // * Retrieving "Most Visited" pages from HistoryService;
// * Retrieving strings from the application resource; // * Retrieving strings from the application resource;
// * Creatng COM objects used by JumpList from PageUsageData objects; // * Creating COM objects used by JumpList from PageUsageData objects;
// * Adding COM objects to JumpList, etc. // * Adding COM objects to JumpList, etc.
// //
// This class also implements TabRestoreServiceObserver. So, once we call // This class observes the tabs and policies of the given Profile and updates
// AddObserver() and register this class as an observer, it automatically // the JumpList whenever a change is detected.
// updates a JumpList when a tab is added or removed.
// //
// Updating a JumpList requires some file operations and it is not good to // Updating a JumpList requires some file operations and it is not good to
// update it in a UI thread. To solve this problem, this class posts to a // update it in a UI thread. To solve this problem, this class posts to a
...@@ -55,19 +56,13 @@ class JumpList : public TabRestoreServiceObserver, ...@@ -55,19 +56,13 @@ class JumpList : public TabRestoreServiceObserver,
public base::RefCountedThreadSafe< public base::RefCountedThreadSafe<
JumpList, content::BrowserThread::DeleteOnUIThread> { JumpList, content::BrowserThread::DeleteOnUIThread> {
public: public:
JumpList(); explicit JumpList(Profile* profile);
// NotificationObserver implementation. // NotificationObserver implementation.
virtual void Observe(int type, virtual void Observe(int type,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details); const content::NotificationDetails& details);
// Registers (or unregisters) this object as an observer.
// When the TabRestoreService object notifies the tab status is changed, this
// class automatically updates an application JumpList.
bool AddObserver(Profile* profile);
void RemoveObserver();
// Observer callback for TabRestoreService::Observer to notify when a tab is // Observer callback for TabRestoreService::Observer to notify when a tab is
// added or removed. // added or removed.
virtual void TabRestoreServiceChanged(TabRestoreService* service); virtual void TabRestoreServiceChanged(TabRestoreService* service);
...@@ -79,16 +74,21 @@ class JumpList : public TabRestoreServiceObserver, ...@@ -79,16 +74,21 @@ class JumpList : public TabRestoreServiceObserver,
// Cancel a pending jumplist update. // Cancel a pending jumplist update.
void CancelPendingUpdate(); void CancelPendingUpdate();
// Terminate the jumplist: cancel any pending updates and remove observer // Terminate the jumplist: cancel any pending updates and stop observing
// from TabRestoreService. This must be called before the profile provided // the Profile and its services. This must be called before the |profile_|
// in the AddObserver method is destroyed. // is destroyed.
void Terminate(); void Terminate();
// Returns true if the custom JumpList is enabled. // Returns true if the custom JumpList is enabled.
// The custom jumplist works only on Windows 7 and above. // The custom jumplist works only on Windows 7 and above.
static bool Enabled(); static bool Enabled();
protected: private:
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<JumpList>;
virtual ~JumpList();
// Creates a ShellLinkItem object from a tab (or a window) and add it to the // Creates a ShellLinkItem object from a tab (or a window) and add it to the
// given list. // given list.
// These functions are copied from the RecentlyClosedTabsHandler class for // These functions are copied from the RecentlyClosedTabsHandler class for
...@@ -120,20 +120,20 @@ class JumpList : public TabRestoreServiceObserver, ...@@ -120,20 +120,20 @@ class JumpList : public TabRestoreServiceObserver,
void OnMostVisitedURLsAvailable( void OnMostVisitedURLsAvailable(
const history::MostVisitedURLList& data); const history::MostVisitedURLList& data);
// Callback for changes to the incognito mode availability pref.
void OnIncognitoAvailabilityChanged();
// Helper for RunUpdate() that determines its parameters.
void PostRunUpdate();
// Runnable method that updates the jumplist, once all the data // Runnable method that updates the jumplist, once all the data
// has been fetched. // has been fetched.
void RunUpdate(); void RunUpdate(IncognitoModePrefs::Availability incognito_availability);
// Helper method for RunUpdate to create icon files for the asynchrounously // Helper method for RunUpdate to create icon files for the asynchrounously
// loaded icons. // loaded icons.
void CreateIconFiles(const ShellLinkItemList& item_list); void CreateIconFiles(const ShellLinkItemList& item_list);
private:
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<JumpList>;
~JumpList();
// For callbacks may be run after destruction. // For callbacks may be run after destruction.
base::WeakPtrFactory<JumpList> weak_ptr_factory_; base::WeakPtrFactory<JumpList> weak_ptr_factory_;
...@@ -145,6 +145,7 @@ class JumpList : public TabRestoreServiceObserver, ...@@ -145,6 +145,7 @@ class JumpList : public TabRestoreServiceObserver,
// Lives on the UI thread. // Lives on the UI thread.
scoped_ptr<content::NotificationRegistrar> registrar_; scoped_ptr<content::NotificationRegistrar> registrar_;
scoped_ptr<PrefChangeRegistrar> pref_change_registrar_;
// App id to associate with the jump list. // App id to associate with the jump list.
std::wstring app_id_; std::wstring app_id_;
......
...@@ -2020,8 +2020,7 @@ void BrowserView::LoadingAnimationCallback() { ...@@ -2020,8 +2020,7 @@ void BrowserView::LoadingAnimationCallback() {
void BrowserView::OnLoadCompleted() { void BrowserView::OnLoadCompleted() {
#if defined(OS_WIN) #if defined(OS_WIN)
DCHECK(!jumplist_); DCHECK(!jumplist_);
jumplist_ = new JumpList(); jumplist_ = new JumpList(browser_->profile());
jumplist_->AddObserver(browser_->profile());
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment