Fix possible NPE while finding device override value from resource

Bug: 12949735
Change-Id: Iffda08db413b3b3d338ab9bf625bb0968c2e48dd
main
Tadashi G. Takaoka 2014-02-10 12:54:45 +09:00
parent e592c1b291
commit bd9887a574
9 changed files with 21 additions and 90 deletions

View File

@ -33,7 +33,5 @@
<!-- Preferable keyboard height in absolute scale: 45.0mm --> <!-- Preferable keyboard height in absolute scale: 45.0mm -->
<!-- Xoom --> <!-- Xoom -->
<item>HARDWARE=stingray,265.4378</item> <item>HARDWARE=stingray,265.4378</item>
<!-- Default value for unknown device: empty string -->
<item>,</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -33,7 +33,5 @@
<!-- Preferable keyboard height in absolute scale: 48.0mm --> <!-- Preferable keyboard height in absolute scale: 48.0mm -->
<!-- Xoom --> <!-- Xoom -->
<item>HARDWARE=stingray,283.1337</item> <item>HARDWARE=stingray,283.1337</item>
<!-- Default value for unknown device: empty string -->
<item>,</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -59,7 +59,5 @@
<item>MODEL=XT1035:MANUFACTURER=motorola,18</item> <item>MODEL=XT1035:MANUFACTURER=motorola,18</item>
<!-- Sony Xperia Z, Z Ultra --> <!-- Sony Xperia Z, Z Ultra -->
<item>MODEL=C6603|C6806:MANUFACTURER=Sony,35</item> <item>MODEL=C6603|C6806:MANUFACTURER=Sony,35</item>
<!-- Default value for unknown device. The negative value means system default. -->
<item>,-1</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -26,7 +26,5 @@
<item>HARDWARE=grouper,0.3f</item> <item>HARDWARE=grouper,0.3f</item>
<item>HARDWARE=mako,0.3f</item> <item>HARDWARE=mako,0.3f</item>
<item>HARDWARE=manta,0.2f</item> <item>HARDWARE=manta,0.2f</item>
<!-- Default value for unknown device. The negative value means system default. -->
<item>,-1.0f</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -23,7 +23,5 @@
See {@link com.android.inputmethod.keyboard.PointerTracker}. --> See {@link com.android.inputmethod.keyboard.PointerTracker}. -->
<!-- Xoom --> <!-- Xoom -->
<item>HARDWARE=stingray,true</item> <item>HARDWARE=stingray,true</item>
<!-- Default value for unknown device -->
<item>,false</item>
</string-array> </string-array>
</resources> </resources>

View File

@ -215,8 +215,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
final Resources res = mainKeyboardViewAttr.getResources(); final Resources res = mainKeyboardViewAttr.getResources();
sNeedsPhantomSuddenMoveEventHack = Boolean.parseBoolean( sNeedsPhantomSuddenMoveEventHack = Boolean.parseBoolean(
ResourceUtils.getDeviceOverrideValue( ResourceUtils.getDeviceOverrideValue(res,
res, R.array.phantom_sudden_move_event_device_list)); R.array.phantom_sudden_move_event_device_list, Boolean.FALSE.toString()));
BogusMoveEventDetector.init(res); BogusMoveEventDetector.init(res);
sTimerProxy = timerProxy; sTimerProxy = timerProxy;

View File

