summaryrefslogtreecommitdiffstats
path: root/build/tools/extract_utils.sh
diff options
context:
space:
mode:
Diffstat (limited to 'build/tools/extract_utils.sh')
-rw-r--r--build/tools/extract_utils.sh102
1 files changed, 102 insertions, 0 deletions
diff --git a/build/tools/extract_utils.sh b/build/tools/extract_utils.sh
index aaae375..b4b8faf 100644
--- a/build/tools/extract_utils.sh
+++ b/build/tools/extract_utils.sh
@@ -20,6 +20,11 @@ PRODUCT_PACKAGES_LIST=()
PACKAGE_LIST=()
VENDOR_STATE=-1
COMMON=-1
+ARCHES=
+FULLY_DEODEXED=-1
+
+TMPDIR="/tmp/extractfiles.$$"
+mkdir "$TMPDIR"
#
# setup_vendor
@@ -533,6 +538,91 @@ function write_makefiles() {
}
#
+# get_file:
+#
+# $1: input file
+# $2: target file/folder
+# $3: source of the file (can be "adb" or a local folder)
+#
+# Silently extracts the input file to defined target
+# Returns success if file can be pulled from the device or found locally
+#
+function get_file() {
+ local SRC="$3"
+
+ if [ "$SRC" = "adb" ]; then
+ # try to pull
+ adb pull "$1" "$2" >/dev/null 2>&1 && return 0
+
+ return 1
+ else
+ # try to copy
+ cp "$SRC/$1" "$2" 2>/dev/null && return 0
+
+ return 1
+ fi
+};
+
+#
+# oat2dex:
+#
+# $1: extracted apk|jar (to check if deodex is required)
+# $2: odexed apk|jar to deodex
+# $3: source of the odexed apk|jar
+#
+# Convert apk|jar .odex in the corresposing classes.dex
+#
+function oat2dex() {
+ local CM_TARGET="$1"
+ local OEM_TARGET="$2"
+ local SRC="$3"
+ local TARGET=
+ local OAT=
+
+ if [ -z "$BAKSMALIJAR" ] || [ -z "$SMALIJAR" ]; then
+ export BAKSMALIJAR="$CM_ROOT"/vendor/cm/build/tools/smali/baksmali.jar
+ export SMALIJAR="$CM_ROOT"/vendor/cm/build/tools/smali/smali.jar
+ fi
+
+ # Extract existing boot.oats to the temp folder
+ if [ -z "$ARCHES" ]; then
+ echo "Checking if system is odexed and extracting boot.oats, if applicable. This may take a while..."
+ for ARCH in "arm64" "arm" "x86_64" "x86"; do
+ if get_file "system/framework/$ARCH/boot.oat" "$TMPDIR/boot_$ARCH.oat" "$SRC"; then
+ ARCHES+="$ARCH "
+ fi
+ done
+ fi
+
+ if [ -z "$ARCHES" ]; then
+ FULLY_DEODEXED=1 && return 0 # system is fully deodexed, return
+ fi
+
+ if grep "classes.dex" "$CM_TARGET" >/dev/null; then
+ return 0 # target apk|jar is already odexed, return
+ fi
+
+ for ARCH in $ARCHES; do
+ BOOTOAT="$TMPDIR/boot_$ARCH.oat"
+
+ local OAT="$(dirname "$OEM_TARGET")/oat/$ARCH/$(basename "$OEM_TARGET" ."${OEM_TARGET##*.}").odex"
+
+ if get_file "$OAT" "$TMPDIR" "$SRC"; then
+ java -jar "$BAKSMALIJAR" -x -o "$TMPDIR/dexout" -c "$BOOTOAT" -d "$TMPDIR" "$TMPDIR/$(basename "$OAT")"
+ elif [[ "$CM_TARGET" =~ .jar$ ]]; then
+ # try to extract classes.dex from boot.oat for framework jars
+ java -jar "$BAKSMALIJAR" -x -o "$TMPDIR/dexout" -c "$BOOTOAT" -d "$TMPDIR" -e "/$OEM_TARGET" "$BOOTOAT"
+ else
+ continue
+ fi
+
+ java -jar "$SMALIJAR" "$TMPDIR/dexout" -o "$TMPDIR/classes.dex" && break
+ done
+
+ rm -rf "$TMPDIR/dexout"
+}
+
+#
# init_adb_connection:
#
# Starts adb server and waits for the device
@@ -640,6 +730,18 @@ function extract() {
fi
fi
+ if [ "$?" == "0" ]; then
+ # Deodex apk|jar if that's the case
+ if [[ "$FULLY_DEODEXED" -ne "1" && "$DEST" =~ .(apk|jar)$ ]]; then
+ oat2dex "$DEST" "$FILE" "$SRC"
+ if [ -f "$TMPDIR/classes.dex" ]; then
+ zip -gjq "$DEST" "$TMPDIR/classes.dex"
+ rm "$TMPDIR/classes.dex"
+ printf ' (updated %s from odex files)\n' "/$FILE"
+ fi
+ fi
+ fi
+
local TYPE="${DIR##*/}"
if [ "$TYPE" = "bin" -o "$TYPE" = "sbin" ]; then
chmod 755 "$DEST"