Add decompiled APK source code (JADX)

- 28,932 files
- Full Java source code
- Smali files
- Resources

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-02-18 14:52:23 -08:00
parent cc210a65ea
commit f9d20bb3fc
26991 changed files with 2541449 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
package androidx.multidex;
/* loaded from: classes.dex */
public final class BuildConfig {
public static final String APPLICATION_ID = "androidx.multidex";
public static final String BUILD_TYPE = "release";
public static final boolean DEBUG = false;
public static final String FLAVOR = "";
public static final int VERSION_CODE = -1;
public static final String VERSION_NAME = "";
}

View File

@@ -0,0 +1,450 @@
package androidx.multidex;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.util.Log;
import csdk.gluads.Consts;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexFile;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.zip.ZipFile;
/* loaded from: classes.dex */
public final class MultiDex {
private static final String CODE_CACHE_NAME = "code_cache";
private static final String CODE_CACHE_SECONDARY_FOLDER_NAME = "secondary-dexes";
private static final int MAX_SUPPORTED_SDK_VERSION = 20;
private static final int MIN_SDK_VERSION = 4;
private static final String NO_KEY_PREFIX = "";
private static final String OLD_SECONDARY_FOLDER_NAME = "secondary-dexes";
static final String TAG = "MultiDex";
private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2;
private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1;
private static final Set<File> installedApk = new HashSet();
private static final boolean IS_VM_MULTIDEX_CAPABLE = isVMMultidexCapable(System.getProperty("java.vm.version"));
private MultiDex() {
}
public static void install(Context context) {
if (IS_VM_MULTIDEX_CAPABLE) {
return;
}
try {
ApplicationInfo applicationInfo = getApplicationInfo(context);
if (applicationInfo == null) {
return;
}
doInstallation(context, new File(applicationInfo.sourceDir), new File(applicationInfo.dataDir), "secondary-dexes", "", true);
} catch (Exception e) {
Log.e(TAG, "MultiDex installation failure", e);
throw new RuntimeException("MultiDex installation failed (" + e.getMessage() + ").");
}
}
public static void installInstrumentation(Context context, Context context2) {
ApplicationInfo applicationInfo;
if (IS_VM_MULTIDEX_CAPABLE) {
return;
}
try {
ApplicationInfo applicationInfo2 = getApplicationInfo(context);
if (applicationInfo2 == null || (applicationInfo = getApplicationInfo(context2)) == null) {
return;
}
String str = context.getPackageName() + Consts.STRING_PERIOD;
File file = new File(applicationInfo.dataDir);
doInstallation(context2, new File(applicationInfo2.sourceDir), file, str + "secondary-dexes", str, false);
doInstallation(context2, new File(applicationInfo.sourceDir), file, "secondary-dexes", "", false);
} catch (Exception e) {
Log.e(TAG, "MultiDex installation failure", e);
throw new RuntimeException("MultiDex installation failed (" + e.getMessage() + ").");
}
}
private static void doInstallation(Context context, File file, File file2, String str, String str2, boolean z) throws IOException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException {
Set<File> set = installedApk;
synchronized (set) {
try {
if (set.contains(file)) {
return;
}
set.add(file);
Log.w(TAG, "MultiDex is not guaranteed to work in SDK version " + Build.VERSION.SDK_INT + ": SDK version higher than 20 should be backed by runtime with built-in multidex capabilty but it's not the case here: java.vm.version=\"" + System.getProperty("java.vm.version") + "\"");
ClassLoader dexClassloader = getDexClassloader(context);
if (dexClassloader == null) {
return;
}
try {
clearOldDexDir(context);
} catch (Throwable th) {
Log.w(TAG, "Something went wrong when trying to clear old MultiDex extraction, continuing without cleaning.", th);
}
File dexDir = getDexDir(context, file2, str);
MultiDexExtractor multiDexExtractor = new MultiDexExtractor(file, dexDir);
try {
try {
installSecondaryDexes(dexClassloader, dexDir, multiDexExtractor.load(context, str2, false));
} catch (IOException e) {
if (!z) {
throw e;
}
Log.w(TAG, "Failed to install extracted secondary dex files, retrying with forced extraction", e);
installSecondaryDexes(dexClassloader, dexDir, multiDexExtractor.load(context, str2, true));
}
try {
e = null;
} catch (IOException e2) {
e = e2;
}
if (e != null) {
throw e;
}
} finally {
try {
multiDexExtractor.close();
} catch (IOException unused) {
}
}
} catch (Throwable th2) {
throw th2;
}
}
}
private static ClassLoader getDexClassloader(Context context) {
try {
ClassLoader classLoader = context.getClassLoader();
if (classLoader instanceof BaseDexClassLoader) {
return classLoader;
}
Log.e(TAG, "Context class loader is null or not dex-capable. Must be running in test mode. Skip patching.");
return null;
} catch (RuntimeException e) {
Log.w(TAG, "Failure while trying to obtain Context class loader. Must be running in test mode. Skip patching.", e);
return null;
}
}
private static ApplicationInfo getApplicationInfo(Context context) {
try {
return context.getApplicationInfo();
} catch (RuntimeException e) {
Log.w(TAG, "Failure while trying to obtain ApplicationInfo from Context. Must be running in test mode. Skip patching.", e);
return null;
}
}
public static boolean isVMMultidexCapable(String str) {
boolean z = false;
if (str != null) {
StringTokenizer stringTokenizer = new StringTokenizer(str, Consts.STRING_PERIOD);
String nextToken = stringTokenizer.hasMoreTokens() ? stringTokenizer.nextToken() : null;
String nextToken2 = stringTokenizer.hasMoreTokens() ? stringTokenizer.nextToken() : null;
if (nextToken != null && nextToken2 != null) {
try {
int parseInt = Integer.parseInt(nextToken);
int parseInt2 = Integer.parseInt(nextToken2);
if (parseInt > 2 || (parseInt == 2 && parseInt2 >= 1)) {
z = true;
}
} catch (NumberFormatException unused) {
}
}
}
StringBuilder sb = new StringBuilder();
sb.append("VM with version ");
sb.append(str);
sb.append(z ? " has multidex support" : " does not have multidex support");
return z;
}
private static void installSecondaryDexes(ClassLoader classLoader, File file, List<? extends File> list) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IOException, SecurityException, ClassNotFoundException, InstantiationException {
if (list.isEmpty()) {
return;
}
V19.install(classLoader, list, file);
}
/* JADX INFO: Access modifiers changed from: private */
public static Field findField(Object obj, String str) throws NoSuchFieldException {
for (Class<?> cls = obj.getClass(); cls != null; cls = cls.getSuperclass()) {
try {
Field declaredField = cls.getDeclaredField(str);
if (!declaredField.isAccessible()) {
declaredField.setAccessible(true);
}
return declaredField;
} catch (NoSuchFieldException unused) {
}
}
throw new NoSuchFieldException("Field " + str + " not found in " + obj.getClass());
}
/* JADX INFO: Access modifiers changed from: private */
public static Method findMethod(Object obj, String str, Class<?>... clsArr) throws NoSuchMethodException {
for (Class<?> cls = obj.getClass(); cls != null; cls = cls.getSuperclass()) {
try {
Method declaredMethod = cls.getDeclaredMethod(str, clsArr);
if (!declaredMethod.isAccessible()) {
declaredMethod.setAccessible(true);
}
return declaredMethod;
} catch (NoSuchMethodException unused) {
}
}
throw new NoSuchMethodException("Method " + str + " with parameters " + Arrays.asList(clsArr) + " not found in " + obj.getClass());
}
/* JADX INFO: Access modifiers changed from: private */
public static void expandFieldArray(Object obj, String str, Object[] objArr) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field findField = findField(obj, str);
Object[] objArr2 = (Object[]) findField.get(obj);
Object[] objArr3 = (Object[]) Array.newInstance(objArr2.getClass().getComponentType(), objArr2.length + objArr.length);
System.arraycopy(objArr2, 0, objArr3, 0, objArr2.length);
System.arraycopy(objArr, 0, objArr3, objArr2.length, objArr.length);
findField.set(obj, objArr3);
}
private static void clearOldDexDir(Context context) throws Exception {
File file = new File(context.getFilesDir(), "secondary-dexes");
if (file.isDirectory()) {
StringBuilder sb = new StringBuilder();
sb.append("Clearing old secondary dex dir (");
sb.append(file.getPath());
sb.append(").");
File[] listFiles = file.listFiles();
if (listFiles == null) {
Log.w(TAG, "Failed to list secondary dex dir content (" + file.getPath() + ").");
return;
}
for (File file2 : listFiles) {
StringBuilder sb2 = new StringBuilder();
sb2.append("Trying to delete old file ");
sb2.append(file2.getPath());
sb2.append(" of size ");
sb2.append(file2.length());
if (file2.delete()) {
StringBuilder sb3 = new StringBuilder();
sb3.append("Deleted old file ");
sb3.append(file2.getPath());
} else {
Log.w(TAG, "Failed to delete old file " + file2.getPath());
}
}
if (!file.delete()) {
Log.w(TAG, "Failed to delete secondary dex dir " + file.getPath());
return;
}
StringBuilder sb4 = new StringBuilder();
sb4.append("Deleted old secondary dex dir ");
sb4.append(file.getPath());
}
}
private static File getDexDir(Context context, File file, String str) throws IOException {
File file2 = new File(file, CODE_CACHE_NAME);
try {
mkdirChecked(file2);
} catch (IOException unused) {
file2 = new File(context.getFilesDir(), CODE_CACHE_NAME);
mkdirChecked(file2);
}
File file3 = new File(file2, str);
mkdirChecked(file3);
return file3;
}
private static void mkdirChecked(File file) throws IOException {
file.mkdir();
if (file.isDirectory()) {
return;
}
File parentFile = file.getParentFile();
if (parentFile == null) {
Log.e(TAG, "Failed to create dir " + file.getPath() + ". Parent file is null.");
} else {
Log.e(TAG, "Failed to create dir " + file.getPath() + ". parent file is a dir " + parentFile.isDirectory() + ", a file " + parentFile.isFile() + ", exists " + parentFile.exists() + ", readable " + parentFile.canRead() + ", writable " + parentFile.canWrite());
}
throw new IOException("Failed to create directory " + file.getPath());
}
public static final class V19 {
private V19() {
}
public static void install(ClassLoader classLoader, List<? extends File> list, File file) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IOException {
IOException[] iOExceptionArr;
Object obj = MultiDex.findField(classLoader, "pathList").get(classLoader);
ArrayList arrayList = new ArrayList();
MultiDex.expandFieldArray(obj, "dexElements", makeDexElements(obj, new ArrayList(list), file, arrayList));
if (arrayList.size() > 0) {
Iterator it = arrayList.iterator();
while (it.hasNext()) {
Log.w(MultiDex.TAG, "Exception in makeDexElement", (IOException) it.next());
}
Field findField = MultiDex.findField(obj, "dexElementsSuppressedExceptions");
IOException[] iOExceptionArr2 = (IOException[]) findField.get(obj);
if (iOExceptionArr2 == null) {
iOExceptionArr = (IOException[]) arrayList.toArray(new IOException[arrayList.size()]);
} else {
IOException[] iOExceptionArr3 = new IOException[arrayList.size() + iOExceptionArr2.length];
arrayList.toArray(iOExceptionArr3);
System.arraycopy(iOExceptionArr2, 0, iOExceptionArr3, arrayList.size(), iOExceptionArr2.length);
iOExceptionArr = iOExceptionArr3;
}
findField.set(obj, iOExceptionArr);
IOException iOException = new IOException("I/O exception during makeDexElement");
iOException.initCause((Throwable) arrayList.get(0));
throw iOException;
}
}
private static Object[] makeDexElements(Object obj, ArrayList<File> arrayList, File file, ArrayList<IOException> arrayList2) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
return (Object[]) MultiDex.findMethod(obj, "makeDexElements", ArrayList.class, File.class, ArrayList.class).invoke(obj, arrayList, file, arrayList2);
}
}
public static final class V14 {
private static final int EXTRACTED_SUFFIX_LENGTH = 4;
private final ElementConstructor elementConstructor;
public interface ElementConstructor {
Object newInstance(File file, DexFile dexFile) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, IOException;
}
public static class ICSElementConstructor implements ElementConstructor {
private final Constructor<?> elementConstructor;
public ICSElementConstructor(Class<?> cls) throws SecurityException, NoSuchMethodException {
Constructor<?> constructor = cls.getConstructor(File.class, ZipFile.class, DexFile.class);
this.elementConstructor = constructor;
constructor.setAccessible(true);
}
@Override // androidx.multidex.MultiDex.V14.ElementConstructor
public Object newInstance(File file, DexFile dexFile) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
return this.elementConstructor.newInstance(file, new ZipFile(file), dexFile);
}
}
public static class JBMR11ElementConstructor implements ElementConstructor {
private final Constructor<?> elementConstructor;
public JBMR11ElementConstructor(Class<?> cls) throws SecurityException, NoSuchMethodException {
Constructor<?> constructor = cls.getConstructor(File.class, File.class, DexFile.class);
this.elementConstructor = constructor;
constructor.setAccessible(true);
}
@Override // androidx.multidex.MultiDex.V14.ElementConstructor
public Object newInstance(File file, DexFile dexFile) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
return this.elementConstructor.newInstance(file, file, dexFile);
}
}
public static class JBMR2ElementConstructor implements ElementConstructor {
private final Constructor<?> elementConstructor;
public JBMR2ElementConstructor(Class<?> cls) throws SecurityException, NoSuchMethodException {
Constructor<?> constructor = cls.getConstructor(File.class, Boolean.TYPE, File.class, DexFile.class);
this.elementConstructor = constructor;
constructor.setAccessible(true);
}
@Override // androidx.multidex.MultiDex.V14.ElementConstructor
public Object newInstance(File file, DexFile dexFile) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
return this.elementConstructor.newInstance(file, Boolean.FALSE, file, dexFile);
}
}
public static void install(ClassLoader classLoader, List<? extends File> list) throws IOException, SecurityException, IllegalArgumentException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
Object obj = MultiDex.findField(classLoader, "pathList").get(classLoader);
Object[] makeDexElements = new V14().makeDexElements(list);
try {
MultiDex.expandFieldArray(obj, "dexElements", makeDexElements);
} catch (NoSuchFieldException e) {
Log.w(MultiDex.TAG, "Failed find field 'dexElements' attempting 'pathElements'", e);
MultiDex.expandFieldArray(obj, "pathElements", makeDexElements);
}
}
private V14() throws ClassNotFoundException, SecurityException, NoSuchMethodException {
ElementConstructor jBMR2ElementConstructor;
Class<?> cls = Class.forName("dalvik.system.DexPathList$Element");
try {
try {
jBMR2ElementConstructor = new ICSElementConstructor(cls);
} catch (NoSuchMethodException unused) {
jBMR2ElementConstructor = new JBMR11ElementConstructor(cls);
}
} catch (NoSuchMethodException unused2) {
jBMR2ElementConstructor = new JBMR2ElementConstructor(cls);
}
this.elementConstructor = jBMR2ElementConstructor;
}
private Object[] makeDexElements(List<? extends File> list) throws IOException, SecurityException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
int size = list.size();
Object[] objArr = new Object[size];
for (int i = 0; i < size; i++) {
File file = list.get(i);
objArr[i] = this.elementConstructor.newInstance(file, DexFile.loadDex(file.getPath(), optimizedPathFor(file), 0));
}
return objArr;
}
private static String optimizedPathFor(File file) {
File parentFile = file.getParentFile();
String name = file.getName();
return new File(parentFile, name.substring(0, name.length() - EXTRACTED_SUFFIX_LENGTH) + ".dex").getPath();
}
}
public static final class V4 {
private V4() {
}
public static void install(ClassLoader classLoader, List<? extends File> list) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, IOException {
int size = list.size();
Field findField = MultiDex.findField(classLoader, "path");
StringBuilder sb = new StringBuilder((String) findField.get(classLoader));
String[] strArr = new String[size];
File[] fileArr = new File[size];
ZipFile[] zipFileArr = new ZipFile[size];
DexFile[] dexFileArr = new DexFile[size];
ListIterator<? extends File> listIterator = list.listIterator();
while (listIterator.hasNext()) {
File next = listIterator.next();
String absolutePath = next.getAbsolutePath();
sb.append(':');
sb.append(absolutePath);
int previousIndex = listIterator.previousIndex();
strArr[previousIndex] = absolutePath;
fileArr[previousIndex] = next;
zipFileArr[previousIndex] = new ZipFile(next);
dexFileArr[previousIndex] = DexFile.loadDex(absolutePath, absolutePath + ".dex", 0);
}
findField.set(classLoader, sb.toString());
MultiDex.expandFieldArray(classLoader, "mPaths", strArr);
MultiDex.expandFieldArray(classLoader, "mFiles", fileArr);
MultiDex.expandFieldArray(classLoader, "mZips", zipFileArr);
MultiDex.expandFieldArray(classLoader, "mDexs", dexFileArr);
}
}
}

