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;
}