aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/latin/ImfUtils.java7
-rw-r--r--java/src/com/android/inputmethod/latin/ResizableIntArray.java69
-rw-r--r--java/src/com/android/inputmethod/latin/SubtypeSwitcher.java6
-rw-r--r--tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java97
4 files changed, 148 insertions, 31 deletions
diff --git a/java/src/com/android/inputmethod/latin/ImfUtils.java b/java/src/com/android/inputmethod/latin/ImfUtils.java
index b882a4860..1461c0240 100644
--- a/java/src/com/android/inputmethod/latin/ImfUtils.java
+++ b/java/src/com/android/inputmethod/latin/ImfUtils.java
@@ -90,6 +90,13 @@ public class ImfUtils {
return false;
}
+ public static InputMethodSubtype getCurrentInputMethodSubtype(Context context,
+ InputMethodSubtype defaultSubtype) {
+ final InputMethodManager imm = getInputMethodManager(context);
+ final InputMethodSubtype currentSubtype = imm.getCurrentInputMethodSubtype();
+ return (currentSubtype != null) ? currentSubtype : defaultSubtype;
+ }
+
public static boolean hasMultipleEnabledIMEsOrSubtypes(Context context,
final boolean shouldIncludeAuxiliarySubtypes) {
final InputMethodManager imm = getInputMethodManager(context);
diff --git a/java/src/com/android/inputmethod/latin/ResizableIntArray.java b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
index 6feae9c5a..387d45a53 100644
--- a/java/src/com/android/inputmethod/latin/ResizableIntArray.java
+++ b/java/src/com/android/inputmethod/latin/ResizableIntArray.java
@@ -28,38 +28,49 @@ public class ResizableIntArray {
}
public int get(final int index) {
- if (index < 0 || index >= mLength) {
- throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index);
+ if (index < mLength) {
+ return mArray[index];
}
- return mArray[index];
+ throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index);
}
public void add(final int index, final int val) {
- if (mLength < index + 1) {
+ if (index < mLength) {
+ mArray[index] = val;
+ } else {
mLength = index;
add(val);
- } else {
- mArray[index] = val;
}
}
public void add(final int val) {
- final int nextLength = mLength + 1;
- ensureCapacity(nextLength);
- mArray[mLength] = val;
- mLength = nextLength;
+ final int currentLength = mLength;
+ ensureCapacity(currentLength + 1);
+ mArray[currentLength] = val;
+ mLength = currentLength + 1;
+ }
+
+ /**
+ * Calculate the new capacity of {@code mArray}.
+ * @param minimumCapacity the minimum capacity that the {@code mArray} should have.
+ * @return the new capacity that the {@code mArray} should have. Returns zero when there is no
+ * need to expand {@code mArray}.
+ */
+ private int calculateCapacity(final int minimumCapacity) {
+ final int currentCapcity = mArray.length;
+ if (currentCapcity < minimumCapacity) {
+ final int nextCapacity = currentCapcity * 2;
+ // The following is the same as return Math.max(minimumCapacity, nextCapacity);
+ return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity;
+ }
+ return 0;
}
private void ensureCapacity(final int minimumCapacity) {
- if (mArray.length < minimumCapacity) {
- final int nextCapacity = mArray.length * 2;
- // The following is the same as newLength =
- // Math.max(minimumCapacity, nextCapacity);
- final int newLength = minimumCapacity > nextCapacity
- ? minimumCapacity
- : nextCapacity;
+ final int newCapacity = calculateCapacity(minimumCapacity);
+ if (newCapacity > 0) {
// TODO: Implement primitive array pool.
- mArray = Arrays.copyOf(mArray, newLength);
+ mArray = Arrays.copyOf(mArray, newCapacity);
}
}
@@ -89,17 +100,35 @@ public class ResizableIntArray {
}
public void copy(final ResizableIntArray ip) {
- // TODO: Avoid useless coping of values.
- ensureCapacity(ip.mLength);
+ final int newCapacity = calculateCapacity(ip.mLength);
+ if (newCapacity > 0) {
+ // TODO: Implement primitive array pool.
+ mArray = new int[newCapacity];
+ }
System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength);
mLength = ip.mLength;
}
public void append(final ResizableIntArray src, final int startPos, final int length) {
+ if (length == 0) {
+ return;
+ }
final int currentLength = mLength;
final int newLength = currentLength + length;
ensureCapacity(newLength);
System.arraycopy(src.mArray, startPos, mArray, currentLength, length);
mLength = newLength;
}
+
+ public void fill(final int value, final int startPos, final int length) {
+ if (startPos < 0 || length < 0) {
+ throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length);
+ }
+ final int endPos = startPos + length;
+ ensureCapacity(endPos);
+ Arrays.fill(mArray, startPos, endPos, value);
+ if (mLength < endPos) {
+ mLength = endPos;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
index 664de6774..a7a5fcb5f 100644
--- a/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/SubtypeSwitcher.java
@@ -98,9 +98,9 @@ public class SubtypeSwitcher {
mConnectivityManager = (ConnectivityManager) service.getSystemService(
Context.CONNECTIVITY_SERVICE);
mCurrentSystemLocale = mResources.getConfiguration().locale;
- mCurrentSubtype = mImm.getCurrentInputMethodSubtype();
mNoLanguageSubtype = ImfUtils.findSubtypeByLocaleAndKeyboardLayoutSet(
service, SubtypeLocale.NO_LANGUAGE, SubtypeLocale.QWERTY);
+ mCurrentSubtype = ImfUtils.getCurrentInputMethodSubtype(service, mNoLanguageSubtype);
if (mNoLanguageSubtype == null) {
throw new RuntimeException("Can't find no lanugage with QWERTY subtype");
}
@@ -113,7 +113,7 @@ public class SubtypeSwitcher {
// Only configuration changed event is allowed to call this because this is heavy.
private void updateAllParameters() {
mCurrentSystemLocale = mResources.getConfiguration().locale;
- updateSubtype(mImm.getCurrentInputMethodSubtype());
+ updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype));
updateParametersOnStartInputView();
}
@@ -142,7 +142,7 @@ public class SubtypeSwitcher {
+ currentSubtype.getLocale() + "/" + currentSubtype.getExtraValue());
Log.w(TAG, "Last subtype was disabled. Update to the current one.");
}
- updateSubtype(mImm.getCurrentInputMethodSubtype());
+ updateSubtype(ImfUtils.getCurrentInputMethodSubtype(mService, mNoLanguageSubtype));
}
}
diff --git a/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java b/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
index 80e5f9cb1..995fc14ea 100644
--- a/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
+++ b/tests/src/com/android/inputmethod/latin/ResizableIntArrayTests.java
@@ -37,8 +37,12 @@ public class ResizableIntArrayTests extends AndroidTestCase {
for (int i = 0; i < limit; i++) {
src.add(i);
assertEquals("length after add " + i, i + 1, src.getLength());
- if (i == DEFAULT_CAPACITY) array2 = src.getPrimitiveArray();
- if (i == DEFAULT_CAPACITY * 2) array3 = src.getPrimitiveArray();
+ if (i == DEFAULT_CAPACITY) {
+ array2 = src.getPrimitiveArray();
+ }
+ if (i == DEFAULT_CAPACITY * 2) {
+ array3 = src.getPrimitiveArray();
+ }
if (i < DEFAULT_CAPACITY) {
assertSame("array after add " + i, array, src.getPrimitiveArray());
} else if (i < DEFAULT_CAPACITY * 2) {
@@ -110,7 +114,9 @@ public class ResizableIntArrayTests extends AndroidTestCase {
for (int i = 0; i < DEFAULT_CAPACITY; i++) {
src.add(i);
assertEquals("length after add " + i, i + 1, src.getLength());
- if (i == smallerLength) array3 = src.getPrimitiveArray();
+ if (i == smallerLength) {
+ array3 = src.getPrimitiveArray();
+ }
if (i < smallerLength) {
assertSame("array after add " + i, array2, src.getPrimitiveArray());
} else if (i < smallerLength * 2) {
@@ -133,11 +139,13 @@ public class ResizableIntArrayTests extends AndroidTestCase {
assertEquals("length after larger setLength", largerLength, src.getLength());
assertNotSame("array after larger setLength", array, array2);
assertEquals("array length after larger setLength", largerLength, array2.length);
- for (int i = 0; i < DEFAULT_CAPACITY; i++) {
- assertEquals("value at " + i, i, src.get(i));
- }
- for (int i = DEFAULT_CAPACITY; i < largerLength; i++) {
- assertEquals("value at " + i, 0, src.get(i));
+ for (int i = 0; i < largerLength; i++) {
+ final int v = src.get(i);
+ if (i < DEFAULT_CAPACITY) {
+ assertEquals("value at " + i, i, v);
+ } else {
+ assertEquals("value at " + i, 0, v);
+ }
}
final int smallerLength = DEFAULT_CAPACITY / 2;
@@ -236,6 +244,79 @@ public class ResizableIntArrayTests extends AndroidTestCase {
src.getPrimitiveArray(), 0, dst.getPrimitiveArray(), dstLen + srcLen, srcLen);
}
+ public void testFill() {
+ final int srcLen = DEFAULT_CAPACITY;
+ final ResizableIntArray src = new ResizableIntArray(srcLen);
+ for (int i = 0; i < srcLen; i++) {
+ src.add(i);
+ }
+ final int[] array = src.getPrimitiveArray();
+
+ final int startPos = srcLen / 3;
+ final int length = srcLen / 3;
+ final int endPos = startPos + length;
+ assertTrue(startPos >= 1);
+ final int value = 123;
+ try {
+ src.fill(value, -1, length);
+ fail("fill from -1 shouldn't succeed");
+ } catch (IllegalArgumentException e) {
+ // success
+ }
+ try {
+ src.fill(value, startPos, -1);
+ fail("fill negative length shouldn't succeed");
+ } catch (IllegalArgumentException e) {
+ // success
+ }
+
+ src.fill(value, startPos, length);
+ assertEquals("length after fill", srcLen, src.getLength());
+ assertSame("array after fill", array, src.getPrimitiveArray());
+ for (int i = 0; i < srcLen; i++) {
+ final int v = src.get(i);
+ if (i >= startPos && i < endPos) {
+ assertEquals("new values after fill at " + i, value, v);
+ } else {
+ assertEquals("unmodified values after fill at " + i, i, v);
+ }
+ }
+
+ final int length2 = srcLen * 2 - startPos;
+ final int largeEnd = startPos + length2;
+ assertTrue(largeEnd > srcLen);
+ final int value2 = 456;
+ src.fill(value2, startPos, length2);
+ assertEquals("length after large fill", largeEnd, src.getLength());
+ assertNotSame("array after large fill", array, src.getPrimitiveArray());
+ for (int i = 0; i < largeEnd; i++) {
+ final int v = src.get(i);
+ if (i >= startPos && i < largeEnd) {
+ assertEquals("new values after large fill at " + i, value2, v);
+ } else {
+ assertEquals("unmodified values after large fill at " + i, i, v);
+ }
+ }
+
+ final int startPos2 = largeEnd + length2;
+ final int endPos2 = startPos2 + length2;
+ final int value3 = 789;
+ src.fill(value3, startPos2, length2);
+ assertEquals("length after disjoint fill", endPos2, src.getLength());
+ for (int i = 0; i < endPos2; i++) {
+ final int v = src.get(i);
+ if (i >= startPos2 && i < endPos2) {
+ assertEquals("new values after disjoint fill at " + i, value3, v);
+ } else if (i >= startPos && i < largeEnd) {
+ assertEquals("unmodified values after disjoint fill at " + i, value2, v);
+ } else if (i < startPos) {
+ assertEquals("unmodified values after disjoint fill at " + i, i, v);
+ } else {
+ assertEquals("gap values after disjoint fill at " + i, 0, v);
+ }
+ }
+ }
+
private static void assertArrayEquals(String message, int[] expecteds, int expectedPos,
int[] actuals, int actualPos, int length) {
if (expecteds == null && actuals == null) {