@Override
  public boolean onTouchEvent(MotionEvent event) {

    Point point = new Point();
    point.x = (int) event.getX();
    point.y = (int) event.getY();

    int count = 0;
    for (PieSlice slice : slices) {
      Region r = new Region();
      r.setPath(slice.getPath(), slice.getRegion());
      if (r.contains(point.x, point.y) && event.getAction() == MotionEvent.ACTION_DOWN) {
        indexSelected = count;
      } else if (event.getAction() == MotionEvent.ACTION_UP) {
        if (r.contains(point.x, point.y) && listener != null) {
          if (indexSelected > -1) {
            listener.onClick(indexSelected);
          }
          indexSelected = -1;
        }
      }
      count++;
    }

    if (event.getAction() == MotionEvent.ACTION_DOWN
        || event.getAction() == MotionEvent.ACTION_UP) {
      postInvalidate();
    }

    return true;
  }
示例#2
0
 public void addPathAndClear() {
   Path path = new Path();
   int size = mPoints.size();
   FileUtil.printToFile("\n<<<<<<添加一个热区>>>>>", "hotarea.txt");
   for (int i = 0; i < size; i++) {
     Point p = mPoints.get(i);
     if (i == 0) {
       path.moveTo(p.x, p.y);
       FileUtil.printToFile(
           "p.moveTo(getGujia_width("
               + df.format((float) p.x / (float) mWidth)
               + "f), getGujia_height("
               + df.format((float) p.y / (float) mHeight)
               + "f));",
           "hotarea.txt");
     } else {
       path.lineTo(p.x, p.y);
       FileUtil.printToFile(
           "p.lineTo(getGujia_width("
               + df.format((float) p.x / (float) mWidth)
               + "f), getGujia_height("
               + df.format((float) p.y / (float) mHeight)
               + "f));",
           "hotarea.txt");
     }
   }
   path.close();
   m_paths.add(path);
   Region region = new Region();
   region.setPath(path, new Region(0, 0, mWidth, mHeight));
   m_regions.add(region);
   startAddPoint();
 }
 public void setBounds(Region bounds) {
   synchronized (mWindowManagerService.mWindowMap) {
     if (mBounds.equals(bounds)) {
       return;
     }
     mBounds.set(bounds);
     invalidate(mDirtyRect);
     if (DEBUG_VIEWPORT_WINDOW) {
       Slog.i(LOG_TAG, "ViewportWindow set bounds: " + bounds);
     }
   }
 }
 public boolean MinContains(int x, int y) {
   // 先进行矩形检测。
   if (rect.contains(x, y)) {
     return true;
   }
   return false;
 }
示例#5
0
 public boolean a(MotionEvent motionevent) {
   if (e == null) {
     return true;
   } else {
     return e.contains((int) motionevent.getX(), (int) motionevent.getY());
   }
 }
