Removed regionId from updateTapExcludeRegion request.

There was no need for regionId in the request since you can just replace
the previous region with a new one. This reduces confusion and
simplifies the code. This also allowed TapExcludeRegionHolder to get
deleted and just store the excluded region in the WindowState.

Additionally, this fixed a bug where the excluded region would get
overwritten when the window region was smaller. If the window region was
resized later, the exclude region would remain small.

This is also preparing for more uses of this API with embedded windows
and window magnification.

Test: ActivityViewTest
Change-Id: Ia151115b5a5e8f2ce5e606fe627821dcfef5d9b5
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index b154da4..d746691 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1309,7 +1309,7 @@
                         // If a window has tap exclude region, we need to account it.
                         final Region displayRegion = new Region(windowState.getDisplayFrameLw());
                         final Region tapExcludeRegion = new Region();
-                        windowState.amendTapExcludeRegion(tapExcludeRegion);
+                        windowState.getTapExcludeRegion(tapExcludeRegion);
                         displayRegion.op(tapExcludeRegion, displayRegion,
                                 Region.Op.REVERSE_DIFFERENCE);
                         unaccountedSpace.op(displayRegion, unaccountedSpace,
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5bf8e05..cf0cc7b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2489,10 +2489,13 @@
      * @param inOutRegion The region to be amended.
      */
     private void amendWindowTapExcludeRegion(Region inOutRegion) {
+        final Region region = Region.obtain();
         for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
             final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
-            win.amendTapExcludeRegion(inOutRegion);
+            win.getTapExcludeRegion(region);
+            inOutRegion.op(region, Op.UNION);
         }
+        region.recycle();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index a175d63..5198602 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -448,10 +448,10 @@
     }
 
     @Override
