/* 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", ""));
  }
Example #2
0
  /** 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);
 }