示例#6
0
  @Override
  public boolean gatherTransparentRegion(Region region) {
    if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
      return super.gatherTransparentRegion(region);
    }

    boolean opaque = true;
    if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
      // this view draws, remove it from the transparent region
      opaque = super.gatherTransparentRegion(region);
    } else if (region != null) {
      int w = getWidth();
      int h = getHeight();
      if (w > 0 && h > 0) {
        getLocationInWindow(mLocation);
        // otherwise, punch a hole in the whole hierarchy
        int l = mLocation[0];
        int t = mLocation[1];
        region.op(l, t, l + w, t + h, Region.Op.UNION);
      }
    }
    if (PixelFormat.formatHasAlpha(mRequestedFormat)) {
      opaque = false;
    }
    return opaque;
  }
 public void onWindowTransitionLocked(WindowState windowState, int transition) {
   if (DEBUG_WINDOW_TRANSITIONS) {
     Slog.i(
         LOG_TAG,
         "Window transition: "
             + AppTransition.appTransitionToString(transition)
             + " displayId: "
             + windowState.getDisplayId());
   }
   final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
   final int type = windowState.mAttrs.type;
   switch (transition) {
     case WindowManagerPolicy.TRANSIT_ENTER:
     case WindowManagerPolicy.TRANSIT_SHOW:
       {
         if (!magnifying) {
           break;
         }
         switch (type) {
           case WindowManager.LayoutParams.TYPE_APPLICATION:
           case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
           case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
           case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
           case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG:
           case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
           case WindowManager.LayoutParams.TYPE_PHONE:
           case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
           case WindowManager.LayoutParams.TYPE_TOAST:
           case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
           case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
           case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
           case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
           case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
           case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
           case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
           case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY:
             {
               Rect magnifiedRegionBounds = mTempRect2;
               mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds);
               Rect touchableRegionBounds = mTempRect1;
               windowState.getTouchableRegion(mTempRegion1);
               mTempRegion1.getBounds(touchableRegionBounds);
               if (!magnifiedRegionBounds.intersect(touchableRegionBounds)) {
                 try {
                   mCallbacks.onRectangleOnScreenRequested(
                       touchableRegionBounds.left,
                       touchableRegionBounds.top,
                       touchableRegionBounds.right,
                       touchableRegionBounds.bottom);
                 } catch (RemoteException re) {
                   /* ignore */
                 }
               }
             }
             break;
         }
         break;
       }
   }
 }
 public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
   if (shown) {
     mFullRedrawNeeded = true;
     mOldMagnifiedBounds.set(0, 0, 0, 0);
   }
   mWindow.setShown(shown, animate);
 }
  /**
   * Setups up the web view.
   *
   * @param context
   */
  protected void setup(Context context) {

    // On Touch Listener
    setOnLongClickListener(this);
    setOnTouchListener(this);

    // Webview setup
    getSettings().setJavaScriptEnabled(true);
    getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
    getSettings().setPluginState(WebSettings.PluginState.ON);
    // getSettings().setBuiltInZoomControls(true);

    // Webview client.
    setWebViewClient(
        new WebViewClient() {
          // This is how it is supposed to work, so I'll leave it in, but this doesn't get called on
          // pinch
          // So for now I have to use deprecated getScale method.
          @Override
          public void onScaleChanged(WebView view, float oldScale, float newScale) {
            super.onScaleChanged(view, oldScale, newScale);
            mCurrentScale = newScale;
          }
        });

    // Zoom out fully
    // getSettings().setLoadWithOverviewMode(true);
    // getSettings().setUseWideViewPort(true);

    // Javascript interfaces
    mTextSelectionJSInterface = new TextSelectionJavascriptInterface(context, this);
    addJavascriptInterface(mTextSelectionJSInterface, mTextSelectionJSInterface.getInterfaceName());

    // Create the selection handles
    createSelectionLayer(context);

    // Set to the empty region
    Region region = new Region();
    region.setEmpty();
    mLastSelectedRegion = region;

    // Load up the android asset file
    String filePath = "file:///android_asset/content.html";

    // Load the url
    this.loadUrl(filePath);
  }
  public void testGetTransparentRegion() {
    // opaque image
    Region r = mNinePatchDrawable.getTransparentRegion();
    assertNull(r);

    mNinePatchDrawable.setBounds(0, 0, 7, 7);
    r = mNinePatchDrawable.getTransparentRegion();
    assertNull(r);

    // translucent image
    mNinePatchDrawable = getNinePatchDrawable(R.drawable.ninepatch_1);
    r = mNinePatchDrawable.getTransparentRegion();
    assertNull(r);

    mNinePatchDrawable.setBounds(1, 1, 7, 7);
    r = mNinePatchDrawable.getTransparentRegion();
    assertNotNull(r);
    assertEquals(new Rect(1, 1, 7, 7), r.getBounds());
  }
 public static WindowStateInfo obtain(WindowState windowState) {
   WindowStateInfo info = sPool.acquire();
   if (info == null) {
     info = new WindowStateInfo();
   }
   info.mWindowState = windowState;
   windowState.getTouchableRegion(mTempRegion);
   mTempRegion.getBounds(info.mTouchableRegion);
   return info;
 }
      /** NOTE: This has to be called within a surface transaction. */
      public void drawIfNeeded() {
        synchronized (mWindowManagerService.mWindowMap) {
          if (!mInvalidated) {
            return;
          }
          mInvalidated = false;
          Canvas canvas = null;
          try {
            // Empty dirty rectangle means unspecified.
            if (mDirtyRect.isEmpty()) {
              mBounds.getBounds(mDirtyRect);
            }
            mDirtyRect.inset(-mHalfBorderWidth, -mHalfBorderWidth);
            canvas = mSurface.lockCanvas(mDirtyRect);
            if (DEBUG_VIEWPORT_WINDOW) {
              Slog.i(LOG_TAG, "Dirty rect: " + mDirtyRect);
            }
          } catch (IllegalArgumentException iae) {
            /* ignore */
          } catch (Surface.OutOfResourcesException oore) {
            /* ignore */
          }
          if (canvas == null) {
            return;
          }
          if (DEBUG_VIEWPORT_WINDOW) {
            Slog.i(LOG_TAG, "Bounds: " + mBounds);
          }
          canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
          mPaint.setAlpha(mAlpha);
          Path path = mBounds.getBoundaryPath();
          canvas.drawPath(path, mPaint);

          mSurface.unlockCanvasAndPost(canvas);

          if (mAlpha > 0) {
            mSurfaceControl.show();
          } else {
            mSurfaceControl.hide();
          }
        }
      }
 /** Sets the touchable region of this popup to be the area occupied by its content. */
 private void setContentAreaAsTouchableSurface() {
   if (!mPopupWindow.isShowing()) {
     mContentContainer.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
   }
   int width = mContentContainer.getMeasuredWidth();
   int height = mContentContainer.getMeasuredHeight();
   mTouchableRegion.set(
       (int) mContentContainer.getX(),
       (int) mContentContainer.getY(),
       (int) mContentContainer.getX() + width,
       (int) mContentContainer.getY() + height);
 }