@ -310,9 +310,13 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
: readDefaultKeypressSoundVolume(res); : readDefaultKeypressSoundVolume(res);
} }
// Default keypress sound volume for unknown devices.
// The negative value means system default.
private static final String DEFAULT_KEYPRESS_SOUND_VOLUME = Float.toString(-1.0f);
public static float readDefaultKeypressSoundVolume(final Resources res) { public static float readDefaultKeypressSoundVolume(final Resources res) {
return Float.parseFloat( return Float.parseFloat(ResourceUtils.getDeviceOverrideValue(res,
ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_volumes)); R.array.keypress_volumes, DEFAULT_KEYPRESS_SOUND_VOLUME));
} }
public static int readKeyLongpressTimeout(final SharedPreferences prefs, public static int readKeyLongpressTimeout(final SharedPreferences prefs,
@ -335,9 +339,13 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
: readDefaultKeypressVibrationDuration(res); : readDefaultKeypressVibrationDuration(res);
} }
// Default keypress vibration duration for unknown devices.
// The negative value means system default.
private static final String DEFAULT_KEYPRESS_VIBRATION_DURATION = Integer.toString(-1);
public static int readDefaultKeypressVibrationDuration(final Resources res) { public static int readDefaultKeypressVibrationDuration(final Resources res) {
return Integer.parseInt( return Integer.parseInt(ResourceUtils.getDeviceOverrideValue(res,
ResourceUtils.getDeviceOverrideValue(res, R.array.keypress_vibration_durations)); R.array.keypress_vibration_durations, DEFAULT_KEYPRESS_VIBRATION_DURATION));
} }
public static boolean readUsabilityStudyMode(final SharedPreferences prefs) { public static boolean readUsabilityStudyMode(final SharedPreferences prefs) {

View File

@ -67,7 +67,8 @@ public final class ResourceUtils {
sBuildKeyValuesDebugString = "[" + TextUtils.join(" ", keyValuePairs) + "]"; sBuildKeyValuesDebugString = "[" + TextUtils.join(" ", keyValuePairs) + "]";
} }
public static String getDeviceOverrideValue(final Resources res, final int overrideResId) { public static String getDeviceOverrideValue(final Resources res, final int overrideResId,
final String defaultValue) {
final int orientation = res.getConfiguration().orientation; final int orientation = res.getConfiguration().orientation;
final String key = overrideResId + "-" + orientation; final String key = overrideResId + "-" + orientation;
if (sDeviceOverrideValueMap.containsKey(key)) { if (sDeviceOverrideValueMap.containsKey(key)) {
@ -86,23 +87,6 @@ public final class ResourceUtils {
return overrideValue; return overrideValue;
} }
String defaultValue = null;
try {
defaultValue = findDefaultConstant(overrideArray);
// The defaultValue might be an empty string.
if (defaultValue == null) {
Log.w(TAG, "Couldn't find override value nor default value:"
+ " resource="+ res.getResourceEntryName(overrideResId)
+ " build=" + sBuildKeyValuesDebugString);
} else {
Log.i(TAG, "Found default value:"
+ " resource="+ res.getResourceEntryName(overrideResId)
+ " build=" + sBuildKeyValuesDebugString
+ " default=" + defaultValue);
}
} catch (final DeviceOverridePatternSyntaxError e) {
Log.w(TAG, "Syntax error, ignored", e);
}
sDeviceOverrideValueMap.put(key, defaultValue); sDeviceOverrideValueMap.put(key, defaultValue);
return defaultValue; return defaultValue;
} }
@ -152,8 +136,7 @@ public final class ResourceUtils {
} }
final String condition = conditionConstant.substring(0, posComma); final String condition = conditionConstant.substring(0, posComma);
if (condition.isEmpty()) { if (condition.isEmpty()) {
// Default condition. The default condition should be searched by Log.w(TAG, "Array element has no condition: " + conditionConstant);
// {@link #findConstantForDefault(String[])}.
continue; continue;
} }
try { try {
@ -199,24 +182,6 @@ public final class ResourceUtils {
return matchedAll; return matchedAll;
} }
@UsedForTesting
static String findDefaultConstant(final String[] conditionConstantArray)
throws DeviceOverridePatternSyntaxError {
if (conditionConstantArray == null) {
return null;
}
for (final String condition : conditionConstantArray) {
final int posComma = condition.indexOf(',');
if (posComma < 0) {
throw new DeviceOverridePatternSyntaxError("Array element has no comma", condition);
}
if (posComma == 0) { // condition is empty.
return condition.substring(posComma + 1);
}
}
return null;
}
public static int getDefaultKeyboardWidth(final Resources res) { public static int getDefaultKeyboardWidth(final Resources res) {
final DisplayMetrics dm = res.getDisplayMetrics(); final DisplayMetrics dm = res.getDisplayMetrics();
return dm.widthPixels; return dm.widthPixels;
@ -224,12 +189,13 @@ public final class ResourceUtils {
public static int getDefaultKeyboardHeight(final Resources res) { public static int getDefaultKeyboardHeight(final Resources res) {
final DisplayMetrics dm = res.getDisplayMetrics(); final DisplayMetrics dm = res.getDisplayMetrics();
final String keyboardHeightString = getDeviceOverrideValue(res, R.array.keyboard_heights); final String keyboardHeightInDp = getDeviceOverrideValue(
res, R.array.keyboard_heights, null /* defaultValue */);
final float keyboardHeight; final float keyboardHeight;
if (TextUtils.isEmpty(keyboardHeightString)) { if (TextUtils.isEmpty(keyboardHeightInDp)) {
keyboardHeight = res.getDimension(R.dimen.config_default_keyboard_height); keyboardHeight = res.getDimension(R.dimen.config_default_keyboard_height);
} else { } else {
keyboardHeight = Float.parseFloat(keyboardHeightString) * dm.density; keyboardHeight = Float.parseFloat(keyboardHeightInDp) * dm.density;
} }
final float maxKeyboardHeight = res.getFraction( final float maxKeyboardHeight = res.getFraction(
R.fraction.config_max_keyboard_height, dm.heightPixels, dm.heightPixels); R.fraction.config_max_keyboard_height, dm.heightPixels, dm.heightPixels);

View File

@ -19,43 +19,10 @@ package com.android.inputmethod.latin.utils;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import com.android.inputmethod.latin.utils.ResourceUtils.DeviceOverridePatternSyntaxError;
import java.util.HashMap; import java.util.HashMap;
@SmallTest @SmallTest
public class ResourceUtilsTests extends AndroidTestCase { public class ResourceUtilsTests extends AndroidTestCase {
public void testFindDefaultConstant() {
final String[] nullArray = null;
final String[] emptyArray = {};
final String[] array = {
"HARDWARE=grouper,0.3",
"HARDWARE=mako,0.4",
",defaultValue1",
"HARDWARE=manta,0.2",
",defaultValue2",
};
try {
assertNull(ResourceUtils.findDefaultConstant(nullArray));
assertNull(ResourceUtils.findDefaultConstant(emptyArray));
assertEquals(ResourceUtils.findDefaultConstant(array), "defaultValue1");
} catch (final DeviceOverridePatternSyntaxError e) {
fail(e.getMessage());
}
final String[] errorArray = {
"HARDWARE=grouper,0.3",
"no_comma"
};
try {
final String defaultValue = ResourceUtils.findDefaultConstant(errorArray);
fail("exception should be thrown: defaultValue=" + defaultValue);
} catch (final DeviceOverridePatternSyntaxError e) {
assertEquals("Array element has no comma: no_comma", e.getMessage());
}
}
public void testFindConstantForKeyValuePairsSimple() { public void testFindConstantForKeyValuePairsSimple() {
final HashMap<String,String> anyKeyValue = CollectionUtils.newHashMap(); final HashMap<String,String> anyKeyValue = CollectionUtils.newHashMap();
anyKeyValue.put("anyKey", "anyValue"); anyKeyValue.put("anyKey", "anyValue");