View File

@@ -0,0 +1,13 @@
package androidx.multidex;
import android.app.Application;
import android.content.Context;
/* loaded from: classes.dex */
public class MultiDexApplication extends Application {
@Override // android.content.ContextWrapper
public void attachBaseContext(Context context) {
super.attachBaseContext(context);
MultiDex.install(this);
}
}

View File

@@ -0,0 +1,352 @@
package androidx.multidex;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import com.facebook.internal.AnalyticsEvents;
import com.ironsource.v8;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/* loaded from: classes.dex */
final class MultiDexExtractor implements Closeable {
private static final int BUFFER_SIZE = 16384;
private static final String DEX_PREFIX = "classes";
static final String DEX_SUFFIX = ".dex";
private static final String EXTRACTED_NAME_EXT = ".classes";
static final String EXTRACTED_SUFFIX = ".zip";
private static final String KEY_CRC = "crc";
private static final String KEY_DEX_CRC = "dex.crc.";
private static final String KEY_DEX_NUMBER = "dex.number";
private static final String KEY_DEX_TIME = "dex.time.";
private static final String KEY_TIME_STAMP = "timestamp";
private static final String LOCK_FILENAME = "MultiDex.lock";
private static final int MAX_EXTRACT_ATTEMPTS = 3;
private static final long NO_VALUE = -1;
private static final String PREFS_FILE = "multidex.version";
private static final String TAG = "MultiDex";
private final FileLock cacheLock;
private final File dexDir;
private final FileChannel lockChannel;
private final RandomAccessFile lockRaf;
private final File sourceApk;
private final long sourceCrc;
public static class ExtractedDex extends File {
public long crc;
public ExtractedDex(File file, String str) {
super(file, str);
this.crc = -1L;
}
}
public MultiDexExtractor(File file, File file2) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("MultiDexExtractor(");
sb.append(file.getPath());
sb.append(", ");
sb.append(file2.getPath());
sb.append(")");
this.sourceApk = file;
this.dexDir = file2;
this.sourceCrc = getZipCrc(file);
File file3 = new File(file2, LOCK_FILENAME);
RandomAccessFile randomAccessFile = new RandomAccessFile(file3, "rw");
this.lockRaf = randomAccessFile;
try {
FileChannel channel = randomAccessFile.getChannel();
this.lockChannel = channel;
try {
StringBuilder sb2 = new StringBuilder();
sb2.append("Blocking on lock ");
sb2.append(file3.getPath());
this.cacheLock = channel.lock();
StringBuilder sb3 = new StringBuilder();
sb3.append(file3.getPath());
sb3.append(" locked");
} catch (IOException e) {
e = e;
closeQuietly(this.lockChannel);
throw e;
} catch (Error e2) {
e = e2;
closeQuietly(this.lockChannel);
throw e;
} catch (RuntimeException e3) {
e = e3;
closeQuietly(this.lockChannel);
throw e;
}
} catch (IOException e4) {
e = e4;
closeQuietly(this.lockRaf);
throw e;
} catch (Error e5) {
e = e5;
closeQuietly(this.lockRaf);
throw e;
} catch (RuntimeException e6) {
e = e6;
closeQuietly(this.lockRaf);
throw e;
}
}
public List<? extends File> load(Context context, String str, boolean z) throws IOException {
List<ExtractedDex> performExtractions;
StringBuilder sb = new StringBuilder();
sb.append("MultiDexExtractor.load(");
sb.append(this.sourceApk.getPath());
sb.append(", ");
sb.append(z);
sb.append(", ");
sb.append(str);
sb.append(")");
if (!this.cacheLock.isValid()) {
throw new IllegalStateException("MultiDexExtractor was closed");
}
if (!z && !isModified(context, this.sourceApk, this.sourceCrc, str)) {
try {
performExtractions = loadExistingExtractions(context, str);
} catch (IOException e) {
Log.w(TAG, "Failed to reload existing extracted secondary dex files, falling back to fresh extraction", e);
performExtractions = performExtractions();
putStoredApkInfo(context, str, getTimeStamp(this.sourceApk), this.sourceCrc, performExtractions);
}
} else {
performExtractions = performExtractions();
putStoredApkInfo(context, str, getTimeStamp(this.sourceApk), this.sourceCrc, performExtractions);
}
StringBuilder sb2 = new StringBuilder();
sb2.append("load found ");
sb2.append(performExtractions.size());
sb2.append(" secondary dex files");
return performExtractions;
}
@Override // java.io.Closeable, java.lang.AutoCloseable
public void close() throws IOException {
this.cacheLock.release();
this.lockChannel.close();
this.lockRaf.close();
}
private List<ExtractedDex> loadExistingExtractions(Context context, String str) throws IOException {
String str2 = this.sourceApk.getName() + EXTRACTED_NAME_EXT;
SharedPreferences multiDexPreferences = getMultiDexPreferences(context);
int i = multiDexPreferences.getInt(str + KEY_DEX_NUMBER, 1);
ArrayList arrayList = new ArrayList(i + (-1));
int i2 = 2;
while (i2 <= i) {
ExtractedDex extractedDex = new ExtractedDex(this.dexDir, str2 + i2 + EXTRACTED_SUFFIX);
if (extractedDex.isFile()) {
extractedDex.crc = getZipCrc(extractedDex);
long j = multiDexPreferences.getLong(str + KEY_DEX_CRC + i2, -1L);
long j2 = multiDexPreferences.getLong(str + KEY_DEX_TIME + i2, -1L);
long lastModified = extractedDex.lastModified();
if (j2 == lastModified) {
String str3 = str2;
SharedPreferences sharedPreferences = multiDexPreferences;
if (j == extractedDex.crc) {
arrayList.add(extractedDex);
i2++;
multiDexPreferences = sharedPreferences;
str2 = str3;
}
}
throw new IOException("Invalid extracted dex: " + extractedDex + " (key \"" + str + "\"), expected modification time: " + j2 + ", modification time: " + lastModified + ", expected crc: " + j + ", file crc: " + extractedDex.crc);
}
throw new IOException("Missing extracted secondary dex file '" + extractedDex.getPath() + "'");
}
return arrayList;
}
private static boolean isModified(Context context, File file, long j, String str) {
SharedPreferences multiDexPreferences = getMultiDexPreferences(context);
if (multiDexPreferences.getLong(str + "timestamp", -1L) == getTimeStamp(file)) {
if (multiDexPreferences.getLong(str + KEY_CRC, -1L) == j) {
return false;
}
}
return true;
}
private static long getTimeStamp(File file) {
long lastModified = file.lastModified();
return lastModified == -1 ? lastModified - 1 : lastModified;
}
private static long getZipCrc(File file) throws IOException {
long zipCrc = ZipUtil.getZipCrc(file);
return zipCrc == -1 ? zipCrc - 1 : zipCrc;
}
private List<ExtractedDex> performExtractions() throws IOException {
boolean z;
String str = this.sourceApk.getName() + EXTRACTED_NAME_EXT;
clearDexDir();
ArrayList arrayList = new ArrayList();
ZipFile zipFile = new ZipFile(this.sourceApk);
try {
int i = 2;
ZipEntry entry = zipFile.getEntry(DEX_PREFIX + 2 + DEX_SUFFIX);
while (entry != null) {
ExtractedDex extractedDex = new ExtractedDex(this.dexDir, str + i + EXTRACTED_SUFFIX);
arrayList.add(extractedDex);
StringBuilder sb = new StringBuilder();
sb.append("Extraction is needed for file ");
sb.append(extractedDex);
int i2 = 0;
boolean z2 = false;
while (i2 < 3 && !z2) {
int i3 = i2 + 1;
extract(zipFile, entry, extractedDex, str);
try {
extractedDex.crc = getZipCrc(extractedDex);
z = true;
} catch (IOException e) {
Log.w(TAG, "Failed to read crc from " + extractedDex.getAbsolutePath(), e);
z = false;
}
StringBuilder sb2 = new StringBuilder();
sb2.append("Extraction ");
sb2.append(z ? AnalyticsEvents.PARAMETER_SHARE_OUTCOME_SUCCEEDED : v8.h.t);
sb2.append(" '");
sb2.append(extractedDex.getAbsolutePath());
sb2.append("': length ");
sb2.append(extractedDex.length());
sb2.append(" - crc: ");
sb2.append(extractedDex.crc);
if (!z) {
extractedDex.delete();
if (extractedDex.exists()) {
Log.w(TAG, "Failed to delete corrupted secondary dex '" + extractedDex.getPath() + "'");
}
}
z2 = z;
i2 = i3;
}
if (!z2) {
throw new IOException("Could not create zip file " + extractedDex.getAbsolutePath() + " for secondary dex (" + i + ")");
}
i++;
entry = zipFile.getEntry(DEX_PREFIX + i + DEX_SUFFIX);
}
try {
zipFile.close();
} catch (IOException e2) {
Log.w(TAG, "Failed to close resource", e2);
}
return arrayList;
} finally {
}
}
private static void putStoredApkInfo(Context context, String str, long j, long j2, List<ExtractedDex> list) {
SharedPreferences.Editor edit = getMultiDexPreferences(context).edit();
edit.putLong(str + "timestamp", j);
edit.putLong(str + KEY_CRC, j2);
edit.putInt(str + KEY_DEX_NUMBER, list.size() + 1);
int i = 2;
for (ExtractedDex extractedDex : list) {
edit.putLong(str + KEY_DEX_CRC + i, extractedDex.crc);
edit.putLong(str + KEY_DEX_TIME + i, extractedDex.lastModified());
i++;
}
edit.commit();
}
private static SharedPreferences getMultiDexPreferences(Context context) {
return context.getSharedPreferences(PREFS_FILE, 4);
}
private void clearDexDir() {
File[] listFiles = this.dexDir.listFiles(new FileFilter() { // from class: androidx.multidex.MultiDexExtractor.1
@Override // java.io.FileFilter
public boolean accept(File file) {
return !file.getName().equals(MultiDexExtractor.LOCK_FILENAME);
}
});
if (listFiles == null) {
Log.w(TAG, "Failed to list secondary dex dir content (" + this.dexDir.getPath() + ").");
return;
}
for (File file : listFiles) {
StringBuilder sb = new StringBuilder();
sb.append("Trying to delete old file ");
sb.append(file.getPath());
sb.append(" of size ");
sb.append(file.length());
if (file.delete()) {
StringBuilder sb2 = new StringBuilder();
sb2.append("Deleted old file ");
sb2.append(file.getPath());
} else {
Log.w(TAG, "Failed to delete old file " + file.getPath());
}
}
}
private static void extract(ZipFile zipFile, ZipEntry zipEntry, File file, String str) throws IOException, FileNotFoundException {
InputStream inputStream = zipFile.getInputStream(zipEntry);
File createTempFile = File.createTempFile("tmp-" + str, EXTRACTED_SUFFIX, file.getParentFile());
StringBuilder sb = new StringBuilder();
sb.append("Extracting ");
sb.append(createTempFile.getPath());
try {
ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(createTempFile)));
try {
ZipEntry zipEntry2 = new ZipEntry("classes.dex");
zipEntry2.setTime(zipEntry.getTime());
zipOutputStream.putNextEntry(zipEntry2);
byte[] bArr = new byte[16384];
for (int read = inputStream.read(bArr); read != -1; read = inputStream.read(bArr)) {
zipOutputStream.write(bArr, 0, read);
}
zipOutputStream.closeEntry();
zipOutputStream.close();
if (!createTempFile.setReadOnly()) {
throw new IOException("Failed to mark readonly \"" + createTempFile.getAbsolutePath() + "\" (tmp of \"" + file.getAbsolutePath() + "\")");
}
StringBuilder sb2 = new StringBuilder();
sb2.append("Renaming to ");
sb2.append(file.getPath());
if (!createTempFile.renameTo(file)) {
throw new IOException("Failed to rename \"" + createTempFile.getAbsolutePath() + "\" to \"" + file.getAbsolutePath() + "\"");
}
closeQuietly(inputStream);
createTempFile.delete();
} catch (Throwable th) {
zipOutputStream.close();
throw th;
}
} catch (Throwable th2) {
closeQuietly(inputStream);
createTempFile.delete();
throw th2;
}
}
private static void closeQuietly(Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
Log.w(TAG, "Failed to close resource", e);
}
}
}

