ADD week 5
This commit is contained in:
@ -0,0 +1,64 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import androidx.profileinstaller.ProfileInstallReceiver;
|
||||
import java.io.File;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
class BenchmarkOperation {
|
||||
private BenchmarkOperation() {
|
||||
}
|
||||
|
||||
static void dropShaderCache(Context context, ProfileInstallReceiver.ResultDiagnostics resultDiagnostics) {
|
||||
File cacheDir;
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
cacheDir = Api24ContextHelper.getDeviceProtectedCodeCacheDir(context);
|
||||
} else if (Build.VERSION.SDK_INT >= 23) {
|
||||
cacheDir = Api21ContextHelper.getCodeCacheDir(context);
|
||||
} else {
|
||||
cacheDir = context.getCacheDir();
|
||||
}
|
||||
if (deleteFilesRecursively(cacheDir)) {
|
||||
resultDiagnostics.onResultReceived(14, null);
|
||||
} else {
|
||||
resultDiagnostics.onResultReceived(15, null);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean deleteFilesRecursively(File file) {
|
||||
if (file.isDirectory()) {
|
||||
File[] listFiles = file.listFiles();
|
||||
if (listFiles == null) {
|
||||
return false;
|
||||
}
|
||||
boolean z = true;
|
||||
for (File file2 : listFiles) {
|
||||
z = deleteFilesRecursively(file2) && z;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
file.delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static class Api21ContextHelper {
|
||||
private Api21ContextHelper() {
|
||||
}
|
||||
|
||||
static File getCodeCacheDir(Context context) {
|
||||
return context.getCodeCacheDir();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Api24ContextHelper {
|
||||
private Api24ContextHelper() {
|
||||
}
|
||||
|
||||
static File getDeviceProtectedCodeCacheDir(Context context) {
|
||||
Context createDeviceProtectedStorageContext;
|
||||
createDeviceProtectedStorageContext = context.createDeviceProtectedStorageContext();
|
||||
return createDeviceProtectedStorageContext.getCodeCacheDir();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,299 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Build;
|
||||
import androidx.profileinstaller.ProfileInstaller;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class DeviceProfileWriter {
|
||||
private final String mApkName;
|
||||
private final AssetManager mAssetManager;
|
||||
private final File mCurProfile;
|
||||
private final ProfileInstaller.DiagnosticsCallback mDiagnostics;
|
||||
private final Executor mExecutor;
|
||||
private DexProfileData[] mProfile;
|
||||
private final String mProfileMetaSourceLocation;
|
||||
private final String mProfileSourceLocation;
|
||||
private byte[] mTranscodedProfile;
|
||||
private boolean mDeviceSupportsAotProfile = false;
|
||||
private final byte[] mDesiredVersion = desiredVersion();
|
||||
|
||||
private static boolean requiresMetadata() {
|
||||
if (Build.VERSION.SDK_INT < 24 || Build.VERSION.SDK_INT > 33) {
|
||||
return false;
|
||||
}
|
||||
int i = Build.VERSION.SDK_INT;
|
||||
if (i != 24 && i != 25) {
|
||||
switch (i) {
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void result(final int i, final Object obj) {
|
||||
this.mExecutor.execute(new Runnable() { // from class: androidx.profileinstaller.DeviceProfileWriter$$ExternalSyntheticLambda0
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
DeviceProfileWriter.this.m169lambda$result$0$androidxprofileinstallerDeviceProfileWriter(i, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* renamed from: lambda$result$0$androidx-profileinstaller-DeviceProfileWriter, reason: not valid java name */
|
||||
/* synthetic */ void m169lambda$result$0$androidxprofileinstallerDeviceProfileWriter(int i, Object obj) {
|
||||
this.mDiagnostics.onResultReceived(i, obj);
|
||||
}
|
||||
|
||||
public DeviceProfileWriter(AssetManager assetManager, Executor executor, ProfileInstaller.DiagnosticsCallback diagnosticsCallback, String str, String str2, String str3, File file) {
|
||||
this.mAssetManager = assetManager;
|
||||
this.mExecutor = executor;
|
||||
this.mDiagnostics = diagnosticsCallback;
|
||||
this.mApkName = str;
|
||||
this.mProfileSourceLocation = str2;
|
||||
this.mProfileMetaSourceLocation = str3;
|
||||
this.mCurProfile = file;
|
||||
}
|
||||
|
||||
public boolean deviceAllowsProfileInstallerAotWrites() {
|
||||
if (this.mDesiredVersion == null) {
|
||||
result(3, Integer.valueOf(Build.VERSION.SDK_INT));
|
||||
return false;
|
||||
}
|
||||
if (this.mCurProfile.canWrite()) {
|
||||
this.mDeviceSupportsAotProfile = true;
|
||||
return true;
|
||||
}
|
||||
result(4, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void assertDeviceAllowsProfileInstallerAotWritesCalled() {
|
||||
if (!this.mDeviceSupportsAotProfile) {
|
||||
throw new IllegalStateException("This device doesn't support aot. Did you call deviceSupportsAotProfile()?");
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceProfileWriter read() {
|
||||
DeviceProfileWriter addMetadata;
|
||||
assertDeviceAllowsProfileInstallerAotWritesCalled();
|
||||
if (this.mDesiredVersion == null) {
|
||||
return this;
|
||||
}
|
||||
InputStream profileInputStream = getProfileInputStream(this.mAssetManager);
|
||||
if (profileInputStream != null) {
|
||||
this.mProfile = readProfileInternal(profileInputStream);
|
||||
}
|
||||
DexProfileData[] dexProfileDataArr = this.mProfile;
|
||||
return (dexProfileDataArr == null || !requiresMetadata() || (addMetadata = addMetadata(dexProfileDataArr, this.mDesiredVersion)) == null) ? this : addMetadata;
|
||||
}
|
||||
|
||||
private InputStream openStreamFromAssets(AssetManager assetManager, String str) throws IOException {
|
||||
try {
|
||||
return assetManager.openFd(str).createInputStream();
|
||||
} catch (FileNotFoundException e) {
|
||||
String message = e.getMessage();
|
||||
if (message != null && message.contains("compressed")) {
|
||||
this.mDiagnostics.onDiagnosticReceived(5, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getProfileInputStream(AssetManager assetManager) {
|
||||
try {
|
||||
return openStreamFromAssets(assetManager, this.mProfileSourceLocation);
|
||||
} catch (FileNotFoundException e) {
|
||||
this.mDiagnostics.onResultReceived(6, e);
|
||||
return null;
|
||||
} catch (IOException e2) {
|
||||
this.mDiagnostics.onResultReceived(7, e2);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private DexProfileData[] readProfileInternal(InputStream inputStream) {
|
||||
try {
|
||||
} catch (IOException e) {
|
||||
this.mDiagnostics.onResultReceived(7, e);
|
||||
}
|
||||
try {
|
||||
try {
|
||||
DexProfileData[] readProfile = ProfileTranscoder.readProfile(inputStream, ProfileTranscoder.readHeader(inputStream, ProfileTranscoder.MAGIC_PROF), this.mApkName);
|
||||
try {
|
||||
inputStream.close();
|
||||
return readProfile;
|
||||
} catch (IOException e2) {
|
||||
this.mDiagnostics.onResultReceived(7, e2);
|
||||
return readProfile;
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e3) {
|
||||
this.mDiagnostics.onResultReceived(7, e3);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
} catch (IOException e4) {
|
||||
this.mDiagnostics.onResultReceived(7, e4);
|
||||
inputStream.close();
|
||||
return null;
|
||||
} catch (IllegalStateException e5) {
|
||||
this.mDiagnostics.onResultReceived(8, e5);
|
||||
inputStream.close();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private DeviceProfileWriter addMetadata(DexProfileData[] dexProfileDataArr, byte[] bArr) {
|
||||
InputStream openStreamFromAssets;
|
||||
try {
|
||||
openStreamFromAssets = openStreamFromAssets(this.mAssetManager, this.mProfileMetaSourceLocation);
|
||||
} catch (FileNotFoundException e) {
|
||||
this.mDiagnostics.onResultReceived(9, e);
|
||||
} catch (IOException e2) {
|
||||
this.mDiagnostics.onResultReceived(7, e2);
|
||||
} catch (IllegalStateException e3) {
|
||||
this.mProfile = null;
|
||||
this.mDiagnostics.onResultReceived(8, e3);
|
||||
}
|
||||
if (openStreamFromAssets == null) {
|
||||
if (openStreamFromAssets != null) {
|
||||
openStreamFromAssets.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
this.mProfile = ProfileTranscoder.readMeta(openStreamFromAssets, ProfileTranscoder.readHeader(openStreamFromAssets, ProfileTranscoder.MAGIC_PROFM), bArr, dexProfileDataArr);
|
||||
if (openStreamFromAssets != null) {
|
||||
openStreamFromAssets.close();
|
||||
}
|
||||
return this;
|
||||
} catch (Throwable th) {
|
||||
if (openStreamFromAssets != null) {
|
||||
try {
|
||||
openStreamFromAssets.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
public DeviceProfileWriter transcodeIfNeeded() {
|
||||
ByteArrayOutputStream byteArrayOutputStream;
|
||||
DexProfileData[] dexProfileDataArr = this.mProfile;
|
||||
byte[] bArr = this.mDesiredVersion;
|
||||
if (dexProfileDataArr != null && bArr != null) {
|
||||
assertDeviceAllowsProfileInstallerAotWritesCalled();
|
||||
try {
|
||||
byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
ProfileTranscoder.writeHeader(byteArrayOutputStream, bArr);
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.mDiagnostics.onResultReceived(7, e);
|
||||
} catch (IllegalStateException e2) {
|
||||
this.mDiagnostics.onResultReceived(8, e2);
|
||||
}
|
||||
if (!ProfileTranscoder.transcodeAndWriteBody(byteArrayOutputStream, bArr, dexProfileDataArr)) {
|
||||
this.mDiagnostics.onResultReceived(5, null);
|
||||
this.mProfile = null;
|
||||
byteArrayOutputStream.close();
|
||||
return this;
|
||||
}
|
||||
this.mTranscodedProfile = byteArrayOutputStream.toByteArray();
|
||||
byteArrayOutputStream.close();
|
||||
this.mProfile = null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/* JADX WARN: Multi-variable type inference failed */
|
||||
public boolean write() {
|
||||
byte[] bArr = this.mTranscodedProfile;
|
||||
if (bArr == null) {
|
||||
return false;
|
||||
}
|
||||
assertDeviceAllowsProfileInstallerAotWritesCalled();
|
||||
try {
|
||||
try {
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bArr);
|
||||
try {
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(this.mCurProfile);
|
||||
try {
|
||||
Encoding.writeAll(byteArrayInputStream, fileOutputStream);
|
||||
result(1, null);
|
||||
fileOutputStream.close();
|
||||
byteArrayInputStream.close();
|
||||
return true;
|
||||
} finally {
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayInputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
} finally {
|
||||
this.mTranscodedProfile = null;
|
||||
this.mProfile = null;
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
result(6, e);
|
||||
return false;
|
||||
} catch (IOException e2) {
|
||||
result(7, e2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] desiredVersion() {
|
||||
if (Build.VERSION.SDK_INT < 24 || Build.VERSION.SDK_INT > 33) {
|
||||
return null;
|
||||
}
|
||||
switch (Build.VERSION.SDK_INT) {
|
||||
case 24:
|
||||
case 25:
|
||||
return ProfileVersion.V001_N;
|
||||
case 26:
|
||||
return ProfileVersion.V005_O;
|
||||
case 27:
|
||||
return ProfileVersion.V009_O_MR1;
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
return ProfileVersion.V010_P;
|
||||
case 31:
|
||||
case 32:
|
||||
case 33:
|
||||
return ProfileVersion.V015_S;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
class DexProfileData {
|
||||
final String apkName;
|
||||
int classSetSize;
|
||||
int[] classes;
|
||||
final long dexChecksum;
|
||||
final String dexName;
|
||||
final int hotMethodRegionSize;
|
||||
long mTypeIdCount;
|
||||
final TreeMap<Integer, Integer> methods;
|
||||
final int numMethodIds;
|
||||
|
||||
DexProfileData(String str, String str2, long j, long j2, int i, int i2, int i3, int[] iArr, TreeMap<Integer, Integer> treeMap) {
|
||||
this.apkName = str;
|
||||
this.dexName = str2;
|
||||
this.dexChecksum = j;
|
||||
this.mTypeIdCount = j2;
|
||||
this.classSetSize = i;
|
||||
this.hotMethodRegionSize = i2;
|
||||
this.numMethodIds = i3;
|
||||
this.classes = iArr;
|
||||
this.methods = treeMap;
|
||||
}
|
||||
}
|
218
02-Easy5/E5/sources/androidx/profileinstaller/Encoding.java
Normal file
218
02-Easy5/E5/sources/androidx/profileinstaller/Encoding.java
Normal file
@ -0,0 +1,218 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import kotlin.UByte;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
class Encoding {
|
||||
static final int SIZEOF_BYTE = 8;
|
||||
static final int UINT_16_SIZE = 2;
|
||||
static final int UINT_32_SIZE = 4;
|
||||
static final int UINT_8_SIZE = 1;
|
||||
|
||||
private Encoding() {
|
||||
}
|
||||
|
||||
static int utf8Length(String str) {
|
||||
return str.getBytes(StandardCharsets.UTF_8).length;
|
||||
}
|
||||
|
||||
static void writeUInt(OutputStream outputStream, long j, int i) throws IOException {
|
||||
byte[] bArr = new byte[i];
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
bArr[i2] = (byte) ((j >> (i2 * 8)) & 255);
|
||||
}
|
||||
outputStream.write(bArr);
|
||||
}
|
||||
|
||||
static void writeUInt8(OutputStream outputStream, int i) throws IOException {
|
||||
writeUInt(outputStream, i, 1);
|
||||
}
|
||||
|
||||
static void writeUInt16(OutputStream outputStream, int i) throws IOException {
|
||||
writeUInt(outputStream, i, 2);
|
||||
}
|
||||
|
||||
static void writeUInt32(OutputStream outputStream, long j) throws IOException {
|
||||
writeUInt(outputStream, j, 4);
|
||||
}
|
||||
|
||||
static void writeString(OutputStream outputStream, String str) throws IOException {
|
||||
outputStream.write(str.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
static int bitsToBytes(int i) {
|
||||
return ((i + 7) & (-8)) / 8;
|
||||
}
|
||||
|
||||
static byte[] read(InputStream inputStream, int i) throws IOException {
|
||||
byte[] bArr = new byte[i];
|
||||
int i2 = 0;
|
||||
while (i2 < i) {
|
||||
int read = inputStream.read(bArr, i2, i - i2);
|
||||
if (read < 0) {
|
||||
throw error("Not enough bytes to read: " + i);
|
||||
}
|
||||
i2 += read;
|
||||
}
|
||||
return bArr;
|
||||
}
|
||||
|
||||
static long readUInt(InputStream inputStream, int i) throws IOException {
|
||||
byte[] read = read(inputStream, i);
|
||||
long j = 0;
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
j += (read[i2] & UByte.MAX_VALUE) << (i2 * 8);
|
||||
}
|
||||
return j;
|
||||
}
|
||||
|
||||
static int readUInt8(InputStream inputStream) throws IOException {
|
||||
return (int) readUInt(inputStream, 1);
|
||||
}
|
||||
|
||||
static int readUInt16(InputStream inputStream) throws IOException {
|
||||
return (int) readUInt(inputStream, 2);
|
||||
}
|
||||
|
||||
static long readUInt32(InputStream inputStream) throws IOException {
|
||||
return readUInt(inputStream, 4);
|
||||
}
|
||||
|
||||
static String readString(InputStream inputStream, int i) throws IOException {
|
||||
return new String(read(inputStream, i), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/* JADX WARN: Code restructure failed: missing block: B:27:0x0059, code lost:
|
||||
|
||||
if (r0.finished() == false) goto L25;
|
||||
*/
|
||||
/* JADX WARN: Code restructure failed: missing block: B:29:0x005e, code lost:
|
||||
|
||||
return r1;
|
||||
*/
|
||||
/* JADX WARN: Code restructure failed: missing block: B:31:0x0065, code lost:
|
||||
|
||||
throw error("Inflater did not finish");
|
||||
*/
|
||||
/*
|
||||
Code decompiled incorrectly, please refer to instructions dump.
|
||||
To view partially-correct add '--show-bad-code' argument
|
||||
*/
|
||||
static byte[] readCompressed(java.io.InputStream r8, int r9, int r10) throws java.io.IOException {
|
||||
/*
|
||||
java.util.zip.Inflater r0 = new java.util.zip.Inflater
|
||||
r0.<init>()
|
||||
byte[] r1 = new byte[r10] // Catch: java.lang.Throwable -> L84
|
||||
r2 = 2048(0x800, float:2.87E-42)
|
||||
byte[] r2 = new byte[r2] // Catch: java.lang.Throwable -> L84
|
||||
r3 = 0
|
||||
r4 = 0
|
||||
r5 = 0
|
||||
Le:
|
||||
boolean r6 = r0.finished() // Catch: java.lang.Throwable -> L84
|
||||
if (r6 != 0) goto L53
|
||||
boolean r6 = r0.needsDictionary() // Catch: java.lang.Throwable -> L84
|
||||
if (r6 != 0) goto L53
|
||||
if (r4 >= r9) goto L53
|
||||
int r6 = r8.read(r2) // Catch: java.lang.Throwable -> L84
|
||||
if (r6 < 0) goto L38
|
||||
r0.setInput(r2, r3, r6) // Catch: java.lang.Throwable -> L84
|
||||
int r7 = r10 - r5
|
||||
int r7 = r0.inflate(r1, r5, r7) // Catch: java.util.zip.DataFormatException -> L2e java.lang.Throwable -> L84
|
||||
int r5 = r5 + r7
|
||||
int r4 = r4 + r6
|
||||
goto Le
|
||||
L2e:
|
||||
r8 = move-exception
|
||||
java.lang.String r8 = r8.getMessage() // Catch: java.lang.Throwable -> L84
|
||||
java.lang.RuntimeException r8 = error(r8) // Catch: java.lang.Throwable -> L84
|
||||
throw r8 // Catch: java.lang.Throwable -> L84
|
||||
L38:
|
||||
java.lang.StringBuilder r8 = new java.lang.StringBuilder // Catch: java.lang.Throwable -> L84
|
||||
r8.<init>() // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r10 = "Invalid zip data. Stream ended after $totalBytesRead bytes. Expected "
|
||||
r8.append(r10) // Catch: java.lang.Throwable -> L84
|
||||
r8.append(r9) // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r9 = " bytes"
|
||||
r8.append(r9) // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r8 = r8.toString() // Catch: java.lang.Throwable -> L84
|
||||
java.lang.RuntimeException r8 = error(r8) // Catch: java.lang.Throwable -> L84
|
||||
throw r8 // Catch: java.lang.Throwable -> L84
|
||||
L53:
|
||||
if (r4 != r9) goto L66
|
||||
boolean r8 = r0.finished() // Catch: java.lang.Throwable -> L84
|
||||
if (r8 == 0) goto L5f
|
||||
r0.end()
|
||||
return r1
|
||||
L5f:
|
||||
java.lang.String r8 = "Inflater did not finish"
|
||||
java.lang.RuntimeException r8 = error(r8) // Catch: java.lang.Throwable -> L84
|
||||
throw r8 // Catch: java.lang.Throwable -> L84
|
||||
L66:
|
||||
java.lang.StringBuilder r8 = new java.lang.StringBuilder // Catch: java.lang.Throwable -> L84
|
||||
r8.<init>() // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r10 = "Didn't read enough bytes during decompression. expected="
|
||||
r8.append(r10) // Catch: java.lang.Throwable -> L84
|
||||
r8.append(r9) // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r9 = " actual="
|
||||
r8.append(r9) // Catch: java.lang.Throwable -> L84
|
||||
r8.append(r4) // Catch: java.lang.Throwable -> L84
|
||||
java.lang.String r8 = r8.toString() // Catch: java.lang.Throwable -> L84
|
||||
java.lang.RuntimeException r8 = error(r8) // Catch: java.lang.Throwable -> L84
|
||||
throw r8 // Catch: java.lang.Throwable -> L84
|
||||
L84:
|
||||
r8 = move-exception
|
||||
r0.end()
|
||||
throw r8
|
||||
*/
|
||||
throw new UnsupportedOperationException("Method not decompiled: androidx.profileinstaller.Encoding.readCompressed(java.io.InputStream, int, int):byte[]");
|
||||
}
|
||||
|
||||
static void writeCompressed(OutputStream outputStream, byte[] bArr) throws IOException {
|
||||
writeUInt32(outputStream, bArr.length);
|
||||
byte[] compress = compress(bArr);
|
||||
writeUInt32(outputStream, compress.length);
|
||||
outputStream.write(compress);
|
||||
}
|
||||
|
||||
static byte[] compress(byte[] bArr) throws IOException {
|
||||
Deflater deflater = new Deflater(1);
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
|
||||
try {
|
||||
deflaterOutputStream.write(bArr);
|
||||
deflaterOutputStream.close();
|
||||
deflater.end();
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
} finally {
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
deflater.end();
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
static void writeAll(InputStream inputStream, OutputStream outputStream) throws IOException {
|
||||
byte[] bArr = new byte[512];
|
||||
while (true) {
|
||||
int read = inputStream.read(bArr);
|
||||
if (read <= 0) {
|
||||
return;
|
||||
} else {
|
||||
outputStream.write(bArr, 0, read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static RuntimeException error(String str) {
|
||||
return new IllegalStateException(str);
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
enum FileSectionType {
|
||||
DEX_FILES(0),
|
||||
EXTRA_DESCRIPTORS(1),
|
||||
CLASSES(2),
|
||||
METHODS(3),
|
||||
AGGREGATION_COUNT(4);
|
||||
|
||||
private final long mValue;
|
||||
|
||||
public long getValue() {
|
||||
return this.mValue;
|
||||
}
|
||||
|
||||
FileSectionType(long j) {
|
||||
this.mValue = j;
|
||||
}
|
||||
|
||||
static FileSectionType fromValue(long j) {
|
||||
FileSectionType[] values = values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (values[i].getValue() == j) {
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported FileSection Type " + j);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/* compiled from: D8$$SyntheticClass */
|
||||
/* loaded from: classes.dex */
|
||||
public final /* synthetic */ class ProfileInstallReceiver$$ExternalSyntheticLambda0 implements Executor {
|
||||
@Override // java.util.concurrent.Executor
|
||||
public final void execute(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import androidx.profileinstaller.ProfileInstaller;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ProfileInstallReceiver extends BroadcastReceiver {
|
||||
public static final String ACTION_BENCHMARK_OPERATION = "androidx.profileinstaller.action.BENCHMARK_OPERATION";
|
||||
public static final String ACTION_INSTALL_PROFILE = "androidx.profileinstaller.action.INSTALL_PROFILE";
|
||||
public static final String ACTION_SAVE_PROFILE = "androidx.profileinstaller.action.SAVE_PROFILE";
|
||||
public static final String ACTION_SKIP_FILE = "androidx.profileinstaller.action.SKIP_FILE";
|
||||
private static final String EXTRA_BENCHMARK_OPERATION = "EXTRA_BENCHMARK_OPERATION";
|
||||
private static final String EXTRA_BENCHMARK_OPERATION_DROP_SHADER_CACHE = "DROP_SHADER_CACHE";
|
||||
private static final String EXTRA_SKIP_FILE_OPERATION = "EXTRA_SKIP_FILE_OPERATION";
|
||||
private static final String EXTRA_SKIP_FILE_OPERATION_DELETE = "DELETE_SKIP_FILE";
|
||||
private static final String EXTRA_SKIP_FILE_OPERATION_WRITE = "WRITE_SKIP_FILE";
|
||||
|
||||
@Override // android.content.BroadcastReceiver
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Bundle extras;
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
String action = intent.getAction();
|
||||
if (ACTION_INSTALL_PROFILE.equals(action)) {
|
||||
ProfileInstaller.writeProfile(context, new ProfileInstallReceiver$$ExternalSyntheticLambda0(), new ResultDiagnostics(), true);
|
||||
return;
|
||||
}
|
||||
if (ACTION_SKIP_FILE.equals(action)) {
|
||||
Bundle extras2 = intent.getExtras();
|
||||
if (extras2 != null) {
|
||||
String string = extras2.getString(EXTRA_SKIP_FILE_OPERATION);
|
||||
if (EXTRA_SKIP_FILE_OPERATION_WRITE.equals(string)) {
|
||||
ProfileInstaller.writeSkipFile(context, new ProfileInstallReceiver$$ExternalSyntheticLambda0(), new ResultDiagnostics());
|
||||
return;
|
||||
} else {
|
||||
if (EXTRA_SKIP_FILE_OPERATION_DELETE.equals(string)) {
|
||||
ProfileInstaller.deleteSkipFile(context, new ProfileInstallReceiver$$ExternalSyntheticLambda0(), new ResultDiagnostics());
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (ACTION_SAVE_PROFILE.equals(action)) {
|
||||
saveProfile(new ResultDiagnostics());
|
||||
return;
|
||||
}
|
||||
if (!ACTION_BENCHMARK_OPERATION.equals(action) || (extras = intent.getExtras()) == null) {
|
||||
return;
|
||||
}
|
||||
String string2 = extras.getString(EXTRA_BENCHMARK_OPERATION);
|
||||
ResultDiagnostics resultDiagnostics = new ResultDiagnostics();
|
||||
if (EXTRA_BENCHMARK_OPERATION_DROP_SHADER_CACHE.equals(string2)) {
|
||||
BenchmarkOperation.dropShaderCache(context, resultDiagnostics);
|
||||
} else {
|
||||
resultDiagnostics.onResultReceived(16, null);
|
||||
}
|
||||
}
|
||||
|
||||
static void saveProfile(ProfileInstaller.DiagnosticsCallback diagnosticsCallback) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
Process.sendSignal(Process.myPid(), 10);
|
||||
diagnosticsCallback.onResultReceived(12, null);
|
||||
} else {
|
||||
diagnosticsCallback.onResultReceived(13, null);
|
||||
}
|
||||
}
|
||||
|
||||
class ResultDiagnostics implements ProfileInstaller.DiagnosticsCallback {
|
||||
ResultDiagnostics() {
|
||||
}
|
||||
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onDiagnosticReceived(int i, Object obj) {
|
||||
ProfileInstaller.LOG_DIAGNOSTICS.onDiagnosticReceived(i, obj);
|
||||
}
|
||||
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onResultReceived(int i, Object obj) {
|
||||
ProfileInstaller.LOG_DIAGNOSTICS.onResultReceived(i, obj);
|
||||
ProfileInstallReceiver.this.setResultCode(i);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
import androidx.profileinstaller.ProfileInstaller;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ProfileInstaller {
|
||||
public static final int DIAGNOSTIC_CURRENT_PROFILE_DOES_NOT_EXIST = 2;
|
||||
public static final int DIAGNOSTIC_CURRENT_PROFILE_EXISTS = 1;
|
||||
public static final int DIAGNOSTIC_PROFILE_IS_COMPRESSED = 5;
|
||||
public static final int DIAGNOSTIC_REF_PROFILE_DOES_NOT_EXIST = 4;
|
||||
public static final int DIAGNOSTIC_REF_PROFILE_EXISTS = 3;
|
||||
private static final DiagnosticsCallback EMPTY_DIAGNOSTICS = new DiagnosticsCallback() { // from class: androidx.profileinstaller.ProfileInstaller.1
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onDiagnosticReceived(int i, Object obj) {
|
||||
}
|
||||
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onResultReceived(int i, Object obj) {
|
||||
}
|
||||
};
|
||||
static final DiagnosticsCallback LOG_DIAGNOSTICS = new DiagnosticsCallback() { // from class: androidx.profileinstaller.ProfileInstaller.2
|
||||
static final String TAG = "ProfileInstaller";
|
||||
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onDiagnosticReceived(int i, Object obj) {
|
||||
Log.d(TAG, i != 1 ? i != 2 ? i != 3 ? i != 4 ? i != 5 ? "" : "DIAGNOSTIC_PROFILE_IS_COMPRESSED" : "DIAGNOSTIC_REF_PROFILE_DOES_NOT_EXIST" : "DIAGNOSTIC_REF_PROFILE_EXISTS" : "DIAGNOSTIC_CURRENT_PROFILE_DOES_NOT_EXIST" : "DIAGNOSTIC_CURRENT_PROFILE_EXISTS");
|
||||
}
|
||||
|
||||
@Override // androidx.profileinstaller.ProfileInstaller.DiagnosticsCallback
|
||||
public void onResultReceived(int i, Object obj) {
|
||||
String str;
|
||||
switch (i) {
|
||||
case 1:
|
||||
str = "RESULT_INSTALL_SUCCESS";
|
||||
break;
|
||||
case 2:
|
||||
str = "RESULT_ALREADY_INSTALLED";
|
||||
break;
|
||||
case 3:
|
||||
str = "RESULT_UNSUPPORTED_ART_VERSION";
|
||||
break;
|
||||
case 4:
|
||||
str = "RESULT_NOT_WRITABLE";
|
||||
break;
|
||||
case 5:
|
||||
str = "RESULT_DESIRED_FORMAT_UNSUPPORTED";
|
||||
break;
|
||||
case 6:
|
||||
str = "RESULT_BASELINE_PROFILE_NOT_FOUND";
|
||||
break;
|
||||
case 7:
|
||||
str = "RESULT_IO_EXCEPTION";
|
||||
break;
|
||||
case 8:
|
||||
str = "RESULT_PARSE_EXCEPTION";
|
||||
break;
|
||||
case 9:
|
||||
default:
|
||||
str = "";
|
||||
break;
|
||||
case 10:
|
||||
str = "RESULT_INSTALL_SKIP_FILE_SUCCESS";
|
||||
break;
|
||||
case 11:
|
||||
str = "RESULT_DELETE_SKIP_FILE_SUCCESS";
|
||||
break;
|
||||
}
|
||||
if (i == 6 || i == 7 || i == 8) {
|
||||
Log.e(TAG, str, (Throwable) obj);
|
||||
} else {
|
||||
Log.d(TAG, str);
|
||||
}
|
||||
}
|
||||
};
|
||||
private static final String PROFILE_BASE_DIR = "/data/misc/profiles/cur/0";
|
||||
private static final String PROFILE_FILE = "primary.prof";
|
||||
private static final String PROFILE_INSTALLER_SKIP_FILE_NAME = "profileinstaller_profileWrittenFor_lastUpdateTime.dat";
|
||||
private static final String PROFILE_META_LOCATION = "dexopt/baseline.profm";
|
||||
private static final String PROFILE_SOURCE_LOCATION = "dexopt/baseline.prof";
|
||||
public static final int RESULT_ALREADY_INSTALLED = 2;
|
||||
public static final int RESULT_BASELINE_PROFILE_NOT_FOUND = 6;
|
||||
public static final int RESULT_BENCHMARK_OPERATION_FAILURE = 15;
|
||||
public static final int RESULT_BENCHMARK_OPERATION_SUCCESS = 14;
|
||||
public static final int RESULT_BENCHMARK_OPERATION_UNKNOWN = 16;
|
||||
public static final int RESULT_DELETE_SKIP_FILE_SUCCESS = 11;
|
||||
public static final int RESULT_DESIRED_FORMAT_UNSUPPORTED = 5;
|
||||
public static final int RESULT_INSTALL_SKIP_FILE_SUCCESS = 10;
|
||||
public static final int RESULT_INSTALL_SUCCESS = 1;
|
||||
public static final int RESULT_IO_EXCEPTION = 7;
|
||||
public static final int RESULT_META_FILE_REQUIRED_BUT_NOT_FOUND = 9;
|
||||
public static final int RESULT_NOT_WRITABLE = 4;
|
||||
public static final int RESULT_PARSE_EXCEPTION = 8;
|
||||
public static final int RESULT_SAVE_PROFILE_SIGNALLED = 12;
|
||||
public static final int RESULT_SAVE_PROFILE_SKIPPED = 13;
|
||||
public static final int RESULT_UNSUPPORTED_ART_VERSION = 3;
|
||||
private static final String TAG = "ProfileInstaller";
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DiagnosticCode {
|
||||
}
|
||||
|
||||
public interface DiagnosticsCallback {
|
||||
void onDiagnosticReceived(int i, Object obj);
|
||||
|
||||
void onResultReceived(int i, Object obj);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ResultCode {
|
||||
}
|
||||
|
||||
private ProfileInstaller() {
|
||||
}
|
||||
|
||||
static void result(Executor executor, final DiagnosticsCallback diagnosticsCallback, final int i, final Object obj) {
|
||||
executor.execute(new Runnable() { // from class: androidx.profileinstaller.ProfileInstaller$$ExternalSyntheticLambda0
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
ProfileInstaller.DiagnosticsCallback.this.onResultReceived(i, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void diagnostic(Executor executor, final DiagnosticsCallback diagnosticsCallback, final int i, final Object obj) {
|
||||
executor.execute(new Runnable() { // from class: androidx.profileinstaller.ProfileInstaller$$ExternalSyntheticLambda1
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
ProfileInstaller.DiagnosticsCallback.this.onDiagnosticReceived(i, obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static boolean hasAlreadyWrittenProfileForThisInstall(PackageInfo packageInfo, File file, DiagnosticsCallback diagnosticsCallback) {
|
||||
File file2 = new File(file, PROFILE_INSTALLER_SKIP_FILE_NAME);
|
||||
if (!file2.exists()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file2));
|
||||
try {
|
||||
long readLong = dataInputStream.readLong();
|
||||
dataInputStream.close();
|
||||
boolean z = readLong == packageInfo.lastUpdateTime;
|
||||
if (z) {
|
||||
diagnosticsCallback.onResultReceived(2, null);
|
||||
}
|
||||
return z;
|
||||
} finally {
|
||||
}
|
||||
} catch (IOException unused) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void noteProfileWrittenFor(PackageInfo packageInfo, File file) {
|
||||
try {
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(new File(file, PROFILE_INSTALLER_SKIP_FILE_NAME)));
|
||||
try {
|
||||
dataOutputStream.writeLong(packageInfo.lastUpdateTime);
|
||||
dataOutputStream.close();
|
||||
} finally {
|
||||
}
|
||||
} catch (IOException unused) {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean deleteProfileWrittenFor(File file) {
|
||||
return new File(file, PROFILE_INSTALLER_SKIP_FILE_NAME).delete();
|
||||
}
|
||||
|
||||
private static boolean transcodeAndWrite(AssetManager assetManager, String str, PackageInfo packageInfo, File file, String str2, Executor executor, DiagnosticsCallback diagnosticsCallback) {
|
||||
DeviceProfileWriter deviceProfileWriter = new DeviceProfileWriter(assetManager, executor, diagnosticsCallback, str2, PROFILE_SOURCE_LOCATION, PROFILE_META_LOCATION, new File(new File(PROFILE_BASE_DIR, str), PROFILE_FILE));
|
||||
if (!deviceProfileWriter.deviceAllowsProfileInstallerAotWrites()) {
|
||||
return false;
|
||||
}
|
||||
boolean write = deviceProfileWriter.read().transcodeIfNeeded().write();
|
||||
if (write) {
|
||||
noteProfileWrittenFor(packageInfo, file);
|
||||
}
|
||||
return write;
|
||||
}
|
||||
|
||||
public static void writeProfile(Context context) {
|
||||
writeProfile(context, new ProfileInstallReceiver$$ExternalSyntheticLambda0(), EMPTY_DIAGNOSTICS);
|
||||
}
|
||||
|
||||
public static void writeProfile(Context context, Executor executor, DiagnosticsCallback diagnosticsCallback) {
|
||||
writeProfile(context, executor, diagnosticsCallback, false);
|
||||
}
|
||||
|
||||
static void writeProfile(Context context, Executor executor, DiagnosticsCallback diagnosticsCallback, boolean z) {
|
||||
Context applicationContext = context.getApplicationContext();
|
||||
String packageName = applicationContext.getPackageName();
|
||||
ApplicationInfo applicationInfo = applicationContext.getApplicationInfo();
|
||||
AssetManager assets = applicationContext.getAssets();
|
||||
String name = new File(applicationInfo.sourceDir).getName();
|
||||
boolean z2 = false;
|
||||
try {
|
||||
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||
File filesDir = context.getFilesDir();
|
||||
if (z || !hasAlreadyWrittenProfileForThisInstall(packageInfo, filesDir, diagnosticsCallback)) {
|
||||
Log.d(TAG, "Installing profile for " + context.getPackageName());
|
||||
if (transcodeAndWrite(assets, packageName, packageInfo, filesDir, name, executor, diagnosticsCallback) && z) {
|
||||
z2 = true;
|
||||
}
|
||||
ProfileVerifier.writeProfileVerification(context, z2);
|
||||
return;
|
||||
}
|
||||
Log.d(TAG, "Skipping profile installation for " + context.getPackageName());
|
||||
ProfileVerifier.writeProfileVerification(context, false);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
diagnosticsCallback.onResultReceived(7, e);
|
||||
ProfileVerifier.writeProfileVerification(context, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeSkipFile(Context context, Executor executor, DiagnosticsCallback diagnosticsCallback) {
|
||||
try {
|
||||
noteProfileWrittenFor(context.getPackageManager().getPackageInfo(context.getApplicationContext().getPackageName(), 0), context.getFilesDir());
|
||||
result(executor, diagnosticsCallback, 10, null);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
result(executor, diagnosticsCallback, 7, e);
|
||||
}
|
||||
}
|
||||
|
||||
static void deleteSkipFile(Context context, Executor executor, DiagnosticsCallback diagnosticsCallback) {
|
||||
deleteProfileWrittenFor(context.getFilesDir());
|
||||
result(executor, diagnosticsCallback, 11, null);
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Choreographer;
|
||||
import androidx.startup.Initializer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ProfileInstallerInitializer implements Initializer<Result> {
|
||||
private static final int DELAY_MS = 5000;
|
||||
|
||||
public static class Result {
|
||||
}
|
||||
|
||||
/* JADX WARN: Can't rename method to resolve collision */
|
||||
@Override // androidx.startup.Initializer
|
||||
public Result create(Context context) {
|
||||
if (Build.VERSION.SDK_INT < 24) {
|
||||
return new Result();
|
||||
}
|
||||
delayAfterFirstFrame(context.getApplicationContext());
|
||||
return new Result();
|
||||
}
|
||||
|
||||
void delayAfterFirstFrame(final Context context) {
|
||||
Choreographer16Impl.postFrameCallback(new Runnable() { // from class: androidx.profileinstaller.ProfileInstallerInitializer$$ExternalSyntheticLambda1
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
ProfileInstallerInitializer.this.m170xfbd6c934(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* JADX INFO: Access modifiers changed from: package-private */
|
||||
/* renamed from: installAfterDelay, reason: merged with bridge method [inline-methods] */
|
||||
public void m170xfbd6c934(final Context context) {
|
||||
Handler handler;
|
||||
if (Build.VERSION.SDK_INT >= 28) {
|
||||
handler = Handler28Impl.createAsync(Looper.getMainLooper());
|
||||
} else {
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
handler.postDelayed(new Runnable() { // from class: androidx.profileinstaller.ProfileInstallerInitializer$$ExternalSyntheticLambda0
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
ProfileInstallerInitializer.writeInBackground(context);
|
||||
}
|
||||
}, new Random().nextInt(Math.max(1000, 1)) + DELAY_MS);
|
||||
}
|
||||
|
||||
@Override // androidx.startup.Initializer
|
||||
public List<Class<? extends Initializer<?>>> dependencies() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/* JADX INFO: Access modifiers changed from: private */
|
||||
public static void writeInBackground(final Context context) {
|
||||
new ThreadPoolExecutor(0, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()).execute(new Runnable() { // from class: androidx.profileinstaller.ProfileInstallerInitializer$$ExternalSyntheticLambda2
|
||||
@Override // java.lang.Runnable
|
||||
public final void run() {
|
||||
ProfileInstaller.writeProfile(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* JADX INFO: Access modifiers changed from: private */
|
||||
static class Choreographer16Impl {
|
||||
private Choreographer16Impl() {
|
||||
}
|
||||
|
||||
public static void postFrameCallback(final Runnable runnable) {
|
||||
Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() { // from class: androidx.profileinstaller.ProfileInstallerInitializer$Choreographer16Impl$$ExternalSyntheticLambda0
|
||||
@Override // android.view.Choreographer.FrameCallback
|
||||
public final void doFrame(long j) {
|
||||
runnable.run();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static class Handler28Impl {
|
||||
private Handler28Impl() {
|
||||
}
|
||||
|
||||
public static Handler createAsync(Looper looper) {
|
||||
Handler createAsync;
|
||||
createAsync = Handler.createAsync(looper);
|
||||
return createAsync;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,655 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
class ProfileTranscoder {
|
||||
private static final int HOT = 1;
|
||||
private static final int INLINE_CACHE_MEGAMORPHIC_ENCODING = 7;
|
||||
private static final int INLINE_CACHE_MISSING_TYPES_ENCODING = 6;
|
||||
static final byte[] MAGIC_PROF = {112, 114, 111, 0};
|
||||
static final byte[] MAGIC_PROFM = {112, 114, 109, 0};
|
||||
private static final int POST_STARTUP = 4;
|
||||
private static final int STARTUP = 2;
|
||||
|
||||
private static int roundUpToByte(int i) {
|
||||
return (i + 7) & (-8);
|
||||
}
|
||||
|
||||
private ProfileTranscoder() {
|
||||
}
|
||||
|
||||
static byte[] readHeader(InputStream inputStream, byte[] bArr) throws IOException {
|
||||
if (!Arrays.equals(bArr, Encoding.read(inputStream, bArr.length))) {
|
||||
throw Encoding.error("Invalid magic");
|
||||
}
|
||||
return Encoding.read(inputStream, ProfileVersion.V010_P.length);
|
||||
}
|
||||
|
||||
static void writeHeader(OutputStream outputStream, byte[] bArr) throws IOException {
|
||||
outputStream.write(MAGIC_PROF);
|
||||
outputStream.write(bArr);
|
||||
}
|
||||
|
||||
static boolean transcodeAndWriteBody(OutputStream outputStream, byte[] bArr, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
if (Arrays.equals(bArr, ProfileVersion.V015_S)) {
|
||||
writeProfileForS(outputStream, dexProfileDataArr);
|
||||
return true;
|
||||
}
|
||||
if (Arrays.equals(bArr, ProfileVersion.V010_P)) {
|
||||
writeProfileForP(outputStream, dexProfileDataArr);
|
||||
return true;
|
||||
}
|
||||
if (Arrays.equals(bArr, ProfileVersion.V005_O)) {
|
||||
writeProfileForO(outputStream, dexProfileDataArr);
|
||||
return true;
|
||||
}
|
||||
if (Arrays.equals(bArr, ProfileVersion.V009_O_MR1)) {
|
||||
writeProfileForO_MR1(outputStream, dexProfileDataArr);
|
||||
return true;
|
||||
}
|
||||
if (!Arrays.equals(bArr, ProfileVersion.V001_N)) {
|
||||
return false;
|
||||
}
|
||||
writeProfileForN(outputStream, dexProfileDataArr);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void writeProfileForN(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
Encoding.writeUInt16(outputStream, dexProfileDataArr.length);
|
||||
for (DexProfileData dexProfileData : dexProfileDataArr) {
|
||||
String generateDexKey = generateDexKey(dexProfileData.apkName, dexProfileData.dexName, ProfileVersion.V001_N);
|
||||
Encoding.writeUInt16(outputStream, Encoding.utf8Length(generateDexKey));
|
||||
Encoding.writeUInt16(outputStream, dexProfileData.methods.size());
|
||||
Encoding.writeUInt16(outputStream, dexProfileData.classes.length);
|
||||
Encoding.writeUInt32(outputStream, dexProfileData.dexChecksum);
|
||||
Encoding.writeString(outputStream, generateDexKey);
|
||||
Iterator<Integer> it = dexProfileData.methods.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Encoding.writeUInt16(outputStream, it.next().intValue());
|
||||
}
|
||||
for (int i : dexProfileData.classes) {
|
||||
Encoding.writeUInt16(outputStream, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeProfileForS(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
writeProfileSections(outputStream, dexProfileDataArr);
|
||||
}
|
||||
|
||||
private static void writeProfileSections(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
int length;
|
||||
ArrayList arrayList = new ArrayList(3);
|
||||
ArrayList arrayList2 = new ArrayList(3);
|
||||
arrayList.add(writeDexFileSection(dexProfileDataArr));
|
||||
arrayList.add(createCompressibleClassSection(dexProfileDataArr));
|
||||
arrayList.add(createCompressibleMethodsSection(dexProfileDataArr));
|
||||
long length2 = ProfileVersion.V015_S.length + MAGIC_PROF.length + 4 + (arrayList.size() * 16);
|
||||
Encoding.writeUInt32(outputStream, arrayList.size());
|
||||
for (int i = 0; i < arrayList.size(); i++) {
|
||||
WritableFileSection writableFileSection = (WritableFileSection) arrayList.get(i);
|
||||
Encoding.writeUInt32(outputStream, writableFileSection.mType.getValue());
|
||||
Encoding.writeUInt32(outputStream, length2);
|
||||
if (writableFileSection.mNeedsCompression) {
|
||||
long length3 = writableFileSection.mContents.length;
|
||||
byte[] compress = Encoding.compress(writableFileSection.mContents);
|
||||
arrayList2.add(compress);
|
||||
Encoding.writeUInt32(outputStream, compress.length);
|
||||
Encoding.writeUInt32(outputStream, length3);
|
||||
length = compress.length;
|
||||
} else {
|
||||
arrayList2.add(writableFileSection.mContents);
|
||||
Encoding.writeUInt32(outputStream, writableFileSection.mContents.length);
|
||||
Encoding.writeUInt32(outputStream, 0L);
|
||||
length = writableFileSection.mContents.length;
|
||||
}
|
||||
length2 += length;
|
||||
}
|
||||
for (int i2 = 0; i2 < arrayList2.size(); i2++) {
|
||||
outputStream.write((byte[]) arrayList2.get(i2));
|
||||
}
|
||||
}
|
||||
|
||||
private static WritableFileSection writeDexFileSection(DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
Encoding.writeUInt16(byteArrayOutputStream, dexProfileDataArr.length);
|
||||
int i = 2;
|
||||
for (DexProfileData dexProfileData : dexProfileDataArr) {
|
||||
Encoding.writeUInt32(byteArrayOutputStream, dexProfileData.dexChecksum);
|
||||
Encoding.writeUInt32(byteArrayOutputStream, dexProfileData.mTypeIdCount);
|
||||
Encoding.writeUInt32(byteArrayOutputStream, dexProfileData.numMethodIds);
|
||||
String generateDexKey = generateDexKey(dexProfileData.apkName, dexProfileData.dexName, ProfileVersion.V015_S);
|
||||
int utf8Length = Encoding.utf8Length(generateDexKey);
|
||||
Encoding.writeUInt16(byteArrayOutputStream, utf8Length);
|
||||
i = i + 14 + utf8Length;
|
||||
Encoding.writeString(byteArrayOutputStream, generateDexKey);
|
||||
}
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
if (i != byteArray.length) {
|
||||
throw Encoding.error("Expected size " + i + ", does not match actual size " + byteArray.length);
|
||||
}
|
||||
WritableFileSection writableFileSection = new WritableFileSection(FileSectionType.DEX_FILES, i, byteArray, false);
|
||||
byteArrayOutputStream.close();
|
||||
return writableFileSection;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
private static WritableFileSection createCompressibleClassSection(DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
int i = 0;
|
||||
for (int i2 = 0; i2 < dexProfileDataArr.length; i2++) {
|
||||
try {
|
||||
DexProfileData dexProfileData = dexProfileDataArr[i2];
|
||||
Encoding.writeUInt16(byteArrayOutputStream, i2);
|
||||
Encoding.writeUInt16(byteArrayOutputStream, dexProfileData.classSetSize);
|
||||
i = i + 4 + (dexProfileData.classSetSize * 2);
|
||||
writeClasses(byteArrayOutputStream, dexProfileData);
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
if (i != byteArray.length) {
|
||||
throw Encoding.error("Expected size " + i + ", does not match actual size " + byteArray.length);
|
||||
}
|
||||
WritableFileSection writableFileSection = new WritableFileSection(FileSectionType.CLASSES, i, byteArray, true);
|
||||
byteArrayOutputStream.close();
|
||||
return writableFileSection;
|
||||
}
|
||||
|
||||
private static WritableFileSection createCompressibleMethodsSection(DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
int i = 0;
|
||||
for (int i2 = 0; i2 < dexProfileDataArr.length; i2++) {
|
||||
try {
|
||||
DexProfileData dexProfileData = dexProfileDataArr[i2];
|
||||
int computeMethodFlags = computeMethodFlags(dexProfileData);
|
||||
byte[] createMethodBitmapRegion = createMethodBitmapRegion(dexProfileData);
|
||||
byte[] createMethodsWithInlineCaches = createMethodsWithInlineCaches(dexProfileData);
|
||||
Encoding.writeUInt16(byteArrayOutputStream, i2);
|
||||
int length = createMethodBitmapRegion.length + 2 + createMethodsWithInlineCaches.length;
|
||||
Encoding.writeUInt32(byteArrayOutputStream, length);
|
||||
Encoding.writeUInt16(byteArrayOutputStream, computeMethodFlags);
|
||||
byteArrayOutputStream.write(createMethodBitmapRegion);
|
||||
byteArrayOutputStream.write(createMethodsWithInlineCaches);
|
||||
i = i + 6 + length;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
if (i != byteArray.length) {
|
||||
throw Encoding.error("Expected size " + i + ", does not match actual size " + byteArray.length);
|
||||
}
|
||||
WritableFileSection writableFileSection = new WritableFileSection(FileSectionType.METHODS, i, byteArray, true);
|
||||
byteArrayOutputStream.close();
|
||||
return writableFileSection;
|
||||
}
|
||||
|
||||
private static byte[] createMethodBitmapRegion(DexProfileData dexProfileData) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
writeMethodBitmap(byteArrayOutputStream, dexProfileData);
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
byteArrayOutputStream.close();
|
||||
return byteArray;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] createMethodsWithInlineCaches(DexProfileData dexProfileData) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
try {
|
||||
writeMethodsWithInlineCaches(byteArrayOutputStream, dexProfileData);
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
byteArrayOutputStream.close();
|
||||
return byteArray;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
private static int computeMethodFlags(DexProfileData dexProfileData) {
|
||||
Iterator<Map.Entry<Integer, Integer>> it = dexProfileData.methods.entrySet().iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
i |= it.next().getValue().intValue();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private static void writeProfileForP(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
byte[] createCompressibleBody = createCompressibleBody(dexProfileDataArr, ProfileVersion.V010_P);
|
||||
Encoding.writeUInt8(outputStream, dexProfileDataArr.length);
|
||||
Encoding.writeCompressed(outputStream, createCompressibleBody);
|
||||
}
|
||||
|
||||
private static void writeProfileForO_MR1(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
byte[] createCompressibleBody = createCompressibleBody(dexProfileDataArr, ProfileVersion.V009_O_MR1);
|
||||
Encoding.writeUInt8(outputStream, dexProfileDataArr.length);
|
||||
Encoding.writeCompressed(outputStream, createCompressibleBody);
|
||||
}
|
||||
|
||||
private static void writeProfileForO(OutputStream outputStream, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
Encoding.writeUInt8(outputStream, dexProfileDataArr.length);
|
||||
for (DexProfileData dexProfileData : dexProfileDataArr) {
|
||||
int size = dexProfileData.methods.size() * 4;
|
||||
String generateDexKey = generateDexKey(dexProfileData.apkName, dexProfileData.dexName, ProfileVersion.V005_O);
|
||||
Encoding.writeUInt16(outputStream, Encoding.utf8Length(generateDexKey));
|
||||
Encoding.writeUInt16(outputStream, dexProfileData.classes.length);
|
||||
Encoding.writeUInt32(outputStream, size);
|
||||
Encoding.writeUInt32(outputStream, dexProfileData.dexChecksum);
|
||||
Encoding.writeString(outputStream, generateDexKey);
|
||||
Iterator<Integer> it = dexProfileData.methods.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Encoding.writeUInt16(outputStream, it.next().intValue());
|
||||
Encoding.writeUInt16(outputStream, 0);
|
||||
}
|
||||
for (int i : dexProfileData.classes) {
|
||||
Encoding.writeUInt16(outputStream, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] createCompressibleBody(DexProfileData[] dexProfileDataArr, byte[] bArr) throws IOException {
|
||||
int i = 0;
|
||||
int i2 = 0;
|
||||
for (DexProfileData dexProfileData : dexProfileDataArr) {
|
||||
i2 += Encoding.utf8Length(generateDexKey(dexProfileData.apkName, dexProfileData.dexName, bArr)) + 16 + (dexProfileData.classSetSize * 2) + dexProfileData.hotMethodRegionSize + getMethodBitmapStorageSize(dexProfileData.numMethodIds);
|
||||
}
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(i2);
|
||||
if (Arrays.equals(bArr, ProfileVersion.V009_O_MR1)) {
|
||||
int length = dexProfileDataArr.length;
|
||||
while (i < length) {
|
||||
DexProfileData dexProfileData2 = dexProfileDataArr[i];
|
||||
writeLineHeader(byteArrayOutputStream, dexProfileData2, generateDexKey(dexProfileData2.apkName, dexProfileData2.dexName, bArr));
|
||||
writeLineData(byteArrayOutputStream, dexProfileData2);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (DexProfileData dexProfileData3 : dexProfileDataArr) {
|
||||
writeLineHeader(byteArrayOutputStream, dexProfileData3, generateDexKey(dexProfileData3.apkName, dexProfileData3.dexName, bArr));
|
||||
}
|
||||
int length2 = dexProfileDataArr.length;
|
||||
while (i < length2) {
|
||||
writeLineData(byteArrayOutputStream, dexProfileDataArr[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (byteArrayOutputStream.size() != i2) {
|
||||
throw Encoding.error("The bytes saved do not match expectation. actual=" + byteArrayOutputStream.size() + " expected=" + i2);
|
||||
}
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
private static int getMethodBitmapStorageSize(int i) {
|
||||
return roundUpToByte(i * 2) / 8;
|
||||
}
|
||||
|
||||
private static void setMethodBitmapBit(byte[] bArr, int i, int i2, DexProfileData dexProfileData) {
|
||||
int methodFlagBitmapIndex = methodFlagBitmapIndex(i, i2, dexProfileData.numMethodIds);
|
||||
int i3 = methodFlagBitmapIndex / 8;
|
||||
bArr[i3] = (byte) ((1 << (methodFlagBitmapIndex % 8)) | bArr[i3]);
|
||||
}
|
||||
|
||||
private static void writeLineHeader(OutputStream outputStream, DexProfileData dexProfileData, String str) throws IOException {
|
||||
Encoding.writeUInt16(outputStream, Encoding.utf8Length(str));
|
||||
Encoding.writeUInt16(outputStream, dexProfileData.classSetSize);
|
||||
Encoding.writeUInt32(outputStream, dexProfileData.hotMethodRegionSize);
|
||||
Encoding.writeUInt32(outputStream, dexProfileData.dexChecksum);
|
||||
Encoding.writeUInt32(outputStream, dexProfileData.numMethodIds);
|
||||
Encoding.writeString(outputStream, str);
|
||||
}
|
||||
|
||||
private static void writeLineData(OutputStream outputStream, DexProfileData dexProfileData) throws IOException {
|
||||
writeMethodsWithInlineCaches(outputStream, dexProfileData);
|
||||
writeClasses(outputStream, dexProfileData);
|
||||
writeMethodBitmap(outputStream, dexProfileData);
|
||||
}
|
||||
|
||||
private static void writeMethodsWithInlineCaches(OutputStream outputStream, DexProfileData dexProfileData) throws IOException {
|
||||
int i = 0;
|
||||
for (Map.Entry<Integer, Integer> entry : dexProfileData.methods.entrySet()) {
|
||||
int intValue = entry.getKey().intValue();
|
||||
if ((entry.getValue().intValue() & 1) != 0) {
|
||||
Encoding.writeUInt16(outputStream, intValue - i);
|
||||
Encoding.writeUInt16(outputStream, 0);
|
||||
i = intValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeClasses(OutputStream outputStream, DexProfileData dexProfileData) throws IOException {
|
||||
int i = 0;
|
||||
for (int i2 : dexProfileData.classes) {
|
||||
Integer valueOf = Integer.valueOf(i2);
|
||||
Encoding.writeUInt16(outputStream, valueOf.intValue() - i);
|
||||
i = valueOf.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeMethodBitmap(OutputStream outputStream, DexProfileData dexProfileData) throws IOException {
|
||||
byte[] bArr = new byte[getMethodBitmapStorageSize(dexProfileData.numMethodIds)];
|
||||
for (Map.Entry<Integer, Integer> entry : dexProfileData.methods.entrySet()) {
|
||||
int intValue = entry.getKey().intValue();
|
||||
int intValue2 = entry.getValue().intValue();
|
||||
if ((intValue2 & 2) != 0) {
|
||||
setMethodBitmapBit(bArr, 2, intValue, dexProfileData);
|
||||
}
|
||||
if ((intValue2 & 4) != 0) {
|
||||
setMethodBitmapBit(bArr, 4, intValue, dexProfileData);
|
||||
}
|
||||
}
|
||||
outputStream.write(bArr);
|
||||
}
|
||||
|
||||
static DexProfileData[] readProfile(InputStream inputStream, byte[] bArr, String str) throws IOException {
|
||||
if (!Arrays.equals(bArr, ProfileVersion.V010_P)) {
|
||||
throw Encoding.error("Unsupported version");
|
||||
}
|
||||
int readUInt8 = Encoding.readUInt8(inputStream);
|
||||
byte[] readCompressed = Encoding.readCompressed(inputStream, (int) Encoding.readUInt32(inputStream), (int) Encoding.readUInt32(inputStream));
|
||||
if (inputStream.read() > 0) {
|
||||
throw Encoding.error("Content found after the end of file");
|
||||
}
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(readCompressed);
|
||||
try {
|
||||
DexProfileData[] readUncompressedBody = readUncompressedBody(byteArrayInputStream, str, readUInt8);
|
||||
byteArrayInputStream.close();
|
||||
return readUncompressedBody;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayInputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
static DexProfileData[] readMeta(InputStream inputStream, byte[] bArr, byte[] bArr2, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
if (Arrays.equals(bArr, ProfileVersion.METADATA_V001_N)) {
|
||||
if (Arrays.equals(ProfileVersion.V015_S, bArr2)) {
|
||||
throw Encoding.error("Requires new Baseline Profile Metadata. Please rebuild the APK with Android Gradle Plugin 7.2 Canary 7 or higher");
|
||||
}
|
||||
return readMetadata001(inputStream, bArr, dexProfileDataArr);
|
||||
}
|
||||
if (Arrays.equals(bArr, ProfileVersion.METADATA_V002)) {
|
||||
return readMetadataV002(inputStream, bArr2, dexProfileDataArr);
|
||||
}
|
||||
throw Encoding.error("Unsupported meta version");
|
||||
}
|
||||
|
||||
static DexProfileData[] readMetadata001(InputStream inputStream, byte[] bArr, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
if (!Arrays.equals(bArr, ProfileVersion.METADATA_V001_N)) {
|
||||
throw Encoding.error("Unsupported meta version");
|
||||
}
|
||||
int readUInt8 = Encoding.readUInt8(inputStream);
|
||||
byte[] readCompressed = Encoding.readCompressed(inputStream, (int) Encoding.readUInt32(inputStream), (int) Encoding.readUInt32(inputStream));
|
||||
if (inputStream.read() > 0) {
|
||||
throw Encoding.error("Content found after the end of file");
|
||||
}
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(readCompressed);
|
||||
try {
|
||||
DexProfileData[] readMetadataForNBody = readMetadataForNBody(byteArrayInputStream, readUInt8, dexProfileDataArr);
|
||||
byteArrayInputStream.close();
|
||||
return readMetadataForNBody;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayInputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
static DexProfileData[] readMetadataV002(InputStream inputStream, byte[] bArr, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
int readUInt16 = Encoding.readUInt16(inputStream);
|
||||
byte[] readCompressed = Encoding.readCompressed(inputStream, (int) Encoding.readUInt32(inputStream), (int) Encoding.readUInt32(inputStream));
|
||||
if (inputStream.read() > 0) {
|
||||
throw Encoding.error("Content found after the end of file");
|
||||
}
|
||||
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(readCompressed);
|
||||
try {
|
||||
DexProfileData[] readMetadataV002Body = readMetadataV002Body(byteArrayInputStream, bArr, readUInt16, dexProfileDataArr);
|
||||
byteArrayInputStream.close();
|
||||
return readMetadataV002Body;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
byteArrayInputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
private static DexProfileData[] readMetadataV002Body(InputStream inputStream, byte[] bArr, int i, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
if (inputStream.available() == 0) {
|
||||
return new DexProfileData[0];
|
||||
}
|
||||
if (i != dexProfileDataArr.length) {
|
||||
throw Encoding.error("Mismatched number of dex files found in metadata");
|
||||
}
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
Encoding.readUInt16(inputStream);
|
||||
String readString = Encoding.readString(inputStream, Encoding.readUInt16(inputStream));
|
||||
long readUInt32 = Encoding.readUInt32(inputStream);
|
||||
int readUInt16 = Encoding.readUInt16(inputStream);
|
||||
DexProfileData findByDexName = findByDexName(dexProfileDataArr, readString);
|
||||
if (findByDexName == null) {
|
||||
throw Encoding.error("Missing profile key: " + readString);
|
||||
}
|
||||
findByDexName.mTypeIdCount = readUInt32;
|
||||
int[] readClasses = readClasses(inputStream, readUInt16);
|
||||
if (Arrays.equals(bArr, ProfileVersion.V001_N)) {
|
||||
findByDexName.classSetSize = readUInt16;
|
||||
findByDexName.classes = readClasses;
|
||||
}
|
||||
}
|
||||
return dexProfileDataArr;
|
||||
}
|
||||
|
||||
private static DexProfileData findByDexName(DexProfileData[] dexProfileDataArr, String str) {
|
||||
if (dexProfileDataArr.length <= 0) {
|
||||
return null;
|
||||
}
|
||||
String extractKey = extractKey(str);
|
||||
for (int i = 0; i < dexProfileDataArr.length; i++) {
|
||||
if (dexProfileDataArr[i].dexName.equals(extractKey)) {
|
||||
return dexProfileDataArr[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static DexProfileData[] readMetadataForNBody(InputStream inputStream, int i, DexProfileData[] dexProfileDataArr) throws IOException {
|
||||
if (inputStream.available() == 0) {
|
||||
return new DexProfileData[0];
|
||||
}
|
||||
if (i != dexProfileDataArr.length) {
|
||||
throw Encoding.error("Mismatched number of dex files found in metadata");
|
||||
}
|
||||
String[] strArr = new String[i];
|
||||
int[] iArr = new int[i];
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
int readUInt16 = Encoding.readUInt16(inputStream);
|
||||
iArr[i2] = Encoding.readUInt16(inputStream);
|
||||
strArr[i2] = Encoding.readString(inputStream, readUInt16);
|
||||
}
|
||||
for (int i3 = 0; i3 < i; i3++) {
|
||||
DexProfileData dexProfileData = dexProfileDataArr[i3];
|
||||
if (!dexProfileData.dexName.equals(strArr[i3])) {
|
||||
throw Encoding.error("Order of dexfiles in metadata did not match baseline");
|
||||
}
|
||||
dexProfileData.classSetSize = iArr[i3];
|
||||
dexProfileData.classes = readClasses(inputStream, dexProfileData.classSetSize);
|
||||
}
|
||||
return dexProfileDataArr;
|
||||
}
|
||||
|
||||
private static String generateDexKey(String str, String str2, byte[] bArr) {
|
||||
String dexKeySeparator = ProfileVersion.dexKeySeparator(bArr);
|
||||
if (str.length() <= 0) {
|
||||
return enforceSeparator(str2, dexKeySeparator);
|
||||
}
|
||||
if (str2.equals("classes.dex")) {
|
||||
return str;
|
||||
}
|
||||
if (str2.contains("!") || str2.contains(":")) {
|
||||
return enforceSeparator(str2, dexKeySeparator);
|
||||
}
|
||||
if (str2.endsWith(".apk")) {
|
||||
return str2;
|
||||
}
|
||||
return str + ProfileVersion.dexKeySeparator(bArr) + str2;
|
||||
}
|
||||
|
||||
private static String enforceSeparator(String str, String str2) {
|
||||
if ("!".equals(str2)) {
|
||||
return str.replace(":", "!");
|
||||
}
|
||||
return ":".equals(str2) ? str.replace("!", ":") : str;
|
||||
}
|
||||
|
||||
private static String extractKey(String str) {
|
||||
int indexOf = str.indexOf("!");
|
||||
if (indexOf < 0) {
|
||||
indexOf = str.indexOf(":");
|
||||
}
|
||||
return indexOf > 0 ? str.substring(indexOf + 1) : str;
|
||||
}
|
||||
|
||||
private static DexProfileData[] readUncompressedBody(InputStream inputStream, String str, int i) throws IOException {
|
||||
if (inputStream.available() == 0) {
|
||||
return new DexProfileData[0];
|
||||
}
|
||||
DexProfileData[] dexProfileDataArr = new DexProfileData[i];
|
||||
for (int i2 = 0; i2 < i; i2++) {
|
||||
int readUInt16 = Encoding.readUInt16(inputStream);
|
||||
int readUInt162 = Encoding.readUInt16(inputStream);
|
||||
long readUInt32 = Encoding.readUInt32(inputStream);
|
||||
dexProfileDataArr[i2] = new DexProfileData(str, Encoding.readString(inputStream, readUInt16), Encoding.readUInt32(inputStream), 0L, readUInt162, (int) readUInt32, (int) Encoding.readUInt32(inputStream), new int[readUInt162], new TreeMap());
|
||||
}
|
||||
for (int i3 = 0; i3 < i; i3++) {
|
||||
DexProfileData dexProfileData = dexProfileDataArr[i3];
|
||||
readHotMethodRegion(inputStream, dexProfileData);
|
||||
dexProfileData.classes = readClasses(inputStream, dexProfileData.classSetSize);
|
||||
readMethodBitmap(inputStream, dexProfileData);
|
||||
}
|
||||
return dexProfileDataArr;
|
||||
}
|
||||
|
||||
private static void readHotMethodRegion(InputStream inputStream, DexProfileData dexProfileData) throws IOException {
|
||||
int available = inputStream.available() - dexProfileData.hotMethodRegionSize;
|
||||
int i = 0;
|
||||
while (inputStream.available() > available) {
|
||||
i += Encoding.readUInt16(inputStream);
|
||||
dexProfileData.methods.put(Integer.valueOf(i), 1);
|
||||
for (int readUInt16 = Encoding.readUInt16(inputStream); readUInt16 > 0; readUInt16--) {
|
||||
skipInlineCache(inputStream);
|
||||
}
|
||||
}
|
||||
if (inputStream.available() != available) {
|
||||
throw Encoding.error("Read too much data during profile line parse");
|
||||
}
|
||||
}
|
||||
|
||||
private static void skipInlineCache(InputStream inputStream) throws IOException {
|
||||
Encoding.readUInt16(inputStream);
|
||||
int readUInt8 = Encoding.readUInt8(inputStream);
|
||||
if (readUInt8 == 6 || readUInt8 == 7) {
|
||||
return;
|
||||
}
|
||||
while (readUInt8 > 0) {
|
||||
Encoding.readUInt8(inputStream);
|
||||
for (int readUInt82 = Encoding.readUInt8(inputStream); readUInt82 > 0; readUInt82--) {
|
||||
Encoding.readUInt16(inputStream);
|
||||
}
|
||||
readUInt8--;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] readClasses(InputStream inputStream, int i) throws IOException {
|
||||
int[] iArr = new int[i];
|
||||
int i2 = 0;
|
||||
for (int i3 = 0; i3 < i; i3++) {
|
||||
i2 += Encoding.readUInt16(inputStream);
|
||||
iArr[i3] = i2;
|
||||
}
|
||||
return iArr;
|
||||
}
|
||||
|
||||
private static void readMethodBitmap(InputStream inputStream, DexProfileData dexProfileData) throws IOException {
|
||||
BitSet valueOf = BitSet.valueOf(Encoding.read(inputStream, Encoding.bitsToBytes(dexProfileData.numMethodIds * 2)));
|
||||
for (int i = 0; i < dexProfileData.numMethodIds; i++) {
|
||||
int readFlagsFromBitmap = readFlagsFromBitmap(valueOf, i, dexProfileData.numMethodIds);
|
||||
if (readFlagsFromBitmap != 0) {
|
||||
Integer num = dexProfileData.methods.get(Integer.valueOf(i));
|
||||
if (num == null) {
|
||||
num = 0;
|
||||
}
|
||||
dexProfileData.methods.put(Integer.valueOf(i), Integer.valueOf(readFlagsFromBitmap | num.intValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int readFlagsFromBitmap(BitSet bitSet, int i, int i2) {
|
||||
int i3 = bitSet.get(methodFlagBitmapIndex(2, i, i2)) ? 2 : 0;
|
||||
return bitSet.get(methodFlagBitmapIndex(4, i, i2)) ? i3 | 4 : i3;
|
||||
}
|
||||
|
||||
private static int methodFlagBitmapIndex(int i, int i2, int i3) {
|
||||
if (i == 1) {
|
||||
throw Encoding.error("HOT methods are not stored in the bitmap");
|
||||
}
|
||||
if (i == 2) {
|
||||
return i2;
|
||||
}
|
||||
if (i == 4) {
|
||||
return i2 + i3;
|
||||
}
|
||||
throw Encoding.error("Unexpected flag: " + i);
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import androidx.concurrent.futures.ResolvableFuture;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Objects;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public final class ProfileVerifier {
|
||||
private static final String CUR_PROFILES_BASE_DIR = "/data/misc/profiles/cur/0/";
|
||||
private static final String PROFILE_FILE_NAME = "primary.prof";
|
||||
private static final String PROFILE_INSTALLED_CACHE_FILE_NAME = "profileInstalled";
|
||||
private static final String REF_PROFILES_BASE_DIR = "/data/misc/profiles/ref/";
|
||||
private static final String TAG = "ProfileVerifier";
|
||||
private static final ResolvableFuture<CompilationStatus> sFuture = ResolvableFuture.create();
|
||||
private static final Object SYNC_OBJ = new Object();
|
||||
private static CompilationStatus sCompilationStatus = null;
|
||||
|
||||
public static ListenableFuture<CompilationStatus> getCompilationStatusAsync() {
|
||||
return sFuture;
|
||||
}
|
||||
|
||||
private ProfileVerifier() {
|
||||
}
|
||||
|
||||
public static CompilationStatus writeProfileVerification(Context context) {
|
||||
return writeProfileVerification(context, false);
|
||||
}
|
||||
|
||||
/* JADX WARN: Can't wrap try/catch for region: R(20:14|(1:78)(1:18)|19|(1:77)(1:23)|24|25|26|(2:63|64)(1:28)|29|(8:36|(1:40)|(1:47)|48|(2:55|56)|52|53|54)|(1:62)|(1:40)|(3:42|45|47)|48|(1:50)|55|56|52|53|54) */
|
||||
/* JADX WARN: Code restructure failed: missing block: B:58:0x00cf, code lost:
|
||||
|
||||
r3 = androidx.profileinstaller.ProfileVerifier.CompilationStatus.RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE;
|
||||
*/
|
||||
/* JADX WARN: Code restructure failed: missing block: B:60:0x00a0, code lost:
|
||||
|
||||
r3 = 1;
|
||||
*/
|
||||
/*
|
||||
Code decompiled incorrectly, please refer to instructions dump.
|
||||
To view partially-correct add '--show-bad-code' argument
|
||||
*/
|
||||
static androidx.profileinstaller.ProfileVerifier.CompilationStatus writeProfileVerification(android.content.Context r18, boolean r19) {
|
||||
/*
|
||||
Method dump skipped, instructions count: 234
|
||||
To view this dump add '--comments-level debug' option
|
||||
*/
|
||||
throw new UnsupportedOperationException("Method not decompiled: androidx.profileinstaller.ProfileVerifier.writeProfileVerification(android.content.Context, boolean):androidx.profileinstaller.ProfileVerifier$CompilationStatus");
|
||||
}
|
||||
|
||||
private static CompilationStatus setCompilationStatus(int i, boolean z, boolean z2) {
|
||||
CompilationStatus compilationStatus = new CompilationStatus(i, z, z2);
|
||||
sCompilationStatus = compilationStatus;
|
||||
sFuture.set(compilationStatus);
|
||||
return sCompilationStatus;
|
||||
}
|
||||
|
||||
private static long getPackageLastUpdateTime(Context context) throws PackageManager.NameNotFoundException {
|
||||
PackageManager packageManager = context.getApplicationContext().getPackageManager();
|
||||
if (Build.VERSION.SDK_INT >= 33) {
|
||||
return Api33Impl.getPackageInfo(packageManager, context).lastUpdateTime;
|
||||
}
|
||||
return packageManager.getPackageInfo(context.getPackageName(), 0).lastUpdateTime;
|
||||
}
|
||||
|
||||
static class Cache {
|
||||
private static final int SCHEMA = 1;
|
||||
final long mInstalledCurrentProfileSize;
|
||||
final long mPackageLastUpdateTime;
|
||||
final int mResultCode;
|
||||
final int mSchema;
|
||||
|
||||
Cache(int i, int i2, long j, long j2) {
|
||||
this.mSchema = i;
|
||||
this.mResultCode = i2;
|
||||
this.mPackageLastUpdateTime = j;
|
||||
this.mInstalledCurrentProfileSize = j2;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null || !(obj instanceof Cache)) {
|
||||
return false;
|
||||
}
|
||||
Cache cache = (Cache) obj;
|
||||
return this.mResultCode == cache.mResultCode && this.mPackageLastUpdateTime == cache.mPackageLastUpdateTime && this.mSchema == cache.mSchema && this.mInstalledCurrentProfileSize == cache.mInstalledCurrentProfileSize;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(Integer.valueOf(this.mResultCode), Long.valueOf(this.mPackageLastUpdateTime), Integer.valueOf(this.mSchema), Long.valueOf(this.mInstalledCurrentProfileSize));
|
||||
}
|
||||
|
||||
void writeOnFile(File file) throws IOException {
|
||||
file.delete();
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(file));
|
||||
try {
|
||||
dataOutputStream.writeInt(this.mSchema);
|
||||
dataOutputStream.writeInt(this.mResultCode);
|
||||
dataOutputStream.writeLong(this.mPackageLastUpdateTime);
|
||||
dataOutputStream.writeLong(this.mInstalledCurrentProfileSize);
|
||||
dataOutputStream.close();
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
dataOutputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
|
||||
static Cache readFromFile(File file) throws IOException {
|
||||
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
|
||||
try {
|
||||
Cache cache = new Cache(dataInputStream.readInt(), dataInputStream.readInt(), dataInputStream.readLong(), dataInputStream.readLong());
|
||||
dataInputStream.close();
|
||||
return cache;
|
||||
} catch (Throwable th) {
|
||||
try {
|
||||
dataInputStream.close();
|
||||
} catch (Throwable th2) {
|
||||
th.addSuppressed(th2);
|
||||
}
|
||||
throw th;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompilationStatus {
|
||||
public static final int RESULT_CODE_COMPILED_WITH_PROFILE = 1;
|
||||
public static final int RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING = 3;
|
||||
public static final int RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ = 131072;
|
||||
public static final int RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE = 196608;
|
||||
private static final int RESULT_CODE_ERROR_CODE_BIT_SHIFT = 16;
|
||||
public static final int RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST = 65536;
|
||||
public static final int RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION = 262144;
|
||||
public static final int RESULT_CODE_NO_PROFILE = 0;
|
||||
public static final int RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION = 2;
|
||||
private final boolean mHasCurrentProfile;
|
||||
private final boolean mHasReferenceProfile;
|
||||
final int mResultCode;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface ResultCode {
|
||||
}
|
||||
|
||||
public int getProfileInstallResultCode() {
|
||||
return this.mResultCode;
|
||||
}
|
||||
|
||||
public boolean hasProfileEnqueuedForCompilation() {
|
||||
return this.mHasCurrentProfile;
|
||||
}
|
||||
|
||||
public boolean isCompiledWithProfile() {
|
||||
return this.mHasReferenceProfile;
|
||||
}
|
||||
|
||||
CompilationStatus(int i, boolean z, boolean z2) {
|
||||
this.mResultCode = i;
|
||||
this.mHasCurrentProfile = z2;
|
||||
this.mHasReferenceProfile = z;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Api33Impl {
|
||||
private Api33Impl() {
|
||||
}
|
||||
|
||||
static PackageInfo getPackageInfo(PackageManager packageManager, Context context) throws PackageManager.NameNotFoundException {
|
||||
return packageManager.getPackageInfo(context.getPackageName(), PackageManager.PackageInfoFlags.of(0L));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public class ProfileVersion {
|
||||
public static final int MAX_SUPPORTED_SDK = 33;
|
||||
public static final int MIN_SUPPORTED_SDK = 24;
|
||||
static final byte[] V015_S = {48, 49, 53, 0};
|
||||
static final byte[] V010_P = {48, 49, 48, 0};
|
||||
static final byte[] V009_O_MR1 = {48, 48, 57, 0};
|
||||
static final byte[] V005_O = {48, 48, 53, 0};
|
||||
static final byte[] V001_N = {48, 48, 49, 0};
|
||||
static final byte[] METADATA_V001_N = {48, 48, 49, 0};
|
||||
static final byte[] METADATA_V002 = {48, 48, 50, 0};
|
||||
|
||||
private ProfileVersion() {
|
||||
}
|
||||
|
||||
static String dexKeySeparator(byte[] bArr) {
|
||||
return (Arrays.equals(bArr, V001_N) || Arrays.equals(bArr, V005_O)) ? ":" : "!";
|
||||
}
|
||||
}
|
7
02-Easy5/E5/sources/androidx/profileinstaller/R.java
Normal file
7
02-Easy5/E5/sources/androidx/profileinstaller/R.java
Normal file
@ -0,0 +1,7 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
public final class R {
|
||||
private R() {
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package androidx.profileinstaller;
|
||||
|
||||
/* loaded from: classes.dex */
|
||||
class WritableFileSection {
|
||||
final byte[] mContents;
|
||||
final int mExpectedInflateSize;
|
||||
final boolean mNeedsCompression;
|
||||
final FileSectionType mType;
|
||||
|
||||
WritableFileSection(FileSectionType fileSectionType, int i, byte[] bArr, boolean z) {
|
||||
this.mType = fileSectionType;
|
||||
this.mExpectedInflateSize = i;
|
||||
this.mContents = bArr;
|
||||
this.mNeedsCompression = z;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user