Handle BCP additional fields (script & variant)

layoutDirection was being read in error. layoutDirection is read
via bit shifting over screenLayout (byte 32, 33)

The then removed layoutDirection freed up 2 bytes. This gave us
12 bytes of unknown space from byte 36 to 48. This corresponded
to localeScript[4] and localeVariant[8]

Adding proper support for those bytes fixed BCP support
This commit is contained in:
Connor Tumbleson 2015-02-19 09:05:00 -06:00
parent af65dea319
commit d40710005f

View File

@ -291,9 +291,11 @@ public class ARSCDecoder {
screenHeightDp = mIn.readShort();
}
short layoutDirection = 0;
if (size >= 38) {
layoutDirection = mIn.readShort();
char[] localeScript = {'\00'};
char[] localeVariant = {'\00'};
if (size >= 48) {
localeScript = this.readScriptOrVariantChar(4).toCharArray();
localeVariant = this.readScriptOrVariantChar(8).toCharArray();
}
int exceedingSize = size - KNOWN_CONFIG_BYTES;
@ -313,29 +315,40 @@ public class ARSCDecoder {
}
}
return new ResConfigFlags(mcc, mnc, language, country, layoutDirection,
return new ResConfigFlags(mcc, mnc, language, country,
orientation, touchscreen, density, keyboard, navigation,
inputFlags, screenWidth, screenHeight, sdkVersion,
screenLayout, uiMode, smallestScreenWidthDp, screenWidthDp,
screenHeightDp, isInvalid);
screenHeightDp, localeScript, localeVariant, isInvalid);
}
private char[] unpackLanguageOrRegion(byte in0, byte in1, char base) throws AndrolibException {
if (in0 == 0 && in1 == 0) {
return new char[] {(char) in0, (char) in1};
} else {
// check high bit, if so we have a packed 3 letter code
if (((in0 >> 7) & 1) == 1) {
int first = in1 & 0x1F;
int second = ((in1 & 0xE0) >> 5) + ((in0 & 0x03) << 3);
int third = (in0 & 0x7C) >> 2;
// check high bit, if so we have a packed 3 letter code
if (((in0 >> 7) & 1) == 1) {
int first = in1 & 0x1F;
int second = ((in1 & 0xE0) >> 5) + ((in0 & 0x03) << 3);
int third = (in0 & 0x7C) >> 2;
// since this function handles languages & regions, we add the value(s) to the base char
// which is usually 'a' or '0' depending on language or region.
return new char[] { (char) (first + base), (char) (second + base), (char) (third + base) };
}
return new char[] { (char) in0, (char) in1 };
// since this function handles languages & regions, we add the value(s) to the base char
// which is usually 'a' or '0' depending on language or region.
return new char[] { (char) (first + base), (char) (second + base), (char) (third + base) };
}
return new char[] { (char) in0, (char) in1 };
}
private String readScriptOrVariantChar(int length) throws AndrolibException, IOException {
StringBuilder string = new StringBuilder(16);
while(length-- != 0) {
short ch = mIn.readByte();
if (ch == 0) {
break;
}
string.append((char) ch);
}
mIn.skipBytes(length);
return string.toString();
}
private void addMissingResSpecs() throws AndrolibException {
@ -434,7 +447,7 @@ public class ARSCDecoder {
}
private static final Logger LOGGER = Logger.getLogger(ARSCDecoder.class.getName());
private static final int KNOWN_CONFIG_BYTES = 38;
private static final int KNOWN_CONFIG_BYTES = 48;
public static class ARSCData {