Index: chrome/browser/banners/app_banner_manager.h |
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h |
index 20969abb1a74ed8bbec2558d8442e49f45c71a7d..a022de1774ab735e8fe358a35264dba0630a0464 100644 |
--- a/chrome/browser/banners/app_banner_manager.h |
+++ b/chrome/browser/banners/app_banner_manager.h |
@@ -8,105 +8,263 @@ |
#include <memory> |
#include <vector> |
+#include "base/callback_forward.h" |
#include "base/macros.h" |
-#include "base/memory/ref_counted.h" |
#include "base/memory/weak_ptr.h" |
-#include "chrome/browser/banners/app_banner_data_fetcher.h" |
#include "chrome/browser/engagement/site_engagement_observer.h" |
+#include "chrome/browser/installable/installable_logging.h" |
+#include "chrome/browser/installable/installable_manager.h" |
#include "content/public/browser/web_contents_observer.h" |
#include "third_party/WebKit/public/platform/modules/app_banner/WebAppBannerPromptReply.h" |
+class SkBitmap; |
+struct WebApplicationInfo; |
+ |
+namespace content { |
+class RenderFrameHost; |
+class WebContents; |
+} |
+ |
+// This forward declaration exists solely for the DidFinishCreatingBookmarkApp |
+// callback, implemented and called on desktop platforms only. |
+namespace extensions { |
+class Extension; |
+} |
+ |
namespace banners { |
-class AppBannerDataFetcher; |
- |
-/** |
- * Creates an app banner. |
- * |
- * Hooks the wiring together for getting the data for a particular app. |
- * Monitors at most one app at a time, tracking the info for the most recently |
- * requested app. Any work in progress for other apps is discarded. |
- */ |
+ |
+// Coordinates the creation of an app banner, from detecting eligibility to |
+// fetching data and creating the infobar. Sites declare that they want an app |
+// banner using the web app manifest. One web/native app may occupy the pipeline |
+// at a time; navigation resets the manager and discards any work in progress. |
+// |
+// This class contains the generic functionality shared between all platforms, |
+// as well as no-op callbacks that the platform-specific implementations pass to |
+// base::Bind. This allows a WeakPtrFactory to be housed in this class. |
+// |
+// The InstallableManager fetches and validate a site's eligibility for banners. |
+// The manager is first called to fetch the manifest, so we can verify whether |
+// the site is already installed (and on Android, divert the flow to a |
+// native app banner if requested). The second call completes the checking for a |
+// web app banner (checking manifest validity, service worker, and icon). |
class AppBannerManager : public content::WebContentsObserver, |
- public AppBannerDataFetcher::Delegate, |
public SiteEngagementObserver { |
public: |
static void DisableSecureSchemeCheckForTesting(); |
+ // Returns the current time. |
+ static base::Time GetCurrentTime(); |
+ |
+ // Fast-forwards the current time for testing. |
+ static void SetTimeDeltaForTesting(int days); |
+ |
+ // Sets the weights applied to direct and indirect navigations for triggering |
+ // the banner. Deprecated and will be removed when app banners fully migrates |
+ // to using site engagement as a trigger. |
static void SetEngagementWeights(double direct_engagement, |
double indirect_engagement); |
// Returns whether or not the URLs match for everything except for the ref. |
static bool URLsAreForTheSamePage(const GURL& first, const GURL& second); |
- // Requests an app banner. Set |is_debug_mode| when it is triggered by the |
- // developer's action in DevTools. |
+ // Requests an app banner. If |is_debug_mode| is true, any failure in the |
+ // pipeline will be reported to the devtools console. |
virtual void RequestAppBanner(const GURL& validated_url, bool is_debug_mode); |
- ~AppBannerManager() override; |
+ // Overridden and passed through base::Bind on desktop platforms. Called when |
+ // the bookmark app install initiated by a banner has completed. Not used on |
+ // Android. |
+ virtual void DidFinishCreatingBookmarkApp( |
+ const extensions::Extension* extension, |
+ const WebApplicationInfo& web_app_info) { } |
+ |
+ // Overridden and passed through base::Bind on Android. Called when the |
+ // download of a native app's icon is complete, as native banners use an icon |
+ // provided from the Play Store rather than the web manifest. Not used on |
+ // desktop platforms. |
+ virtual void OnAppIconFetched(const SkBitmap& bitmap) { } |
+ |
+ // Overridden and passed through base::Bind on Android. Called after a web app |
+ // banner was successfully used to add a web app to homescreen to kick off an |
+ // asynchronous fetch of a splash screen icon. Not used on desktop platforms. |
+ virtual base::Closure FetchWebappSplashScreenImageCallback( |
+ const std::string& webapp_id); |
protected: |
explicit AppBannerManager(content::WebContents* web_contents); |
+ ~AppBannerManager() override; |
- void ReplaceWebContents(content::WebContents* web_contents); |
+ // Return a string identifying this app for metrics. |
+ virtual std::string GetAppIdentifier(); |
- // Creates an AppBannerDataFetcher, which constructs an app banner. |
- virtual AppBannerDataFetcher* CreateAppBannerDataFetcher( |
- base::WeakPtr<AppBannerDataFetcher::Delegate> weak_delegate, |
- bool is_debug_mode) = 0; |
+ // Return a string describing what type of banner is being created. Used when |
+ // alerting websites that a banner is about to be created. |
+ virtual std::string GetBannerType(); |
- // Return whether the AppBannerDataFetcher is active. |
- bool IsFetcherActive(); |
+ // Returns a string parameter for a devtools console message corresponding to |
+ // |code|. Returns the empty string if |code| requires no parameter. |
+ std::string GetErrorParam(InstallableErrorCode code); |
- scoped_refptr<AppBannerDataFetcher> data_fetcher() { return data_fetcher_; } |
+ // Returns the ideal and minimum icon sizes required for being installable. |
+ virtual int GetIdealIconSizeInDp(); |
+ virtual int GetMinimumIconSizeInDp(); |
- private: |
- // WebContentsObserver overrides. |
- void DidStartNavigation( |
- content::NavigationHandle* navigation_handle) override; |
- void DidFinishNavigation( |
- content::NavigationHandle* navigation_handle) override; |
+ // Returns a WeakPtr to this object. Exposed so subclasses/infobars may |
+ // may bind callbacks without needing their own WeakPtrFactory. |
+ base::WeakPtr<AppBannerManager> GetWeakPtr(); |
+ |
+ // Returns true if |is_debug_mode_| is true or the |
+ // kBypassAppBannerEngagementChecks flag is set. |
+ bool IsDebugMode() const; |
+ |
+ // Returns true if the webapp at |start_url| has already been installed. |
+ virtual bool IsWebAppInstalled(content::BrowserContext* browser_context, |
+ const GURL& start_url); |
+ |
+ // Callback invoked by the InstallableManager once it has fetched the page's |
+ // manifest. |
+ void OnDidGetManifest(const InstallableData& result); |
+ |
+ // Run at the conclusion of OnDidGetManifest. For web app banners, this calls |
+ // back to the InstallableManager to continue checking criteria. For native |
+ // app banners, this checks whether native apps are preferred in the manifest, |
+ // and calls to Java to verify native app details. If a native banner isn't or |
+ // can't be requested, it continues with the web app banner checks. |
+ virtual void PerformInstallableCheck(); |
+ |
+ // Callback invoked by the InstallableManager once it has finished checking |
+ // all other installable properties. |
+ void OnDidPerformInstallableCheck(const InstallableData& result); |
+ |
+ // Records that a banner was shown. The |event_name| corresponds to the RAPPOR |
+ // metric being recorded. |
+ void RecordDidShowBanner(const std::string& event_name); |
+ |
+ // Logs an error message corresponding to |code| to the devtools console |
+ // attached to |web_contents|. Does nothing if IsDebugMode() returns false. |
+ void ReportError(content::WebContents* web_contents, |
+ InstallableErrorCode code); |
+ |
+ // Stops the banner pipeline. Any callback currently running will terminate |
+ // the next time they check |is_active_|. |
+ virtual void Stop(); |
+ |
+ // Sends a message to the renderer that the page has met the requirements to |
+ // show a banner. The page can respond to cancel the banner (and possibly |
+ // display it later), or otherwise allow it to be shown. This is virtual to |
+ // allow tests to mock out the renderer IPC. |
+ virtual void SendBannerPromptRequest(); |
+ |
+ // content::WebContentsObserver overrides. |
+ void DidStartNavigation(content::NavigationHandle* handle) override; |
+ void DidFinishNavigation(content::NavigationHandle* handle) override; |
void DidFinishLoad(content::RenderFrameHost* render_frame_host, |
const GURL& validated_url) override; |
void MediaStartedPlaying(const MediaPlayerId& id) override; |
void MediaStoppedPlaying(const MediaPlayerId& id) override; |
- |
- // AppBannerDataFetcher::Delegate overrides. |
- bool HandleNonWebApp(const std::string& platform, |
- const GURL& url, |
- const std::string& id, |
- bool is_debug_mode) override; |
+ void WebContentsDestroyed() override; |
// SiteEngagementObserver overrides. |
void OnEngagementIncreased(content::WebContents* web_contents, |
const GURL& url, |
double score) override; |
- // Cancels an active DataFetcher, stopping its banners from appearing. |
- void CancelActiveFetcher(); |
+ // Subclass accessors for private fields which should not be changed outside |
+ // this class. |
+ InstallableManager* manager() const { return manager_; } |
+ int event_request_id() const { return event_request_id_; } |
+ bool is_active() const { return is_active_; } |
+ |
+ // The title to display in the banner. |
+ base::string16 app_title_; |
+ |
+ // The URL for which the banner check is being conducted. |
+ GURL validated_url_; |
+ |
+ // The URL of the manifest. |
+ GURL manifest_url_; |
+ |
+ // The manifest object. |
+ content::Manifest manifest_; |
+ |
+ // The URL of the icon. |
+ GURL icon_url_; |
+ |
+ // The icon object. |
+ std::unique_ptr<SkBitmap> icon_; |
+ |
+ // The referrer string (if any) specified in the app URL. Used only for native |
+ // app banners. |
+ std::string referrer_; |
+ |
+ private: |
+ friend class AppBannerManagerTest; |
+ |
+ // Record that the banner could be shown at this point, if the triggering |
+ // heuristic allowed. |
+ void RecordCouldShowBanner(); |
+ |
+ // Creates a banner for the app. Overridden by subclasses as the infobar is |
+ // platform-specific. |
+ virtual void ShowBanner() = 0; |
+ |
+ // Returns true if the banner should be shown. |
+ bool CheckIfShouldShowBanner(); |
+ |
+ bool OnMessageReceived(const IPC::Message& message, |
+ content::RenderFrameHost* render_frame_host) override; |
+ |
+ // Called after the manager sends a message to the renderer regarding its |
+ // intention to show a prompt. The renderer will send a message back with the |
+ // opportunity to cancel. |
+ void OnBannerPromptReply(content::RenderFrameHost* render_frame_host, |
+ int request_id, |
+ blink::WebAppBannerPromptReply reply, |
+ std::string referrer); |
+ |
+ // Called when the client has prevented a banner from being shown, and is |
+ // now requesting that it be shown later. |
+ void OnRequestShowAppBanner(content::RenderFrameHost* render_frame_host, |
+ int request_id); |
// The type of navigation made to the page |
ui::PageTransition last_transition_type_; |
// Fetches the data required to display a banner for the current page. |
- scoped_refptr<AppBannerDataFetcher> data_fetcher_; |
+ InstallableManager* manager_; |
+ |
+ // A monotonically increasing id to verify the response to the |
+ // beforeinstallprompt event from the renderer. |
+ int event_request_id_; |
// We do not want to trigger a banner when the manager is attached to |
// a WebContents that is playing video. Banners triggering on a site in the |
// background will appear when the tab is reactivated. |
std::vector<MediaPlayerId> active_media_players_; |
+ // Whether we are currently working on whether to show a banner. |
+ bool is_active_; |
+ |
// If a banner is requested before the page has finished loading, defer |
// triggering the pipeline until the load is complete. |
bool banner_request_queued_; |
bool load_finished_; |
- // A weak pointer is used as the lifetime of the ServiceWorkerContext is |
- // longer than the lifetime of this banner manager. The banner manager |
- // might be gone when calls sent to the ServiceWorkerContext are completed. |
+ // Record whether the page decides to defer showing the banner, and if it |
+ // requests for it to be shown later on. |
+ bool was_canceled_by_page_; |
+ bool page_requested_prompt_; |
+ |
+ // Whether we should be logging errors to the console for this request. |
+ bool is_debug_mode_; |
+ |
+ // The concrete subclasses of this class are expected to have their lifetimes |
+ // scoped to the WebContents which they are observing. This allows us to use |
+ // weak pointers for callbacks. |
base::WeakPtrFactory<AppBannerManager> weak_factory_; |
DISALLOW_COPY_AND_ASSIGN(AppBannerManager); |
-}; // class AppBannerManager |
+}; |
} // namespace banners |