Skip to content
Prev Previous commit
Next Next commit
Read assembly from device specific APKs when AndroidUseAssemblyStore …
…is false
  • Loading branch information
jamescrosswell committed May 29, 2025
commit e4faacda79c3fd40ec1febf635bf253e2c9eaf3f
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public AndroidAssemblyDirectoryReaderV2(string apkPath, IList<string> supportedA
logger?.Invoke("Adding {0} to supported architectures for Directory Reader", abi);
SupportedArchitectures.Add(abi.AbiToDeviceArchitecture());
}
_archiveAssemblyHelper = new ArchiveAssemblyHelper(apkPath, logger);
_archiveAssemblyHelper = new ArchiveAssemblyHelper(apkPath, logger, supportedAbis);
}

public PEReader? TryReadAssembly(string name)
Expand Down Expand Up @@ -59,8 +59,9 @@ internal class ArchiveAssemblyHelper

private readonly string _archivePath;
private readonly DebugLogger? _logger;
private readonly IList<string> _supportedAbis;

public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger)
public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger, IList<string> supportedAbis)
{
if (string.IsNullOrEmpty(archivePath))
{
Expand All @@ -69,6 +70,7 @@ public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger)

_archivePath = archivePath;
_logger = logger;
_supportedAbis = supportedAbis;
}

public MemoryStream? ReadEntry(string path, AndroidTargetArch arch = AndroidTargetArch.None, bool uncompressIfNecessary = false)
Expand Down Expand Up @@ -144,21 +146,48 @@ public ArchiveAssemblyHelper(string archivePath, DebugLogger? logger)
return null;
}

using var zip = ZipFile.OpenRead(_archivePath);
foreach (var assemblyPath in potentialEntries)
// First we check the base.apk
if (ReadEntryFromApk(_archivePath) is {} baseEntry)
{
if (zip.GetEntry(assemblyPath) is not { } entry)
_logger?.Invoke("Found entry '{0}' in base archive '{1}'", path, _archivePath);
return baseEntry;
}

// Otherwise check in the device specific APKs
foreach (var supportedAbi in _supportedAbis)
{
var splitFilePath = _archivePath.GetArchivePathForAbi(supportedAbi, _logger);
if (!File.Exists(splitFilePath))
{
_logger?.Invoke("No entry found for path '{0}' in archive '{1}'", assemblyPath, _archivePath);
continue;
_logger?.Invoke("No split config detected at: '{0}'", splitFilePath);
}
else if (ReadEntryFromApk(splitFilePath) is { } splitEntry)
{
return splitEntry;
}

var ret = entry.Extract();
ret.Flush();
return ret;
}

// Finally admit defeat
return null;

MemoryStream? ReadEntryFromApk(string archivePath)
{
using var zip = ZipFile.OpenRead(archivePath);
foreach (var assemblyPath in potentialEntries)
{
if (zip.GetEntry(assemblyPath) is not { } entry)
{
_logger?.Invoke("No entry found for path '{0}' in archive '{1}'", assemblyPath, archivePath);
continue;
}

var ret = entry.Extract();
ret.Flush();
return ret;
}

return null;
}
}

/// <summary>
Expand Down
12 changes: 0 additions & 12 deletions src/Sentry.Android.AssemblyReader/V2/MonoAndroidHelper.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,6 @@ public static string MakeZipArchivePath(string part1, ICollection<string>? pathP
public const string MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER = "lib-";
public const string SATELLITE_CULTURE_END_MARKER_CHAR = "_";

/// <summary>
/// When an AAB file is deployed, the APK is split into multiple APKs so our modules can end up in a companion
/// architecture specific APK like split_config.arm64_v8a.apk. This method returns the path to that split_config APK
/// if it exists... otherwise we just return the original archive path.
/// </summary>
internal static string GetArchivePathForArchitecture(this string archivePath, AndroidTargetArch arch, DebugLogger? logger)
{
return ArchToAbiMap.TryGetValue(arch, out var abi)
? GetArchivePathForAbi(archivePath, abi, logger)
: archivePath;
}

/// <summary>
/// When an AAB file is deployed, the APK is split into multiple APKs so our modules can end up in a companion
/// architecture specific APK like split_config.arm64_v8a.apk. This method returns the path to that split_config APK
Expand Down
Loading