Home | History | Annotate | Download | only in banners
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_MANAGER_H_
      6 #define CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_MANAGER_H_
      7 
      8 #include "base/android/jni_android.h"
      9 #include "base/android/jni_weak_ref.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "chrome/browser/android/meta_tag_observer.h"
     12 #include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
     13 
     14 namespace content {
     15 struct FrameNavigateParams;
     16 struct LoadCommittedDetails;
     17 }  // namespace content
     18 
     19 /**
     20  * Manages when an app banner is created or dismissed.
     21  *
     22  * Hooks the wiring together for getting the data for a particular app.
     23  * Monitors at most one package at a time, and tracks the info for the
     24  * most recent app that was requested.  Any work in progress for other apps is
     25  * discarded.
     26  *
     27  * The procedure for creating a banner spans multiple asynchronous calls across
     28  * the JNI boundary, as well as querying a Service to get info about the app.
     29  *
     30  * 0) A navigation of the main frame is triggered.  Upon completion of the load,
     31  *    the page is parsed for the correct meta tag.  If it doesn't exist, abort.
     32  *
     33  * 1) The AppBannerManager is alerted about the tag's contents, which should
     34  *    be the Play Store package name.  This is sent to the Java side
     35  *    AppBannerManager.
     36  *
     37  * 2) The AppBannerManager's ServiceDelegate is asynchronously queried about the
     38  *    package name.
     39  *
     40  * 3) At some point, the Java-side AppBannerManager is alerted of the completed
     41  *    query and is given back data about the requested package, which includes a
     42  *    URL for the app's icon.  This URL is sent to native code for retrieval.
     43  *
     44  * 4) The process of fetching the icon begins by invoking the BitmapFetcher,
     45  *    which works asynchonously.
     46  *
     47  * 5) Once the icon has been downloaded, the icon is sent to the Java-side
     48  *    AppBannerManager to (finally) create a AppBannerView, assuming that the
     49  *    app we retrieved the details for is still for the page that requested it.
     50  *
     51  * Because of the asynchronous nature of this pipeline, it's entirely possible
     52  * that a request to show a banner is interrupted by another request.  The
     53  * Java side manages what happens in these situations, which will usually result
     54  * in dropping the old banner request on the floor.
     55  */
     56 
     57 namespace banners {
     58 
     59 class AppBannerManager : public chrome::BitmapFetcherDelegate,
     60                          public MetaTagObserver {
     61  public:
     62   AppBannerManager(JNIEnv* env, jobject obj);
     63   virtual ~AppBannerManager();
     64 
     65   // Destroys the AppBannerManager.
     66   void Destroy(JNIEnv* env, jobject obj);
     67 
     68   // Blocks a banner for |package_name| from appearing on the domain for |url|.
     69   void BlockBanner(JNIEnv* env, jobject obj, jstring jurl, jstring jpackage);
     70 
     71   // Observes a new WebContents, if necessary.
     72   void ReplaceWebContents(JNIEnv* env,
     73                           jobject obj,
     74                           jobject jweb_contents);
     75 
     76   // Fetches the icon at the give URL.
     77   // Returns |false| if this couldn't be kicked off.
     78   bool FetchIcon(JNIEnv* env,
     79                  jobject obj,
     80                  jstring jimage_url);
     81 
     82   // WebContentsObserver overrides.
     83   virtual void DidNavigateMainFrame(
     84       const content::LoadCommittedDetails& details,
     85       const content::FrameNavigateParams& params) OVERRIDE;
     86 
     87   // BitmapFetcherDelegate overrides.
     88   virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) OVERRIDE;
     89 
     90  private:
     91   // Kicks off the process of showing a banner for the package designated by
     92   // |tag_content| on the page at the |expected_url|.
     93   virtual void HandleMetaTagContent(const std::string& tag_content,
     94                                     const GURL& expected_url) OVERRIDE;
     95 
     96   // Fetches the icon for an app.
     97   scoped_ptr<chrome::BitmapFetcher> fetcher_;
     98 
     99   // AppBannerManager on the Java side.
    100   JavaObjectWeakGlobalRef weak_java_banner_view_manager_;
    101 
    102   DISALLOW_COPY_AND_ASSIGN(AppBannerManager);
    103 };  // class AppBannerManager
    104 
    105 // Register native methods
    106 bool RegisterAppBannerManager(JNIEnv* env);
    107 
    108 }  // namespace banners
    109 
    110 #endif  // CHROME_BROWSER_ANDROID_BANNERS_APP_BANNER_MANAGER_H_
    111