Merge "Reuse a same buffer per session instead of reallocating each time." into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ccf6f21ad8
@@ -171,39 +171,53 @@ public final class PackageUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #computeSha256DigestForLargeFile(String, String)
|
||||
* Creates a fixed size buffer based on whether the device is low ram or not. This is to be used
|
||||
* with the {@link #computeSha256DigestForLargeFile(String, byte[])} and
|
||||
* {@link #computeSha256DigestForLargeFile(String, byte[], String)} methods.
|
||||
* @return a byte array of size {@link #LOW_RAM_BUFFER_SIZE_BYTES} if the device is a low RAM
|
||||
* device, otherwise a byte array of size {@link #HIGH_RAM_BUFFER_SIZE_BYTES}
|
||||
*/
|
||||
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath) {
|
||||
return computeSha256DigestForLargeFile(filePath, null);
|
||||
public static @NonNull byte[] createLargeFileBuffer() {
|
||||
int bufferSize = ActivityManager.isLowRamDeviceStatic()
|
||||
? LOW_RAM_BUFFER_SIZE_BYTES : HIGH_RAM_BUFFER_SIZE_BYTES;
|
||||
return new byte[bufferSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the SHA256 digest of large files.
|
||||
* @param filePath The path to which the file's content is to be hashed.
|
||||
* @param separator Separator between each pair of characters, such as colon, or null to omit.
|
||||
* @return The digest or null if an error occurs.
|
||||
* @see #computeSha256DigestForLargeFile(String, byte[], String)
|
||||
*/
|
||||
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
|
||||
@Nullable String separator) {
|
||||
@NonNull byte[] fileBuffer) {
|
||||
return computeSha256DigestForLargeFile(filePath, fileBuffer, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the SHA256 digest of large files. This is typically useful for large APEXs.
|
||||
* @param filePath The path to which the file's content is to be hashed.
|
||||
* @param fileBuffer A buffer to read file's content into memory. It is strongly recommended to
|
||||
* make use of the {@link #createLargeFileBuffer()} method to create this
|
||||
* buffer.
|
||||
* @param separator Separator between each pair of characters, such as colon, or null to omit.
|
||||
* @return The SHA256 digest or null if an error occurs.
|
||||
*/
|
||||
public static @Nullable String computeSha256DigestForLargeFile(@NonNull String filePath,
|
||||
@NonNull byte[] fileBuffer, @Nullable String separator) {
|
||||
MessageDigest messageDigest;
|
||||
try {
|
||||
messageDigest = MessageDigest.getInstance("SHA256");
|
||||
messageDigest.reset();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// this shouldn't happen!
|
||||
// this really shouldn't happen!
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
|
||||
int bufferSize = isLowRamDevice ? LOW_RAM_BUFFER_SIZE_BYTES : HIGH_RAM_BUFFER_SIZE_BYTES;
|
||||
|
||||
File f = new File(filePath);
|
||||
try {
|
||||
DigestInputStream digestStream = new DigestInputStream(new FileInputStream(f),
|
||||
DigestInputStream digestInputStream = new DigestInputStream(new FileInputStream(f),
|
||||
messageDigest);
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
while (digestStream.read(buffer) != -1);
|
||||
while (digestInputStream.read(fileBuffer) != -1);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -500,6 +500,7 @@ public class BinaryTransparencyService extends SystemService {
|
||||
// ones appearing out of the blue. Thus, we're going to only go through our cache to check
|
||||
// for changes, rather than freshly invoking `getInstalledPackages()` and
|
||||
// `getInstalledModules()`
|
||||
byte[] largeFileBuffer = PackageUtils.createLargeFileBuffer();
|
||||
for (Map.Entry<String, Long> entry : mBinaryLastUpdateTimes.entrySet()) {
|
||||
String packageName = entry.getKey();
|
||||
try {
|
||||
@@ -513,7 +514,7 @@ public class BinaryTransparencyService extends SystemService {
|
||||
|
||||
// compute the digest for the updated package
|
||||
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(
|
||||
packageInfo.applicationInfo.sourceDir);
|
||||
packageInfo.applicationInfo.sourceDir, largeFileBuffer);
|
||||
if (sha256digest == null) {
|
||||
Slog.e(TAG, "Failed to compute SHA256sum for file at "
|
||||
+ packageInfo.applicationInfo.sourceDir);
|
||||
@@ -545,11 +546,13 @@ public class BinaryTransparencyService extends SystemService {
|
||||
// In general, we care about all APEXs, *and* all Modules, which may include some APKs.
|
||||
|
||||
// First, we deal with all installed APEXs.
|
||||
byte[] largeFileBuffer = PackageUtils.createLargeFileBuffer();
|
||||
for (PackageInfo packageInfo : getInstalledApexs()) {
|
||||
ApplicationInfo appInfo = packageInfo.applicationInfo;
|
||||
|
||||
// compute SHA256 for these APEXs
|
||||
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(appInfo.sourceDir);
|
||||
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(appInfo.sourceDir,
|
||||
largeFileBuffer);
|
||||
if (sha256digest == null) {
|
||||
Slog.e(TAG, String.format("Failed to compute SHA256 digest for %s",
|
||||
packageInfo.packageName));
|
||||
@@ -585,7 +588,7 @@ public class BinaryTransparencyService extends SystemService {
|
||||
|
||||
// compute SHA256 digest for these modules
|
||||
String sha256digest = PackageUtils.computeSha256DigestForLargeFile(
|
||||
appInfo.sourceDir);
|
||||
appInfo.sourceDir, largeFileBuffer);
|
||||
if (sha256digest == null) {
|
||||
Slog.e(TAG, String.format("Failed to compute SHA256 digest for %s",
|
||||
packageName));
|
||||
|
||||
Reference in New Issue
Block a user