123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef COMPONENTS_NTP_TILES_MOST_VISITED_SITES_H_
- #define COMPONENTS_NTP_TILES_MOST_VISITED_SITES_H_
- #include <stddef.h>
- #include <map>
- #include <memory>
- #include <set>
- #include <string>
- #include <vector>
- #include "base/callback_forward.h"
- #include "base/callback_list.h"
- #include "base/compiler_specific.h"
- #include "base/gtest_prod_util.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "base/observer_list_types.h"
- #include "base/scoped_observation.h"
- #include "components/history/core/browser/history_types.h"
- #include "components/history/core/browser/top_sites.h"
- #include "components/history/core/browser/top_sites_observer.h"
- #include "components/ntp_tiles/custom_links_manager.h"
- #include "components/ntp_tiles/ntp_tile.h"
- #include "components/ntp_tiles/popular_sites.h"
- #include "components/ntp_tiles/section_type.h"
- #include "components/ntp_tiles/tile_source.h"
- #include "components/webapps/common/constants.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- #include "url/gurl.h"
- namespace user_prefs {
- class PrefRegistrySyncable;
- }
- class PrefService;
- namespace ntp_tiles {
- class IconCacher;
- // Shim interface for SupervisedUserService.
- class MostVisitedSitesSupervisor {
- public:
- class Observer {
- public:
- virtual void OnBlockedSitesChanged() = 0;
- protected:
- ~Observer() {}
- };
- virtual ~MostVisitedSitesSupervisor() {}
- // Pass non-null to set observer, or null to remove observer.
- // If setting observer, there must not yet be an observer set.
- // If removing observer, there must already be one to remove.
- // Does not take ownership. Observer must outlive this object.
- virtual void SetObserver(Observer* new_observer) = 0;
- // If true, |url| should not be shown on the NTP.
- virtual bool IsBlocked(const GURL& url) = 0;
- // If true, be conservative about suggesting sites from outside sources.
- virtual bool IsChildProfile() = 0;
- };
- // Tracks the list of most visited sites.
- class MostVisitedSites : public history::TopSitesObserver,
- public MostVisitedSitesSupervisor::Observer {
- public:
- // The observer to be notified when the list of most visited sites changes.
- class Observer : public base::CheckedObserver {
- public:
- // |sections| must at least contain the PERSONALIZED section.
- virtual void OnURLsAvailable(
- const std::map<SectionType, NTPTilesVector>& sections) = 0;
- virtual void OnIconMadeAvailable(const GURL& site_url) = 0;
- };
- // This interface delegates the retrieval of the homepage to the
- // platform-specific implementation.
- class HomepageClient {
- public:
- using TitleCallback =
- base::OnceCallback<void(const absl::optional<std::u16string>& title)>;
- virtual ~HomepageClient() = default;
- virtual bool IsHomepageTileEnabled() const = 0;
- virtual GURL GetHomepageUrl() const = 0;
- virtual void QueryHomepageTitle(TitleCallback title_callback) = 0;
- };
- class ExploreSitesClient {
- public:
- virtual ~ExploreSitesClient() = default;
- virtual GURL GetExploreSitesUrl() const = 0;
- virtual std::u16string GetExploreSitesTitle() const = 0;
- };
- // Construct a MostVisitedSites instance.
- //
- // |prefs| and |suggestions| are required and may not be null. |top_sites|,
- // |popular_sites|, |custom_links|, |supervisor| and |homepage_client| are
- // optional and if null, the associated features will be disabled.
- MostVisitedSites(PrefService* prefs,
- scoped_refptr<history::TopSites> top_sites,
- std::unique_ptr<PopularSites> popular_sites,
- std::unique_ptr<CustomLinksManager> custom_links,
- std::unique_ptr<IconCacher> icon_cacher,
- std::unique_ptr<MostVisitedSitesSupervisor> supervisor,
- bool is_default_chrome_app_migrated);
- MostVisitedSites(const MostVisitedSites&) = delete;
- MostVisitedSites& operator=(const MostVisitedSites&) = delete;
- ~MostVisitedSites() override;
- // Returns true if this object was created with a non-null provider for the
- // given NTP tile source. That source may or may not actually provide tiles,
- // depending on its configuration and the priority of different sources.
- bool DoesSourceExist(TileSource source) const;
- // Returns the corresponding object passed at construction.
- history::TopSites* top_sites() { return top_sites_.get(); }
- PopularSites* popular_sites() { return popular_sites_.get(); }
- MostVisitedSitesSupervisor* supervisor() { return supervisor_.get(); }
- // Adds the observer and immediately fetches the current suggestions.
- // All observers will be notified when the suggestions are fetched.
- //
- // Note: only observers that require the same |max_num_sites| could observe
- // the same MostVisitedSites instance. Otherwise, a new Instance should be
- // created for the observer.
- //
- // Does not take ownership of |observer|, which must outlive this object and
- // must not be null. |max_num_sites| indicates the the maximum number of most
- // visited sites to return.
- void AddMostVisitedURLsObserver(Observer* observer, size_t max_num_sites);
- // Removes the observer.
- void RemoveMostVisitedURLsObserver(Observer* observer);
- // Sets the client that provides platform-specific homepage preferences.
- // When used to replace an existing client, the new client will first be
- // used during the construction of a new tile set.
- // |client| must not be null and outlive this object.
- void SetHomepageClient(std::unique_ptr<HomepageClient> client);
- // Sets the client that provides the Explore Sites tile. Can be null if no
- // such tile is desirable.
- void SetExploreSitesClient(std::unique_ptr<ExploreSitesClient> client);
- // Requests an asynchronous refresh of the suggestions. Notifies the observer
- // if the request resulted in the set of tiles changing.
- void Refresh();
- // Forces a rebuild of the current tiles.
- void RefreshTiles();
- // Initializes custom links, which "freezes" the current MV tiles and converts
- // them to custom links. Once custom links is initialized, MostVisitedSites
- // will return only custom links. If the Most Visited tiles have not been
- // loaded yet, does nothing. Custom links must be enabled.
- void InitializeCustomLinks();
- // Uninitializes custom links and reverts back to regular MV tiles. The
- // current custom links will be deleted. Custom links must be enabled.
- void UninitializeCustomLinks();
- // Returns true if custom links has been initialized and not disabled, false
- // otherwise.
- bool IsCustomLinksInitialized();
- // Enables or disables custom links, but does not (un)initialize them. Called
- // when the user switches between custom links and Most Visited sites on the
- // 1P Desktop NTP.
- void EnableCustomLinks(bool enable);
- // Returns whether custom links are enabled.
- bool IsCustomLinksEnabled() const;
- // Sets the visibility of the NTP tiles.
- void SetShortcutsVisible(bool visible);
- // Returns whether NTP tiles should be shown.
- bool IsShortcutsVisible() const;
- // Adds a custom link. If the number of current links is maxed, returns false
- // and does nothing. Will initialize custom links if they have not been
- // initialized yet, unless the action fails. Custom links must be enabled.
- bool AddCustomLink(const GURL& url, const std::u16string& title);
- // Updates the URL and/or title of the custom link specified by |url|. If
- // |url| does not exist or |new_url| already exists in the custom link list,
- // returns false and does nothing. Will initialize custom links if they have
- // not been initialized yet, unless the action fails. Custom links must be
- // enabled.
- bool UpdateCustomLink(const GURL& url,
- const GURL& new_url,
- const std::u16string& new_title);
- // Moves the custom link specified by |url| to the index |new_pos|. If |url|
- // does not exist, or |new_pos| is invalid, returns false and does nothing.
- // Will initialize custom links if they have not been initialized yet, unless
- // the action fails. Custom links must be enabled.
- bool ReorderCustomLink(const GURL& url, size_t new_pos);
- // Deletes the custom link with the specified |url|. If |url| does not exist
- // in the custom link list, returns false and does nothing. Will initialize
- // custom links if they have not been initialized yet, unless the action
- // fails. Custom links must be enabled.
- bool DeleteCustomLink(const GURL& url);
- // Restores the previous state of custom links before the last action that
- // modified them. If there was no action, does nothing. If this is undoing the
- // first action after initialization, uninitializes the links. Custom links
- // must be enabled.
- void UndoCustomLinkAction();
- size_t GetCustomLinkNum();
- void AddOrRemoveBlockedUrl(const GURL& url, bool add_url);
- void ClearBlockedUrls();
- // MostVisitedSitesSupervisor::Observer implementation.
- void OnBlockedSitesChanged() override;
- static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
- static void ResetProfilePrefs(PrefService* prefs);
- // Workhorse for SaveNewTilesAndNotify. Implemented as a separate static and
- // public method for ease of testing.
- static NTPTilesVector MergeTiles(NTPTilesVector personal_tiles,
- NTPTilesVector popular_tiles,
- absl::optional<NTPTile> explore_tile);
- // Verifies if NTPTile App was migrated to a WebApp.
- static bool WasNtpAppMigratedToWebApp(PrefService* prefs, GURL url);
- // Verifies if NTPTile App comes from a PreInstalledApp.
- static bool IsNtpTileFromPreinstalledApp(GURL url);
- private:
- FRIEND_TEST_ALL_PREFIXES(MostVisitedSitesTest,
- ShouldDeduplicateDomainWithNoWwwDomain);
- FRIEND_TEST_ALL_PREFIXES(MostVisitedSitesTest,
- ShouldDeduplicateDomainByRemovingMobilePrefixes);
- FRIEND_TEST_ALL_PREFIXES(MostVisitedSitesTest,
- ShouldDeduplicateDomainByReplacingMobilePrefixes);
- // This function tries to match the given |host| to a close fit in
- // |hosts_to_skip| by removing a prefix that is commonly used to redirect from
- // or to mobile pages (m.xyz.com --> xyz.com).
- // If this approach fails, the prefix is replaced by another prefix.
- // That way, true is returned for m.x.com if www.x.com is in |hosts_to_skip|.
- static bool IsHostOrMobilePageKnown(
- const std::set<std::string>& hosts_to_skip,
- const std::string& host);
- // Returns the maximum number of most visited sites to return. The return
- // value is |max_num_sites_| which is ntp_tiles::kMaxNumMostVisited for
- // Desktop, unless custom links are enabled in which case an additional tile
- // may be returned making up to ntp_tiles::kMaxNumCustomLinks custom links
- // including the "Add shortcut" button.
- size_t GetMaxNumSites() const;
- // Initialize the query to Top Sites.
- void InitiateTopSitesQuery();
- // Callback for when data is available from TopSites.
- void OnMostVisitedURLsAvailable(
- const history::MostVisitedURLList& visited_list);
- // Builds the current tileset based on available caches and notifies the
- // observer.
- void BuildCurrentTiles();
- // Creates tiles for all popular site sections. Uses |num_actual_tiles| and
- // |used_hosts| to restrict results for the PERSONALIZED section.
- std::map<SectionType, NTPTilesVector> CreatePopularSitesSections(
- const std::set<std::string>& used_hosts,
- size_t num_actual_tiles);
- // Creates tiles for |sites_vector|. The returned vector will neither contain
- // more than |num_max_tiles| nor include sites in |hosts_to_skip|.
- NTPTilesVector CreatePopularSitesTiles(
- const PopularSites::SitesVector& sites_vector,
- const std::set<std::string>& hosts_to_skip,
- size_t num_max_tiles);
- // Callback for when an update is reported by CustomLinksManager.
- void OnCustomLinksChanged();
- // Creates tiles for |links| up to |max_num_sites_|. |links| will never exceed
- // a certain maximum.
- void BuildCustomLinks(const std::vector<CustomLinksManager::Link>& links);
- // Initiates a query for the homepage tile if needed and calls
- // |SaveTilesAndNotify| in the end.
- void InitiateNotificationForNewTiles(NTPTilesVector new_tiles);
- // Takes the personal tiles and merges in popular tiles if appropriate. Calls
- // |SaveTilesAndNotify| at the end.
- void MergeMostVisitedTiles(NTPTilesVector personal_tiles);
- // Removes pre installed apps which turn invalid because of migration.
- NTPTilesVector RemoveInvalidPreinstallApps(NTPTilesVector new_tiles);
- // Saves the new tiles and notifies the observer if the tiles were actually
- // changed.
- void SaveTilesAndNotify(NTPTilesVector new_tiles,
- std::map<SectionType, NTPTilesVector> sections);
- void OnPopularSitesDownloaded(bool success);
- void OnIconMadeAvailable(const GURL& site_url);
- // Updates the already used hosts and the total tile count based on given new
- // tiles. Enforces that the required amount of tiles is not exceeded.
- void AddToHostsAndTotalCount(const NTPTilesVector& new_tiles,
- std::set<std::string>* hosts,
- size_t* total_tile_count) const;
- // Adds the homepage as first tile to |tiles| and returns them as new vector.
- // Drops existing tiles with the same host as the home page and tiles that
- // would exceed the maximum.
- NTPTilesVector InsertHomeTile(NTPTilesVector tiles,
- const std::u16string& title) const;
- // Creates a tile for the Explore Sites page, if enabled. The tile is added to
- // the front of the list.
- absl::optional<NTPTile> CreateExploreSitesTile();
- void OnHomepageTitleDetermined(NTPTilesVector tiles,
- const absl::optional<std::u16string>& title);
- // Returns true if there is a valid homepage that can be pinned as tile.
- bool ShouldAddHomeTile() const;
- // history::TopSitesObserver implementation.
- void TopSitesLoaded(history::TopSites* top_sites) override;
- void TopSitesChanged(history::TopSites* top_sites,
- ChangeReason change_reason) override;
- raw_ptr<PrefService> prefs_;
- scoped_refptr<history::TopSites> top_sites_;
- std::unique_ptr<PopularSites> const popular_sites_;
- std::unique_ptr<CustomLinksManager> const custom_links_;
- std::unique_ptr<IconCacher> const icon_cacher_;
- std::unique_ptr<MostVisitedSitesSupervisor> supervisor_;
- std::unique_ptr<HomepageClient> homepage_client_;
- std::unique_ptr<ExploreSitesClient> explore_sites_client_;
- bool is_default_chrome_app_migrated_;
- base::ObserverList<Observer> observers_;
- // The maximum number of most visited sites to return.
- // Do not use directly. Use GetMaxNumSites() instead.
- size_t max_num_sites_;
- // Number of actions after custom link initialization. Set to -1 and not
- // incremented if custom links was not initialized during this session.
- int custom_links_action_count_ = -1;
- bool is_custom_links_enabled_ = true;
- bool is_shortcuts_visible_ = true;
- base::ScopedObservation<history::TopSites, history::TopSitesObserver>
- top_sites_observation_{this};
- base::CallbackListSubscription custom_links_subscription_;
- // The main source of personal tiles - either TOP_SITES or CUSTOM_LINKS.
- TileSource mv_source_;
- // Current set of tiles. Optional so that the observer can be notified
- // whenever it changes, including possibily an initial change from
- // !current_tiles_.has_value() to current_tiles_->empty().
- absl::optional<NTPTilesVector> current_tiles_;
- // Whether has started observing data sources.
- bool is_observing_;
- // For callbacks may be run after destruction, used exclusively for TopSites
- // (since it's used to detect whether there's a query in flight).
- base::WeakPtrFactory<MostVisitedSites> top_sites_weak_ptr_factory_{this};
- };
- } // namespace ntp_tiles
- #endif // COMPONENTS_NTP_TILES_MOST_VISITED_SITES_H_
|