Skip to content

Commit

Permalink
Merge pull request #20 from MindscapeHQ/sean/portable-pdb-support
Browse files Browse the repository at this point in the history
Portable PDB + Offline Store Support
  • Loading branch information
xenolightning authored Jun 18, 2024
2 parents fff1a1d + 6958ecc commit 1e67193
Show file tree
Hide file tree
Showing 9 changed files with 728 additions and 25 deletions.
8 changes: 8 additions & 0 deletions CHANGE-LOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Full Change Log for Raygun4Maui package

### v2.1.1
- Version bump to `Raygun4Net.NetCore v11.0.1`
- This marks the synchronous `Send()` methods as `Obsolete` which can cause deadlocks in MAUI if sending on the UI Thread
- Added support for reading PDB debug information from Android Assembly Store
- This completes the portable pdb support for MAUI, and Android targets are fully compatible
- Introduce dependency on `K4os.Compression.LZ4@1.3.8` for Android
- This is to support decompression of LZ4 binaries in the Assembly Blob Store

### v2.1.0
- Version bump to `Raygun4Net.NetCore v11.0.0`
- Added support for capturing debug information for PDB symbolication
Expand Down
85 changes: 85 additions & 0 deletions Raygun4Maui/Platforms/Android/AndroidUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#nullable enable
using System.IO.Compression;
using System.Runtime.InteropServices;
using System.Text;

namespace Raygun4Maui;

internal static class AndroidUtilities
{
/// <summary>
/// Factory method to create the correct assembly reader for the current application
/// </summary>
/// <returns></returns>
public static IAssemblyReader? CreateAssemblyReader()
{
var apkPath = Android.App.Application.Context.ApplicationInfo?.SourceDir;
var supportedAbis = new List<string>();

if (Android.OS.Build.SupportedAbis != null)
{
supportedAbis.AddRange(Android.OS.Build.SupportedAbis);
}

if (!File.Exists(apkPath))
{
// No apk, so return nothing
return null;
}

if (!IsAndroidArchive(apkPath))
{
// Not a valid android archive so nothing to return
return null;
}

// Open the apk file, and see if it has a manifest, if it does,
// we are using the new assembly store method,
// else it's just a normal zip with assemblies as archive entries
using var zipArchive = ZipFile.Open(apkPath, ZipArchiveMode.Read);

if (zipArchive.GetEntry("assemblies/assemblies.manifest") != null)
{
return new AssemblyBlobStoreReader(zipArchive, supportedAbis);
}

return new AssemblyZipEntryReader(zipArchive, supportedAbis);
}

public static bool IsAndroidArchive(string filePath)
{
return filePath.EndsWith(".aab", StringComparison.OrdinalIgnoreCase) ||
filePath.EndsWith(".apk", StringComparison.OrdinalIgnoreCase) ||
filePath.EndsWith(".zip", StringComparison.OrdinalIgnoreCase);
}

public static ReadOnlyMemory<byte> AsReadOnlyMemory(this Stream stream)
{
ArgumentNullException.ThrowIfNull(stream);

using var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return new ReadOnlyMemory<byte>(memoryStream.ToArray());
}

public static byte[] ToArray(this ReadOnlyMemory<byte> memory)
{
if (!MemoryMarshal.TryGetArray(memory, out var segment))
{
throw new InvalidOperationException("Could not get array segment from ReadOnlyMemory.");
}

return segment.Array!;
}

public static BinaryReader GetBinaryReader(this ReadOnlyMemory<byte> memory, Encoding? encoding = null)
{
return new BinaryReader(memory.AsStream(), encoding ?? Encoding.UTF8, false);
}


public static MemoryStream AsStream(this ReadOnlyMemory<byte> memory)
{
return new MemoryStream(memory.ToArray(), writable: false);
}
}
Loading

0 comments on commit 1e67193

Please sign in to comment.