Commit 5cf2cf1c authored by benwells's avatar benwells Committed by Commit bot

Suppress native app install banner if the site has a manifest.

This is the first step on support 'add to homescreen' banners for sites
that have manifests.

BUG=452825

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

Cr-Commit-Position: refs/heads/master@{#313612}
parent b52e91e1
......@@ -6,6 +6,7 @@
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/android/banners/app_banner_metrics_ids.h"
......@@ -13,11 +14,15 @@
#include "chrome/browser/android/banners/app_banner_utilities.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/android/content_view_core.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/frame_navigate_params.h"
#include "content/public/common/manifest.h"
#include "jni/AppBannerManager_jni.h"
#include "net/base/load_flags.h"
#include "ui/gfx/android/java_bitmap.h"
......@@ -32,8 +37,7 @@ const char kBannerTag[] = "google-play-id";
namespace banners {
AppBannerManager::AppBannerManager(JNIEnv* env, jobject obj)
: MetaTagObserver(kBannerTag),
weak_java_banner_view_manager_(env, obj) {}
: weak_java_banner_view_manager_(env, obj) {}
AppBannerManager::~AppBannerManager() {
}
......@@ -73,6 +77,47 @@ void AppBannerManager::DidNavigateMainFrame(
Java_AppBannerManager_dismissCurrentBanner(env, jobj.obj(), DISMISS_NAVIGATE);
}
void AppBannerManager::DidFinishLoad(
content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
if (render_frame_host->GetParent())
return;
validated_url_ = validated_url;
// See if the page has a manifest. Using Unretained(this) here is safe as the
// lifetime of this object extends beyond the lifetime of the web_contents(),
// and when web_contents() is destroyed it will call OnDidGetManifest.
web_contents()->GetManifest(base::Bind(&AppBannerManager::OnDidGetManifest,
base::Unretained(this)));
}
void AppBannerManager::OnDidGetManifest(const content::Manifest& manifest) {
if (web_contents()->IsBeingDestroyed())
return;
if (manifest.IsEmpty()) {
// No manifest, see if there is a play store meta tag.
Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(),
validated_url_,
kBannerTag));
return;
}
// TODO(benwells): Check triggering parameters here and if there is a meta
// tag.
// TODO(dfalcantara): Show banner for web site with manifest.
}
bool AppBannerManager::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(AppBannerManager, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent,
OnDidRetrieveMetaTagContent)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
if (bitmap) {
JNIEnv* env = base::android::AttachCurrentThread();
......@@ -97,9 +142,17 @@ void AppBannerManager::OnFetchComplete(const GURL url, const SkBitmap* bitmap) {
fetcher_.reset();
}
void AppBannerManager::HandleMetaTagContent(const std::string& tag_content,
const GURL& expected_url) {
void AppBannerManager::OnDidRetrieveMetaTagContent(
bool success,
const std::string& tag_name,
const std::string& tag_content,
const GURL& expected_url) {
DCHECK(web_contents());
if (!success || tag_name != kBannerTag || validated_url_ != expected_url ||
tag_content.size() >= chrome::kMaxMetaTagAttributeLength) {
return;
}
banners::TrackDisplayEvent(DISPLAY_BANNER_REQUESTED);
if (!AppBannerSettingsHelper::IsAllowed(web_contents(),
......
......@@ -8,12 +8,13 @@
#include "base/android/jni_android.h"
#include "base/android/jni_weak_ref.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/android/meta_tag_observer.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
struct FrameNavigateParams;
struct LoadCommittedDetails;
struct Manifest;
} // namespace content
/**
......@@ -57,7 +58,7 @@ struct LoadCommittedDetails;
namespace banners {
class AppBannerManager : public chrome::BitmapFetcherDelegate,
public MetaTagObserver {
public content::WebContentsObserver {
public:
AppBannerManager(JNIEnv* env, jobject obj);
virtual ~AppBannerManager();
......@@ -83,18 +84,31 @@ class AppBannerManager : public chrome::BitmapFetcherDelegate,
virtual void DidNavigateMainFrame(
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) override;
virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
virtual bool OnMessageReceived(const IPC::Message& message) override;
// BitmapFetcherDelegate overrides.
virtual void OnFetchComplete(const GURL url, const SkBitmap* bitmap) override;
private:
// Kicks off the process of showing a banner for the package designated by
// |tag_content| on the page at the |expected_url|.
virtual void HandleMetaTagContent(const std::string& tag_content,
const GURL& expected_url) override;
// Called when the manifest has been retrieved, or if there is no manifest to
// retrieve.
void OnDidGetManifest(const content::Manifest& manifest);
// Called when the renderer has returned information about the meta tag.
// If there is some metadata for the play store tag, this kicks off the
// process of showing a banner for the package designated by |tag_content| on
// the page at the |expected_url|.
void OnDidRetrieveMetaTagContent(bool success,
const std::string& tag_name,
const std::string& tag_content,
const GURL& expected_url);
// Fetches the icon for an app.
scoped_ptr<chrome::BitmapFetcher> fetcher_;
GURL validated_url_;
// AppBannerManager on the Java side.
JavaObjectWeakGlobalRef weak_java_banner_view_manager_;
......
// Copyright 2014 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.
#include "chrome/browser/android/meta_tag_observer.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/render_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
MetaTagObserver::MetaTagObserver(const std::string& meta_tag)
: meta_tag_(meta_tag) {
if (meta_tag_.size() > chrome::kMaxMetaTagAttributeLength) {
VLOG(1) << "Length of the <meta> name attribute is too large.";
NOTREACHED();
}
}
MetaTagObserver::~MetaTagObserver() {
}
void MetaTagObserver::DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) {
if (render_frame_host->GetParent())
return;
validated_url_ = validated_url;
Send(new ChromeViewMsg_RetrieveMetaTagContent(routing_id(),
validated_url,
meta_tag_));
}
bool MetaTagObserver::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(MetaTagObserver, message)
IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DidRetrieveMetaTagContent,
OnDidRetrieveMetaTagContent)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void MetaTagObserver::OnDidRetrieveMetaTagContent(
bool success,
const std::string& tag_name,
const std::string& tag_content,
const GURL& expected_url) {
if (!success || tag_name != meta_tag_ || validated_url_ != expected_url ||
tag_content.size() >= chrome::kMaxMetaTagAttributeLength) {
return;
}
HandleMetaTagContent(tag_content, expected_url);
}
// Copyright 2014 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 CHROME_BROWSER_ANDROID_META_TAG_OBSERVER_H_
#define CHROME_BROWSER_ANDROID_META_TAG_OBSERVER_H_
#include "content/public/browser/web_contents_observer.h"
class GURL;
// Retrieves the content of a particular meta tag when a page has fully loaded.
// Subclasses must implement |HandleMetaTagContent|, which gets called after
// the DOM has been scanned for the tag.
class MetaTagObserver : public content::WebContentsObserver {
public:
explicit MetaTagObserver(const std::string& meta_tag);
virtual ~MetaTagObserver();
// content::WebContentsObserver overrides:
virtual void DidFinishLoad(content::RenderFrameHost* render_frame_host,
const GURL& validated_url) override;
virtual bool OnMessageReceived(const IPC::Message& message) override;
protected:
// Called when the meta tag's content has been retrieved successfully.
virtual void HandleMetaTagContent(const std::string& tag_content,
const GURL& expected_url) = 0;
private:
// Called when the renderer has returned information about the meta tag.
void OnDidRetrieveMetaTagContent(bool success,
const std::string& tag_name,
const std::string& tag_content,
const GURL& expected_url);
const std::string meta_tag_;
GURL validated_url_;
DISALLOW_COPY_AND_ASSIGN(MetaTagObserver);
};
#endif // CHROME_BROWSER_ANDROID_META_TAG_OBSERVER_H_
......@@ -98,8 +98,6 @@
'browser/android/logo_bridge.h',
'browser/android/logo_service.cc',
'browser/android/logo_service.h',
'browser/android/meta_tag_observer.cc',
'browser/android/meta_tag_observer.h',
'browser/android/new_tab_page_prefs.cc',
'browser/android/new_tab_page_prefs.h',
'browser/android/new_tab_page_url_handler.cc',
......
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