Skip to content

Commit

Permalink
Support for hotswapping
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrouget committed Sep 10, 2018
1 parent 776f74b commit 1aca998
Show file tree
Hide file tree
Showing 9 changed files with 509 additions and 10 deletions.
3 changes: 2 additions & 1 deletion app/build.gradle
Expand Up @@ -188,6 +188,7 @@ dependencies {
implementation 'com.android.support:design:27.1.1'
implementation 'com.google.vr:sdk-audio:1.160.0'
implementation "org.mozilla.components:telemetry:0.10"
implementation project(':servoview')
}

if (findProject(':wavesdk')) {
Expand Down Expand Up @@ -245,4 +246,4 @@ android.applicationVariants.all { variant ->
println("Build type: " + buildType)
println("Flavor: " + variant.flavorName)
println("Version code: " + variant.mergedFlavor.versionCode)
}
}
45 changes: 45 additions & 0 deletions app/src/common/shared/org/mozilla/servo/GeckoServoDisplay.java
@@ -0,0 +1,45 @@
package org.mozilla.servo;

import android.view.Surface;

import org.mozilla.gecko.gfx.GeckoDisplay;

public class GeckoServoDisplay {
private GeckoDisplay mGeckoDisplay;
private ServoSession mServoSession;
private boolean mServoInitialized = false;

public GeckoServoDisplay(GeckoDisplay aGeckoDisplay) {
mGeckoDisplay = aGeckoDisplay;
}

public GeckoServoDisplay(ServoSession aServoSession) {
mServoSession = aServoSession;
}

public void surfaceChanged(final Surface surface, final int width, final int height) {
if (isGecko()) {
mGeckoDisplay.surfaceChanged(surface, width, height);
} else {
if (mServoInitialized) {
return;
}
mServoInitialized = true;
mServoSession.onSurfaceReady(surface, width, height);
}
}

public void surfaceDestroyed() {
if (isGecko()) {
mGeckoDisplay.surfaceDestroyed();
}
}

public boolean isGecko() {
return mGeckoDisplay != null;
}

public GeckoDisplay gecko() {
return mGeckoDisplay;
}
}
173 changes: 173 additions & 0 deletions app/src/common/shared/org/mozilla/servo/ServoPanZoomController.java
@@ -0,0 +1,173 @@
package org.mozilla.servo;

import android.view.MotionEvent;
import android.graphics.Rect;
import android.util.Pair;
import android.view.InputDevice;

import java.util.ArrayList;

public final class ServoPanZoomController {

private static final int EVENT_SOURCE_SCROLL = 0;
private static final int EVENT_SOURCE_MOTION = 1;
private final Rect mTempRect = new Rect();
private boolean mAttached;
private float mPointerScrollFactor = 64.0f;
private long mLastDownTime;
private boolean mIsScrolling = false;
private final ServoSession mSession;

ServoPanZoomController(ServoSession session) {
mSession = session;
enableEventQueue();
setAttached(true); // FIXME
}

private ArrayList<Pair<Integer, MotionEvent>> mQueuedEvents;

private boolean handleMotionEvent(
int action, int actionIndex, long time, int metaState,
int pointerId[], float x[], float y[], float orientation[], float pressure[],
float toolMajor[], float toolMinor[]) {

if (action == MotionEvent.ACTION_UP) {
mSession.click((int)x[0], (int)y[0]);
}

return true;
}

private boolean handleScrollEvent(long _time, int _metaState, float x, float y, float hScroll, float vScroll) {
if (!mIsScrolling) {
mSession.scrollStart((int)hScroll, (int)vScroll, (int)x, (int)y);
} else {
mSession.scroll((int)hScroll, (int)vScroll, (int)x, (int)y);
}
mIsScrolling = true;
return true;
}

private boolean handleMotionEvent(MotionEvent event) {
if (!mAttached) {
mQueuedEvents.add(new Pair(EVENT_SOURCE_MOTION, event));
return false;
}

final int action = event.getActionMasked();
final int count = event.getPointerCount();

if (action == MotionEvent.ACTION_DOWN) {
mLastDownTime = event.getDownTime();
} else if (mLastDownTime != event.getDownTime()) {
return false;
}

final int[] pointerId = new int[count];
final float[] x = new float[count];
final float[] y = new float[count];
final float[] orientation = new float[count];
final float[] pressure = new float[count];
final float[] toolMajor = new float[count];
final float[] toolMinor = new float[count];

final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();

for (int i = 0; i < count; i++) {
pointerId[i] = event.getPointerId(i);
event.getPointerCoords(i, coords);
x[i] = coords.x;
y[i] = coords.y;
orientation[i] = coords.orientation;
pressure[i] = coords.pressure;
toolMajor[i] = coords.toolMajor;
toolMinor[i] = coords.toolMinor;
}

return handleMotionEvent(action, event.getActionIndex(), event.getEventTime(),
event.getMetaState(), pointerId, x, y, orientation, pressure,
toolMajor, toolMinor);
}

private boolean handleScrollEvent(MotionEvent event) {
if (!mAttached) {
mQueuedEvents.add(new Pair(EVENT_SOURCE_SCROLL, event));
return false;
}

final int count = event.getPointerCount();

if (count <= 0) {
return false;
}

final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
event.getPointerCoords(0, coords);

// Translate surface origin to client origin for scroll events.
mSession.getSurfaceBounds(mTempRect);
final float x = coords.x - mTempRect.left;
final float y = coords.y - mTempRect.top;

final float hScroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL) * mPointerScrollFactor;
final float vScroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL) * mPointerScrollFactor;

return handleScrollEvent(event.getEventTime(), event.getMetaState(), x, y,
hScroll, vScroll);
}

public boolean onTouchEvent(final MotionEvent event) {
return handleMotionEvent(event);
}

public boolean onMotionEvent(MotionEvent event) {
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_SCROLL) {
if (event.getDownTime() >= mLastDownTime) {
mLastDownTime = event.getDownTime();
} else if ((InputDevice.getDevice(event.getDeviceId()).getSources() &
InputDevice.SOURCE_TOUCHPAD) == InputDevice.SOURCE_TOUCHPAD) {
return false;
}
return handleScrollEvent(event);
} else {
return false;
}
}

private void enableEventQueue() {
if (mQueuedEvents != null) {
throw new IllegalStateException("Already have an event queue");
}
mQueuedEvents = new ArrayList();
}

private void flushEventQueue() {
if (mQueuedEvents == null) {
return;
}

ArrayList<Pair<Integer, MotionEvent>> events = mQueuedEvents;
mQueuedEvents = null;
for (Pair<Integer, MotionEvent> pair : events) {
switch (pair.first) {
case EVENT_SOURCE_MOTION:
handleMotionEvent(pair.second);
break;
case EVENT_SOURCE_SCROLL:
handleScrollEvent(pair.second);
break;
}
}
}

private void setAttached(final boolean attached) {
if (attached) {
mAttached = true;
flushEventQueue();
} else if (mAttached) {
mAttached = false;
enableEventQueue();
}
}
}

0 comments on commit 1aca998

Please sign in to comment.