Commit 4b1f3bce authored by changwan@chromium.org's avatar changwan@chromium.org

[Android] Fix smart clip callback to include URI and title

TEST=passed ContentViewTest
BUG=388961

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282219 0039d316-1c4b-4281-b951-d872f2087c98
parent d7943e32
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package org.chromium.chrome.browser; package org.chromium.chrome.browser;
import android.graphics.Rect; import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.MediumTest;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
...@@ -12,7 +15,6 @@ import org.chromium.base.test.util.Feature; ...@@ -12,7 +15,6 @@ import org.chromium.base.test.util.Feature;
import org.chromium.chrome.shell.ChromeShellActivity; import org.chromium.chrome.shell.ChromeShellActivity;
import org.chromium.chrome.shell.ChromeShellTestBase; import org.chromium.chrome.shell.ChromeShellTestBase;
import org.chromium.content.browser.ContentView; import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewCore;
import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content.browser.test.util.CallbackHelper;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
...@@ -20,16 +22,61 @@ import java.util.concurrent.TimeoutException; ...@@ -20,16 +22,61 @@ import java.util.concurrent.TimeoutException;
/** /**
* Tests for the ContentView. * Tests for the ContentView.
*/ */
public class ContentViewTest extends ChromeShellTestBase { public class ContentViewTest extends ChromeShellTestBase implements Handler.Callback {
private static class MyCallbackHelper extends CallbackHelper {
public String getTitle() {
return mTitle;
}
public String getUrl() {
return mUrl;
}
public void notifyCalled(String title, String url) {
mTitle = title;
mUrl = url;
super.notifyCalled();
}
private String mTitle;
private String mUrl;
}
private ChromeShellActivity mActivity; private ChromeShellActivity mActivity;
private CallbackHelper mCallbackHelper; private MyCallbackHelper mCallbackHelper;
private HandlerThread mHandlerThread;
private Handler mHandler;
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); super.setUp();
mActivity = launchChromeShellWithBlankPage(); mActivity = launchChromeShellWithBlankPage();
mCallbackHelper = new CallbackHelper(); mCallbackHelper = new MyCallbackHelper();
mHandlerThread = new HandlerThread("ContentViewTest thread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper(), this);
}
@Override
public void tearDown() throws Exception {
try {
mHandlerThread.quitSafely();
} finally {
super.tearDown();
}
}
// Implements Handler.Callback
@Override
public boolean handleMessage(Message msg) {
Bundle bundle = msg.getData();
assertNotNull(bundle);
String url = bundle.getString("url");
String title = bundle.getString("title");
// We don't care about other values for now.
mCallbackHelper.notifyCalled(title, url);
return true;
} }
@MediumTest @MediumTest
...@@ -40,15 +87,12 @@ public class ContentViewTest extends ChromeShellTestBase { ...@@ -40,15 +87,12 @@ public class ContentViewTest extends ChromeShellTestBase {
public void run() { public void run() {
ContentView cv = (ContentView) getActivity().getActiveTab().getView(); ContentView cv = (ContentView) getActivity().getActiveTab().getView();
assertNotNull(cv); assertNotNull(cv);
cv.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() { cv.setSmartClipResultHandler(mHandler);
public void onSmartClipDataExtracted(String result, Rect cliprect) { cv.extractSmartClipData(10, 20, 100, 70);
// We don't care about the returned values for now.
mCallbackHelper.notifyCalled();
}
});
cv.extractSmartClipData(10, 10, 100, 100);
} }
}); });
mCallbackHelper.waitForCallback(0, 1); // call count: 0 --> 1 mCallbackHelper.waitForCallback(0, 1); // call count: 0 --> 1
assertNotNull("about:blank", mCallbackHelper.getTitle());
assertNotNull("about:blank", mCallbackHelper.getUrl());
} }
} }
...@@ -62,6 +62,12 @@ ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle( ...@@ -62,6 +62,12 @@ ScopedJavaLocalRef<jstring> WebContentsAndroid::GetTitle(
web_contents_->GetTitle()); web_contents_->GetTitle());
} }
ScopedJavaLocalRef<jstring> WebContentsAndroid::GetVisibleURL(
JNIEnv* env, jobject obj) const {
return base::android::ConvertUTF8ToJavaString(
env, web_contents_->GetVisibleURL().spec());
}
void WebContentsAndroid::Stop(JNIEnv* env, jobject obj) { void WebContentsAndroid::Stop(JNIEnv* env, jobject obj) {
web_contents_->Stop(); web_contents_->Stop();
} }
......
...@@ -36,6 +36,8 @@ class CONTENT_EXPORT WebContentsAndroid ...@@ -36,6 +36,8 @@ class CONTENT_EXPORT WebContentsAndroid
// Methods called from Java // Methods called from Java
base::android::ScopedJavaLocalRef<jstring> GetTitle(JNIEnv* env, base::android::ScopedJavaLocalRef<jstring> GetTitle(JNIEnv* env,
jobject obj) const; jobject obj) const;
base::android::ScopedJavaLocalRef<jstring> GetVisibleURL(JNIEnv* env,
jobject obj) const;
void Stop(JNIEnv* env, jobject obj); void Stop(JNIEnv* env, jobject obj);
private: private:
......
...@@ -9,6 +9,10 @@ import android.content.res.Configuration; ...@@ -9,6 +9,10 @@ import android.content.res.Configuration;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
...@@ -25,7 +29,9 @@ import org.chromium.base.TraceEvent; ...@@ -25,7 +29,9 @@ import org.chromium.base.TraceEvent;
* exposes the various {@link View} functionality to it. * exposes the various {@link View} functionality to it.
*/ */
public class ContentView extends FrameLayout public class ContentView extends FrameLayout
implements ContentViewCore.InternalAccessDelegate { implements ContentViewCore.InternalAccessDelegate, SmartClipProvider {
private static final String TAG = "ContentView";
protected final ContentViewCore mContentViewCore; protected final ContentViewCore mContentViewCore;
...@@ -247,26 +253,35 @@ public class ContentView extends FrameLayout ...@@ -247,26 +253,35 @@ public class ContentView extends FrameLayout
mContentViewCore.onVisibilityChanged(changedView, visibility); mContentViewCore.onVisibilityChanged(changedView, visibility);
} }
/** // Implements SmartClipProvider
* Initiate extraction of text, HTML, and other information for clipping puposes (smart clip) @Override
* from the rectangle area defined by starting positions (x and y), and width height.
*
* NOTE: Some platforms may call this function to extract smart clip data.
* You should not remove it even when there is no caller in the code base.
*/
public void extractSmartClipData(int x, int y, int width, int height) { public void extractSmartClipData(int x, int y, int width, int height) {
mContentViewCore.extractSmartClipData(x, y, width, height); mContentViewCore.extractSmartClipData(x, y, width, height);
} }
/** // Implements SmartClipProvider
* Register a listener for smart clip data extraction. Once extraction is done, @Override
* the listener's onSmartClipDataExtracted callback will be called. public void setSmartClipResultHandler(final Handler resultHandler) {
* if (resultHandler == null) {
* NOTE: Some platforms may call this function to extract smart clip data. mContentViewCore.setSmartClipDataListener(null);
* You should not remove it even when there is no caller in the code base. return;
*/ }
public void setSmartClipDataListener(ContentViewCore.SmartClipDataListener listener) { mContentViewCore.setSmartClipDataListener(new ContentViewCore.SmartClipDataListener() {
mContentViewCore.setSmartClipDataListener(listener); public void onSmartClipDataExtracted(String text, Rect clipRect) {
Bundle bundle = new Bundle();
bundle.putString("url", mContentViewCore.getWebContents().getVisibleUrl());
bundle.putString("title", mContentViewCore.getWebContents().getTitle());
bundle.putParcelable("area", clipRect);
bundle.putString("text", text);
try {
Message msg = Message.obtain(resultHandler, 0);
msg.setData(bundle);
msg.sendToTarget();
} catch (Exception e) {
Log.e(TAG, "Error calling handler for smart clip data: ", e);
}
}
});
} }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
......
// 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.
package org.chromium.content.browser;
import android.os.Handler;
/**
* An interface to provide smart clip data when requested.
*
* NOTE: Some platforms may call these functions to extract smart clip data.
* Please make sure implementation of them is somewhere in the view
* hierarchy.
*/
public interface SmartClipProvider {
/**
* Initiate extraction of text, HTML, and other information for clipping puposes (smart clip)
* from the rectangle area defined by starting positions (x and y), and width and height.
*/
void extractSmartClipData(int x, int y, int width, int height);
/**
* Register a handler to handle smart clip data once extraction is done.
*/
void setSmartClipResultHandler(final Handler resultHandler);
}
...@@ -54,11 +54,17 @@ import org.chromium.content_public.browser.WebContents; ...@@ -54,11 +54,17 @@ import org.chromium.content_public.browser.WebContents;
return nativeGetTitle(mNativeWebContentsAndroid); return nativeGetTitle(mNativeWebContentsAndroid);
} }
@Override
public String getVisibleUrl() {
return nativeGetVisibleURL(mNativeWebContentsAndroid);
}
@Override @Override
public void stop() { public void stop() {
nativeStop(mNativeWebContentsAndroid); nativeStop(mNativeWebContentsAndroid);
} }
private native String nativeGetTitle(long nativeWebContentsAndroid); private native String nativeGetTitle(long nativeWebContentsAndroid);
private native String nativeGetVisibleURL(long nativeWebContentsAndroid);
private native void nativeStop(long nativeWebContentsAndroid); private native void nativeStop(long nativeWebContentsAndroid);
} }
...@@ -18,6 +18,11 @@ public interface WebContents { ...@@ -18,6 +18,11 @@ public interface WebContents {
*/ */
String getTitle(); String getTitle();
/**
* @return The URL for the current visible page.
*/
String getVisibleUrl();
/** /**
* Stop any pending navigation. * Stop any pending navigation.
*/ */
......
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