Add support for triggering Android intents based on content.


BUG=125390
TEST=Chrome on Android UI tests, not ready to be upstreamed yet.


Review URL: https://chromiumcodereview.appspot.com/10695124

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146105 0039d316-1c4b-4281-b951-d872f2087c98
parent 87df4c5d
......@@ -13,10 +13,12 @@
#include "content/public/browser/web_contents.h"
#include "jni/content_view_jni.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::GetClass;
using base::android::HasField;
using base::android::ScopedJavaLocalRef;
namespace {
jfieldID g_native_content_view;
......@@ -24,6 +26,14 @@ jfieldID g_native_content_view;
namespace content {
struct ContentViewImpl::JavaObject {
jweak obj;
ScopedJavaLocalRef<jobject> View(JNIEnv* env) {
return GetRealObject(env, obj);
}
};
// ----------------------------------------------------------------------------
// Implementation of static ContentView public interfaces
......@@ -45,9 +55,17 @@ ContentViewImpl::ContentViewImpl(JNIEnv* env, jobject obj,
tab_crashed_(false) {
DCHECK(web_contents) <<
"A ContentViewImpl should be created with a valid WebContents.";
InitJNI(env, obj);
}
ContentViewImpl::~ContentViewImpl() {
if (java_object_) {
JNIEnv* env = AttachCurrentThread();
env->DeleteWeakGlobalRef(java_object_->obj);
delete java_object_;
java_object_ = 0;
}
}
void ContentViewImpl::Destroy(JNIEnv* env, jobject obj) {
......@@ -60,6 +78,11 @@ void ContentViewImpl::Observe(int type,
// TODO(jrg)
}
void ContentViewImpl::InitJNI(JNIEnv* env, jobject obj) {
java_object_ = new JavaObject;
java_object_->obj = env->NewWeakGlobalRef(obj);
}
// ----------------------------------------------------------------------------
// Methods called from Java via JNI
// ----------------------------------------------------------------------------
......@@ -242,6 +265,15 @@ void ContentViewImpl::OnAcceleratedCompositingStateChange(
NOTIMPLEMENTED() << "not upstreamed yet";
}
void ContentViewImpl::StartContentIntent(const GURL& content_url) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> jcontent_url =
ConvertUTF8ToJavaString(env, content_url.spec());
Java_ContentView_startContentIntent(env,
java_object_->View(env).obj(),
jcontent_url.obj());
}
// --------------------------------------------------------------------------
// Methods called from Java via JNI
// --------------------------------------------------------------------------
......
......@@ -78,6 +78,7 @@ class ContentViewImpl : public ContentView,
void OnAcceleratedCompositingStateChange(RenderWidgetHostViewAndroid* rwhva,
bool activated,
bool force);
virtual void StartContentIntent(const GURL& content_url) OVERRIDE;
// --------------------------------------------------------------------------
// Methods called from native code
......@@ -107,8 +108,13 @@ class ContentViewImpl : public ContentView,
// Other private methods and data
// --------------------------------------------------------------------------
void InitJNI(JNIEnv* env, jobject obj);
void PostLoadUrl(const GURL& url);
struct JavaObject;
JavaObject* java_object_;
// Reference to the current WebContents used to determine how and what to
// display in the ContentView.
WebContents* web_contents_;
......
......@@ -916,6 +916,9 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse)
IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL)
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaNotification, OnMediaNotification)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
#endif
IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission,
OnRequestDesktopNotificationPermission)
IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Show,
......@@ -1791,6 +1794,13 @@ void RenderViewHostImpl::OnMediaNotification(int64 player_cookie,
}
}
#if defined(OS_ANDROID)
void RenderViewHostImpl::OnStartContentIntent(const GURL& content_url) {
if (GetView())
GetView()->StartContentIntent(content_url);
}
#endif
void RenderViewHostImpl::OnRequestDesktopNotificationPermission(
const GURL& source_origin, int callback_context) {
content::GetContentClient()->browser()->RequestDesktopNotificationPermission(
......
......@@ -550,6 +550,10 @@ class CONTENT_EXPORT RenderViewHostImpl
void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params);
#endif
#if defined(OS_ANDROID)
void OnStartContentIntent(const GURL& content_url);
#endif
private:
friend class TestRenderViewHost;
......
......@@ -275,6 +275,12 @@ bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
return false;
}
void RenderWidgetHostViewAndroid::StartContentIntent(
const GURL& content_url) {
if (content_view_)
content_view_->StartContentIntent(content_url);
}
gfx::GLSurfaceHandle RenderWidgetHostViewAndroid::GetCompositingSurface() {
// On Android, we cannot generate a window handle that can be passed to the
// GPU process through the native side. Instead, we send the surface handle
......
......@@ -101,6 +101,8 @@ class RenderWidgetHostViewAndroid : public RenderWidgetHostViewBase {
virtual bool LockMouse() OVERRIDE;
virtual void UnlockMouse() OVERRIDE;
virtual void StartContentIntent(const GURL& content_url) OVERRIDE;
void SetContentView(ContentViewImpl* content_view);
private:
......
......@@ -176,7 +176,10 @@ void TestRenderWidgetHostView::AcceleratedSurfaceSetTransportDIB(
#elif defined(OS_WIN) && !defined(USE_AURA)
void TestRenderWidgetHostView::WillWmDestroy() {
}
#endif
#if defined(OS_ANDROID)
void TestRenderWidgetHostView::StartContentIntent(const GURL&) {}
#endif
#if defined(OS_POSIX) || defined(USE_AURA)
......
......@@ -130,6 +130,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase {
int32 width,
int32 height,
TransportDIB::Handle transport_dib) OVERRIDE;
#elif defined(OS_ANDROID)
virtual void StartContentIntent(const GURL&) OVERRIDE;
#elif defined(OS_WIN) && !defined(USE_AURA)
virtual void WillWmDestroy() OVERRIDE;
#endif
......
......@@ -2092,6 +2092,12 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_SendSerializedHtmlData,
std::string /* data buffer */,
int32 /* complete status */)
#if defined(OS_ANDROID)
// Start an android intent with the given URI.
IPC_MESSAGE_ROUTED1(ViewHostMsg_StartContentIntent,
GURL /* content_url */)
#endif
// Notifies the browser of an event occurring in the media pipeline.
IPC_MESSAGE_CONTROL1(ViewHostMsg_MediaLogEvent,
media::MediaLogEvent /* event */)
......
......@@ -11,6 +11,7 @@ import android.view.View;
import android.webkit.DownloadListener;
import android.widget.FrameLayout;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.WeakContext;
import org.chromium.content.app.AppResource;
......@@ -548,6 +549,12 @@ public class ContentView extends FrameLayout {
return mZoomManager.getZoomControlsViewForTest();
}
@CalledByNative
private void startContentIntent(String contentUrl) {
getContentViewClient().onStartContentIntent(getContext(), contentUrl);
}
/**
* Initialize the ContentView native side.
* Should be called with a valid native WebContents.
......
......@@ -5,6 +5,7 @@
package org.chromium.content.browser;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.graphics.RectF;
......@@ -277,7 +278,7 @@ public class ContentViewClient {
/**
* Called when a new content intent is requested to be started.
*/
public void onStartContentIntent(ContentView chromeView, String contentUrl) {
public void onStartContentIntent(Context context, String contentUrl) {
Intent intent;
// Perform generic parsing of the URI to turn it into an Intent.
try {
......@@ -288,7 +289,7 @@ public class ContentViewClient {
}
try {
chromeView.getContext().startActivity(intent);
context.startActivity(intent);
} catch (ActivityNotFoundException ex) {
Log.w(TAG, "No application can handle " + contentUrl);
}
......
......@@ -7,6 +7,8 @@
#include <jni.h>
class GURL;
namespace content {
class WebContents;
......@@ -33,6 +35,12 @@ class ContentView {
WebContents* web_contents);
static ContentView* GetNativeContentView(JNIEnv* env, jobject obj);
// --------------------------------------------------------------------------
// Public methods that call to Java via JNI
// --------------------------------------------------------------------------
virtual void StartContentIntent(const GURL& content_url) = 0;
protected:
virtual ~ContentView() {};
};
......
......@@ -17,6 +17,7 @@
#endif
class BrowserAccessibilityManager;
class GURL;
namespace gfx {
class Rect;
......@@ -131,6 +132,10 @@ class CONTENT_EXPORT RenderWidgetHostView {
virtual gfx::NativeView BuildInputMethodsGtkMenu() = 0;
#endif // defined(TOOLKIT_GTK)
#if defined(OS_ANDROID)
virtual void StartContentIntent(const GURL& content_url) = 0;
#endif
// Subclasses should override this method to do what is appropriate to set
// the custom background for their platform.
virtual void SetBackground(const SkBitmap& background) = 0;
......
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