зеркало из https://github.com/mozilla/gecko-dev.git
Bug 839641 - Implement the PostDelayedTask callback for APZC in AndroidBridge. r=Cwiiis, blassey
This commit is contained in:
Родитель
084c16d781
Коммит
c4ff270851
|
@ -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)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче