protected boolean dispatchTouchEvent(MotionEvent event) {
   int x = (int) event.getX();
   int y = (int) event.getY();
   int action = event.getAction();
   if (mMotionTarget != null) {
     if (action == MotionEvent.ACTION_DOWN) {
       MotionEvent cancel = MotionEvent.obtain(event);
       cancel.setAction(MotionEvent.ACTION_CANCEL);
       dispatchTouchEvent(cancel, x, y, mMotionTarget, false);
       mMotionTarget = null;
     } else {
       dispatchTouchEvent(event, x, y, mMotionTarget, false);
       if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
         mMotionTarget = null;
       }
       return true;
     }
   }
   if (action == MotionEvent.ACTION_DOWN) {
     // in the reverse rendering order
     for (int i = getComponentCount() - 1; i >= 0; --i) {
       GLView component = getComponent(i);
       if (component.getVisibility() != GLView.VISIBLE) continue;
       if (dispatchTouchEvent(event, x, y, component, true)) {
         mMotionTarget = component;
         return true;
       }
     }
   }
   return onTouch(event);
 }
 private void removeOneComponent(GLView component) {
   if (mMotionTarget == component) {
     long now = SystemClock.uptimeMillis();
     MotionEvent cancelEvent = MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0);
     dispatchTouchEvent(cancelEvent);
     cancelEvent.recycle();
   }
   component.onDetachFromRoot();
   component.mParent = null;
 }
 protected boolean dispatchTouchEvent(
     MotionEvent event, int x, int y, GLView component, boolean checkBounds) {
   Rect rect = component.mBounds;
   int left = rect.left;
   int top = rect.top;
   if (!checkBounds || rect.contains(x, y)) {
     event.offsetLocation(-left, -top);
     if (component.dispatchTouchEvent(event)) {
       event.offsetLocation(left, top);
       return true;
     }
     event.offsetLocation(left, top);
   }
   return false;
 }