Improve Watermark#detect execution performance

Since Watermark#detect used 4 layers loops to match if
the captured screenshot exists the given keyboard bitmap
to idendify the soft-keyboard visiblity.

This may take a lot of time when the device has disabled
Jit compilation.

Follow https://developer.android.com/training/articles/perf-tips#Loops
tips to improve Watermark#robustMatch by using the local
variable or inline the method implementation to prevent the cost when
invoking methods in loops.

Bug: 191111111
Test: 0) Disable Jit compilation with
      - setprop dalvik.vm.usejit false
      - setprop dalvik.vm.usejitprofiles false
      - restart device
      1) testing ImeInsetsVisibilityTest#\
      testEditTextPositionAndPersistWhenAboveImeWindowShown
         to see if TestTimedOutException happens
Change-Id: I78a4775788f2711a017586783d84fb13a3905848
diff --git a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
index b1d8554..ccd8659 100644
--- a/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
+++ b/tests/inputmethod/mockime/src/com/android/cts/mockime/Watermark.java
@@ -20,7 +20,6 @@
 import android.graphics.Color;
 
 import androidx.annotation.AnyThread;
-import androidx.annotation.ColorInt;
 import androidx.annotation.NonNull;
 
 /**
@@ -91,33 +90,6 @@
         }
 
         /**
-         * Returns pixel color in A8R8G8B8 format.
-         *
-         * @param x X coordinate of the pixel.
-         * @param y Y coordinate of the pixel.
-         * @return Pixel color in A8R8G8B8 format.
-         */
-        @ColorInt
-        @AnyThread
-        int getPixel(int x, int y) {
-            return mPixels[y * mWidth + x];
-        }
-
-        /**
-         * Compares two given pixels to determine whether those two pixels are considered to be
-         * the same within {@link #TOLERANCE}.
-         *
-         * @param lhs a color integer to be compared.
-         * @param rhs another color integer to be compared.
-         * @return {@true} if two given pixels are the same within {@link #TOLERANCE}.
-         */
-        private static boolean robustMatchInternal(@ColorInt int lhs, @ColorInt int rhs) {
-            return lhs == rhs || (Math.abs(Color.red(lhs) - Color.red(rhs)) <= TOLERANCE
-                    && Math.abs(Color.green(lhs) - Color.green(rhs)) <= TOLERANCE
-                    && Math.abs(Color.blue(lhs) - Color.blue(rhs)) <= TOLERANCE);
-        }
-
-        /**
          * Checks if the same image can be found in the specified {@link BitmapImage} within
          * within {@link #TOLERANCE}.
          *
@@ -130,19 +102,25 @@
         boolean robustMatch(@NonNull BitmapImage targetImage, int offsetX, int offsetY) {
             final int targetWidth = targetImage.getWidth();
             final int targetHeight = targetImage.getHeight();
+            final int[] targetPixels = targetImage.mPixels;
+            final int[] sourcePixels = mPixels;
+
+            if (offsetX < 0 || targetWidth <= mWidth - 1 + offsetX) return false;
+            if (offsetY < 0 || targetHeight <= mHeight - 1 + offsetY) return false;
 
             for (int y = 0; y < mHeight; ++y) {
                 for (int x = 0; x < mWidth; ++x) {
                     final int targetX = x + offsetX;
-                    if (targetX < 0 || targetWidth <= targetX) {
-                        return false;
-                    }
                     final int targetY = y + offsetY;
-                    if (targetY < 0 || targetHeight <= targetY) {
-                        return false;
-                    }
-                    if (!robustMatchInternal(
-                            targetImage.getPixel(targetX, targetY), getPixel(x, y))) {
+                    final int targetPx = targetPixels[targetY * targetWidth + targetX];
+                    final int sourcePx = sourcePixels[y * mWidth + x];
+                    // Compares two given pixels (targetPx & sourcePx) to determine whether those
+                    // two pixels are considered to be the same within {@link #TOLERANCE}.
+                    boolean match = targetPx == sourcePx
+                            || (Math.abs(Color.red(targetPx) - Color.red(sourcePx)) <= TOLERANCE
+                            && Math.abs(Color.green(targetPx) - Color.green(sourcePx)) <= TOLERANCE
+                            && Math.abs(Color.blue(targetPx) - Color.blue(sourcePx)) <= TOLERANCE);
+                    if (!match) {
                         return false;
                     }
                 }
@@ -252,9 +230,12 @@
      */
     public static boolean detect(@NonNull Bitmap bitmap) {
         final BitmapImage targetImage = BitmapImage.createFromBitmap(bitmap);
+
         // Search from the bottom line with an assumption that the IME is shown at the bottom.
-        for (int offsetY = targetImage.getHeight() - 1; offsetY >= 0; --offsetY) {
-            for (int offsetX = 0; offsetX < targetImage.getWidth(); ++offsetX) {
+        final int targetImageHeight = targetImage.getHeight();
+        final int targetImageWidth = targetImage.getWidth();
+        for (int offsetY = targetImageHeight - 1; offsetY >= 0; --offsetY) {
+            for (int offsetX = 0; offsetX < targetImageWidth; ++offsetX) {
                 if (sImage.robustMatch(targetImage, offsetX, offsetY)) {
                     return true;
                 }