/* Informs Gecko that the screen size has changed. */ private void sendResizeEventIfNecessary(boolean force) { DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); IntSize newScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); IntSize newWindowSize = new IntSize(mView.getWidth(), mView.getHeight()); boolean screenSizeChanged = !mScreenSize.equals(newScreenSize); boolean windowSizeChanged = !mWindowSize.equals(newWindowSize); if (!force && !screenSizeChanged && !windowSizeChanged) { return; } mScreenSize = newScreenSize; mWindowSize = newWindowSize; if (screenSizeChanged) { Log.d(LOGTAG, "Screen-size changed to " + mScreenSize); } if (windowSizeChanged) { Log.d(LOGTAG, "Window-size changed to " + mWindowSize); } GeckoEvent event = GeckoEvent.createSizeChangedEvent( mWindowSize.width, mWindowSize.height, mScreenSize.width, mScreenSize.height); GeckoAppShell.sendEventToGecko(event); GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Window:Resize", "")); }
/** Restore default search engines in Gecko and retrigger a search engine refresh. */ protected void restoreDefaultSearchEngines() { GeckoAppShell.sendEventToGecko( GeckoEvent.createBroadcastEvent("SearchEngines:RestoreDefaults", null)); // Send message to Gecko to get engines. SearchPreferenceCategory listens for the response. GeckoAppShell.sendEventToGecko( GeckoEvent.createBroadcastEvent("SearchEngines:GetVisible", null)); }
boolean scrollBy(PointF displacement) { if (!mOverridePanning) { return false; } if (!mOverrideScrollAck) { mOverrideScrollPending = true; mPendingDisplacement.x += displacement.x; mPendingDisplacement.y += displacement.y; return true; } JSONObject json = new JSONObject(); try { json.put("x", displacement.x); json.put("y", displacement.y); } catch (JSONException e) { Log.e(LOGTAG, "Error forming subwindow scroll message: ", e); } GeckoAppShell.sendEventToGecko( GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString())); mOverrideScrollAck = false; mOverrideScrollPending = false; // clear the |mPendingDisplacement| after serializing |displacement| to // JSON because they might be the same object mPendingDisplacement.x = 0; mPendingDisplacement.y = 0; return true; }
/** Implementation of LayerView.Listener */ public void compositionResumeRequested(int width, int height) { // Asking Gecko to resume the compositor takes too long (see // https://bugzilla.mozilla.org/show_bug.cgi?id=735230#c23), so we // resume the compositor directly. We still need to inform Gecko about // the compositor resuming, so that Gecko knows that it can now draw. if (mCompositorCreated) { GeckoAppShell.scheduleResumeComposition(width, height); GeckoAppShell.sendEventToGecko(GeckoEvent.createCompositorResumeEvent()); } }
@Override public void onRefresh() { final JSONObject response = new JSONObject(); try { response.put(JSON_KEY_PANEL_ID, panelId); response.put(JSON_KEY_VIEW_INDEX, viewIndex); } catch (JSONException e) { Log.e(LOGTAG, "Could not create refresh message", e); return; } final GeckoEvent event = GeckoEvent.createBroadcastEvent("HomePanels:RefreshView", response.toString()); GeckoAppShell.sendEventToGecko(event); }
private void adjustViewport() { ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics()); PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(mBufferSize); viewportMetrics.setViewportOffset(viewportOffset); viewportMetrics.setViewport(viewportMetrics.getClampedViewport()); GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(viewportMetrics)); if (mViewportSizeChanged) { mViewportSizeChanged = false; GeckoAppShell.viewSizeChanged(); } mLastViewportChangeTime = System.currentTimeMillis(); }
private void sendPointToGecko(String event, MotionEvent motionEvent) { String json; try { PointF point = new PointF(motionEvent.getX(), motionEvent.getY()); point = mTarget.convertViewPointToLayerPoint(point); if (point == null) { return; } json = PointUtils.toJSON(point).toString(); } catch (Exception e) { Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e); return; } GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json)); }
/* * Zooming */ @Override public boolean onScaleBegin(SimpleScaleGestureDetector detector) { if (mState == PanZoomState.ANIMATED_ZOOM) return false; if (!mTarget.getZoomConstraints().getAllowZoom()) return false; setState(PanZoomState.PINCHING); mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY()); cancelTouch(); GeckoAppShell.sendEventToGecko( GeckoEvent.createNativeGestureEvent( GeckoEvent.ACTION_MAGNIFY_START, mLastZoomFocus, getMetrics().zoomFactor)); return true; }
private void adjustViewport(DisplayPortMetrics displayPort) { ImmutableViewportMetrics metrics = getViewportMetrics(); ImmutableViewportMetrics clampedMetrics = metrics.clamp(); if (displayPort == null) { displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector()); } mDisplayPort = displayPort; mGeckoViewport = clampedMetrics; if (mRecordDrawTimes) { mDrawTimingQueue.add(displayPort); } GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort)); }
public void handleMessage(String event, JSONObject message) { if ("Viewport:UpdateAndDraw".equals(event)) { mUpdateViewportOnEndDraw = true; // Redraw everything. Rect rect = new Rect(0, 0, mBufferSize.width, mBufferSize.height); GeckoAppShell.sendEventToGecko(GeckoEvent.createDrawEvent(rect)); } else if ("Viewport:UpdateLater".equals(event)) { mUpdateViewportOnEndDraw = true; } else if ("Checkerboard:Toggle".equals(event)) { try { boolean showChecks = message.getBoolean("value"); LayerController controller = getLayerController(); controller.setCheckerboardShowChecks(showChecks); Log.i(LOGTAG, "Showing checks: " + showChecks); } catch (JSONException ex) { Log.e(LOGTAG, "Error decoding JSON", ex); } } }
@Override public void onScaleEnd(SimpleScaleGestureDetector detector) { if (mState == PanZoomState.ANIMATED_ZOOM) return; // switch back to the touching state startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime()); // Force a viewport synchronisation mTarget.setForceRedraw(); PointF point = new PointF(detector.getFocusX(), detector.getFocusY()); GeckoEvent event = GeckoEvent.createNativeGestureEvent( GeckoEvent.ACTION_MAGNIFY_END, point, getMetrics().zoomFactor); if (event == null) { return; } GeckoAppShell.sendEventToGecko(event); }
/* Informs Gecko that the screen size has changed. */ private void sendResizeEventIfNecessary(boolean force) { DisplayMetrics metrics = new DisplayMetrics(); GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); // Return immediately if the screen size hasn't changed or the viewport // size is zero (which indicates that the rendering surface hasn't been // allocated yet). boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width || metrics.heightPixels != mScreenSize.height); boolean viewportSizeValid = (getLayerController() != null && getLayerController().getViewportSize().isPositive()); if (!(force || (screenSizeChanged && viewportSizeValid))) { return; } mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); IntSize bufferSize; IntSize tileSize; // Round up depending on layer implementation to remove texture wastage if (!mHasDirectTexture) { // Round to the next multiple of the tile size bufferSize = new IntSize( ((mScreenSize.width + LayerController.MIN_BUFFER.width - 1) / TILE_SIZE.width + 1) * TILE_SIZE.width, ((mScreenSize.height + LayerController.MIN_BUFFER.height - 1) / TILE_SIZE.height + 1) * TILE_SIZE.height); tileSize = TILE_SIZE; } else { int maxSize = getLayerController().getView().getMaxTextureSize(); // XXX Integrate gralloc/tiling work to circumvent this if (mScreenSize.width > maxSize || mScreenSize.height > maxSize) throw new RuntimeException( "Screen size of " + mScreenSize + " larger than maximum texture size of " + maxSize); // Round to next power of two until we have NPOT texture support, respecting maximum texture // size bufferSize = new IntSize( Math.min( maxSize, IntSize.nextPowerOfTwo(mScreenSize.width + LayerController.MIN_BUFFER.width)), Math.min( maxSize, IntSize.nextPowerOfTwo(mScreenSize.height + LayerController.MIN_BUFFER.height))); tileSize = new IntSize(0, 0); } Log.i(LOGTAG, "Screen-size changed to " + mScreenSize); GeckoEvent event = GeckoEvent.createSizeChangedEvent( bufferSize.width, bufferSize.height, metrics.widthPixels, metrics.heightPixels, tileSize.width, tileSize.height); GeckoAppShell.sendEventToGecko(event); }
@Override public boolean onScale(SimpleScaleGestureDetector detector) { if (GeckoApp.mAppContext == null || GeckoApp.mAppContext.mDOMFullScreen) return false; if (mState != PanZoomState.PINCHING) return false; float prevSpan = detector.getPreviousSpan(); if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) { // let's eat this one to avoid setting the new zoom to infinity (bug 711453) return true; } float spanRatio = detector.getCurrentSpan() / prevSpan; /* * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom * factor toward 1.0. */ float resistance = Math.min(mX.getEdgeResistance(true), mY.getEdgeResistance(true)); if (spanRatio > 1.0f) spanRatio = 1.0f + (spanRatio - 1.0f) * resistance; else spanRatio = 1.0f - (1.0f - spanRatio) * resistance; synchronized (mTarget.getLock()) { float newZoomFactor = getMetrics().zoomFactor * spanRatio; float minZoomFactor = 0.0f; float maxZoomFactor = MAX_ZOOM; ZoomConstraints constraints = mTarget.getZoomConstraints(); if (constraints.getMinZoom() > 0) minZoomFactor = constraints.getMinZoom(); if (constraints.getMaxZoom() > 0) maxZoomFactor = constraints.getMaxZoom(); if (newZoomFactor < minZoomFactor) { // apply resistance when zooming past minZoomFactor, // such that it asymptotically reaches minZoomFactor / 2.0 // but never exceeds that final float rate = 0.5f; // controls how quickly we approach the limit float excessZoom = minZoomFactor - newZoomFactor; excessZoom = 1.0f - (float) Math.exp(-excessZoom * rate); newZoomFactor = minZoomFactor * (1.0f - excessZoom / 2.0f); } if (newZoomFactor > maxZoomFactor) { // apply resistance when zooming past maxZoomFactor, // such that it asymptotically reaches maxZoomFactor + 1.0 // but never exceeds that float excessZoom = newZoomFactor - maxZoomFactor; excessZoom = 1.0f - (float) Math.exp(-excessZoom); newZoomFactor = maxZoomFactor + excessZoom; } scrollBy(mLastZoomFocus.x - detector.getFocusX(), mLastZoomFocus.y - detector.getFocusY()); PointF focus = new PointF(detector.getFocusX(), detector.getFocusY()); scaleWithFocus(newZoomFactor, focus); } mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY()); GeckoEvent event = GeckoEvent.createNativeGestureEvent( GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor); GeckoAppShell.sendEventToGecko(event); return true; }
private void cancelTouch() { GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", ""); GeckoAppShell.sendEventToGecko(e); }