View File

@@ -0,0 +1,7 @@
package androidx.multidex;
/* loaded from: classes.dex */
public final class R {
private R() {
}
}

View File

@@ -0,0 +1,72 @@
package androidx.multidex;
import android.support.v4.media.session.PlaybackStateCompat;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.zip.CRC32;
import java.util.zip.ZipException;
/* loaded from: classes.dex */
final class ZipUtil {
private static final int BUFFER_SIZE = 16384;
private static final int ENDHDR = 22;
private static final int ENDSIG = 101010256;
public static class CentralDirectory {
long offset;
long size;
}
public static long getZipCrc(File file) throws IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
try {
return computeCrcOfCentralDir(randomAccessFile, findCentralDirectory(randomAccessFile));
} finally {
randomAccessFile.close();
}
}
public static CentralDirectory findCentralDirectory(RandomAccessFile randomAccessFile) throws IOException, ZipException {
long length = randomAccessFile.length();
long j = length - 22;
if (j < 0) {
throw new ZipException("File too short to be a zip file: " + randomAccessFile.length());
}
long j2 = length - 65558;
long j3 = j2 >= 0 ? j2 : 0L;
int reverseBytes = Integer.reverseBytes(ENDSIG);
do {
randomAccessFile.seek(j);
if (randomAccessFile.readInt() == reverseBytes) {
randomAccessFile.skipBytes(2);
randomAccessFile.skipBytes(2);
randomAccessFile.skipBytes(2);
randomAccessFile.skipBytes(2);
CentralDirectory centralDirectory = new CentralDirectory();
centralDirectory.size = Integer.reverseBytes(randomAccessFile.readInt()) & 4294967295L;
centralDirectory.offset = Integer.reverseBytes(randomAccessFile.readInt()) & 4294967295L;
return centralDirectory;
}
j--;
} while (j >= j3);
throw new ZipException("End Of Central Directory signature not found");
}
public static long computeCrcOfCentralDir(RandomAccessFile randomAccessFile, CentralDirectory centralDirectory) throws IOException {
CRC32 crc32 = new CRC32();
long j = centralDirectory.size;
randomAccessFile.seek(centralDirectory.offset);
byte[] bArr = new byte[16384];
int read = randomAccessFile.read(bArr, 0, (int) Math.min(PlaybackStateCompat.ACTION_PREPARE, j));
while (read != -1) {
crc32.update(bArr, 0, read);
j -= read;
if (j == 0) {
break;
}
read = randomAccessFile.read(bArr, 0, (int) Math.min(PlaybackStateCompat.ACTION_PREPARE, j));
}
return crc32.getValue();
}
}