@Override
  public void onPreviewFrame(byte[] data) {
    if (mGyroState == OFF) return;

    if (!this.mPrefHardwareGyroscope) {
      this.mVfGyroscope.NewData(data);
      if (mSurfacePreviewAugmented != null) {
        mSurfacePreviewAugmented.onDrawFrame();
      }
    }
  }
  private void updatehHardwareGyro() {
    if (mGyroState == OFF) return;

    if (mSurfacePreviewAugmented != null) {
      mSurfacePreviewAugmented.onDrawFrame();
    }
    handler.postDelayed(
        new Runnable() {
          @Override
          public void run() {
            updatehHardwareGyro();
          }
        },
        50);
  }
  private void initSensors() {
    if (mGyroState == ON) {
      if (mSensorManager == null) {
        mSensorManager =
            (SensorManager) ApplicationScreen.instance.getSystemService(Context.SENSOR_SERVICE);
      }
      if (mSensorManager == null) {
        return;
      }

      mSurfacePreviewAugmented.reset(this.pictureHeight, this.pictureWidth, this.viewAngleY);

      mAugmentedListener = new AugmentedRotationListener(remapOrientation, !mPrefHardwareGyroscope);

      if (this.mGyroscope != null) {
        if (mPrefHardwareGyroscope) {
          mSensorManager.registerListener(
              mAugmentedListener, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
          updatehHardwareGyro();
          handler.postDelayed(
              new Runnable() {
                @Override
                public void run() {
                  updatehHardwareGyro();
                }
              },
              500);
        }
      }

      if (!mPrefHardwareGyroscope) {
        if (mVfGyroscope == null) {
          mVfGyroscope = new VfGyroSensor(null);
        }
        mVfGyroscope.open();
        mVfGyroscope.SetListener(mAugmentedListener);
      }

      mSensorManager.registerListener(
          mAugmentedListener, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
      mSensorManager.registerListener(
          mAugmentedListener, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);

      mAugmentedListener.setReceiver(mSurfacePreviewAugmented);
    }
  }
  @Override
  public void onCameraParametersSetup() {
    this.checkCoordinatesRemapRequired();

    this.pictureWidth = CameraController.getCameraImageSize().getWidth();
    this.pictureHeight = CameraController.getCameraImageSize().getHeight();

    this.previewWidth = ApplicationScreen.getPreviewWidth();
    this.previewHeight = ApplicationScreen.getPreviewHeight();

    try {
      this.viewAngleX = CameraController.getHorizontalViewAngle();
      this.viewAngleY = CameraController.getVerticalViewAngle();
    } catch (final Exception e) {
      // Some bugged camera drivers pop ridiculous exception here, use
      // typical view angles then
      this.viewAngleX = 55.4f;
      this.viewAngleY = 42.7f;
    }

    // some devices report incorrect FOV values, use typical view angles
    // then
    if (this.viewAngleX >= 150) {
      this.viewAngleX = 55.4f;
      this.viewAngleY = 42.7f;
    }

    // Some cameras report incorrect view angles
    // Usually vertical view angle is incorrect, but eg Htc One report
    // incorrect horizontal view angle
    // If aspect ratio from FOV differs by more than 10% from aspect ratio
    // from W/H
    // - re-compute view angle
    float HorizontalViewFromAspect =
        2
            * 180
            * (float)
                Math.atan(
                    (float) this.pictureWidth
                        / (float) this.pictureHeight
                        * (float) Math.tan((float) Math.PI * this.viewAngleY / (2 * 180)))
            / (float) Math.PI;
    float VerticalViewFromAspect =
        2
            * 180
            * (float)
                Math.atan(
                    (float) this.pictureHeight
                        / (float) this.pictureWidth
                        * (float) Math.tan((float) Math.PI * this.viewAngleX / (2 * 180)))
            / (float) Math.PI;
    // not expecting very narrow field of view
    if ((VerticalViewFromAspect > 40.f) && (VerticalViewFromAspect < 0.9f * this.viewAngleY))
      this.viewAngleY = VerticalViewFromAspect;
    else if ((HorizontalViewFromAspect < 0.9f * this.viewAngleX)
        || (HorizontalViewFromAspect > 1.1f * this.viewAngleX))
      this.viewAngleX = HorizontalViewFromAspect;

    mSurfacePreviewAugmented.reset(this.pictureHeight, this.pictureWidth, this.viewAngleY);

    if (!mPrefHardwareGyroscope) {
      mVfGyroscope.SetFrameParameters(
          this.previewWidth, this.previewHeight, this.viewAngleX, this.viewAngleY);
    }
  }