From ad205b2e3f43ab374fe7a573abdcdd45832d0e4b Mon Sep 17 00:00:00 2001
From: "Tadashi G. Takaoka" <takaoka@google.com>
Date: Wed, 10 Apr 2013 17:57:07 +0900
Subject: [PATCH] Protect simultaneously modifying gesture preview data

Bug: 8556775
Change-Id: I83272e3adbfc0c9cc14f9e8b479e926aabf4fa2a
---
 .../keyboard/internal/GesturePreviewTrail.java   | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
index e3e6d39e48..f682b518f4 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
@@ -37,6 +37,7 @@ import com.android.inputmethod.latin.ResizableIntArray;
 final class GesturePreviewTrail {
     private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewPoints.PREVIEW_CAPACITY;
 
+    // These three {@link ResizableIntArray}s should be synchronized by {@link #mEventTimes}.
     private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
     private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
     private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
@@ -90,7 +91,13 @@ final class GesturePreviewTrail {
     }
 
     public void addStroke(final GestureStrokeWithPreviewPoints stroke, final long downTime) {
-        final int trailSize = mEventTimes.getLength();
+        synchronized (mEventTimes) {
+            addStrokeLocked(stroke, downTime);
+        }
+    }
+
+    private void addStrokeLocked(final GestureStrokeWithPreviewPoints stroke, final long downTime) {
+            final int trailSize = mEventTimes.getLength();
         stroke.appendPreviewStroke(mEventTimes, mXCoordinates, mYCoordinates);
         if (mEventTimes.getLength() == trailSize) {
             return;
@@ -169,6 +176,13 @@ final class GesturePreviewTrail {
      */
     public boolean drawGestureTrail(final Canvas canvas, final Paint paint,
             final Rect outBoundsRect, final Params params) {
+        synchronized (mEventTimes) {
+            return drawGestureTrailLocked(canvas, paint, outBoundsRect, params);
+        }
+    }
+
+    private boolean drawGestureTrailLocked(final Canvas canvas, final Paint paint,
+            final Rect outBoundsRect, final Params params) {
         // Initialize bounds rectangle.
         outBoundsRect.setEmpty();
         final int trailSize = mEventTimes.getLength();
-- 
GitLab