-    public void updateTapExcludeRegion(IWindow window, int regionId, Region region) {
+    public void updateTapExcludeRegion(IWindow window, Region region) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mService.updateTapExcludeRegion(window, regionId, region);
+            mService.updateTapExcludeRegion(window, region);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
deleted file mode 100644
index 8f72cda..0000000
--- a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.util.SparseArray;
-
-/**
- * A holder that contains a collection of regions identified by int id. Each individual region can
- * be updated separately.
- */
-class TapExcludeRegionHolder {
-    private SparseArray<Region> mTapExcludeRegions = new SparseArray<>();
-
-    /** Update the specified region with provided position and size. */
-    void updateRegion(int regionId, Region region) {
-        // Remove the previous one because there is a new one incoming.
-        mTapExcludeRegions.remove(regionId);
-
-        if (region == null || region.isEmpty()) {
-            // The incoming region is invalid. Don't use it.
-            return;
-        }
-
-        mTapExcludeRegions.put(regionId, region);
-    }
-
-    /**
-     * Union the provided region with current region formed by this container.
-     */
-    void amendRegion(Region region, Rect bounds) {
-        for (int i = mTapExcludeRegions.size() - 1; i >= 0; --i) {
-            final Region r = mTapExcludeRegions.valueAt(i);
-            if (bounds != null) {
-                r.op(bounds, Region.Op.INTERSECT);
-            }
-            region.op(r, Region.Op.UNION);
-        }
-    }
-
-    /**
-     * Return true if tap exclude region is empty.
-     */
-    boolean isEmpty() {
-        return mTapExcludeRegions.size() == 0;
-    }
-}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ba9e9ce..2d1d245 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6648,14 +6648,14 @@
      * </ol>
      * Passing an invalid region will remove the area from the exclude region of this window.
      */
-    void updateTapExcludeRegion(IWindow client, int regionId, Region region) {
+    void updateTapExcludeRegion(IWindow client, Region region) {
         synchronized (mGlobalLock) {
             final WindowState callingWin = windowForClientLocked(null, client, false);
             if (callingWin == null) {
                 ProtoLog.w(WM_ERROR, "Bad requesting window %s", client);
                 return;
             }
-            callingWin.updateTapExcludeRegion(regionId, region);
+            callingWin.updateTapExcludeRegion(region);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3039d69..0b1f8e5 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -595,7 +595,7 @@
     /**
      * A region inside of this window to be excluded from touch.
      */
-    private TapExcludeRegionHolder mTapExcludeRegionHolder;
+    private final Region mTapExcludeRegion = new Region();
 
     /**
      * Used for testing because the real PowerManager is final.
@@ -1996,11 +1996,10 @@
         if (WindowManagerService.excludeWindowTypeFromTapOutTask(type)) {
             dc.mTapExcludedWindows.remove(this);
         }
-        if (mTapExcludeRegionHolder != null) {
-            // If a tap exclude region container was initialized for this window, then it should've
-            // also been registered in display.
-            dc.mTapExcludeProvidingWindows.remove(this);
-        }
+
+        // Remove this window from mTapExcludeProvidingWindows. If it was not registered, this will
+        // not do anything.
+        dc.mTapExcludeProvidingWindows.remove(this);
         dc.getDisplayPolicy().removeWindowLw(this);
 
         disposeInputChannel();
@@ -3239,11 +3238,11 @@
      * region.
      */
     private void subtractTouchExcludeRegionIfNeeded(Region touchableRegion) {
-        if (mTapExcludeRegionHolder == null) {
+        if (mTapExcludeRegion.isEmpty()) {
             return;
         }
         final Region touchExcludeRegion = Region.obtain();
-        amendTapExcludeRegion(touchExcludeRegion);
+        getTapExcludeRegion(touchExcludeRegion);
         if (!touchExcludeRegion.isEmpty()) {
             touchableRegion.op(touchExcludeRegion, Region.Op.DIFFERENCE);
         }
@@ -5268,21 +5267,25 @@
      * Update a tap exclude region identified by provided id. The requested area will be clipped to
      * the window bounds.
      */
-    void updateTapExcludeRegion(int regionId, Region region) {
+    void updateTapExcludeRegion(Region region) {
         final DisplayContent currentDisplay = getDisplayContent();
         if (currentDisplay == null) {
             throw new IllegalStateException("Trying to update window not attached to any display.");
         }
 
-        if (mTapExcludeRegionHolder == null) {
-            mTapExcludeRegionHolder = new TapExcludeRegionHolder();
-
+        // Clear the tap excluded region if the region passed in is null or empty.
+        if (region == null || region.isEmpty()) {
+            mTapExcludeRegion.setEmpty();
+            // Remove this window from mTapExcludeProvidingWindows since it won't be providing
+            // tap exclude regions.
+            currentDisplay.mTapExcludeProvidingWindows.remove(this);
+        } else {
+            mTapExcludeRegion.set(region);
             // Make sure that this window is registered as one that provides a tap exclude region
             // for its containing display.
             currentDisplay.mTapExcludeProvidingWindows.add(this);
         }
 
-        mTapExcludeRegionHolder.updateRegion(regionId, region);
         // Trigger touch exclude region update on current display.
         currentDisplay.updateTouchExcludeRegion();
         // Trigger touchable region update for this window.
@@ -5290,24 +5293,24 @@
     }
 
     /**
-     * Union the region with current tap exclude region that this window provides.
+     * Get the tap excluded region for this window in screen coordinates.
      *
-     * @param region The region to be amended. It is on the screen coordinates.
+     * @param outRegion The returned tap excluded region. It is on the screen coordinates.
      */
-    void amendTapExcludeRegion(Region region) {
-        final Region tempRegion = Region.obtain();
+    void getTapExcludeRegion(Region outRegion) {
         mTmpRect.set(mWindowFrames.mFrame);
         mTmpRect.offsetTo(0, 0);
-        mTapExcludeRegionHolder.amendRegion(tempRegion, mTmpRect);
-        // The region held by the holder is on the window coordinates. We need to translate it to
-        // the screen coordinates.
-        tempRegion.translate(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top);
-        region.op(tempRegion, Region.Op.UNION);
-        tempRegion.recycle();
+
+        outRegion.set(mTapExcludeRegion);
+        outRegion.op(mTmpRect, Region.Op.INTERSECT);
+
+        // The region is on the window coordinates, so it needs to  be translated into screen
+        // coordinates. There's no need to scale since that will be done by native code.
+        outRegion.translate(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top);
     }
 
     boolean hasTapExcludeRegion() {
-        return mTapExcludeRegionHolder != null && !mTapExcludeRegionHolder.isEmpty();
+        return !mTapExcludeRegion.isEmpty();
     }
 
     @Override