示例#14
0
 public void a(Path path) {
   d = path;
   path = new RectF();
   d.computeBounds(path, true);
   e = new Region();
   e.setPath(
       d,
       new Region(
           (int) ((RectF) (path)).left,
           (int) ((RectF) (path)).top,
           (int) ((RectF) (path)).right,
           (int) ((RectF) (path)).bottom));
 }
 @Override
 public void onPointerEvent(MotionEvent motionEvent) {
   final int action = motionEvent.getAction();
   switch (action & MotionEvent.ACTION_MASK) {
     case MotionEvent.ACTION_DOWN:
       mPointerId = motionEvent.getPointerId(0);
       mDownX = motionEvent.getX();
       mDownY = motionEvent.getY();
       break;
     case MotionEvent.ACTION_MOVE:
       if (mPointerId >= 0) {
         int index = motionEvent.findPointerIndex(mPointerId);
         /// M : ALPS01259500, JE at motionEvent.getX
         /// The value of index sometimes was less than 0
         /// Before using it, need to check the value @{
         if (index < 0) {
           mPointerId = -1;
           break;
         }
         /// @}
         if ((motionEvent.getEventTime() - motionEvent.getDownTime()) > TAP_TIMEOUT_MSEC
             || (motionEvent.getX(index) - mDownX) > mMotionSlop
             || (motionEvent.getY(index) - mDownY) > mMotionSlop) {
           mPointerId = -1;
         }
       }
       break;
     case MotionEvent.ACTION_UP:
     case MotionEvent.ACTION_POINTER_UP:
       {
         int index =
             (action & MotionEvent.ACTION_POINTER_INDEX_MASK)
                 >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
         // Extract the index of the pointer that left the touch sensor
         if (mPointerId == motionEvent.getPointerId(index)) {
           final int x = (int) motionEvent.getX(index);
           final int y = (int) motionEvent.getY(index);
           if ((motionEvent.getEventTime() - motionEvent.getDownTime()) < TAP_TIMEOUT_MSEC
               && (x - mDownX) < mMotionSlop
               && (y - mDownY) < mMotionSlop
               && !mTouchExcludeRegion.contains(x, y)) {
             mService.mH.obtainMessage(H.TAP_OUTSIDE_STACK, x, y, mDisplayContent).sendToTarget();
           }
           mPointerId = -1;
         }
         break;
       }
   }
 }
 @Override
 public boolean gatherTransparentRegion(Region region) {
   Log.i("faceView", "gatherTransparentRegion = " + region);
   if (region != null) {
     final int[] location = new int[2];
     int width = getWidth();
     int height = getHeight();
     getLocationInWindow(location);
     int l = location[0] + width / 2 - width;
     int t = location[1] + height / 2 - height;
     int r = l + width * 2;
     int b = t + height * 2;
     region.op(l, t, r, b, Region.Op.DIFFERENCE);
   }
   return true;
 }
 @Override
 public void handleMessage(Message message) {
   switch (message.what) {
     case MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED:
       {
         Region bounds = (Region) message.obj;
         try {
           mCallbacks.onMagnifedBoundsChanged(bounds);
         } catch (RemoteException re) {
           /* ignore */
         } finally {
           bounds.recycle();
         }
       }
       break;
     case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED:
       {
         SomeArgs args = (SomeArgs) message.obj;
         final int left = args.argi1;
         final int top = args.argi2;
         final int right = args.argi3;
         final int bottom = args.argi4;
         try {
           mCallbacks.onRectangleOnScreenRequested(left, top, right, bottom);
         } catch (RemoteException re) {
           /* ignore */
         } finally {
           args.recycle();
         }
       }
       break;
     case MESSAGE_NOTIFY_USER_CONTEXT_CHANGED:
       {
         try {
           mCallbacks.onUserContextChanged();
         } catch (RemoteException re) {
           /* ignore */
         }
       }
       break;
     case MESSAGE_NOTIFY_ROTATION_CHANGED:
       {
         final int rotation = message.arg1;
         try {
           mCallbacks.onRotationChanged(rotation);
         } catch (RemoteException re) {
           /* ignore */
         }
       }
       break;
     case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED:
       {
         synchronized (mWindowManagerService.mWindowMap) {
           if (mMagnifedViewport.isMagnifyingLocked()) {
             mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true);
             mWindowManagerService.scheduleAnimationLocked();
           }
         }
       }
       break;
       /// M:[ALPS01397351]Fix system server JE @{
     case MESSAGE_ON_ROTATION_CHANGED:
       {
         synchronized (mWindowManagerService.mWindowMap) {
           mMagnifedViewport.onRotationChangedLocked();
         }
       }
       break;
       /// @}
   }
 }
