Bug 839641 - Implement the PostDelayedTask callback for APZC in AndroidBridge. r=Cwiiis, blassey

This commit is contained in:
Kartikaya Gupta 2013-04-26 13:26:46 -04:00
Родитель 084c16d781
Коммит c4ff270851
8 изменённых файлов: 144 добавлений и 4 удалений

Просмотреть файл

@ -869,6 +869,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mView.post(action);
}
/** Implementation of PanZoomTarget */
@Override
public boolean postDelayed(Runnable action, long delayMillis) {
return mView.postDelayed(action, delayMillis);
}
/** Implementation of PanZoomTarget */
@Override
public Object getLock() {

Просмотреть файл

@ -20,10 +20,12 @@ import android.view.View;
class NativePanZoomController implements PanZoomController, GeckoEventListener {
private final PanZoomTarget mTarget;
private final EventDispatcher mDispatcher;
private final CallbackRunnable mCallbackRunnable;
NativePanZoomController(PanZoomTarget target, View view, EventDispatcher dispatcher) {
mTarget = target;
mDispatcher = dispatcher;
mCallbackRunnable = new CallbackRunnable();
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
init();
} else {
@ -74,6 +76,7 @@ class NativePanZoomController implements PanZoomController, GeckoEventListener {
private native void init();
private native void handleTouchEvent(GeckoEvent event);
private native void handleMotionEvent(GeckoEvent event);
private native long runDelayedCallback();
public native void destroy();
public native void notifyDefaultActionPrevented(boolean prevented);
@ -85,4 +88,19 @@ class NativePanZoomController implements PanZoomController, GeckoEventListener {
private void requestContentRepaint(float x, float y, float width, float height, float resolution) {
mTarget.forceRedraw(new DisplayPortMetrics(x, y, x + width, y + height, resolution));
}
/* Invoked from JNI */
private void postDelayedCallback(long delay) {
mTarget.postDelayed(mCallbackRunnable, delay);
}
class CallbackRunnable implements Runnable {
@Override
public void run() {
long nextDelay = runDelayedCallback();
if (nextDelay >= 0) {
mTarget.postDelayed(this, nextDelay);
}
}
}
}

Просмотреть файл

@ -22,6 +22,7 @@ public interface PanZoomTarget {
public void forceRedraw(DisplayPortMetrics displayPort);
public boolean post(Runnable action);
public boolean postDelayed(Runnable action, long delayMillis);
public Object getLock();
public PointF convertViewPointToLayerPoint(PointF viewPoint);
}

Просмотреть файл

@ -69,7 +69,7 @@ class Generator:
returnValue = ''
elif returnType == 'jobject':
returnValue = 'NULL'
elif returnType in ('jint', 'jfloat', 'jdouble'):
elif returnType in ('jint', 'jfloat', 'jdouble', 'jlong'):
returnValue = '0'
elif returnType == 'jboolean':
returnValue = 'false'

Просмотреть файл

@ -457,6 +457,25 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_handleMotionEvent(JNIEnv * ar
#ifdef JNI_STUBS
typedef jlong (*Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback_t)(JNIEnv *, jobject);
static Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback_t f_Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback;
extern "C" NS_EXPORT jlong JNICALL
Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback(JNIEnv * arg0, jobject arg1) {
if (!f_Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return 0;
}
return f_Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback(arg0, arg1);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback", &f_Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback);
#endif
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy_t)(JNIEnv *, jobject);
static Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy_t f_Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy;
extern "C" NS_EXPORT void JNICALL

Просмотреть файл

@ -229,6 +229,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
jclass nativePanZoomControllerClass = jEnv->FindClass("org/mozilla/gecko/gfx/NativePanZoomController");
jRequestContentRepaint = jEnv->GetMethodID(nativePanZoomControllerClass, "requestContentRepaint", "(FFFFF)V");
jPostDelayedCallback = jEnv->GetMethodID(nativePanZoomControllerClass, "postDelayedCallback", "(J)V");
jclass eglClass = jEnv->FindClass("com/google/android/gles_jni/EGLSurfaceImpl");
if (eglClass) {
@ -2771,7 +2772,58 @@ AndroidBridge::SendAsyncScrollDOMEvent(const gfx::Rect& aContentRect, const gfx:
}
void
AndroidBridge::PostDelayedTask(Task* task, int delay_ms)
AndroidBridge::PostDelayedTask(Task* aTask, int aDelayMs)
{
// FIXME implement this
JNIEnv* env = GetJNIForThread();
if (!env || !mNativePanZoomController) {
return;
}
// add the new task into the mDelayedTaskQueue, sorted with
// the earliest task first in the queue
DelayedTask* newTask = new DelayedTask(aTask, aDelayMs);
uint32_t i = 0;
while (i < mDelayedTaskQueue.Length()) {
if (newTask->IsEarlierThan(mDelayedTaskQueue[i])) {
mDelayedTaskQueue.InsertElementAt(i, newTask);
break;
}
i++;
}
if (i == mDelayedTaskQueue.Length()) {
// this new task will run after all the existing tasks in the queue
mDelayedTaskQueue.AppendElement(newTask);
}
if (i == 0) {
// if we're inserting it at the head of the queue, notify Java because
// we need to get a callback at an earlier time than the last scheduled
// callback
AutoLocalJNIFrame jniFrame(env, 0);
env->CallVoidMethod(mNativePanZoomController, jPostDelayedCallback, (int64_t)aDelayMs);
}
}
int64_t
AndroidBridge::RunDelayedTasks()
{
while (mDelayedTaskQueue.Length() > 0) {
DelayedTask* nextTask = mDelayedTaskQueue[0];
int64_t timeLeft = nextTask->MillisecondsToRunTime();
if (timeLeft > 0) {
// this task (and therefore all remaining tasks)
// have not yet reached their runtime. return the
// time left until we should be called again
return timeLeft;
}
// we have a delayed task to run. extract it from
// the wrapper and free the wrapper
mDelayedTaskQueue.RemoveElementAt(0);
Task* task = nextTask->GetTask();
delete nextTask;
task->Run();
}
return -1;
}

Просмотреть файл

@ -30,6 +30,7 @@
#include "mozilla/Likely.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/GeckoContentController.h"
#include "mozilla/TimeStamp.h"
// Some debug #defines
// #define DEBUG_ANDROID_EVENTS
@ -93,6 +94,32 @@ protected:
virtual ~nsFilePickerCallback() {}
};
class DelayedTask {
public:
DelayedTask(Task* aTask, int aDelayMs) {
mTask = aTask;
mRunTime = TimeStamp::Now() + TimeDuration::FromMilliseconds(aDelayMs);
}
bool IsEarlierThan(DelayedTask *aOther) {
return mRunTime < aOther->mRunTime;
}
int64_t MillisecondsToRunTime() {
TimeDuration timeLeft = mRunTime - TimeStamp::Now();
return (int64_t)timeLeft.ToMilliseconds();
}
Task* GetTask() {
return mTask;
}
private:
Task* mTask;
TimeStamp mRunTime;
};
class AndroidBridge : public mozilla::layers::GeckoContentController
{
public:
@ -528,6 +555,7 @@ protected:
jobject mGLControllerObj;
jmethodID jRequestContentRepaint;
jmethodID jPostDelayedCallback;
// some convinient types to have around
jclass jStringClass;
@ -552,6 +580,11 @@ protected:
private:
jobject mNativePanZoomController;
// This will always be accessed from one thread (the APZC "controller"
// thread, which is the Java UI thread), so we don't need to do locking
// to touch it
nsTArray<DelayedTask*> mDelayedTaskQueue;
public:
jobject SetNativePanZoomController(jobject obj);
// GeckoContentController methods
@ -560,7 +593,8 @@ public:
void HandleSingleTap(const nsIntPoint& aPoint) MOZ_OVERRIDE;
void HandleLongTap(const nsIntPoint& aPoint) MOZ_OVERRIDE;
void SendAsyncScrollDOMEvent(const gfx::Rect& aContentRect, const gfx::Size& aScrollableSize) MOZ_OVERRIDE;
void PostDelayedTask(Task* task, int delay_ms) MOZ_OVERRIDE;
void PostDelayedTask(Task* aTask, int aDelayMs) MOZ_OVERRIDE;
int64_t RunDelayedTasks();
};
class AutoJObject {

Просмотреть файл

@ -920,6 +920,16 @@ Java_org_mozilla_gecko_gfx_NativePanZoomController_handleMotionEvent(JNIEnv* env
// FIXME implement this
}
NS_EXPORT jlong JNICALL
Java_org_mozilla_gecko_gfx_NativePanZoomController_runDelayedCallback(JNIEnv* env, jobject instance)
{
if (!AndroidBridge::Bridge()) {
return -1;
}
return AndroidBridge::Bridge()->RunDelayedTasks();
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_gfx_NativePanZoomController_destroy(JNIEnv* env, jobject instance)
{