@Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    if (!onFilterTouchEventForSecurity(event)) return false;
    mLastMotionEvent = event;
    int action = event.getAction();

    double dx = event.getX() - mCenterX;
    double dy = mCenterY - event.getY();
    double radius = Math.sqrt(dx * dx + dy * dy);

    // Ignore the event if too far from the shutter button.
    if ((radius <= (mWheelRadius + mStrokeWidth)) && (radius > mShutterButtonRadius)) {
      double delta = Math.atan2(dy, dx);
      if (delta < 0) delta += Math.PI * 2;
      int index = getTouchIndicatorIndex(delta);
      // Check if the touch event is for zoom control.
      if ((mZoomControl != null) && (index == 0)) {
        mZoomControl.dispatchTouchEvent(event);
      }
      // Move over from one indicator to another.
      if ((index != mPressedIndex) || (action == MotionEvent.ACTION_DOWN)) {
        if (mPressedIndex != -1) {
          injectMotionEvent(mPressedIndex, event, MotionEvent.ACTION_CANCEL);
        } else {
          // Cancel the popup if it is different from the selected.
          if (getSelectedIndicatorIndex() != index) dismissSettingPopup();
        }
        if ((index != -1) && (action == MotionEvent.ACTION_MOVE)) {
          if (mCurrentLevel != 0) {
            injectMotionEvent(index, event, MotionEvent.ACTION_DOWN);
          }
        }
      }
      if ((index != -1) && (action != MotionEvent.ACTION_MOVE)) {
        getChildAt(index).dispatchTouchEvent(event);
      }
      // Do not highlight the CameraPicker or Settings icon if we
      // touch from the zoom control to one of them.
      if ((mCurrentLevel == 0) && (index != 0) && (action == MotionEvent.ACTION_MOVE)) {
        return true;
      }
      // Once the button is up, reset the press index.
      mPressedIndex = (action == MotionEvent.ACTION_UP) ? -1 : index;
      invalidate();
      return true;
    }
    // The event is not on any of the child.
    onTouchOutBound();
    return false;
  }
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    if (!onFilterTouchEventForSecurity(event)) return false;

    int action = event.getAction();

    double dx = event.getX() - mCenterX;
    double dy = mCenterY - event.getY();
    double radius = Math.sqrt(dx * dx + dy * dy);

    // Check if the event should be dispatched to the shutter button.
    if (radius <= mShutterButtonRadius) {
      if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
        mIndicatorControlWheel.onTouchOutBound();
      } else {
        return mZoomControlWheel.dispatchTouchEvent(event);
      }
      if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
        return mShutterButton.dispatchTouchEvent(event);
      }
      return false;
    }

    if (mShutterButton.isPressed()) {
      // Send cancel to the shutter button if it was pressed.
      event.setAction(MotionEvent.ACTION_CANCEL);
      mShutterButton.dispatchTouchEvent(event);
      return true;
    }

    if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
      return mIndicatorControlWheel.dispatchTouchEvent(event);
    } else {
      return mZoomControlWheel.dispatchTouchEvent(event);
    }
  }