示例#18
0
	/**
	 * Get the area, {@link android.graphics.Rect}, of an entry from the entry's {@link android.graphics.Region}
	 *
	 * @param region
	 * @return   {@link android.graphics.Rect} specifying the area of an Entry
	 */
	private Rect getEntryRect(Region region){
		return new Rect(region.getBounds().left - getPaddingLeft(),
				region.getBounds().top - getPaddingTop(),
				region.getBounds().right - getPaddingLeft(),
				region.getBounds().bottom - getPaddingTop());
	}
 @Override
 public boolean clipRegion(final Region region) {
   region.translate(xOffset, yOffset);
   return getWrappedCanvas().clipRegion(region);
 }
 public void getMagnifiedFrameInContentCoordsLocked(Rect rect) {
   MagnificationSpec spec = mMagnificationSpec;
   mMagnifiedBounds.getBounds(rect);
   rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
   rect.scale(1.0f / spec.scale);
 }
示例#21
0
  /**
   * Draw.
   *
   * @param canvas the canvas
   */
  public void draw(Canvas canvas) {
    if (mHidden) {
      return;
    }
    canvas.save();
    Path path = new Path();
    if (!hasFocus()) {
      mOutlinePaint.setColor(0xFF000000);
      canvas.drawRect(mDrawRect, mOutlinePaint);
    } else {
      Rect viewDrawingRect = new Rect();
      mContext.getDrawingRect(viewDrawingRect);
      if (mCircle) {
        float width = mDrawRect.width();
        float height = mDrawRect.height();
        path.addCircle(
            mDrawRect.left + (width / 2),
            mDrawRect.top + (height / 2),
            width / 2,
            Path.Direction.CW);
        mOutlinePaint.setColor(0xFFEF04D6);
      } else {
        path.addRect(new RectF(mDrawRect), Path.Direction.CW);
        mOutlinePaint.setColor(0xFFFF8A00);
      }
      Region region = new Region();
      region.set(viewDrawingRect);
      region.op(mDrawRect, Region.Op.DIFFERENCE);
      RegionIterator iter = new RegionIterator(region);
      Rect r = new Rect();
      while (iter.next(r)) {
        canvas.drawRect(r, hasFocus() ? mFocusPaint : mNoFocusPaint);
      }
      // android 4.0 Support bad.java.lang.UnsupportedOperationException
      // canvas.clipPath(path, Region.Op.DIFFERENCE);
      // canvas.drawRect(viewDrawingRect, hasFocus() ? mFocusPaint : mNoFocusPaint);

      canvas.restore();
      canvas.drawPath(path, mOutlinePaint);

      if (mMode == ModifyMode.Grow) {
        if (mCircle) {
          int width = mResizeDrawableDiagonal.getIntrinsicWidth();
          int height = mResizeDrawableDiagonal.getIntrinsicHeight();

          int d = (int) Math.round(Math.cos(/* 45deg */ Math.PI / 4D) * (mDrawRect.width() / 2D));
          int x = mDrawRect.left + (mDrawRect.width() / 2) + d - width / 2;
          int y = mDrawRect.top + (mDrawRect.height() / 2) - d - height / 2;
          mResizeDrawableDiagonal.setBounds(
              x,
              y,
              x + mResizeDrawableDiagonal.getIntrinsicWidth(),
              y + mResizeDrawableDiagonal.getIntrinsicHeight());
          mResizeDrawableDiagonal.draw(canvas);
        } else {
          //                    int left = mDrawRect.left + 1;
          //                    int right = mDrawRect.right + 1;
          //                    int top = mDrawRect.top + 4;
          //                    int bottom = mDrawRect.bottom + 3;
          //
          //                    int widthWidth = mResizeDrawableWidth.getIntrinsicWidth() / 2;
          //                    int widthHeight = mResizeDrawableWidth.getIntrinsicHeight() / 2;
          //                    int heightHeight = mResizeDrawableHeight.getIntrinsicHeight() / 2;
          //                    int heightWidth = mResizeDrawableHeight.getIntrinsicWidth() / 2;
          //
          //                    int xMiddle = mDrawRect.left + ((mDrawRect.right - mDrawRect.left) /
          // 2);
          //                    int yMiddle = mDrawRect.top + ((mDrawRect.bottom - mDrawRect.top) /
          // 2);
          //
          //                    mResizeDrawableWidth.setBounds(left - widthWidth, yMiddle -
          // widthHeight, left + widthWidth, yMiddle
          //                            + widthHeight);
          //                    mResizeDrawableWidth.draw(canvas);
          //
          //                    mResizeDrawableWidth.setBounds(right - widthWidth, yMiddle -
          // widthHeight, right + widthWidth, yMiddle
          //                            + widthHeight);
          //                    mResizeDrawableWidth.draw(canvas);
          //
          //                    mResizeDrawableHeight.setBounds(xMiddle - heightWidth, top -
          // heightHeight, xMiddle + heightWidth, top
          //                            + heightHeight);
          //                    mResizeDrawableHeight.draw(canvas);
          //
          //                    mResizeDrawableHeight.setBounds(xMiddle - heightWidth, bottom -
          // heightHeight, xMiddle + heightWidth, bottom
          //                            + heightHeight);
          //                    mResizeDrawableHeight.draw(canvas);
        }
      }
      if (mCircle) {

      } else {
        int left = mDrawRect.left + 1;
        int right = mDrawRect.right + 1;
        int top = mDrawRect.top + 4;
        int bottom = mDrawRect.bottom + 3;

        int widthWidth = mResizeDrawableDiagonal.getIntrinsicWidth() / 2;
        int widthHeight = mResizeDrawableDiagonal.getIntrinsicHeight() / 2;

        mResizeDrawableDiagonal2.setBounds(
            left - widthWidth, top - widthHeight, left + widthWidth, top + widthHeight);
        mResizeDrawableDiagonal2.draw(canvas);
        mResizeDrawableDiagonal.setBounds(
            right - widthWidth, top - widthHeight, right + widthWidth, top + widthHeight);
        mResizeDrawableDiagonal.draw(canvas);
        mResizeDrawableDiagonal.setBounds(
            left - widthWidth, bottom - widthHeight, left + widthWidth, bottom + widthHeight);
        mResizeDrawableDiagonal.draw(canvas);
        mResizeDrawableDiagonal2.setBounds(
            right - widthWidth, bottom - widthHeight, right + widthWidth, bottom + widthHeight);
        mResizeDrawableDiagonal2.draw(canvas);
      }
    }
  }
    public void recomputeBoundsLocked() {
      mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
      final int screenWidth = mTempPoint.x;
      final int screenHeight = mTempPoint.y;

      Region magnifiedBounds = mMagnifiedBounds;
      magnifiedBounds.set(0, 0, 0, 0);

      Region availableBounds = mTempRegion1;
      availableBounds.set(0, 0, screenWidth, screenHeight);

      Region nonMagnifiedBounds = mTempRegion4;
      nonMagnifiedBounds.set(0, 0, 0, 0);

      SparseArray<WindowStateInfo> visibleWindows = mTempWindowStateInfos;
      visibleWindows.clear();
      getWindowsOnScreenLocked(visibleWindows);

      final int visibleWindowCount = visibleWindows.size();
      for (int i = visibleWindowCount - 1; i >= 0; i--) {
        WindowStateInfo info = visibleWindows.valueAt(i);
        if (info.mWindowState.mAttrs.type
            == WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
          continue;
        }

        Region windowBounds = mTempRegion2;
        Matrix matrix = mTempMatrix;
        populateTransformationMatrix(info.mWindowState, matrix);
        RectF windowFrame = mTempRectF;

        if (mWindowManagerService.mPolicy.canMagnifyWindow(info.mWindowState.mAttrs.type)) {
          windowFrame.set(info.mWindowState.mFrame);
          windowFrame.offset(-windowFrame.left, -windowFrame.top);
          matrix.mapRect(windowFrame);
          windowBounds.set(
              (int) windowFrame.left,
              (int) windowFrame.top,
              (int) windowFrame.right,
              (int) windowFrame.bottom);
          magnifiedBounds.op(windowBounds, Region.Op.UNION);
          magnifiedBounds.op(availableBounds, Region.Op.INTERSECT);
        } else {
          windowFrame.set(info.mTouchableRegion);
          windowFrame.offset(-info.mWindowState.mFrame.left, -info.mWindowState.mFrame.top);
          matrix.mapRect(windowFrame);
          windowBounds.set(
              (int) windowFrame.left,
              (int) windowFrame.top,
              (int) windowFrame.right,
              (int) windowFrame.bottom);
          nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
          windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE);
          availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
        }

        Region accountedBounds = mTempRegion2;
        accountedBounds.set(magnifiedBounds);
        accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
        accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);

        if (accountedBounds.isRect()) {
          Rect accountedFrame = mTempRect1;
          accountedBounds.getBounds(accountedFrame);
          if (accountedFrame.width() == screenWidth && accountedFrame.height() == screenHeight) {
            break;
          }
        }
      }

      for (int i = visibleWindowCount - 1; i >= 0; i--) {
        WindowStateInfo info = visibleWindows.valueAt(i);
        info.recycle();
        visibleWindows.removeAt(i);
      }

      magnifiedBounds.op(
          mHalfBorderWidth,
          mHalfBorderWidth,
          screenWidth - mHalfBorderWidth,
          screenHeight - mHalfBorderWidth,
          Region.Op.INTERSECT);

      if (!mOldMagnifiedBounds.equals(magnifiedBounds)) {
        Region bounds = Region.obtain();
        bounds.set(magnifiedBounds);
        mHandler
            .obtainMessage(MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED, bounds)
            .sendToTarget();

        mWindow.setBounds(magnifiedBounds);
        Rect dirtyRect = mTempRect1;
        if (mFullRedrawNeeded) {
          mFullRedrawNeeded = false;
          dirtyRect.set(
              mHalfBorderWidth,
              mHalfBorderWidth,
              screenWidth - mHalfBorderWidth,
              screenHeight - mHalfBorderWidth);
          mWindow.invalidate(dirtyRect);
        } else {
          Region dirtyRegion = mTempRegion3;
          dirtyRegion.set(magnifiedBounds);
          dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION);
          dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
          dirtyRegion.getBounds(dirtyRect);
          mWindow.invalidate(dirtyRect);
        }

        mOldMagnifiedBounds.set(magnifiedBounds);
      }
    }
 /** Translate the region in window to screen. */
 public void translateRegionInWindowToScreen(Region transparentRegion) {
   transparentRegion.scale(applicationScale);
 }
 /**
  * Sets the touchable region of this popup to be zero. This means that all touch events on this
  * popup will go through to the surface behind it.
  */
 private void setZeroTouchableSurface() {
   mTouchableRegion.setEmpty();
 }