public void handleMessage(String event, JSONObject message) {
    try {
      if (MESSAGE_ZOOM_RECT.equals(event)) {
        float x = (float) message.getDouble("x");
        float y = (float) message.getDouble("y");
        final RectF zoomRect =
            new RectF(x, y, x + (float) message.getDouble("w"), y + (float) message.getDouble("h"));
        mTarget.post(
            new Runnable() {
              public void run() {
                animatedZoomTo(zoomRect);
              }
            });
      } else if (MESSAGE_ZOOM_PAGE.equals(event)) {
        ImmutableViewportMetrics metrics = getMetrics();
        RectF cssPageRect = metrics.getCssPageRect();

        RectF viewableRect = metrics.getCssViewport();
        float y = viewableRect.top;
        // attempt to keep zoom keep focused on the center of the viewport
        float newHeight = viewableRect.height() * cssPageRect.width() / viewableRect.width();
        float dh = viewableRect.height() - newHeight; // increase in the height
        final RectF r = new RectF(0.0f, y + dh / 2, cssPageRect.width(), y + dh / 2 + newHeight);
        mTarget.post(
            new Runnable() {
              public void run() {
                animatedZoomTo(r);
              }
            });
      }
    } catch (Exception e) {
      Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
    }
  }