mirror of
https://github.com/revanced/Apktool.git
synced 2025-04-30 22:24:25 +02:00
Added current version.
This commit is contained in:
commit
48e1afd6b1
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/nbproject
|
||||
/build
|
||||
/dist
|
||||
/build.xml
|
||||
|
74
src/android/content/res/StringBlock.java
Normal file
74
src/android/content/res/StringBlock.java
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import brut.util.Jar;
|
||||
|
||||
|
||||
/**
|
||||
* Conveniences for retrieving data out of a compiled string resource.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
final class StringBlock {
|
||||
static {
|
||||
Jar.load("/libAndroid.so");
|
||||
}
|
||||
|
||||
private final int mNative;
|
||||
private final boolean mOwnsNative;
|
||||
private CharSequence[] mStrings;
|
||||
|
||||
public CharSequence get(int idx) {
|
||||
synchronized (this) {
|
||||
if (mStrings != null) {
|
||||
CharSequence res = mStrings[idx];
|
||||
if (res != null) {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
final int num = nativeGetSize(mNative);
|
||||
mStrings = new CharSequence[num];
|
||||
}
|
||||
String str = nativeGetString(mNative, idx);
|
||||
CharSequence res = str;
|
||||
mStrings[idx] = res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
if (mOwnsNative) {
|
||||
nativeDestroy(mNative);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from an existing string block native object. This is
|
||||
* -extremely- dangerous -- only use it if you absolutely know what you
|
||||
* are doing! The given native object must exist for the entire lifetime
|
||||
* of this newly creating StringBlock.
|
||||
*/
|
||||
StringBlock(int obj, boolean useSparse) {
|
||||
mNative = obj;
|
||||
mOwnsNative = false;
|
||||
}
|
||||
|
||||
private static final native int nativeGetSize(int obj);
|
||||
private static final native String nativeGetString(int obj, int idx);
|
||||
private static final native void nativeDestroy(int obj);
|
||||
}
|
364
src/android/content/res/XmlBlock.java
Normal file
364
src/android/content/res/XmlBlock.java
Normal file
@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import android.util.TypedValue;
|
||||
|
||||
import brut.util.Jar;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* Wrapper around a compiled XML file.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
final public class XmlBlock {
|
||||
static {
|
||||
Jar.load("/libAndroid.so");
|
||||
}
|
||||
|
||||
private static final boolean DEBUG=false;
|
||||
|
||||
public XmlBlock(byte[] data) {
|
||||
mNative = nativeCreate(data, 0, data.length);
|
||||
mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
|
||||
}
|
||||
|
||||
public XmlBlock(byte[] data, int offset, int size) {
|
||||
mNative = nativeCreate(data, offset, size);
|
||||
mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
synchronized (this) {
|
||||
if (mOpen) {
|
||||
mOpen = false;
|
||||
decOpenCountLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void decOpenCountLocked() {
|
||||
mOpenCount--;
|
||||
if (mOpenCount == 0) {
|
||||
nativeDestroy(mNative);
|
||||
}
|
||||
}
|
||||
|
||||
public XmlPullParser newParser() {
|
||||
synchronized (this) {
|
||||
if (mNative != 0) {
|
||||
return new Parser(nativeCreateParseState(mNative), this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ final class Parser implements XmlPullParser {
|
||||
Parser(int parseState, XmlBlock block) {
|
||||
mParseState = parseState;
|
||||
mBlock = block;
|
||||
block.mOpenCount++;
|
||||
}
|
||||
|
||||
public void setFeature(String name, boolean state) throws XmlPullParserException {
|
||||
if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
|
||||
return;
|
||||
}
|
||||
if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
|
||||
return;
|
||||
}
|
||||
throw new XmlPullParserException("Unsupported feature: " + name);
|
||||
}
|
||||
public boolean getFeature(String name) {
|
||||
if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void setProperty(String name, Object value) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("setProperty() not supported");
|
||||
}
|
||||
public Object getProperty(String name) {
|
||||
return null;
|
||||
}
|
||||
public void setInput(Reader in) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("setInput() not supported");
|
||||
}
|
||||
public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("setInput() not supported");
|
||||
}
|
||||
public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("defineEntityReplacementText() not supported");
|
||||
}
|
||||
public String getNamespacePrefix(int pos) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("getNamespacePrefix() not supported");
|
||||
}
|
||||
public String getInputEncoding() {
|
||||
return null;
|
||||
}
|
||||
public String getNamespace(String prefix) {
|
||||
throw new RuntimeException("getNamespace() not supported");
|
||||
}
|
||||
public int getNamespaceCount(int depth) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("getNamespaceCount() not supported");
|
||||
}
|
||||
public String getPositionDescription() {
|
||||
return "Binary XML file line #" + getLineNumber();
|
||||
}
|
||||
public String getNamespaceUri(int pos) throws XmlPullParserException {
|
||||
throw new XmlPullParserException("getNamespaceUri() not supported");
|
||||
}
|
||||
public int getColumnNumber() {
|
||||
return -1;
|
||||
}
|
||||
public int getDepth() {
|
||||
return mDepth;
|
||||
}
|
||||
public String getText() {
|
||||
int id = nativeGetText(mParseState);
|
||||
return id >= 0 ? mStrings.get(id).toString() : null;
|
||||
}
|
||||
public int getLineNumber() {
|
||||
return nativeGetLineNumber(mParseState);
|
||||
}
|
||||
public int getEventType() throws XmlPullParserException {
|
||||
return mEventType;
|
||||
}
|
||||
public boolean isWhitespace() throws XmlPullParserException {
|
||||
// whitespace was stripped by aapt.
|
||||
return false;
|
||||
}
|
||||
public String getPrefix() {
|
||||
throw new RuntimeException("getPrefix not supported");
|
||||
}
|
||||
public char[] getTextCharacters(int[] holderForStartAndLength) {
|
||||
String txt = getText();
|
||||
char[] chars = null;
|
||||
if (txt != null) {
|
||||
holderForStartAndLength[0] = 0;
|
||||
holderForStartAndLength[1] = txt.length();
|
||||
chars = new char[txt.length()];
|
||||
txt.getChars(0, txt.length(), chars, 0);
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
public String getNamespace() {
|
||||
int id = nativeGetNamespace(mParseState);
|
||||
return id >= 0 ? mStrings.get(id).toString() : "";
|
||||
}
|
||||
public String getName() {
|
||||
int id = nativeGetName(mParseState);
|
||||
return id >= 0 ? mStrings.get(id).toString() : null;
|
||||
}
|
||||
public String getAttributeNamespace(int index) {
|
||||
int id = nativeGetAttributeNamespace(mParseState, index);
|
||||
if (DEBUG) System.out.println("getAttributeNamespace of " + index + " = " + id);
|
||||
if (id >= 0) return mStrings.get(id).toString();
|
||||
else if (id == -1) return "";
|
||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
||||
}
|
||||
public String getAttributeName(int index) {
|
||||
int id = nativeGetAttributeName(mParseState, index);
|
||||
if (DEBUG) System.out.println("getAttributeName of " + index + " = " + id);
|
||||
if (id >= 0) return mStrings.get(id).toString();
|
||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
||||
}
|
||||
public String getAttributePrefix(int index) {
|
||||
throw new RuntimeException("getAttributePrefix not supported");
|
||||
}
|
||||
public boolean isEmptyElementTag() throws XmlPullParserException {
|
||||
// XXX Need to detect this.
|
||||
return false;
|
||||
}
|
||||
public int getAttributeCount() {
|
||||
return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1;
|
||||
}
|
||||
public String getAttributeValue(int index) {
|
||||
int id = nativeGetAttributeStringValue(mParseState, index);
|
||||
if (DEBUG) System.out.println("getAttributeValue of " + index + " = " + id);
|
||||
if (id >= 0) return mStrings.get(id).toString();
|
||||
|
||||
// May be some other type... check and try to convert if so.
|
||||
int t = nativeGetAttributeDataType(mParseState, index);
|
||||
if (t == TypedValue.TYPE_NULL) {
|
||||
throw new IndexOutOfBoundsException(String.valueOf(index));
|
||||
}
|
||||
|
||||
int v = nativeGetAttributeData(mParseState, index);
|
||||
return TypedValue.coerceToString(t, v);
|
||||
}
|
||||
public String getAttributeType(int index) {
|
||||
return "CDATA";
|
||||
}
|
||||
public boolean isAttributeDefault(int index) {
|
||||
return false;
|
||||
}
|
||||
public int nextToken() throws XmlPullParserException,IOException {
|
||||
return next();
|
||||
}
|
||||
public String getAttributeValue(String namespace, String name) {
|
||||
int idx = nativeGetAttributeIndex(mParseState, namespace, name);
|
||||
if (idx >= 0) {
|
||||
if (DEBUG) System.out.println("getAttributeName of "
|
||||
+ namespace + ":" + name + " index = " + idx);
|
||||
if (DEBUG) System.out.println(
|
||||
"Namespace=" + getAttributeNamespace(idx)
|
||||
+ "Name=" + getAttributeName(idx)
|
||||
+ ", Value=" + getAttributeValue(idx));
|
||||
return getAttributeValue(idx);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public int next() throws XmlPullParserException,IOException {
|
||||
if (!mStarted) {
|
||||
mStarted = true;
|
||||
return START_DOCUMENT;
|
||||
}
|
||||
if (mParseState == 0) {
|
||||
return END_DOCUMENT;
|
||||
}
|
||||
int ev = nativeNext(mParseState);
|
||||
if (mDecNextDepth) {
|
||||
mDepth--;
|
||||
mDecNextDepth = false;
|
||||
}
|
||||
switch (ev) {
|
||||
case START_TAG:
|
||||
mDepth++;
|
||||
break;
|
||||
case END_TAG:
|
||||
mDecNextDepth = true;
|
||||
break;
|
||||
}
|
||||
mEventType = ev;
|
||||
if (ev == END_DOCUMENT) {
|
||||
// Automatically close the parse when we reach the end of
|
||||
// a document, since the standard XmlPullParser interface
|
||||
// doesn't have such an API so most clients will leave us
|
||||
// dangling.
|
||||
close();
|
||||
}
|
||||
return ev;
|
||||
}
|
||||
public void require(int type, String namespace, String name) throws XmlPullParserException,IOException {
|
||||
if (type != getEventType()
|
||||
|| (namespace != null && !namespace.equals( getNamespace () ) )
|
||||
|| (name != null && !name.equals( getName() ) ) )
|
||||
throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
|
||||
}
|
||||
public String nextText() throws XmlPullParserException,IOException {
|
||||
if(getEventType() != START_TAG) {
|
||||
throw new XmlPullParserException(
|
||||
getPositionDescription()
|
||||
+ ": parser must be on START_TAG to read next text", this, null);
|
||||
}
|
||||
int eventType = next();
|
||||
if(eventType == TEXT) {
|
||||
String result = getText();
|
||||
eventType = next();
|
||||
if(eventType != END_TAG) {
|
||||
throw new XmlPullParserException(
|
||||
getPositionDescription()
|
||||
+ ": event TEXT it must be immediately followed by END_TAG", this, null);
|
||||
}
|
||||
return result;
|
||||
} else if(eventType == END_TAG) {
|
||||
return "";
|
||||
} else {
|
||||
throw new XmlPullParserException(
|
||||
getPositionDescription()
|
||||
+ ": parser must be on START_TAG or TEXT to read text", this, null);
|
||||
}
|
||||
}
|
||||
public int nextTag() throws XmlPullParserException,IOException {
|
||||
int eventType = next();
|
||||
if(eventType == TEXT && isWhitespace()) { // skip whitespace
|
||||
eventType = next();
|
||||
}
|
||||
if (eventType != START_TAG && eventType != END_TAG) {
|
||||
throw new XmlPullParserException(
|
||||
getPositionDescription()
|
||||
+ ": expected start or end tag", this, null);
|
||||
}
|
||||
return eventType;
|
||||
}
|
||||
public void close() {
|
||||
synchronized (mBlock) {
|
||||
if (mParseState != 0) {
|
||||
nativeDestroyParseState(mParseState);
|
||||
mParseState = 0;
|
||||
mBlock.decOpenCountLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
|
||||
/*package*/ final CharSequence getPooledString(int id) {
|
||||
return mStrings.get(id);
|
||||
}
|
||||
|
||||
/*package*/ int mParseState;
|
||||
private final XmlBlock mBlock;
|
||||
private boolean mStarted = false;
|
||||
private boolean mDecNextDepth = false;
|
||||
private int mDepth = 0;
|
||||
private int mEventType = START_DOCUMENT;
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
|
||||
private final int mNative;
|
||||
private final StringBlock mStrings;
|
||||
private boolean mOpen = true;
|
||||
private int mOpenCount = 1;
|
||||
|
||||
private static final native int nativeCreate(byte[] data,
|
||||
int offset,
|
||||
int size);
|
||||
private static final native int nativeGetStringBlock(int obj);
|
||||
|
||||
private static final native int nativeCreateParseState(int obj);
|
||||
private static final native int nativeNext(int state);
|
||||
private static final native int nativeGetNamespace(int state);
|
||||
private static final native int nativeGetName(int state);
|
||||
private static final native int nativeGetText(int state);
|
||||
private static final native int nativeGetLineNumber(int state);
|
||||
private static final native int nativeGetAttributeCount(int state);
|
||||
private static final native int nativeGetAttributeNamespace(int state, int idx);
|
||||
private static final native int nativeGetAttributeName(int state, int idx);
|
||||
private static final native int nativeGetAttributeDataType(int state, int idx);
|
||||
private static final native int nativeGetAttributeData(int state, int idx);
|
||||
private static final native int nativeGetAttributeStringValue(int state, int idx);
|
||||
private static final native int nativeGetAttributeIndex(int state, String namespace, String name);
|
||||
private static final native void nativeDestroyParseState(int state);
|
||||
|
||||
private static final native void nativeDestroy(int obj);
|
||||
}
|
234
src/android/util/TypedValue.java
Normal file
234
src/android/util/TypedValue.java
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.util;
|
||||
|
||||
/**
|
||||
* Container for a dynamically typed data value. Primarily used with
|
||||
* {@link android.content.res.Resources} for holding resource values.
|
||||
*/
|
||||
public class TypedValue {
|
||||
/** The value contains no data. */
|
||||
public static final int TYPE_NULL = 0x00;
|
||||
|
||||
/** The <var>data</var> field holds a resource identifier. */
|
||||
public static final int TYPE_REFERENCE = 0x01;
|
||||
/** The <var>data</var> field holds an attribute resource
|
||||
* identifier (referencing an attribute in the current theme
|
||||
* style, not a resource entry). */
|
||||
public static final int TYPE_ATTRIBUTE = 0x02;
|
||||
/** The <var>string</var> field holds string data. In addition, if
|
||||
* <var>data</var> is non-zero then it is the string block
|
||||
* index of the string and <var>assetCookie</var> is the set of
|
||||
* assets the string came from. */
|
||||
public static final int TYPE_STRING = 0x03;
|
||||
/** The <var>data</var> field holds an IEEE 754 floating point number. */
|
||||
public static final int TYPE_FLOAT = 0x04;
|
||||
/** The <var>data</var> field holds a complex number encoding a
|
||||
* dimension value. */
|
||||
public static final int TYPE_DIMENSION = 0x05;
|
||||
/** The <var>data</var> field holds a complex number encoding a fraction
|
||||
* of a container. */
|
||||
public static final int TYPE_FRACTION = 0x06;
|
||||
|
||||
/** Identifies the start of plain integer values. Any type value
|
||||
* from this to {@link #TYPE_LAST_INT} means the
|
||||
* <var>data</var> field holds a generic integer value. */
|
||||
public static final int TYPE_FIRST_INT = 0x10;
|
||||
|
||||
/** The <var>data</var> field holds a number that was
|
||||
* originally specified in decimal. */
|
||||
public static final int TYPE_INT_DEC = 0x10;
|
||||
/** The <var>data</var> field holds a number that was
|
||||
* originally specified in hexadecimal (0xn). */
|
||||
public static final int TYPE_INT_HEX = 0x11;
|
||||
/** The <var>data</var> field holds 0 or 1 that was originally
|
||||
* specified as "false" or "true". */
|
||||
public static final int TYPE_INT_BOOLEAN = 0x12;
|
||||
|
||||
/** Identifies the start of integer values that were specified as
|
||||
* color constants (starting with '#'). */
|
||||
public static final int TYPE_FIRST_COLOR_INT = 0x1c;
|
||||
|
||||
/** The <var>data</var> field holds a color that was originally
|
||||
* specified as #aarrggbb. */
|
||||
public static final int TYPE_INT_COLOR_ARGB8 = 0x1c;
|
||||
/** The <var>data</var> field holds a color that was originally
|
||||
* specified as #rrggbb. */
|
||||
public static final int TYPE_INT_COLOR_RGB8 = 0x1d;
|
||||
/** The <var>data</var> field holds a color that was originally
|
||||
* specified as #argb. */
|
||||
public static final int TYPE_INT_COLOR_ARGB4 = 0x1e;
|
||||
/** The <var>data</var> field holds a color that was originally
|
||||
* specified as #rgb. */
|
||||
public static final int TYPE_INT_COLOR_RGB4 = 0x1f;
|
||||
|
||||
/** Identifies the end of integer values that were specified as color
|
||||
* constants. */
|
||||
public static final int TYPE_LAST_COLOR_INT = 0x1f;
|
||||
|
||||
/** Identifies the end of plain integer values. */
|
||||
public static final int TYPE_LAST_INT = 0x1f;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** Complex data: bit location of unit information. */
|
||||
public static final int COMPLEX_UNIT_SHIFT = 0;
|
||||
/** Complex data: mask to extract unit information (after shifting by
|
||||
* {@link #COMPLEX_UNIT_SHIFT}). This gives us 16 possible types, as
|
||||
* defined below. */
|
||||
public static final int COMPLEX_UNIT_MASK = 0xf;
|
||||
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
|
||||
public static final int COMPLEX_UNIT_PX = 0;
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
|
||||
* Pixels. */
|
||||
public static final int COMPLEX_UNIT_DIP = 1;
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
|
||||
public static final int COMPLEX_UNIT_SP = 2;
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
|
||||
public static final int COMPLEX_UNIT_PT = 3;
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
|
||||
public static final int COMPLEX_UNIT_IN = 4;
|
||||
/** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
|
||||
public static final int COMPLEX_UNIT_MM = 5;
|
||||
|
||||
/** {@link #TYPE_FRACTION} complex unit: A basic fraction of the overall
|
||||
* size. */
|
||||
public static final int COMPLEX_UNIT_FRACTION = 0;
|
||||
/** {@link #TYPE_FRACTION} complex unit: A fraction of the parent size. */
|
||||
public static final int COMPLEX_UNIT_FRACTION_PARENT = 1;
|
||||
|
||||
/** Complex data: where the radix information is, telling where the decimal
|
||||
* place appears in the mantissa. */
|
||||
public static final int COMPLEX_RADIX_SHIFT = 4;
|
||||
/** Complex data: mask to extract radix information (after shifting by
|
||||
* {@link #COMPLEX_RADIX_SHIFT}). This give us 4 possible fixed point
|
||||
* representations as defined below. */
|
||||
public static final int COMPLEX_RADIX_MASK = 0x3;
|
||||
|
||||
/** Complex data: the mantissa is an integral number -- i.e., 0xnnnnnn.0 */
|
||||
public static final int COMPLEX_RADIX_23p0 = 0;
|
||||
/** Complex data: the mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn */
|
||||
public static final int COMPLEX_RADIX_16p7 = 1;
|
||||
/** Complex data: the mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn */
|
||||
public static final int COMPLEX_RADIX_8p15 = 2;
|
||||
/** Complex data: the mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn */
|
||||
public static final int COMPLEX_RADIX_0p23 = 3;
|
||||
|
||||
/** Complex data: bit location of mantissa information. */
|
||||
public static final int COMPLEX_MANTISSA_SHIFT = 8;
|
||||
/** Complex data: mask to extract mantissa information (after shifting by
|
||||
* {@link #COMPLEX_MANTISSA_SHIFT}). This gives us 23 bits of precision;
|
||||
* the top bit is the sign. */
|
||||
public static final int COMPLEX_MANTISSA_MASK = 0xffffff;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* If {@link #density} is equal to this value, then the density should be
|
||||
* treated as the system's default density value: {@link DisplayMetrics#DENSITY_DEFAULT}.
|
||||
*/
|
||||
public static final int DENSITY_DEFAULT = 0;
|
||||
|
||||
/**
|
||||
* If {@link #density} is equal to this value, then there is no density
|
||||
* associated with the resource and it should not be scaled.
|
||||
*/
|
||||
public static final int DENSITY_NONE = 0xffff;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
/** The type held by this value, as defined by the constants here.
|
||||
* This tells you how to interpret the other fields in the object. */
|
||||
public int type;
|
||||
|
||||
private static final float MANTISSA_MULT =
|
||||
1.0f / (1<<TypedValue.COMPLEX_MANTISSA_SHIFT);
|
||||
private static final float[] RADIX_MULTS = new float[] {
|
||||
1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
|
||||
1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the base value from a complex data integer. This uses the
|
||||
* {@link #COMPLEX_MANTISSA_MASK} and {@link #COMPLEX_RADIX_MASK} fields of
|
||||
* the data to compute a floating point representation of the number they
|
||||
* describe. The units are ignored.
|
||||
*
|
||||
* @param complex A complex data value.
|
||||
*
|
||||
* @return A floating point value corresponding to the complex data.
|
||||
*/
|
||||
public static float complexToFloat(int complex)
|
||||
{
|
||||
return (complex&(TypedValue.COMPLEX_MANTISSA_MASK
|
||||
<<TypedValue.COMPLEX_MANTISSA_SHIFT))
|
||||
* RADIX_MULTS[(complex>>TypedValue.COMPLEX_RADIX_SHIFT)
|
||||
& TypedValue.COMPLEX_RADIX_MASK];
|
||||
}
|
||||
|
||||
private static final String[] DIMENSION_UNIT_STRS = new String[] {
|
||||
"px", "dip", "sp", "pt", "in", "mm"
|
||||
};
|
||||
private static final String[] FRACTION_UNIT_STRS = new String[] {
|
||||
"%", "%p"
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform type conversion as per {@link #coerceToString()} on an
|
||||
* explicitly supplied type and data.
|
||||
*
|
||||
* @param type The data type identifier.
|
||||
* @param data The data value.
|
||||
*
|
||||
* @return String The coerced string value. If the value is
|
||||
* null or the type is not known, null is returned.
|
||||
*/
|
||||
public static final String coerceToString(int type, int data)
|
||||
{
|
||||
switch (type) {
|
||||
case TYPE_NULL:
|
||||
return null;
|
||||
case TYPE_REFERENCE:
|
||||
return "@" + data;
|
||||
case TYPE_ATTRIBUTE:
|
||||
return "?" + data;
|
||||
case TYPE_FLOAT:
|
||||
return Float.toString(Float.intBitsToFloat(data));
|
||||
case TYPE_DIMENSION:
|
||||
return Float.toString(complexToFloat(data)) + DIMENSION_UNIT_STRS[
|
||||
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
|
||||
case TYPE_FRACTION:
|
||||
return Float.toString(complexToFloat(data)*100) + FRACTION_UNIT_STRS[
|
||||
(data>>COMPLEX_UNIT_SHIFT)&COMPLEX_UNIT_MASK];
|
||||
case TYPE_INT_HEX:
|
||||
return "0x" + Integer.toHexString(data);
|
||||
case TYPE_INT_BOOLEAN:
|
||||
return data != 0 ? "true" : "false";
|
||||
}
|
||||
|
||||
if (type >= TYPE_FIRST_COLOR_INT && type <= TYPE_LAST_COLOR_INT) {
|
||||
return "#" + Integer.toHexString(data);
|
||||
} else if (type >= TYPE_FIRST_INT && type <= TYPE_LAST_INT) {
|
||||
return Integer.toString(data);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
152
src/brut/androlib/Androlib.java
Normal file
152
src/brut/androlib/Androlib.java
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib;
|
||||
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.data.ResTable;
|
||||
import brut.common.BrutException;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import brut.directory.FileDirectory;
|
||||
import brut.directory.Util;
|
||||
import brut.directory.ZipRODirectory;
|
||||
import brut.util.OS;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class Androlib {
|
||||
private final String mAndroidJar;
|
||||
private final AndrolibResources mAndRes;
|
||||
private final AndrolibSmali mSmali;
|
||||
|
||||
public Androlib(String androidJar) {
|
||||
mAndroidJar = androidJar;
|
||||
mAndRes = new AndrolibResources(mAndroidJar);
|
||||
mSmali = new AndrolibSmali();
|
||||
}
|
||||
|
||||
public void decode(String apkFileName, String outDirName)
|
||||
throws AndrolibException {
|
||||
decode(new File(apkFileName), new File(outDirName));
|
||||
}
|
||||
|
||||
public void decode(File apkFile, File outDir)
|
||||
throws AndrolibException {
|
||||
try {
|
||||
OS.rmdir(outDir);
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
outDir.mkdirs();
|
||||
|
||||
ResTable resTable = mAndRes.getResTable(apkFile);
|
||||
|
||||
mAndRes.decode(resTable, apkFile, outDir);
|
||||
|
||||
File smaliDir = new File(outDir.getPath() + "/smali");
|
||||
mSmali.baksmali(apkFile, smaliDir);
|
||||
mAndRes.tagSmaliResIDs(resTable, smaliDir);
|
||||
|
||||
try {
|
||||
Directory in = new ZipRODirectory(apkFile);
|
||||
Directory out = new FileDirectory(outDir);
|
||||
if (in.containsDir("assets")) {
|
||||
Util.copyFiles(in.getDir("assets"), out.createDir("assets"));
|
||||
}
|
||||
if (in.containsDir("lib")) {
|
||||
Util.copyFiles(in.getDir("lib"), out.createDir("lib"));
|
||||
}
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException("Could not decode apk", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildAll() throws AndrolibException {
|
||||
clean();
|
||||
new File("build/apk").mkdirs();
|
||||
buildCopyRawFiles();
|
||||
buildResources();
|
||||
buildClasses();
|
||||
buildPackage();
|
||||
}
|
||||
|
||||
public void clean() throws AndrolibException {
|
||||
try {
|
||||
OS.rmdir("build");
|
||||
OS.rmdir("dist");
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildCopyRawFiles() throws AndrolibException {
|
||||
try {
|
||||
if (new File("assets").exists()) {
|
||||
OS.cpdir("assets", "build/apk/assets");
|
||||
}
|
||||
if (new File("lib").exists()) {
|
||||
OS.cpdir("lib", "build/apk/lib");
|
||||
}
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void buildResources() throws AndrolibException {
|
||||
File apkFile;
|
||||
try {
|
||||
apkFile = File.createTempFile("APKTOOL", null);
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
apkFile.delete();
|
||||
|
||||
mAndRes.aaptPackage(
|
||||
apkFile,
|
||||
new File("AndroidManifest.xml"),
|
||||
new File("res")
|
||||
);
|
||||
mAndRes.updateSmaliResIDs(
|
||||
mAndRes.getResTable(apkFile), new File("smali"));
|
||||
|
||||
try {
|
||||
Util.copyFiles(new ZipRODirectory(apkFile),
|
||||
new FileDirectory("build/apk"));
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
|
||||
apkFile.delete();
|
||||
}
|
||||
|
||||
public void buildClasses() throws AndrolibException {
|
||||
new AndrolibSmali().smali("smali", "build/apk/classes.dex");
|
||||
}
|
||||
|
||||
public void buildPackage() throws AndrolibException {
|
||||
File distDir = new File("dist");
|
||||
if (! distDir.exists()) {
|
||||
distDir.mkdirs();
|
||||
}
|
||||
mAndRes.aaptPackage(new File("dist/out.apk"), null, null,
|
||||
new File("build/apk"), false);
|
||||
}
|
||||
}
|
40
src/brut/androlib/AndrolibException.java
Normal file
40
src/brut/androlib/AndrolibException.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib;
|
||||
|
||||
import brut.common.BrutException;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class AndrolibException extends BrutException {
|
||||
public AndrolibException() {
|
||||
}
|
||||
|
||||
public AndrolibException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AndrolibException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AndrolibException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
50
src/brut/androlib/AndrolibSmali.java
Normal file
50
src/brut/androlib/AndrolibSmali.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.jf.baksmali.baksmali;
|
||||
import org.jf.dexlib.DexFile;
|
||||
import org.jf.smali.main;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
class AndrolibSmali {
|
||||
public void baksmali(File apkFile, File dir) throws AndrolibException {
|
||||
baksmali(apkFile.getAbsolutePath(), dir.getAbsolutePath());
|
||||
}
|
||||
|
||||
public void baksmali(String apkFile, String dir) throws AndrolibException {
|
||||
try {
|
||||
DexFile dexFile = new DexFile(apkFile);
|
||||
baksmali.disassembleDexFile(dexFile, false, dir, new String[]{}, "", false, true, true, true, false, 0, false);
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void smali(File dir, File dexFile) throws AndrolibException {
|
||||
smali(dir.getAbsolutePath(), dexFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
public void smali(String dir, String dexFile) throws AndrolibException {
|
||||
main.main(new String[]{"smali", dir, "-o", dexFile});
|
||||
}
|
||||
}
|
146
src/brut/androlib/ApkFile.java
Normal file
146
src/brut/androlib/ApkFile.java
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib;
|
||||
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.data.ResTable;
|
||||
import brut.common.BrutException;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import brut.directory.FileDirectory;
|
||||
import brut.directory.ZipRODirectory;
|
||||
import brut.util.OS;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ApkFile {
|
||||
private final AndrolibResources mAndRes;
|
||||
private final File mApkFile;
|
||||
private final AndrolibSmali mSmali;
|
||||
|
||||
private ResTable mResTable;
|
||||
|
||||
public ApkFile(AndrolibResources andRes, String apkFileName) {
|
||||
this(andRes, new File(apkFileName));
|
||||
}
|
||||
|
||||
public ApkFile(AndrolibResources andRes, File apkFile) {
|
||||
mAndRes = andRes;
|
||||
mApkFile = apkFile;
|
||||
mSmali = new AndrolibSmali();
|
||||
}
|
||||
|
||||
public void decode(String outDirName) throws AndrolibException {
|
||||
decode(new File(outDirName));
|
||||
}
|
||||
|
||||
public void decode(File outDir) throws AndrolibException {
|
||||
if (outDir.exists()) {
|
||||
throw new AndrolibException("Output directory already exists: " +
|
||||
outDir.getAbsolutePath());
|
||||
}
|
||||
outDir.mkdirs();
|
||||
|
||||
File smaliDir = new File(outDir.getPath() + "/smali");
|
||||
|
||||
mAndRes.decode(getResTable(), mApkFile, outDir);
|
||||
mSmali.baksmali(mApkFile, smaliDir);
|
||||
mAndRes.tagSmaliResIDs(getResTable(), smaliDir);
|
||||
|
||||
try {
|
||||
Directory in = new ZipRODirectory(mApkFile);
|
||||
Directory out = new FileDirectory(outDir);
|
||||
if (in.containsDir("assets")) {
|
||||
Directory in2 = in.getDir("assets");
|
||||
Directory out2 = out.createDir("assets");
|
||||
for (String fileName : in2.getFiles(true)) {
|
||||
IOUtils.copy(in2.getFileInput(fileName),
|
||||
out2.getFileOutput(fileName));
|
||||
}
|
||||
}
|
||||
if (in.containsDir("lib")) {
|
||||
Directory in2 = in.getDir("lib");
|
||||
Directory out2 = out.createDir("lib");
|
||||
for (String fileName : in2.getFiles(true)) {
|
||||
IOUtils.copy(in2.getFileInput(fileName),
|
||||
out2.getFileOutput(fileName));
|
||||
}
|
||||
}
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException("Could not decode apk", ex);
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException("Could not decode apk", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void build(String inDir) throws AndrolibException {
|
||||
build(new File(inDir));
|
||||
}
|
||||
|
||||
public void build(File inDir) throws AndrolibException {
|
||||
try {
|
||||
File smaliDir = new File(inDir.getPath() + "/smali");
|
||||
|
||||
mAndRes.aaptPackage(
|
||||
mApkFile,
|
||||
new File(inDir.getPath() + "/AndroidManifest.xml"),
|
||||
new File(inDir.getPath() + "/res")
|
||||
);
|
||||
mAndRes.updateSmaliResIDs(getResTable(), smaliDir);
|
||||
|
||||
File tmpDir = OS.createTempDirectory();
|
||||
try {
|
||||
mSmali.smali(smaliDir,
|
||||
new File(tmpDir.getPath() + "/classes.dex"));
|
||||
if (new File(inDir.getPath() + "/assets").exists()) {
|
||||
OS.cpdir(inDir.getPath() + "/assets",
|
||||
tmpDir.getPath() + "/assets");
|
||||
}
|
||||
if (new File(inDir.getPath() + "/lib").exists()) {
|
||||
OS.cpdir(inDir.getPath() + "/lib",
|
||||
tmpDir.getPath() + "/lib");
|
||||
}
|
||||
|
||||
mAndRes.aaptPackage(
|
||||
mApkFile,
|
||||
null,
|
||||
null,
|
||||
tmpDir,
|
||||
true
|
||||
);
|
||||
|
||||
} finally {
|
||||
OS.rmdir(tmpDir);
|
||||
}
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not build apk for dir: " + inDir.getAbsolutePath(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ResTable getResTable() throws AndrolibException {
|
||||
if (mResTable == null) {
|
||||
mResTable = mAndRes.getResTable(mApkFile);
|
||||
}
|
||||
return mResTable;
|
||||
}
|
||||
}
|
218
src/brut/androlib/res/AndrolibResources.java
Normal file
218
src/brut/androlib/res/AndrolibResources.java
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res;
|
||||
|
||||
import brut.androlib.*;
|
||||
import brut.androlib.res.data.*;
|
||||
import brut.androlib.res.data.value.ResFileValue;
|
||||
import brut.androlib.res.data.value.ResXmlSerializable;
|
||||
import brut.androlib.res.decoder.*;
|
||||
import brut.androlib.res.jni.JniPackage;
|
||||
import brut.androlib.res.jni.JniPackageGroup;
|
||||
import brut.common.BrutException;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import brut.directory.FileDirectory;
|
||||
import brut.directory.ZipRODirectory;
|
||||
import brut.util.Jar;
|
||||
import brut.util.OS;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
final public class AndrolibResources {
|
||||
static {
|
||||
Jar.load("/libAndroid.so");
|
||||
}
|
||||
|
||||
private final File mAndroidJar;
|
||||
|
||||
public AndrolibResources(String androidJar) {
|
||||
this(new File(androidJar));
|
||||
}
|
||||
|
||||
public AndrolibResources(File androidJar) {
|
||||
this.mAndroidJar = androidJar;
|
||||
}
|
||||
|
||||
public ResTable getResTable(File apkFile) throws AndrolibException {
|
||||
ResTable resTable = new ResTable();
|
||||
loadApk(resTable, new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath()), false);
|
||||
loadApk(resTable, apkFile, true);
|
||||
return resTable;
|
||||
}
|
||||
|
||||
public void decode(ResTable resTable, File apkFile, File outDir)
|
||||
throws AndrolibException {
|
||||
ResXmlSerializer serial = getResXmlSerializer(resTable);
|
||||
ResFileDecoder fileDecoder = getResFileDecoder(serial);
|
||||
serial.setCurrentPackage(
|
||||
resTable.listMainPackages().iterator().next());
|
||||
|
||||
Directory in, out;
|
||||
try {
|
||||
in = new ZipRODirectory(apkFile);
|
||||
out = new FileDirectory(outDir);
|
||||
|
||||
fileDecoder.decode(
|
||||
in, "AndroidManifest.xml", out, "AndroidManifest.xml", "xml");
|
||||
|
||||
in = in.getDir("res");
|
||||
out = out.createDir("res");
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
|
||||
for (ResPackage pkg : resTable.listMainPackages()) {
|
||||
serial.setCurrentPackage(pkg);
|
||||
for (ResResource res : pkg.listFiles()) {
|
||||
ResFileValue fileValue = (ResFileValue) res.getValue();
|
||||
fileDecoder.decode(in, fileValue.getStrippedPath(),
|
||||
out, res.getFilePath());
|
||||
}
|
||||
for (ResValuesFile valuesFile : pkg.listValuesFiles()) {
|
||||
generateValuesFile(valuesFile, out, serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void aaptPackage(File apkFile, File manifest, File resDir)
|
||||
throws AndrolibException {
|
||||
aaptPackage(apkFile, manifest, resDir, null, false);
|
||||
}
|
||||
|
||||
public void aaptPackage(File apkFile, File manifest, File resDir,
|
||||
File rawDir, boolean update) throws AndrolibException {
|
||||
String[] cmd = new String[12];
|
||||
int i = 0;
|
||||
cmd[i++] = "aapt";
|
||||
cmd[i++] = "p";
|
||||
if (update) {
|
||||
cmd[i++] = "-u";
|
||||
}
|
||||
cmd[i++] = "-F";
|
||||
cmd[i++] = apkFile.getAbsolutePath();
|
||||
cmd[i++] = "-I";
|
||||
cmd[i++] = mAndroidJar.getAbsolutePath();
|
||||
if (manifest != null) {
|
||||
cmd[i++] = "-M";
|
||||
cmd[i++] = manifest.getAbsolutePath();
|
||||
}
|
||||
if (resDir != null) {
|
||||
cmd[i++] = "-S";
|
||||
cmd[i++] = resDir.getAbsolutePath();
|
||||
}
|
||||
if (rawDir != null) {
|
||||
cmd[i++] = rawDir.getAbsolutePath();
|
||||
}
|
||||
|
||||
try {
|
||||
OS.exec(Arrays.copyOf(cmd, i));
|
||||
} catch (BrutException ex) {
|
||||
throw new AndrolibException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void tagSmaliResIDs(ResTable resTable, File smaliDir)
|
||||
throws AndrolibException {
|
||||
new ResSmaliUpdater().tagResIDs(resTable, smaliDir);
|
||||
}
|
||||
|
||||
public void updateSmaliResIDs(ResTable resTable, File smaliDir) throws AndrolibException {
|
||||
new ResSmaliUpdater().updateResIDs(resTable, smaliDir);
|
||||
}
|
||||
|
||||
public ResFileDecoder getResFileDecoder(ResXmlSerializer serializer) {
|
||||
ResStreamDecoderContainer decoders =
|
||||
new ResStreamDecoderContainer();
|
||||
decoders.setDecoder("raw", new ResRawStreamDecoder());
|
||||
decoders.setDecoder("xml",
|
||||
new ResXmlStreamDecoder(serializer));
|
||||
return new ResFileDecoder(decoders);
|
||||
}
|
||||
|
||||
public ResXmlSerializer getResXmlSerializer(ResTable resTable) {
|
||||
ResXmlSerializer serial = new ResXmlSerializer();
|
||||
serial.setProperty(serial.PROPERTY_SERIALIZER_INDENTATION, " ");
|
||||
return serial;
|
||||
}
|
||||
|
||||
private void generateValuesFile(ResValuesFile valuesFile, Directory out,
|
||||
ResXmlSerializer serial) throws AndrolibException {
|
||||
try {
|
||||
OutputStream outStream = out.getFileOutput(valuesFile.getPath());
|
||||
serial.setOutput((outStream), null);
|
||||
serial.setDecodingEnabled(false);
|
||||
serial.startDocument(null, null);
|
||||
serial.startTag(null, "resources");
|
||||
|
||||
for (ResResource res : valuesFile.listResources()) {
|
||||
|
||||
((ResXmlSerializable) res.getValue())
|
||||
.serializeToXml(serial, res);
|
||||
}
|
||||
|
||||
serial.endTag(null, "resources");
|
||||
serial.endDocument();
|
||||
serial.flush();
|
||||
outStream.close();
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate: " + valuesFile.getPath(), ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not generate: " + valuesFile.getPath(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadApk(ResTable resTable, File apkFile, boolean main)
|
||||
throws AndrolibException {
|
||||
JniPackageGroup[] groups =
|
||||
nativeGetPackageGroups(apkFile.getAbsolutePath());
|
||||
if (groups.length != 1) {
|
||||
throw new AndrolibException(
|
||||
"Apk's with multiple or zero package groups not supported");
|
||||
}
|
||||
for (int i = 0; i < groups.length; i++) {
|
||||
// if (groups.length != 1 && i == 0) {
|
||||
// continue;
|
||||
// }
|
||||
for (JniPackage jniPkg : groups[i].packages) {
|
||||
ResPackage pkg = new JniPackageDecoder().decode(jniPkg, resTable);
|
||||
resTable.addPackage(pkg, main);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String escapeForResXml(String value) {
|
||||
value = value.replace("'", "\\'");
|
||||
value = value.replace("\n", "\\n\n");
|
||||
char c = value.charAt(0);
|
||||
if (c == '@' || c == '#' || c == '?') {
|
||||
return '\\' + value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static final native JniPackageGroup[] nativeGetPackageGroups(
|
||||
String apkFileName);
|
||||
}
|
146
src/brut/androlib/res/ResSmaliUpdater.java
Normal file
146
src/brut/androlib/res/ResSmaliUpdater.java
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResSpec;
|
||||
import brut.androlib.res.data.ResTable;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import brut.directory.FileDirectory;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResSmaliUpdater {
|
||||
public void tagResIDs(ResTable resTable, File smaliDir)
|
||||
throws AndrolibException {
|
||||
Directory dir = null;
|
||||
try {
|
||||
dir = new FileDirectory(smaliDir);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag res IDs", ex);
|
||||
}
|
||||
for (String fileName : dir.getFiles(true)) {
|
||||
try {
|
||||
Iterator<String> it =
|
||||
IOUtils.readLines(dir.getFileInput(fileName)).iterator();
|
||||
PrintWriter out = new PrintWriter(dir.getFileOutput(fileName));
|
||||
while (it.hasNext()) {
|
||||
String line = it.next();
|
||||
if (RES_NAME_PATTERN.matcher(line).matches()) {
|
||||
out.println(line);
|
||||
out.println(it.next());
|
||||
continue;
|
||||
}
|
||||
Matcher m = RES_ID_PATTERN.matcher(line);
|
||||
if (m.matches()) {
|
||||
int resID = parseResID(m.group(3));
|
||||
if (resID != -1) {
|
||||
ResResSpec spec = resTable.getResSpec(resID);
|
||||
out.println(String.format(
|
||||
RES_NAME_FORMAT, spec.getFullName()));
|
||||
}
|
||||
}
|
||||
out.println(line);
|
||||
}
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag resIDs for file: " + fileName, ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag resIDs for file: " + fileName, ex);
|
||||
} catch (AndrolibException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag resIDs for file: " + fileName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateResIDs(ResTable resTable, File smaliDir)
|
||||
throws AndrolibException {
|
||||
try {
|
||||
Directory dir = new FileDirectory(smaliDir);
|
||||
for (String fileName : dir.getFiles(true)) {
|
||||
Iterator<String> it =
|
||||
IOUtils.readLines(dir.getFileInput(fileName)).iterator();
|
||||
PrintWriter out = new PrintWriter(dir.getFileOutput(fileName));
|
||||
while (it.hasNext()) {
|
||||
String line = it.next();
|
||||
out.println(line);
|
||||
Matcher m1 = RES_NAME_PATTERN.matcher(line);
|
||||
if (! m1.matches()) {
|
||||
continue;
|
||||
}
|
||||
Matcher m2 = RES_ID_PATTERN.matcher(it.next());
|
||||
if (! m2.matches()) {
|
||||
throw new AndrolibException();
|
||||
}
|
||||
int resID = resTable.getPackage(m1.group(1))
|
||||
.getType(m1.group(2)).getResSpec(m1.group(3))
|
||||
.getId().id;
|
||||
if (m2.group(1) != null) {
|
||||
out.println(String.format(
|
||||
RES_ID_FORMAT_FIELD, m2.group(1), resID));
|
||||
} else {
|
||||
out.println(String.format(
|
||||
RES_ID_FORMAT_CONST, m2.group(2), resID));
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag res IDs for: " + smaliDir.getAbsolutePath(), ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(
|
||||
"Could not tag res IDs for: " + smaliDir.getAbsolutePath(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private int parseResID(String resIDHex) {
|
||||
if (resIDHex.endsWith("ff")) {
|
||||
return -1;
|
||||
}
|
||||
int resID = Integer.valueOf(resIDHex, 16);
|
||||
if (resIDHex.length() == 4) {
|
||||
resID = resID << 16;
|
||||
}
|
||||
return resID;
|
||||
}
|
||||
|
||||
private final static String RES_ID_FORMAT_FIELD =
|
||||
".field %s:I = 0x%08x";
|
||||
private final static String RES_ID_FORMAT_CONST =
|
||||
" const %s, 0x%08x";
|
||||
private final static Pattern RES_ID_PATTERN = Pattern.compile(
|
||||
"^(?:\\.field (.+?):I =| const(?:|/(?:|high)16) ([pv]\\d+?),) 0x(7[a-f]0[1-9a-f](?:|[0-9a-f]{4}))$");
|
||||
private final static String RES_NAME_FORMAT =
|
||||
"# APKTOOL/RES_NAME: %s";
|
||||
private final static Pattern RES_NAME_PATTERN = Pattern.compile(
|
||||
"^# APKTOOL/RES_NAME: ([a-zA-Z0-9.]+):([a-z]+)/([a-zA-Z0-9._]+)$");
|
||||
}
|
69
src/brut/androlib/res/data/ResConfig.java
Normal file
69
src/brut/androlib/res/data/ResConfig.java
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResConfig {
|
||||
private final ResConfigFlags mFlags;
|
||||
private final Map<ResResSpec, ResResource> mResources =
|
||||
new LinkedHashMap<ResResSpec, ResResource>();
|
||||
|
||||
public ResConfig(ResConfigFlags flags) {
|
||||
this.mFlags = flags;
|
||||
}
|
||||
|
||||
public Set<ResResource> listResources() {
|
||||
return new LinkedHashSet<ResResource>(mResources.values());
|
||||
}
|
||||
|
||||
public ResResource getResource(ResResSpec spec) throws AndrolibException {
|
||||
ResResource res = mResources.get(spec);
|
||||
if (res == null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Undefined resource: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Set<ResResSpec> listResSpecs() {
|
||||
return mResources.keySet();
|
||||
}
|
||||
|
||||
public ResConfigFlags getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public void addResource(ResResource res)
|
||||
throws AndrolibException {
|
||||
ResResSpec spec = res.getResSpec();
|
||||
if (mResources.put(spec, res) != null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple resources: spec=%s, config=%s", spec, this));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mFlags.toString();
|
||||
}
|
||||
}
|
342
src/brut/androlib/res/data/ResConfigFlags.java
Normal file
342
src/brut/androlib/res/data/ResConfigFlags.java
Normal file
@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.jni.JniConfig;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResConfigFlags {
|
||||
public final int mcc;
|
||||
public final int mnc;
|
||||
|
||||
public final char[] language;
|
||||
public final char[] country;
|
||||
|
||||
// public final Orientation orientation;
|
||||
// public final Touchscreen touchscreen;
|
||||
public final int orientation;
|
||||
public final int touchscreen;
|
||||
public final int density;
|
||||
|
||||
// public final Keyboard keyboard;
|
||||
// public final Navigation navigation;
|
||||
// public final Keys keys;
|
||||
// public final Nav nav;
|
||||
public final int keyboard;
|
||||
public final int navigation;
|
||||
public final int inputFlags;
|
||||
|
||||
public final int screenWidth;
|
||||
public final int screenHeight;
|
||||
// public final ScreenSize screenSize;
|
||||
// public final ScreenLong screenLong;
|
||||
public final int screenLayout;
|
||||
|
||||
public final int sdkVersion;
|
||||
|
||||
private final String mQualifiers;
|
||||
|
||||
public ResConfigFlags() {
|
||||
mcc = 0;
|
||||
mnc = 0;
|
||||
language = new char[]{'\00', '\00'};
|
||||
country = new char[]{'\00', '\00'};
|
||||
orientation = ORIENTATION_ANY;
|
||||
touchscreen = TOUCHSCREEN_ANY;
|
||||
density = DENSITY_DEFAULT;
|
||||
keyboard = KEYBOARD_ANY;
|
||||
navigation = NAVIGATION_ANY;
|
||||
inputFlags = KEYSHIDDEN_ANY | NAVHIDDEN_ANY;
|
||||
screenWidth = 0;
|
||||
screenHeight = 0;
|
||||
screenLayout = SCREENLONG_ANY | SCREENSIZE_ANY;
|
||||
sdkVersion = 0;
|
||||
mQualifiers = "";
|
||||
}
|
||||
|
||||
public ResConfigFlags(JniConfig cfg) throws AndrolibException {
|
||||
// if (cfg.mcc == 0 && mnc != 0) {
|
||||
// throw new AndrolibException(String.format(
|
||||
// "Invalid IMSI: mcc=%3d, mnc=%3d", mcc, mnc));
|
||||
// }
|
||||
mcc = cfg.mcc;
|
||||
mnc = cfg.mnc;
|
||||
|
||||
// if (cfg.language.length == 0 && cfg.country.length != 0) {
|
||||
// throw new AndrolibException(String.format(
|
||||
// "Invalid local: language=%s, country=%s",
|
||||
// cfg.language, cfg.country));
|
||||
// }
|
||||
language = cfg.language;
|
||||
country = cfg.country;
|
||||
//
|
||||
// switch (cfg.orientation) {
|
||||
// case ORIENTATION_ANY:
|
||||
// orientation = Orientation.ANY;
|
||||
// break;
|
||||
// case ORIENTATION_LAND:
|
||||
// orientation = Orientation.LAND;
|
||||
// break;
|
||||
// case ORIENTATION_PORT:
|
||||
// orientation = Orientation.PORT;
|
||||
// break;
|
||||
// case ORIENTATION_SQUARE:
|
||||
// orientation = Orientation.SQUARE;
|
||||
// break;
|
||||
// default:
|
||||
// throw new AndrolibException(String.format(
|
||||
// "Invalid orientation: %d", cfg.orientation));
|
||||
// }
|
||||
|
||||
orientation = cfg.orientation;
|
||||
touchscreen = cfg.touchscreen;
|
||||
density = cfg.density;
|
||||
keyboard = cfg.keyboard;
|
||||
navigation = cfg.navigation;
|
||||
inputFlags = cfg.inputFlags;
|
||||
screenWidth = cfg.screenWidth;
|
||||
screenHeight = cfg.screenHeight;
|
||||
screenLayout = cfg.screenLayout;
|
||||
sdkVersion = cfg.sdkVersion;
|
||||
|
||||
mQualifiers = generateQualifiers();
|
||||
}
|
||||
|
||||
public String getQualifiers() {
|
||||
return mQualifiers;
|
||||
}
|
||||
|
||||
private String generateQualifiers() {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
if (mcc != 0) {
|
||||
ret.append("-mcc").append(mcc);
|
||||
if (mnc != 0) {
|
||||
ret.append("-mnc").append(mnc);
|
||||
}
|
||||
}
|
||||
if (language[0] != '\00') {
|
||||
ret.append('-').append(language);
|
||||
if (country[0] != '\00') {
|
||||
ret.append("-r").append(country);
|
||||
}
|
||||
}
|
||||
switch (screenLayout & MASK_SCREENSIZE) {
|
||||
case SCREENSIZE_SMALL:
|
||||
ret.append("-small");
|
||||
break;
|
||||
case SCREENSIZE_NORMAL:
|
||||
ret.append("-normal");
|
||||
break;
|
||||
case SCREENSIZE_LARGE:
|
||||
ret.append("-large");
|
||||
break;
|
||||
}
|
||||
switch (screenLayout & MASK_SCREENLONG) {
|
||||
case SCREENLONG_YES:
|
||||
ret.append("-long");
|
||||
break;
|
||||
case SCREENLONG_NO:
|
||||
ret.append("-notlong");
|
||||
break;
|
||||
}
|
||||
switch (orientation) {
|
||||
case ORIENTATION_PORT:
|
||||
ret.append("-port");
|
||||
break;
|
||||
case ORIENTATION_LAND:
|
||||
ret.append("-land");
|
||||
break;
|
||||
case ORIENTATION_SQUARE:
|
||||
ret.append("-square");
|
||||
break;
|
||||
}
|
||||
switch (density) {
|
||||
case DENSITY_DEFAULT:
|
||||
break;
|
||||
case DENSITY_LOW:
|
||||
ret.append("-ldpi");
|
||||
break;
|
||||
case DENSITY_MEDIUM:
|
||||
ret.append("-mdpi");
|
||||
break;
|
||||
case DENSITY_HIGH:
|
||||
ret.append("-hdpi");
|
||||
break;
|
||||
case DENSITY_NONE:
|
||||
ret.append("-nodpi");
|
||||
break;
|
||||
default:
|
||||
ret.append('-').append(density).append("dpi");
|
||||
}
|
||||
switch (touchscreen) {
|
||||
case TOUCHSCREEN_NOTOUCH:
|
||||
ret.append("-notouch");
|
||||
break;
|
||||
case TOUCHSCREEN_STYLUS:
|
||||
ret.append("-stylus");
|
||||
break;
|
||||
case TOUCHSCREEN_FINGER:
|
||||
ret.append("-finger");
|
||||
break;
|
||||
}
|
||||
switch (inputFlags & MASK_KEYSHIDDEN) {
|
||||
case KEYSHIDDEN_NO:
|
||||
ret.append("-keysexposed");
|
||||
break;
|
||||
case KEYSHIDDEN_YES:
|
||||
ret.append("-keyshidden");
|
||||
break;
|
||||
case KEYSHIDDEN_SOFT:
|
||||
ret.append("-keyssoft");
|
||||
break;
|
||||
}
|
||||
switch (keyboard) {
|
||||
case KEYBOARD_NOKEYS:
|
||||
ret.append("-nokeys");
|
||||
break;
|
||||
case KEYBOARD_QWERTY:
|
||||
ret.append("-qwerty");
|
||||
break;
|
||||
case KEYBOARD_12KEY:
|
||||
ret.append("-12key");
|
||||
break;
|
||||
}
|
||||
switch (inputFlags & MASK_NAVHIDDEN) {
|
||||
case NAVHIDDEN_NO:
|
||||
ret.append("-navexposed");
|
||||
break;
|
||||
case NAVHIDDEN_YES:
|
||||
ret.append("-navhidden");
|
||||
break;
|
||||
}
|
||||
switch (navigation) {
|
||||
case NAVIGATION_NONAV:
|
||||
ret.append("-nonav");
|
||||
break;
|
||||
case NAVIGATION_DPAD:
|
||||
ret.append("-dpad");
|
||||
break;
|
||||
case NAVIGATION_TRACKBALL:
|
||||
ret.append("-trackball");
|
||||
break;
|
||||
case NAVIGATION_WHEEL:
|
||||
ret.append("-wheel");
|
||||
break;
|
||||
}
|
||||
if (screenWidth != 0 && screenHeight != 0) {
|
||||
if (screenWidth > screenHeight) {
|
||||
ret.append(String.format("-%dx%d", screenWidth, screenHeight));
|
||||
} else {
|
||||
ret.append(String.format("-%dx%d", screenHeight, screenWidth));
|
||||
}
|
||||
}
|
||||
if (sdkVersion != 0) {
|
||||
ret.append("-v").append(sdkVersion);
|
||||
}
|
||||
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ! getQualifiers().equals("") ? getQualifiers() : "[DEFAULT]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ResConfigFlags other = (ResConfigFlags) obj;
|
||||
if ((this.mQualifiers == null) ? (other.mQualifiers != null) : !this.mQualifiers.equals(other.mQualifiers)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
hash = 97 * hash + (this.mQualifiers != null ? this.mQualifiers.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
// public enum Orientation {ANY, PORT, LAND, SQUARE}
|
||||
// public enum Touchscreen {ANY, NOTOUCH, STYLUS, FINGER}
|
||||
// public enum Keyboard {ANY, NOKEYS, QWERTY, KEY12}
|
||||
// public enum Navigation {ANY, NONAV, DPAD, TRACKBALL, WHEEL}
|
||||
// public enum Keys {ANY, EXPOSED, HIDDEN, SOFT}
|
||||
// public enum Nav {ANY, EXPOSED, HIDDEN}
|
||||
// public enum ScreenSize {ANY, SMALL, NORMAL, LARGE}
|
||||
// public enum ScreenLong {ANY, LONG, NOTLONG}
|
||||
|
||||
public final static int ORIENTATION_ANY = 0x0000;
|
||||
public final static int ORIENTATION_PORT = 0x0001;
|
||||
public final static int ORIENTATION_LAND = 0x0002;
|
||||
public final static int ORIENTATION_SQUARE = 0x0003;
|
||||
|
||||
public final static int TOUCHSCREEN_ANY = 0x0000;
|
||||
public final static int TOUCHSCREEN_NOTOUCH = 0x0001;
|
||||
public final static int TOUCHSCREEN_STYLUS = 0x0002;
|
||||
public final static int TOUCHSCREEN_FINGER = 0x0003;
|
||||
|
||||
public final static int DENSITY_DEFAULT = 0;
|
||||
public final static int DENSITY_LOW = 120;
|
||||
public final static int DENSITY_MEDIUM = 160;
|
||||
public final static int DENSITY_HIGH = 240;
|
||||
public final static int DENSITY_NONE = 0xffff;
|
||||
|
||||
public final static int KEYBOARD_ANY = 0x0000;
|
||||
public final static int KEYBOARD_NOKEYS = 0x0001;
|
||||
public final static int KEYBOARD_QWERTY = 0x0002;
|
||||
public final static int KEYBOARD_12KEY = 0x0003;
|
||||
|
||||
public final static int NAVIGATION_ANY = 0x0000;
|
||||
public final static int NAVIGATION_NONAV = 0x0001;
|
||||
public final static int NAVIGATION_DPAD = 0x0002;
|
||||
public final static int NAVIGATION_TRACKBALL = 0x0003;
|
||||
public final static int NAVIGATION_WHEEL = 0x0004;
|
||||
|
||||
public final static int MASK_KEYSHIDDEN = 0x0003;
|
||||
public final static int KEYSHIDDEN_ANY = 0x0000;
|
||||
public final static int KEYSHIDDEN_NO = 0x0001;
|
||||
public final static int KEYSHIDDEN_YES = 0x0002;
|
||||
public final static int KEYSHIDDEN_SOFT = 0x0003;
|
||||
|
||||
public final static int MASK_NAVHIDDEN = 0x000c;
|
||||
public final static int NAVHIDDEN_ANY = 0x0000;
|
||||
public final static int NAVHIDDEN_NO = 0x0004;
|
||||
public final static int NAVHIDDEN_YES = 0x0008;
|
||||
|
||||
public final static int MASK_SCREENSIZE = 0x0f;
|
||||
public final static int SCREENSIZE_ANY = 0x00;
|
||||
public final static int SCREENSIZE_SMALL = 0x01;
|
||||
public final static int SCREENSIZE_NORMAL = 0x02;
|
||||
public final static int SCREENSIZE_LARGE = 0x03;
|
||||
|
||||
public final static int MASK_SCREENLONG = 0x30;
|
||||
public final static int SCREENLONG_ANY = 0x00;
|
||||
public final static int SCREENLONG_NO = 0x10;
|
||||
public final static int SCREENLONG_YES = 0x20;
|
||||
}
|
71
src/brut/androlib/res/data/ResID.java
Normal file
71
src/brut/androlib/res/data/ResID.java
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResID {
|
||||
public final int package_;
|
||||
public final int type;
|
||||
public final int entry;
|
||||
|
||||
public final int id;
|
||||
|
||||
public ResID(int package_, int type, int entry) {
|
||||
this(package_, type, entry, (package_ << 24) + (type << 16) + entry);
|
||||
}
|
||||
|
||||
public ResID(int id) {
|
||||
this(id >> 24, (id >> 16) & 0x000000ff, id & 0x0000ffff, id);
|
||||
}
|
||||
|
||||
public ResID(int package_, int type, int entry, int id) {
|
||||
this.package_ = package_;
|
||||
this.type = type;
|
||||
this.entry = entry;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("0x%08x", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 59 * hash + this.id;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ResID other = (ResID) obj;
|
||||
if (this.id != other.id) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
195
src/brut/androlib/res/data/ResPackage.java
Normal file
195
src/brut/androlib/res/data/ResPackage.java
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.value.ResFileValue;
|
||||
import brut.androlib.res.data.value.ResValue;
|
||||
import brut.androlib.res.data.value.ResValueFactory;
|
||||
import brut.androlib.res.data.value.ResXmlSerializable;
|
||||
import brut.util.Duo;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResPackage {
|
||||
private final ResTable mResTable;
|
||||
private final int mId;
|
||||
private final String mName;
|
||||
private final Map<ResID, ResResSpec> mResSpecs =
|
||||
new LinkedHashMap<ResID, ResResSpec>();
|
||||
private final Map<ResConfigFlags, ResConfig> mConfigs =
|
||||
new LinkedHashMap<ResConfigFlags, ResConfig>();
|
||||
private final Map<String, ResType> mTypes =
|
||||
new LinkedHashMap<String, ResType>();
|
||||
private final Set<ResResource> mFiles = new LinkedHashSet<ResResource>();
|
||||
private final Map<Duo<ResType, ResConfig>, ResValuesFile> mValuesFiles =
|
||||
new LinkedHashMap<Duo<ResType, ResConfig>, ResValuesFile>();
|
||||
|
||||
private ResValueFactory mValueFactory;
|
||||
|
||||
public ResPackage(ResTable resTable, int id, String name) {
|
||||
this.mResTable = resTable;
|
||||
this.mId = id;
|
||||
this.mName = name;
|
||||
}
|
||||
|
||||
public List<ResResSpec> listResSpecs() {
|
||||
return new ArrayList<ResResSpec>(mResSpecs.values());
|
||||
}
|
||||
|
||||
public boolean hasResSpec(ResID resID) {
|
||||
return mResSpecs.containsKey(resID);
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(ResID resID) throws AndrolibException {
|
||||
ResResSpec spec = mResSpecs.get(resID);
|
||||
if (spec == null) {
|
||||
throw new AndrolibException("Undefined resource spec: " + resID);
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
public List<ResConfig> getConfigs() {
|
||||
return new ArrayList<ResConfig>(mConfigs.values());
|
||||
}
|
||||
|
||||
public boolean hasConfig(ResConfigFlags flags) {
|
||||
return mConfigs.containsKey(flags);
|
||||
}
|
||||
|
||||
public ResConfig getConfig(ResConfigFlags flags) throws AndrolibException {
|
||||
ResConfig config = mConfigs.get(flags);
|
||||
if (config == null) {
|
||||
throw new AndrolibException("Undefined config: " + flags);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public List<ResType> listTypes() {
|
||||
return new ArrayList<ResType>(mTypes.values());
|
||||
}
|
||||
|
||||
public boolean hasType(String typeName) {
|
||||
return mTypes.containsKey(typeName);
|
||||
}
|
||||
|
||||
public ResType getType(String typeName) throws AndrolibException {
|
||||
ResType type = mTypes.get(typeName);
|
||||
if (type == null) {
|
||||
throw new AndrolibException("Undefined type: " + typeName);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public Set<ResResource> listFiles() {
|
||||
return mFiles;
|
||||
}
|
||||
|
||||
public Collection<ResValuesFile> listValuesFiles() {
|
||||
return mValuesFiles.values();
|
||||
}
|
||||
|
||||
public ResTable getResTable() {
|
||||
return mResTable;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void addResSpec(ResResSpec spec) throws AndrolibException {
|
||||
if (mResSpecs.put(spec.getId(), spec) != null) {
|
||||
throw new AndrolibException("Multiple resource specs: " + spec);
|
||||
}
|
||||
}
|
||||
|
||||
public void addConfig(ResConfig config) throws AndrolibException {
|
||||
if (mConfigs.put(config.getFlags(), config) != null) {
|
||||
throw new AndrolibException("Multiple configs: " + config);
|
||||
}
|
||||
}
|
||||
|
||||
public void addType(ResType type) throws AndrolibException {
|
||||
if (mTypes.put(type.getName(), type) != null) {
|
||||
throw new AndrolibException("Multiple types: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public void addResource(ResResource res) {
|
||||
ResValue value = res.getValue();
|
||||
if (value instanceof ResFileValue) {
|
||||
mFiles.add(res);
|
||||
}
|
||||
if (value instanceof ResXmlSerializable) {
|
||||
ResType type = res.getResSpec().getType();
|
||||
ResConfig config = res.getConfig();
|
||||
Duo<ResType, ResConfig> key =
|
||||
new Duo<ResType, ResConfig>(type, config);
|
||||
ResValuesFile values = mValuesFiles.get(key);
|
||||
if (values == null) {
|
||||
values = new ResValuesFile(type, config);
|
||||
mValuesFiles.put(key, values);
|
||||
}
|
||||
values.addResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ResPackage other = (ResPackage) obj;
|
||||
if (this.mResTable != other.mResTable && (this.mResTable == null || !this.mResTable.equals(other.mResTable))) {
|
||||
return false;
|
||||
}
|
||||
if (this.mId != other.mId) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 37 * hash + (this.mResTable != null ? this.mResTable.hashCode() : 0);
|
||||
hash = 37 * hash + this.mId;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public ResValueFactory getValueFactory() {
|
||||
if (mValueFactory == null) {
|
||||
mValueFactory = new ResValueFactory(this);
|
||||
}
|
||||
return mValueFactory;
|
||||
}
|
||||
}
|
108
src/brut/androlib/res/data/ResResSpec.java
Normal file
108
src/brut/androlib/res/data/ResResSpec.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResResSpec {
|
||||
private final ResID mId;
|
||||
private final String mName;
|
||||
private final ResPackage mPackage;
|
||||
private final ResType mType;
|
||||
private final Map<ResConfigFlags, ResResource> mResources =
|
||||
new LinkedHashMap<ResConfigFlags, ResResource>();
|
||||
|
||||
public ResResSpec(ResID id, String name, ResPackage pkg, ResType type) {
|
||||
this.mId = id;
|
||||
this.mName = name;
|
||||
this.mPackage = pkg;
|
||||
this.mType = type;
|
||||
}
|
||||
|
||||
public Set<ResResource> listResources() {
|
||||
return new LinkedHashSet<ResResource>(mResources.values());
|
||||
}
|
||||
|
||||
public ResResource getResource(ResConfig config) throws AndrolibException {
|
||||
return getResource(config.getFlags());
|
||||
}
|
||||
|
||||
public ResResource getResource(ResConfigFlags config)
|
||||
throws AndrolibException {
|
||||
ResResource res = mResources.get(config);
|
||||
if (res == null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Undefined resource: spec=%s, config=%s", this, config));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public ResResource getDefaultResource() throws AndrolibException {
|
||||
return getResource(new ResConfigFlags());
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return getFullName(false, false);
|
||||
}
|
||||
|
||||
public String getFullName(ResPackage relativeToPackage,
|
||||
boolean excludeType) {
|
||||
return getFullName(
|
||||
getPackage().equals(relativeToPackage), excludeType);
|
||||
}
|
||||
|
||||
public String getFullName(boolean excludePackage, boolean excludeType) {
|
||||
return
|
||||
(excludePackage ? "" : getPackage().getName() + ":") +
|
||||
(excludeType ? "" : getType().getName() + "/") + getName();
|
||||
}
|
||||
|
||||
public ResID getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public ResPackage getPackage() {
|
||||
return mPackage;
|
||||
}
|
||||
|
||||
public ResType getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public void addResource(ResResource res)
|
||||
throws AndrolibException {
|
||||
ResConfigFlags flags = res.getConfig().getFlags();
|
||||
if (mResources.put(flags, res) != null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple resources: spec=%s, config=%s", this, flags));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mId.toString() + " " + mType.toString() + "/" + mName;
|
||||
}
|
||||
}
|
58
src/brut/androlib/res/data/ResResource.java
Normal file
58
src/brut/androlib/res/data/ResResource.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.res.data.value.ResValue;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResResource {
|
||||
private final ResConfig mConfig;
|
||||
private final ResResSpec mResSpec;
|
||||
private final ResValue mValue;
|
||||
|
||||
public ResResource(ResConfig config, ResResSpec spec,
|
||||
ResValue value) {
|
||||
this.mConfig = config;
|
||||
this.mResSpec = spec;
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return mResSpec.getType().getName() +
|
||||
mConfig.getFlags().getQualifiers() + "/" + mResSpec.getName();
|
||||
}
|
||||
|
||||
public ResConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec() {
|
||||
return mResSpec;
|
||||
}
|
||||
|
||||
public ResValue getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getFilePath();
|
||||
}
|
||||
}
|
97
src/brut/androlib/res/data/ResTable.java
Normal file
97
src/brut/androlib/res/data/ResTable.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.value.ResAttr;
|
||||
import brut.androlib.res.data.value.ResValue;
|
||||
import brut.androlib.res.data.value.ResValueFactory;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResTable {
|
||||
private final Map<Integer, ResPackage> mPackagesById =
|
||||
new HashMap<Integer, ResPackage>();
|
||||
private final Map<String, ResPackage> mPackagesByName =
|
||||
new HashMap<String, ResPackage>();
|
||||
private final Set<ResPackage> mMainPackages =
|
||||
new LinkedHashSet<ResPackage>();
|
||||
|
||||
public ResTable() {
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(int resID) throws AndrolibException {
|
||||
return getResSpec(new ResID(resID));
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(ResID resID) throws AndrolibException {
|
||||
return getPackage(resID.package_).getResSpec(resID);
|
||||
}
|
||||
|
||||
public Set<ResPackage> listMainPackages() {
|
||||
return mMainPackages;
|
||||
}
|
||||
|
||||
public ResPackage getPackage(int id) throws AndrolibException {
|
||||
ResPackage pkg = mPackagesById.get(id);
|
||||
if (pkg == null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Undefined package: id=%d", id));
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
public ResPackage getPackage(String name) throws AndrolibException {
|
||||
ResPackage pkg = mPackagesByName.get(name);
|
||||
if (pkg == null) {
|
||||
throw new AndrolibException("Undefined package: name=" + name);
|
||||
}
|
||||
return pkg;
|
||||
}
|
||||
|
||||
public ResValue getValue(String package_, String type, String name)
|
||||
throws AndrolibException {
|
||||
return getPackage(package_).getType(type).getResSpec(name)
|
||||
.getDefaultResource().getValue();
|
||||
}
|
||||
|
||||
public void addPackage(ResPackage pkg, boolean main)
|
||||
throws AndrolibException {
|
||||
Integer id = pkg.getId();
|
||||
if (mPackagesById.containsKey(id)) {
|
||||
throw new AndrolibException(
|
||||
"Multiple packages: id=" + id.toString());
|
||||
}
|
||||
String name = pkg.getName();
|
||||
if (mPackagesByName.containsKey(name)) {
|
||||
throw new AndrolibException("Multiple packages: name=" + name);
|
||||
}
|
||||
|
||||
mPackagesById.put(id, pkg);
|
||||
mPackagesByName.put(name, pkg);
|
||||
if (main) {
|
||||
mMainPackages.add(pkg);
|
||||
}
|
||||
}
|
||||
}
|
294
src/brut/androlib/res/data/ResType.java
Normal file
294
src/brut/androlib/res/data/ResType.java
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.decoder.ResFileDecoder;
|
||||
import brut.androlib.res.decoder.ResXmlSerializer;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public final class ResType {
|
||||
private final String mName;
|
||||
// private final TypeConfig mConfig;
|
||||
private final Map<String, ResResSpec> mResSpecs =
|
||||
new LinkedHashMap<String, ResResSpec>();
|
||||
|
||||
private final ResTable mResTable;
|
||||
private final ResPackage mPackage;
|
||||
|
||||
public ResType(String name, ResTable resTable,
|
||||
ResPackage package_) {
|
||||
this.mName = name;
|
||||
this.mResTable = resTable;
|
||||
this.mPackage = package_;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public Set<ResResSpec> listResSpecs() {
|
||||
return new LinkedHashSet<ResResSpec>(mResSpecs.values());
|
||||
}
|
||||
|
||||
public ResResSpec getResSpec(String name) throws AndrolibException {
|
||||
ResResSpec spec = mResSpecs.get(name);
|
||||
if (spec == null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Undefined resource spec: %s/%s", getName(), name));
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
//
|
||||
// public void decode(AndrolibResources andRes, ResXmlSerializer serial,
|
||||
// Directory in, Directory out) throws AndrolibException {
|
||||
// decodeFiles(andRes, serial, in, out);
|
||||
// decodeValues(andRes, serial, out);
|
||||
// }
|
||||
//
|
||||
// public void decodeFiles(AndrolibResources andRes, ResXmlSerializer serial,
|
||||
// Directory in, Directory out) throws AndrolibException {
|
||||
// if (! mConfig.isFile) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// ResFileDecoder decoder = andRes.getResFileDecoder(serial);
|
||||
//
|
||||
// for (ResResSpec res : listResources()) {
|
||||
// for (ResResource value : res.listResources()) {
|
||||
// if (! value.isStrVal()) {
|
||||
// continue;
|
||||
// }
|
||||
// String fileName = value.getStrVal();
|
||||
// if (! fileName.startsWith("res/")) {
|
||||
// throw new AndrolibException(
|
||||
// "Invalid res file location: " + fileName);
|
||||
// }
|
||||
// decoder.decode(in, fileName.substring(4), out,
|
||||
// value.getFilePath());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void decodeValues(AndrolibResources andRes, ResXmlSerializer serial,
|
||||
// Directory out) throws AndrolibException {
|
||||
// if (! mConfig.isValues) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// boolean oldEscapeRefs = serial.setEscapeRefs(false);
|
||||
//
|
||||
// for (Entry<ResConfigFlags, Set<ResResource>> entry :
|
||||
// groupValuesByConfig().entrySet()) {
|
||||
// ResConfigFlags config = entry.getKey();
|
||||
// String filePath = "values" + config.getQualifiers() + "/"
|
||||
// + mConfig.valuesFileName + ".xml";
|
||||
//
|
||||
// try {
|
||||
// serial.setOutput(out.getFileOutput(filePath), null);
|
||||
// serial.startDocument(null, null);
|
||||
// serial.startTag(null, "resources");
|
||||
//
|
||||
// for (ResResource value : entry.getValue()) {
|
||||
// if (mName.equals("array")) {
|
||||
// decodeArrayValue(serial, value);
|
||||
// } else {
|
||||
// serial.startTag(null, mConfig.valuesTagName);
|
||||
// serial.attribute(
|
||||
// null, "name", value.getResSpec().getName());
|
||||
//
|
||||
// if (mName.equals("style")) {
|
||||
// decodeStyleValue(serial, value);
|
||||
// } else if (mName.equals("attr")) {
|
||||
// decodeAttrValue(serial, value);
|
||||
// } else {
|
||||
// decodeSimpleValue(serial, value);
|
||||
// }
|
||||
//
|
||||
// serial.endTag(null, mConfig.valuesTagName);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// serial.endTag(null, "resources");
|
||||
// serial.endDocument();
|
||||
// } catch (IOException ex) {
|
||||
// throw new AndrolibException(
|
||||
// "Could not decode values for:" + filePath, ex);
|
||||
// } catch (DirectoryException ex) {
|
||||
// throw new AndrolibException(
|
||||
// "Could not decode values for:" + filePath, ex);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// serial.setEscapeRefs(oldEscapeRefs);
|
||||
// }
|
||||
//
|
||||
// private void decodeSimpleValue(ResXmlSerializer serial, ResResource value)
|
||||
// throws IOException, AndrolibException {
|
||||
// serial.text(value.toResXMlText());
|
||||
// }
|
||||
//
|
||||
// private void decodeArrayValue(ResXmlSerializer serial, ResResource value)
|
||||
// throws IOException, AndrolibException {
|
||||
// String arrType = value.getBag().getType();
|
||||
// String tagName = (arrType != null ? arrType + "-" : "") + "array";
|
||||
// serial.startTag(null, tagName);
|
||||
// serial.attribute(
|
||||
// null, "name", value.getResSpec().getName());
|
||||
// for (ResResource item : value.getBag().getItems().values()) {
|
||||
// serial.startTag(null, "item");
|
||||
// serial.text(item.getStrVal());
|
||||
// serial.endTag(null, "item");
|
||||
// }
|
||||
// serial.endTag(null, tagName);
|
||||
// }
|
||||
//
|
||||
// private void decodeAttrValue(ResXmlSerializer serial, ResResource value)
|
||||
// throws IOException, AndrolibException {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private void decodeStyleValue(ResXmlSerializer serial, ResResource value)
|
||||
// throws IOException, AndrolibException {
|
||||
// ResBag bag = value.getBag();
|
||||
// if (bag.getParent().id != 0) {
|
||||
// serial.attribute(null, "parent", bag.getParentRes()
|
||||
// .getResReference(false, mPackage.getName()));
|
||||
//
|
||||
// for (Entry<ResID, ResResource> entry : bag.getItems().entrySet()) {
|
||||
// serial.startTag(null, "item");
|
||||
//
|
||||
// ResResSpec attr = mResTable.getResSpec(entry.getKey());
|
||||
// serial.attribute(null, "name", attr.getResReference(false, mPackage.getName(), true).substring(1));
|
||||
// serial.text(attr.getDefaultResource().decodeAttrValue(entry.getValue().getAsString(), false, mPackage.getName()));
|
||||
// serial.endTag(null, "item");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void addResSpec(ResResSpec spec)
|
||||
throws AndrolibException {
|
||||
if (mResSpecs.put(spec.getName(), spec) != null) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Multiple res specs: %s/%s", getName(), spec.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mName;
|
||||
}
|
||||
//
|
||||
// private Map<ResConfigFlags, Set<ResResource>> groupValuesByConfig() {
|
||||
// Map<ResConfigFlags, Set<ResResource>> grouped =
|
||||
// new LinkedHashMap<ResConfigFlags, Set<ResResource>>();
|
||||
//
|
||||
// for (ResResSpec res : listResSpecs()) {
|
||||
// for (ResResource value : res.listResources()) {
|
||||
// ResConfigFlags config = value.getConfig().getFlags();
|
||||
// Set<ResResource> values = grouped.get(config);
|
||||
// if (values == null) {
|
||||
// values = new LinkedHashSet<ResResource>();
|
||||
// grouped.put(config, values);
|
||||
// }
|
||||
// values.add(value);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return grouped;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static ResType factory(String name, ResTable resTable,
|
||||
// ResPackage package_) throws AndrolibException {
|
||||
// if (typesConfig == null) {
|
||||
// loadTypesConfig();
|
||||
// }
|
||||
// TypeConfig config = typesConfig.get(name);
|
||||
// if (config == null) {
|
||||
// throw new AndrolibException("Invalid type name: " + name);
|
||||
// }
|
||||
// return new ResType(name, config, resTable, package_);
|
||||
// }
|
||||
//
|
||||
// private static void loadTypesConfig() {
|
||||
// typesConfig = new HashMap<String, TypeConfig>();
|
||||
// typesConfig.put("anim", new FileTypeConfig());
|
||||
// typesConfig.put("drawable", new FileTypeConfig());
|
||||
// typesConfig.put("layout", new FileTypeConfig());
|
||||
// typesConfig.put("menu", new FileTypeConfig());
|
||||
// typesConfig.put("raw", new FileTypeConfig());
|
||||
// typesConfig.put("xml", new FileTypeConfig());
|
||||
//
|
||||
// typesConfig.put("attr", new ValuesTypeConfig("attrs", "attr"));
|
||||
// typesConfig.put("dimen", new ValuesTypeConfig("dimens", "dimen"));
|
||||
// typesConfig.put("string", new ValuesTypeConfig("strings", "string"));
|
||||
// typesConfig.put("integer", new ValuesTypeConfig("integers", "integer"));
|
||||
// typesConfig.put("array", new ValuesTypeConfig("arrays", "array"));
|
||||
// typesConfig.put("style", new ValuesTypeConfig("styles", "style"));
|
||||
//
|
||||
// typesConfig.put("color", new TypeConfig(true, true, "colors", "color"));
|
||||
//
|
||||
// typesConfig.put("bool", new TypeConfig());
|
||||
// typesConfig.put("id", new TypeConfig());
|
||||
//// typesConfig.put("integer", new TypeConfig());
|
||||
// typesConfig.put("plurals", new TypeConfig());
|
||||
// }
|
||||
//
|
||||
// private static Map<String, TypeConfig> typesConfig;
|
||||
//
|
||||
//
|
||||
// public static class TypeConfig {
|
||||
// public final boolean isFile;
|
||||
// public final boolean isValues;
|
||||
// public final String valuesFileName;
|
||||
// public final String valuesTagName;
|
||||
//
|
||||
// public TypeConfig() {
|
||||
// this(false, false, null, null);
|
||||
// }
|
||||
//
|
||||
// public TypeConfig(boolean isFile, boolean isValues,
|
||||
// String valuesFileName, String valuesTagName) {
|
||||
// this.isFile = isFile;
|
||||
// this.isValues = isValues;
|
||||
// this.valuesFileName = valuesFileName;
|
||||
// this.valuesTagName = valuesTagName;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static class FileTypeConfig extends TypeConfig {
|
||||
// public FileTypeConfig() {
|
||||
// super(true, false, null, null);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static class ValuesTypeConfig extends TypeConfig {
|
||||
// public ValuesTypeConfig(String fileName, String tagName) {
|
||||
// super(false, true, fileName, tagName);
|
||||
// }
|
||||
// }
|
||||
}
|
85
src/brut/androlib/res/data/ResValuesFile.java
Normal file
85
src/brut/androlib/res/data/ResValuesFile.java
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResValuesFile {
|
||||
private final ResType mType;
|
||||
private final ResConfig mConfig;
|
||||
private final Set<ResResource> mResources =
|
||||
new LinkedHashSet<ResResource>();
|
||||
|
||||
public ResValuesFile(ResType type, ResConfig config) {
|
||||
this.mType = type;
|
||||
this.mConfig = config;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return "values" + mConfig.getFlags().getQualifiers()
|
||||
+ "/" + mType.getName()
|
||||
+ (mType.getName().endsWith("s") ? "" : "s")
|
||||
+ ".xml";
|
||||
}
|
||||
|
||||
public Set<ResResource> listResources() {
|
||||
return mResources;
|
||||
}
|
||||
|
||||
public ResType getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public ResConfig getConfig() {
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
public void addResource(ResResource res) {
|
||||
mResources.add(res);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ResValuesFile other = (ResValuesFile) obj;
|
||||
if (this.mType != other.mType && (this.mType == null || !this.mType.equals(other.mType))) {
|
||||
return false;
|
||||
}
|
||||
if (this.mConfig != other.mConfig && (this.mConfig == null || !this.mConfig.equals(other.mConfig))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 37 * hash + (this.mType != null ? this.mType.hashCode() : 0);
|
||||
hash = 37 * hash + (this.mConfig != null ? this.mConfig.hashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
65
src/brut/androlib/res/data/value/ResArrayValue.java
Normal file
65
src/brut/androlib/res/data/value/ResArrayValue.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResArrayValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResArrayValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
}
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
String type = getType();
|
||||
type = (type == null ? "" : type + "-") + "array";
|
||||
|
||||
serializer.startTag(null, type);
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
for (ResScalarValue item : mItems.values()) {
|
||||
serializer.startTag(null, "item");
|
||||
serializer.text(item.toResXmlFormat());
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
serializer.endTag(null, type);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
if (mItems.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
Iterator<ResScalarValue> it = mItems.values().iterator();
|
||||
String type = it.next().getType();
|
||||
while (it.hasNext()) {
|
||||
String itemType = it.next().getType();
|
||||
if (! type.equals(itemType)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
100
src/brut/androlib/res/data/value/ResAttr.java
Normal file
100
src/brut/androlib/res/data/value/ResAttr.java
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResAttr extends ResBagValue implements ResXmlSerializable {
|
||||
private final int mType;
|
||||
|
||||
public ResAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items);
|
||||
mType = type;
|
||||
}
|
||||
|
||||
public String convertToResXmlFormat(ResScalarValue value)
|
||||
throws AndrolibException {
|
||||
return value.toResXmlFormat();
|
||||
}
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
String type = getTypeAsString();
|
||||
|
||||
serializer.startTag(null, "attr");
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
if (type != null) {
|
||||
serializer.attribute(null, "format", type);
|
||||
}
|
||||
serializeBody(serializer, res);
|
||||
serializer.endTag(null, "attr");
|
||||
}
|
||||
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {}
|
||||
|
||||
protected String getTypeAsString() {
|
||||
String s = "";
|
||||
if ((mType & TYPE_REFERENCE) != 0) {
|
||||
s += "|reference";
|
||||
}
|
||||
if ((mType & TYPE_STRING) != 0) {
|
||||
s += "|string";
|
||||
}
|
||||
if ((mType & TYPE_INT) != 0) {
|
||||
s += "|integer";
|
||||
}
|
||||
if ((mType & TYPE_BOOL) != 0) {
|
||||
s += "|boolean";
|
||||
}
|
||||
if ((mType & TYPE_COLOR) != 0) {
|
||||
s += "|color";
|
||||
}
|
||||
if ((mType & TYPE_FLOAT) != 0) {
|
||||
s += "|float";
|
||||
}
|
||||
if ((mType & TYPE_DIMEN) != 0) {
|
||||
s += "|dimension";
|
||||
}
|
||||
if ((mType & TYPE_FRACTION) != 0) {
|
||||
s += "|fraction";
|
||||
}
|
||||
if (s.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return s.substring(1);
|
||||
}
|
||||
|
||||
private final static int TYPE_REFERENCE = 0x01;
|
||||
private final static int TYPE_STRING = 0x02;
|
||||
private final static int TYPE_INT = 0x04;
|
||||
private final static int TYPE_BOOL = 0x08;
|
||||
private final static int TYPE_COLOR = 0x10;
|
||||
private final static int TYPE_FLOAT = 0x20;
|
||||
private final static int TYPE_DIMEN = 0x40;
|
||||
private final static int TYPE_FRACTION = 0x80;
|
||||
private final static int TYPE_ANY_STRING = 0xee;
|
||||
}
|
42
src/brut/androlib/res/data/value/ResAttrFactory.java
Normal file
42
src/brut/androlib/res/data/value/ResAttrFactory.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResAttrFactory {
|
||||
static ResValue factory(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
int type = ((ResIntValue) items.values().iterator().next()).getValue();
|
||||
|
||||
int attrType = type & 0x0000ffff;
|
||||
switch (type & 0x00ff0000) {
|
||||
case TYPE_ENUM:
|
||||
return new ResEnumAttr(parent, items, attrType);
|
||||
case TYPE_SET:
|
||||
return new ResSetAttr(parent, items, attrType);
|
||||
}
|
||||
return new ResAttr(parent, items, attrType);
|
||||
}
|
||||
|
||||
private final static int TYPE_ENUM = 0x00010000;
|
||||
private final static int TYPE_SET = 0x00020000;
|
||||
}
|
42
src/brut/androlib/res/data/value/ResBagValue.java
Normal file
42
src/brut/androlib/res/data/value/ResBagValue.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResBagValue extends ResValue {
|
||||
protected final ResReferenceValue mParent;
|
||||
protected final Map<ResReferenceValue, ResScalarValue> mItems;
|
||||
|
||||
public ResBagValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
this.mParent = parent;
|
||||
this.mItems = items;
|
||||
}
|
||||
|
||||
public ResReferenceValue getParent() {
|
||||
return mParent;
|
||||
}
|
||||
|
||||
public Map<ResReferenceValue, ResScalarValue> getItems() {
|
||||
return mItems;
|
||||
}
|
||||
}
|
39
src/brut/androlib/res/data/value/ResBoolValue.java
Normal file
39
src/brut/androlib/res/data/value/ResBoolValue.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResBoolValue extends ResScalarValue implements ResXmlSerializable {
|
||||
private final boolean mValue;
|
||||
|
||||
public ResBoolValue(boolean value) {
|
||||
super("bool");
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public boolean getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() {
|
||||
return mValue ? "true" : "false";
|
||||
}
|
||||
}
|
32
src/brut/androlib/res/data/value/ResColorValue.java
Normal file
32
src/brut/androlib/res/data/value/ResColorValue.java
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResColorValue extends ResIntValue {
|
||||
public ResColorValue(int value) {
|
||||
super(value, "color");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() {
|
||||
return String.format("#%08x", mValue);
|
||||
}
|
||||
}
|
58
src/brut/androlib/res/data/value/ResEnumAttr.java
Normal file
58
src/brut/androlib/res/data/value/ResEnumAttr.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResEnumAttr extends ResMapAttr {
|
||||
public ResEnumAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToResXmlFormat(ResScalarValue value)
|
||||
throws AndrolibException {
|
||||
if (value instanceof ResIntValue) {
|
||||
String ret = getItemsMap().get(((ResIntValue) value).getValue());
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return super.convertToResXmlFormat(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
serializer.startTag(null, "enum");
|
||||
serializer.attribute(null, "name", entry.getValue());
|
||||
serializer.attribute(null, "value", String.valueOf(entry.getKey()));
|
||||
serializer.endTag(null, "enum");
|
||||
}
|
||||
}
|
||||
}
|
43
src/brut/androlib/res/data/value/ResFileValue.java
Normal file
43
src/brut/androlib/res/data/value/ResFileValue.java
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResFileValue extends ResValue {
|
||||
private final String mPath;
|
||||
|
||||
public ResFileValue(String path) {
|
||||
this.mPath = path;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return mPath;
|
||||
}
|
||||
|
||||
public String getStrippedPath() throws AndrolibException {
|
||||
if (! mPath.startsWith("res/")) {
|
||||
throw new AndrolibException(
|
||||
"File path does not start with \"res/\": " + mPath);
|
||||
}
|
||||
return mPath.substring(4);
|
||||
}
|
||||
}
|
39
src/brut/androlib/res/data/value/ResFloatValue.java
Normal file
39
src/brut/androlib/res/data/value/ResFloatValue.java
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResFloatValue extends ResScalarValue {
|
||||
private final float mValue;
|
||||
|
||||
public ResFloatValue(float value) {
|
||||
super("float");
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public float getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() {
|
||||
return String.valueOf(mValue);
|
||||
}
|
||||
}
|
36
src/brut/androlib/res/data/value/ResIdValue.java
Normal file
36
src/brut/androlib/res/data/value/ResIdValue.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResIdValue extends ResValue {
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "item");
|
||||
serializer.attribute(null, "type", "id");
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
}
|
45
src/brut/androlib/res/data/value/ResIntValue.java
Normal file
45
src/brut/androlib/res/data/value/ResIntValue.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResIntValue extends ResScalarValue implements ResXmlSerializable {
|
||||
protected final int mValue;
|
||||
|
||||
public ResIntValue(int value) {
|
||||
this(value, "integer");
|
||||
}
|
||||
|
||||
public ResIntValue(int value, String type) {
|
||||
super(type);
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() throws AndrolibException {
|
||||
return String.valueOf(mValue);
|
||||
}
|
||||
}
|
61
src/brut/androlib/res/data/value/ResMapAttr.java
Normal file
61
src/brut/androlib/res/data/value/ResMapAttr.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public abstract class ResMapAttr extends ResAttr {
|
||||
private Map<Integer, String> mMap;
|
||||
|
||||
public ResMapAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
}
|
||||
|
||||
protected Map<Integer, String> getItemsMap() throws AndrolibException {
|
||||
if (mMap == null) {
|
||||
loadItemsMap();
|
||||
}
|
||||
return mMap;
|
||||
}
|
||||
|
||||
private void loadItemsMap() throws AndrolibException {
|
||||
mMap = new LinkedHashMap<Integer, String>();
|
||||
Iterator<Entry<ResReferenceValue, ResScalarValue>> it =
|
||||
mItems.entrySet().iterator();
|
||||
it.next();
|
||||
|
||||
while (it.hasNext()) {
|
||||
Entry<ResReferenceValue, ResScalarValue> entry = it.next();
|
||||
// TODO
|
||||
if (entry.getKey().getValue() < 0x01010000) {
|
||||
continue;
|
||||
}
|
||||
mMap.put(
|
||||
((ResIntValue) entry.getValue()).getValue(),
|
||||
entry.getKey().getReferent().getName());
|
||||
}
|
||||
}
|
||||
}
|
75
src/brut/androlib/res/data/value/ResPluralsValue.java
Normal file
75
src/brut/androlib/res/data/value/ResPluralsValue.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResPluralsValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResPluralsValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
}
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "plurals");
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
for (Entry<String, String> entry : getPluralsMap().entrySet()) {
|
||||
serializer.startTag(null, "item");
|
||||
serializer.attribute(null, "quantity", entry.getKey());
|
||||
serializer.text(entry.getValue());
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
serializer.endTag(null, "plurals");
|
||||
}
|
||||
|
||||
private Map<String, String> getPluralsMap() {
|
||||
Map<String, String> plurals = new LinkedHashMap<String, String>();
|
||||
for (Entry<ResReferenceValue, ResScalarValue> entry
|
||||
: mItems.entrySet()) {
|
||||
String quantity = getQuantityMap()[
|
||||
(entry.getKey().getValue() & 0xffff) - 4];
|
||||
if (quantity != null) {
|
||||
String value = ((ResStringValue) entry.getValue()).getValue();
|
||||
plurals.put(quantity, AndrolibResources.escapeForResXml(value));
|
||||
|
||||
}
|
||||
}
|
||||
return plurals;
|
||||
}
|
||||
|
||||
private static String[] getQuantityMap() {
|
||||
if (quantityMap == null) {
|
||||
quantityMap = new String[]
|
||||
{"other", "zero", "one", "two", "few", "many"};
|
||||
}
|
||||
return quantityMap;
|
||||
}
|
||||
|
||||
private static String[] quantityMap;
|
||||
}
|
62
src/brut/androlib/res/data/value/ResReferenceValue.java
Normal file
62
src/brut/androlib/res/data/value/ResReferenceValue.java
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResPackage;
|
||||
import brut.androlib.res.data.ResResSpec;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResReferenceValue extends ResIntValue {
|
||||
private final ResPackage mPackage;
|
||||
private final boolean mTheme;
|
||||
|
||||
public ResReferenceValue(ResPackage package_, int value) {
|
||||
this(package_, value, false);
|
||||
}
|
||||
|
||||
public ResReferenceValue(ResPackage package_, int value, boolean theme) {
|
||||
super(value);
|
||||
mPackage = package_;
|
||||
mTheme = theme;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() throws AndrolibException {
|
||||
if (isNull()) {
|
||||
return "@null";
|
||||
}
|
||||
// try {
|
||||
return
|
||||
(mTheme ? '?' : '@') +
|
||||
getReferent().getFullName(mPackage, mTheme);
|
||||
// } catch (AndrolibException ex) {
|
||||
// return "@" + String.valueOf(mValue);
|
||||
// }
|
||||
}
|
||||
|
||||
public ResResSpec getReferent() throws AndrolibException {
|
||||
return mPackage.getResTable().getResSpec(getValue());
|
||||
}
|
||||
|
||||
public boolean isNull() {
|
||||
return mValue == 0;
|
||||
}
|
||||
}
|
50
src/brut/androlib/res/data/value/ResScalarValue.java
Normal file
50
src/brut/androlib/res/data/value/ResScalarValue.java
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public abstract class ResScalarValue extends ResValue
|
||||
implements ResXmlPrintable, ResXmlSerializable {
|
||||
protected final String mType;
|
||||
|
||||
protected ResScalarValue(String type) {
|
||||
mType = type;
|
||||
}
|
||||
|
||||
public abstract String toResXmlFormat() throws AndrolibException;
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
String tagName = res.getResSpec().getType().getName();
|
||||
serializer.startTag(null, tagName);
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
serializer.text(toResXmlFormat());
|
||||
serializer.endTag(null, tagName);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return mType;
|
||||
}
|
||||
}
|
67
src/brut/androlib/res/data/value/ResSetAttr.java
Normal file
67
src/brut/androlib/res/data/value/ResSetAttr.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResSetAttr extends ResMapAttr {
|
||||
public ResSetAttr(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items, int type) {
|
||||
super(parent, items, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToResXmlFormat(ResScalarValue value)
|
||||
throws AndrolibException {
|
||||
if (! (value instanceof ResIntValue)) {
|
||||
return super.convertToResXmlFormat(value);
|
||||
}
|
||||
int intVal = ((ResIntValue) value).getValue();
|
||||
String strVal = "";
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
int flag = entry.getKey();
|
||||
if ((intVal & flag) == flag) {
|
||||
strVal += "|" + entry.getValue();
|
||||
}
|
||||
}
|
||||
if (strVal.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return strVal.substring(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void serializeBody(XmlSerializer serializer, ResResource res)
|
||||
throws AndrolibException, IOException {
|
||||
for (Entry<Integer, String> entry : getItemsMap().entrySet()) {
|
||||
serializer.startTag(null, "flag");
|
||||
serializer.attribute(null, "name", entry.getValue());
|
||||
serializer.attribute(null, "value",
|
||||
String.format("0x%08x", entry.getKey()));
|
||||
serializer.endTag(null, "flag");
|
||||
}
|
||||
}
|
||||
}
|
45
src/brut/androlib/res/data/value/ResStringValue.java
Normal file
45
src/brut/androlib/res/data/value/ResStringValue.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResStringValue extends ResScalarValue
|
||||
implements ResXmlSerializable {
|
||||
private final String mValue;
|
||||
|
||||
public ResStringValue(String value) {
|
||||
super("string");
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toResXmlFormat() {
|
||||
if (mValue.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return AndrolibResources.escapeForResXml(mValue);
|
||||
}
|
||||
}
|
62
src/brut/androlib/res/data/value/ResStyleValue.java
Normal file
62
src/brut/androlib/res/data/value/ResStyleValue.java
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResSpec;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResStyleValue extends ResBagValue implements ResXmlSerializable {
|
||||
public ResStyleValue(ResReferenceValue parent,
|
||||
Map<ResReferenceValue, ResScalarValue> items) {
|
||||
super(parent, items);
|
||||
}
|
||||
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException {
|
||||
serializer.startTag(null, "style");
|
||||
serializer.attribute(null, "name", res.getResSpec().getName());
|
||||
if (! mParent.isNull()) {
|
||||
serializer.attribute(null, "parent", mParent.toResXmlFormat());
|
||||
}
|
||||
for (Entry<ResReferenceValue, ResScalarValue> entry
|
||||
: mItems.entrySet()) {
|
||||
ResResSpec spec = entry.getKey().getReferent();
|
||||
ResAttr attr = (ResAttr) spec.getDefaultResource().getValue();
|
||||
String value = attr.convertToResXmlFormat(entry.getValue());
|
||||
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
serializer.startTag(null, "item");
|
||||
serializer.attribute(null, "name",
|
||||
spec.getFullName(res.getResSpec().getPackage(), true));
|
||||
serializer.text(value);
|
||||
serializer.endTag(null, "item");
|
||||
}
|
||||
serializer.endTag(null, "style");
|
||||
}
|
||||
}
|
25
src/brut/androlib/res/data/value/ResValue.java
Normal file
25
src/brut/androlib/res/data/value/ResValue.java
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResValue {
|
||||
|
||||
}
|
157
src/brut/androlib/res/data/value/ResValueFactory.java
Normal file
157
src/brut/androlib/res/data/value/ResValueFactory.java
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResPackage;
|
||||
import brut.androlib.res.data.ResTable;
|
||||
import brut.androlib.res.data.ResType;
|
||||
import brut.androlib.res.jni.JniBagItem;
|
||||
import brut.androlib.res.jni.JniEntry;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResValueFactory {
|
||||
private final ResPackage mPackage;
|
||||
|
||||
public ResValueFactory(ResPackage pakage_) {
|
||||
this.mPackage = pakage_;
|
||||
}
|
||||
|
||||
public ResScalarValue factory(String string) {
|
||||
if (string.isEmpty()) {
|
||||
return new ResStringValue(string);
|
||||
}
|
||||
char c = string.charAt(0);
|
||||
if (c == '@' || c == '?') {
|
||||
return newReference(
|
||||
Integer.parseInt(string.substring(1)), c == '?');
|
||||
}
|
||||
if (c == '#') {
|
||||
return new ResColorValue(
|
||||
(int) Long.parseLong(string.substring(1), 16));
|
||||
}
|
||||
try {
|
||||
if (string.startsWith("0x")) {
|
||||
return new ResIntValue(
|
||||
(int) Long.parseLong(string.substring(2), 16));
|
||||
}
|
||||
return new ResIntValue(Integer.parseInt(string));
|
||||
} catch (NumberFormatException ex) {}
|
||||
return new ResStringValue(string);
|
||||
}
|
||||
|
||||
public ResValue factory(JniEntry entry)
|
||||
throws AndrolibException {
|
||||
if ("id".equals(entry.type)) {
|
||||
return new ResIdValue();
|
||||
}
|
||||
switch (entry.valueType) {
|
||||
case TYPE_BAG:
|
||||
return bagFactory(entry);
|
||||
case TYPE_REFERENCE:
|
||||
return newReference(entry.intVal);
|
||||
case TYPE_ATTRIBUTE:
|
||||
return newReference(entry.intVal, true);
|
||||
case TYPE_INT_BOOLEAN:
|
||||
return new ResBoolValue(entry.boolVal);
|
||||
case TYPE_INT_DEC:
|
||||
case TYPE_INT_HEX:
|
||||
return new ResIntValue(entry.intVal);
|
||||
case TYPE_FLOAT:
|
||||
return new ResFloatValue(entry.floatVal);
|
||||
case TYPE_INT_COLOR_ARGB4:
|
||||
case TYPE_INT_COLOR_ARGB8:
|
||||
case TYPE_INT_COLOR_RGB4:
|
||||
case TYPE_INT_COLOR_RGB8:
|
||||
return new ResColorValue(entry.intVal);
|
||||
case TYPE_STRING:
|
||||
if (entry.strVal.startsWith("res/")) {
|
||||
return new ResFileValue(entry.strVal);
|
||||
}
|
||||
case TYPE_DIMENSION:
|
||||
case TYPE_FRACTION:
|
||||
return new ResStringValue(entry.strVal);
|
||||
}
|
||||
throw new AndrolibException(String.format(
|
||||
"Unknown value type for %s/%s: ",
|
||||
entry.type, entry.name, String.valueOf(entry.valueType)));
|
||||
}
|
||||
|
||||
private ResValue bagFactory(JniEntry entry)
|
||||
throws AndrolibException {
|
||||
ResReferenceValue parent = newReference(entry.bagParent);
|
||||
Map<ResReferenceValue, ResScalarValue> items =
|
||||
convertItems(entry.bagItems);
|
||||
String type = entry.type;
|
||||
|
||||
if ("array".equals(type)) {
|
||||
return new ResArrayValue(parent, items);
|
||||
}
|
||||
if ("style".equals(type)) {
|
||||
return new ResStyleValue(parent, items);
|
||||
}
|
||||
if ("plurals".equals(type)) {
|
||||
return new ResPluralsValue(parent, items);
|
||||
}
|
||||
if ("attr".equals(type)) {
|
||||
return ResAttrFactory.factory(parent, items);
|
||||
}
|
||||
return new ResBagValue(parent, items);
|
||||
}
|
||||
|
||||
private ResReferenceValue newReference(int resID) {
|
||||
return newReference(resID, false);
|
||||
}
|
||||
|
||||
private ResReferenceValue newReference(int resID, boolean theme) {
|
||||
return new ResReferenceValue(mPackage, resID, theme);
|
||||
}
|
||||
|
||||
private Map<ResReferenceValue, ResScalarValue> convertItems(
|
||||
JniBagItem[] jniItems) throws AndrolibException {
|
||||
Map<ResReferenceValue, ResScalarValue> items =
|
||||
new LinkedHashMap<ResReferenceValue, ResScalarValue>();
|
||||
for (int i = 0; i < jniItems.length; i++) {
|
||||
JniBagItem jniItem = jniItems[i];
|
||||
items.put(newReference(jniItem.resID),
|
||||
(ResScalarValue) factory(jniItem.entry));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private final static int TYPE_NULL = 0x00;
|
||||
private final static int TYPE_REFERENCE = 0x01;
|
||||
private final static int TYPE_ATTRIBUTE = 0x02;
|
||||
private final static int TYPE_STRING = 0x03;
|
||||
private final static int TYPE_FLOAT = 0x04;
|
||||
private final static int TYPE_DIMENSION = 0x05;
|
||||
private final static int TYPE_FRACTION = 0x06;
|
||||
private final static int TYPE_INT_DEC = 0x10;
|
||||
private final static int TYPE_INT_HEX = 0x11;
|
||||
private final static int TYPE_INT_BOOLEAN = 0x12;
|
||||
private final static int TYPE_INT_COLOR_ARGB8 = 0x1c;
|
||||
private final static int TYPE_INT_COLOR_RGB8 = 0x1d;
|
||||
private final static int TYPE_INT_COLOR_ARGB4 = 0x1e;
|
||||
private final static int TYPE_INT_COLOR_RGB4 = 0x1f;
|
||||
|
||||
private final static int TYPE_BAG = -0x01;
|
||||
}
|
27
src/brut/androlib/res/data/value/ResXmlPrintable.java
Normal file
27
src/brut/androlib/res/data/value/ResXmlPrintable.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public interface ResXmlPrintable {
|
||||
public String toResXmlFormat() throws AndrolibException;
|
||||
}
|
31
src/brut/androlib/res/data/value/ResXmlSerializable.java
Normal file
31
src/brut/androlib/res/data/value/ResXmlSerializable.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.data.value;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.ResResource;
|
||||
import java.io.IOException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public interface ResXmlSerializable {
|
||||
public void serializeToXml(XmlSerializer serializer, ResResource res)
|
||||
throws IOException, AndrolibException;
|
||||
}
|
83
src/brut/androlib/res/decoder/JniPackageDecoder.java
Normal file
83
src/brut/androlib/res/decoder/JniPackageDecoder.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.androlib.res.data.*;
|
||||
import brut.androlib.res.data.value.ResValue;
|
||||
import brut.androlib.res.data.value.ResValueFactory;
|
||||
import brut.androlib.res.jni.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniPackageDecoder {
|
||||
public ResPackage decode(JniPackage jniPkg, ResTable resTable)
|
||||
throws AndrolibException {
|
||||
ResPackage pkg = new ResPackage(resTable, jniPkg.id, jniPkg.name);
|
||||
ResValueFactory valueFactory = pkg.getValueFactory();
|
||||
|
||||
JniConfig[] jniConfigs = jniPkg.configs;
|
||||
for (int i = 0; i < jniConfigs.length; i++) {
|
||||
JniConfig jniConfig = jniConfigs[i];
|
||||
|
||||
ResConfigFlags flags = new ResConfigFlags(jniConfig);
|
||||
ResConfig config;
|
||||
if (pkg.hasConfig(flags)) {
|
||||
config = pkg.getConfig(flags);
|
||||
} else {
|
||||
config = new ResConfig(flags);
|
||||
pkg.addConfig(config);
|
||||
}
|
||||
|
||||
JniEntry[] jniEntries = jniConfig.entries;
|
||||
for (int j = 0; j < jniEntries.length; j++) {
|
||||
JniEntry jniEntry = jniEntries[j];
|
||||
|
||||
ResType type;
|
||||
String typeName = jniEntry.type;
|
||||
if (pkg.hasType(typeName)) {
|
||||
type = pkg.getType(typeName);
|
||||
} else {
|
||||
type = new ResType(typeName, resTable, pkg);
|
||||
pkg.addType(type);
|
||||
}
|
||||
|
||||
ResID resID = new ResID(jniEntry.resID);
|
||||
ResResSpec spec;
|
||||
if (pkg.hasResSpec(resID)) {
|
||||
spec = pkg.getResSpec(resID);
|
||||
} else {
|
||||
spec = new ResResSpec(resID, jniEntry.name, pkg, type);
|
||||
pkg.addResSpec(spec);
|
||||
type.addResSpec(spec);
|
||||
}
|
||||
|
||||
ResValue value = valueFactory.factory(jniEntry);
|
||||
ResResource res =
|
||||
new ResResource(config, spec, value);
|
||||
|
||||
config.addResource(res);
|
||||
spec.addResource(res);
|
||||
pkg.addResource(res);
|
||||
}
|
||||
}
|
||||
|
||||
return pkg;
|
||||
}
|
||||
}
|
87
src/brut/androlib/res/decoder/ResFileDecoder.java
Normal file
87
src/brut/androlib/res/decoder/ResFileDecoder.java
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import brut.directory.Directory;
|
||||
import brut.directory.DirectoryException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResFileDecoder {
|
||||
private final ResStreamDecoderContainer mDecoders;
|
||||
|
||||
public ResFileDecoder(ResStreamDecoderContainer decoders) {
|
||||
this.mDecoders = decoders;
|
||||
}
|
||||
|
||||
public void decode(Directory inDir, String inFileName, Directory outDir,
|
||||
String outResName) throws AndrolibException {
|
||||
String ext = "";
|
||||
int extPos = inFileName.lastIndexOf(".");
|
||||
if (extPos != -1) {
|
||||
ext = inFileName.substring(extPos);
|
||||
}
|
||||
|
||||
if (inFileName.startsWith("raw/")) {
|
||||
decode(inDir, inFileName, outDir, outResName + ext, "raw");
|
||||
return;
|
||||
}
|
||||
if (inFileName.endsWith(".9.png")) {
|
||||
decode(inDir, inFileName, outDir, outResName + ".png", "raw");
|
||||
return;
|
||||
}
|
||||
if (inFileName.endsWith(".xml")) {
|
||||
decode(inDir, inFileName, outDir, outResName + ".xml", "xml");
|
||||
return;
|
||||
}
|
||||
if (inFileName.endsWith(".html")) {
|
||||
decode(inDir, inFileName, outDir, outResName + ".html", "xml");
|
||||
return;
|
||||
}
|
||||
|
||||
decode(inDir, inFileName, outDir, outResName + ext, "raw");
|
||||
}
|
||||
|
||||
public void decode(Directory inDir, String inFileName, Directory outDir,
|
||||
String outFileName, String decoder) throws AndrolibException {
|
||||
try {
|
||||
InputStream in = inDir.getFileInput(inFileName);
|
||||
OutputStream out = outDir.getFileOutput(outFileName);
|
||||
mDecoders.decode(in, out, decoder);
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (AndrolibException ex) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Could not decode file \"%s\" to \"%s\"",
|
||||
inFileName, outFileName), ex);
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Could not decode file \"%s\" to \"%s\"",
|
||||
inFileName, outFileName), ex);
|
||||
} catch (DirectoryException ex) {
|
||||
throw new AndrolibException(String.format(
|
||||
"Could not decode file \"%s\" to \"%s\"",
|
||||
inFileName, outFileName), ex);
|
||||
}
|
||||
}
|
||||
}
|
38
src/brut/androlib/res/decoder/ResRawStreamDecoder.java
Normal file
38
src/brut/androlib/res/decoder/ResRawStreamDecoder.java
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResRawStreamDecoder implements ResStreamDecoder {
|
||||
public void decode(InputStream in, OutputStream out)
|
||||
throws AndrolibException {
|
||||
try {
|
||||
IOUtils.copy(in, out);
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException("Could not decode raw stream", ex);
|
||||
}
|
||||
}
|
||||
}
|
30
src/brut/androlib/res/decoder/ResStreamDecoder.java
Normal file
30
src/brut/androlib/res/decoder/ResStreamDecoder.java
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public interface ResStreamDecoder {
|
||||
public void decode(InputStream in, OutputStream out)
|
||||
throws AndrolibException;
|
||||
}
|
49
src/brut/androlib/res/decoder/ResStreamDecoderContainer.java
Normal file
49
src/brut/androlib/res/decoder/ResStreamDecoderContainer.java
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResStreamDecoderContainer {
|
||||
private final Map<String, ResStreamDecoder> mDecoders =
|
||||
new HashMap<String, ResStreamDecoder>();
|
||||
|
||||
public void decode(InputStream in, OutputStream out, String decoderName)
|
||||
throws AndrolibException {
|
||||
getDecoder(decoderName).decode(in, out);
|
||||
}
|
||||
|
||||
public ResStreamDecoder getDecoder(String name) throws AndrolibException {
|
||||
ResStreamDecoder decoder = mDecoders.get(name);
|
||||
if (decoder== null) {
|
||||
throw new AndrolibException("Undefined decoder: " + name);
|
||||
}
|
||||
return decoder;
|
||||
}
|
||||
|
||||
public void setDecoder(String name, ResStreamDecoder decoder) {
|
||||
mDecoders.put(name, decoder);
|
||||
}
|
||||
}
|
109
src/brut/androlib/res/decoder/ResXmlSerializer.java
Normal file
109
src/brut/androlib/res/decoder/ResXmlSerializer.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import brut.androlib.*;
|
||||
import brut.androlib.res.AndrolibResources;
|
||||
import brut.androlib.res.data.ResPackage;
|
||||
import brut.androlib.res.data.value.ResAttr;
|
||||
import java.io.IOException;
|
||||
import org.xmlpull.mxp1_serializer.MXSerializer;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResXmlSerializer extends MXSerializer {
|
||||
private final static String RES_NAMESPACE =
|
||||
"http://schemas.android.com/apk/res/android";
|
||||
|
||||
private ResPackage mCurrentPackage;
|
||||
private boolean mDecodingEnabled = true;
|
||||
|
||||
@Override
|
||||
public XmlSerializer attribute(String namespace, String name, String value)
|
||||
throws IOException, IllegalArgumentException, IllegalStateException
|
||||
{
|
||||
if (! mDecodingEnabled) {
|
||||
return super.attribute(namespace, name, value);
|
||||
}
|
||||
if (namespace == null || namespace.isEmpty()) {
|
||||
return super.attribute(namespace, name,
|
||||
// AndrolibResources.escapeForResXml(value)
|
||||
value
|
||||
);
|
||||
}
|
||||
String pkgName = RES_NAMESPACE.equals(namespace) ?
|
||||
"android" : mCurrentPackage.getName();
|
||||
|
||||
try {
|
||||
ResAttr attr = (ResAttr) mCurrentPackage.getResTable()
|
||||
.getValue(pkgName, "attr", name);
|
||||
value = attr.convertToResXmlFormat(
|
||||
mCurrentPackage.getValueFactory().factory(value));
|
||||
} catch (AndrolibException ex) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"could not decode attribute: ns=%s, name=%s, value=%s",
|
||||
getPrefix(namespace, false), name, value), ex);
|
||||
}
|
||||
|
||||
if (value == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// if ("id".equals(name) && value.startsWith("@id")) {
|
||||
if (value.startsWith("@id")) {
|
||||
value = "@+id" + value.substring(3);
|
||||
}
|
||||
return super.attribute(namespace, name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlSerializer text(String text) throws IOException {
|
||||
if (mDecodingEnabled) {
|
||||
text = AndrolibResources.escapeForResXml(text);
|
||||
}
|
||||
return super.text(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlSerializer text(char[] buf, int start, int len) throws IOException {
|
||||
if (mDecodingEnabled) {
|
||||
return this.text(new String(buf, start, len));
|
||||
}
|
||||
return super.text(buf, start, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDocument(String encoding, Boolean standalone) throws
|
||||
IOException, IllegalArgumentException, IllegalStateException {
|
||||
super.startDocument(encoding != null ? encoding : "UTF-8", standalone);
|
||||
super.out.write("\n");
|
||||
super.setPrefix("android", RES_NAMESPACE);
|
||||
}
|
||||
|
||||
public void setCurrentPackage(ResPackage package_) {
|
||||
mCurrentPackage = package_;
|
||||
}
|
||||
|
||||
public boolean setDecodingEnabled(boolean escapeRefs) {
|
||||
boolean oldVal = mDecodingEnabled;
|
||||
this.mDecodingEnabled = escapeRefs;
|
||||
return oldVal;
|
||||
}
|
||||
}
|
80
src/brut/androlib/res/decoder/ResXmlStreamDecoder.java
Normal file
80
src/brut/androlib/res/decoder/ResXmlStreamDecoder.java
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.decoder;
|
||||
|
||||
import android.content.res.XmlBlock;
|
||||
import brut.androlib.AndrolibException;
|
||||
import java.io.*;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.xmlpull.v1.*;
|
||||
import org.xmlpull.v1.wrapper.*;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class ResXmlStreamDecoder implements ResStreamDecoder {
|
||||
private final ResXmlSerializer mSerializer;
|
||||
|
||||
public ResXmlStreamDecoder(ResXmlSerializer serializer) {
|
||||
this.mSerializer = serializer;
|
||||
}
|
||||
|
||||
public void decode(InputStream in, OutputStream out)
|
||||
throws AndrolibException {
|
||||
try {
|
||||
XmlPullParserWrapper par =
|
||||
getResXmlParserWrapper(in);
|
||||
XmlSerializerWrapper ser =
|
||||
getXmlWrapperFactory().newSerializerWrapper(mSerializer);
|
||||
ser.setOutput(out, null);
|
||||
mSerializer.setDecodingEnabled(true);
|
||||
|
||||
while (par.nextToken() != XmlPullParser.END_DOCUMENT) {
|
||||
ser.event(par);
|
||||
}
|
||||
ser.flush();
|
||||
} catch (IOException ex) {
|
||||
throw new AndrolibException("could not decode XML stream", ex);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new AndrolibException("could not decode XML stream", ex);
|
||||
} catch (IllegalStateException ex) {
|
||||
throw new AndrolibException("could not decode XML stream", ex);
|
||||
} catch (XmlPullParserException ex) {
|
||||
throw new AndrolibException("could not decode XML stream", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private XmlPullParserWrapper getResXmlParserWrapper(InputStream in)
|
||||
throws IOException, XmlPullParserException {
|
||||
XmlBlock xml = new XmlBlock(copyStreamToByteArray(in));
|
||||
XmlPullParser parser = xml.newParser();
|
||||
return getXmlWrapperFactory().newPullParserWrapper(parser);
|
||||
}
|
||||
|
||||
private XmlPullWrapperFactory getXmlWrapperFactory()
|
||||
throws XmlPullParserException {
|
||||
return XmlPullWrapperFactory.newInstance();
|
||||
}
|
||||
|
||||
private byte[] copyStreamToByteArray(InputStream in) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
IOUtils.copy(in, out);
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
}
|
31
src/brut/androlib/res/jni/JniBagItem.java
Normal file
31
src/brut/androlib/res/jni/JniBagItem.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniBagItem {
|
||||
public final int resID;
|
||||
public final JniEntry entry;
|
||||
|
||||
public JniBagItem(int resID, JniEntry entry) {
|
||||
this.resID = resID;
|
||||
this.entry = entry;
|
||||
}
|
||||
}
|
66
src/brut/androlib/res/jni/JniConfig.java
Normal file
66
src/brut/androlib/res/jni/JniConfig.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniConfig {
|
||||
public final int mcc;
|
||||
public final int mnc;
|
||||
|
||||
public final char[] language;
|
||||
public final char[] country;
|
||||
|
||||
public final int orientation;
|
||||
public final int touchscreen;
|
||||
public final int density;
|
||||
|
||||
public final int keyboard;
|
||||
public final int navigation;
|
||||
public final int inputFlags;
|
||||
|
||||
public final int screenWidth;
|
||||
public final int screenHeight;
|
||||
public final int screenLayout;
|
||||
|
||||
public final int sdkVersion;
|
||||
|
||||
public final JniEntry[] entries;
|
||||
|
||||
public JniConfig(int mcc, int mnc, char[] language, char[] country,
|
||||
int orientation, int touchscreen, int density, int keyboard,
|
||||
int navigation, int inputFlags, int screenWidth, int screenHeight,
|
||||
int screenLayout, int sdkVersion, JniEntry[] entries) {
|
||||
this.mcc = mcc;
|
||||
this.mnc = mnc;
|
||||
this.language = language;
|
||||
this.country = country;
|
||||
this.orientation = orientation;
|
||||
this.touchscreen = touchscreen;
|
||||
this.density = density;
|
||||
this.keyboard = keyboard;
|
||||
this.navigation = navigation;
|
||||
this.inputFlags = inputFlags;
|
||||
this.screenWidth = screenWidth;
|
||||
this.screenHeight = screenHeight;
|
||||
this.screenLayout = screenLayout;
|
||||
this.sdkVersion = sdkVersion;
|
||||
this.entries = entries;
|
||||
}
|
||||
}
|
52
src/brut/androlib/res/jni/JniEntry.java
Normal file
52
src/brut/androlib/res/jni/JniEntry.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniEntry {
|
||||
public final int resID;
|
||||
public final String name;
|
||||
public final String type;
|
||||
|
||||
public final int valueType;
|
||||
|
||||
public final boolean boolVal;
|
||||
public final int intVal;
|
||||
public final float floatVal;
|
||||
public final String strVal;
|
||||
|
||||
public final int bagParent;
|
||||
public final JniBagItem[] bagItems;
|
||||
|
||||
public JniEntry(int resID, String name, String type, int valueType,
|
||||
boolean boolVal, int intVal, float floatVal, String strVal,
|
||||
int bagParent, JniBagItem[] bagItems) {
|
||||
this.resID = resID;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.valueType = valueType;
|
||||
this.boolVal = boolVal;
|
||||
this.intVal = intVal;
|
||||
this.floatVal = floatVal;
|
||||
this.strVal = strVal;
|
||||
this.bagParent = bagParent;
|
||||
this.bagItems = bagItems;
|
||||
}
|
||||
}
|
33
src/brut/androlib/res/jni/JniPackage.java
Normal file
33
src/brut/androlib/res/jni/JniPackage.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniPackage {
|
||||
public final int id;
|
||||
public final String name;
|
||||
public final JniConfig[] configs;
|
||||
|
||||
public JniPackage(int id, String name, JniConfig[] configs) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.configs = configs;
|
||||
}
|
||||
}
|
29
src/brut/androlib/res/jni/JniPackageGroup.java
Normal file
29
src/brut/androlib/res/jni/JniPackageGroup.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniPackageGroup {
|
||||
public final JniPackage[] packages;
|
||||
|
||||
public JniPackageGroup(JniPackage[] packages) {
|
||||
this.packages = packages;
|
||||
}
|
||||
}
|
33
src/brut/androlib/res/jni/JniType.java
Normal file
33
src/brut/androlib/res/jni/JniType.java
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package brut.androlib.res.jni;
|
||||
|
||||
/**
|
||||
* @author Ryszard Wiśniewski <brut.alll@gmail.com>
|
||||
*/
|
||||
public class JniType {
|
||||
public final int entryCount;
|
||||
public final int typeSpecFlags;
|
||||
public final JniConfig[] configs;
|
||||
|
||||
public JniType(int entryCount, int typeSpecFlags, JniConfig[] configs) {
|
||||
this.entryCount = entryCount;
|
||||
this.typeSpecFlags = typeSpecFlags;
|
||||
this.configs = configs;
|
||||
}
|
||||
}
|
BIN
src/resources.arsc
Normal file
BIN
src/resources.arsc
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user