Files
AdvDebug-Brovan/Brovan/Android/AndroidNative.cs
T
AdvDebug dbcbc5084a Add Android host support (arm64, GDI, Vulkan)
Brovan now runs on Android as a third host alongside Windows and Linux.

New Brovan android embedding layer. The emulator becomes a NativeAOT shared
library driven by a host app rather than a process with a Main:

- BrovanAndroidApi - exported C ABI (init, surface, start, input injection,
  window enumeration, debugger commands).
- AndroidWinManager - IDisplayConnection over ANativeWindow, plus
  IGdiRenderSupport.
- AndroidGdiSurface - software rasteriser (lines, rects, ellipses, polygons)
  into a per-guest-window backbuffer posted via ANativeWindow_lock/
  unlockAndPost, white background.
- AndroidVulkanWsi and a generator branch - VK_KHR_android_surface instead of
  Win32/Xcb.
- AndroidInput, AndroidLog, AndroidHost, AndroidGuestWindows, JNI shim, Java
  bindings.
- Launcher app: Material 3 library, in-app program import via SAF, settings,
  on-screen joystick/D-pad/touchpad controls, opt-in developer console wired to
  the debugger.
- build-apk.sh - Unicorn cross-build, linux-bionic-arm64 publish, bundled
  OpenSSL, APK assembly.

Changes to shared emulator code:

- Case-insensitive shipped-DLL resolution in GetWindowsLibPath. Import tables
  say KERNEL32.dll, System32 ships kernel32.dll; broken on any case-sensitive
  host, and it surfaced as a guest loading zero modules.
- GlobalPropertiesToRemove on the generator ProjectReference. Target-shaped
  properties leaked into the analyzer, csc silently refused to load it (CS8034
  is only a warning), and every source generator emitted nothing.
- GdiPrimitive.Hwnd. The four EnqueueGdi* helpers already had the guest HWND and
  dropped it, making per-window compositing impossible.
- Program.SplitCommandLine widened to internal for embedders.
Windows and Linux behaviour is unchanged; the new paths are gated on the RID or
!IsWindows.
2026-08-02 19:10:51 +03:00

67 lines
2.7 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace Brovan.Android
{
internal static partial class AndroidNative
{
public const int LogInfo = 4;
public const int LogWarn = 5;
public const int LogError = 6;
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_acquire")]
public static partial void NativeWindowAcquire(IntPtr window);
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_release")]
public static partial void NativeWindowRelease(IntPtr window);
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_getWidth")]
public static partial int NativeWindowGetWidth(IntPtr window);
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_getHeight")]
public static partial int NativeWindowGetHeight(IntPtr window);
public const int WindowFormatRgba8888 = 1;
[StructLayout(LayoutKind.Sequential)]
public struct NativeWindowBuffer
{
public int Width;
public int Height;
public int Stride;
public int Format;
public IntPtr Bits;
public uint Reserved0;
public uint Reserved1;
public uint Reserved2;
public uint Reserved3;
public uint Reserved4;
public uint Reserved5;
}
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_setBuffersGeometry")]
public static partial int NativeWindowSetBuffersGeometry(IntPtr window, int width, int height, int format);
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_lock")]
public static unsafe partial int NativeWindowLock(IntPtr window, NativeWindowBuffer* buffer, IntPtr dirtyBounds);
[LibraryImport("libandroid.so", EntryPoint = "ANativeWindow_unlockAndPost")]
public static partial int NativeWindowUnlockAndPost(IntPtr window);
[LibraryImport("liblog.so", EntryPoint = "__android_log_write", StringMarshalling = StringMarshalling.Utf8)]
public static partial int LogWrite(int priority, string tag, string text);
[LibraryImport("libc", EntryPoint = "pipe", SetLastError = true)]
public static unsafe partial int Pipe(int* fds);
[LibraryImport("libc", EntryPoint = "dup2", SetLastError = true)]
public static partial int Dup2(int oldFd, int newFd);
[LibraryImport("libc", EntryPoint = "realpath", SetLastError = true, StringMarshalling = StringMarshalling.Utf8)]
public static partial IntPtr RealPath(string path, IntPtr resolved);
[LibraryImport("libc", EntryPoint = "free")]
public static partial void Free(IntPtr pointer);
}
}