Repository: AvaloniaUI/Avalonia
File: src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs (C#)

Code before:
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Android.Runtime;
using Android.Views;
using Avalonia.Platform;

namespace Avalonia.Android.Platform.SkiaPlatform
{
    unsafe class AndroidFramebuffer : ILockedFramebuffer
    {
        private IntPtr _window;

        public AndroidFramebuffer(Surface surface, double scaling)
        {
            if(surface == null)
                throw new ArgumentNullException(nameof(surface));
            _window = ANativeWindow_fromSurface(JNIEnv.Handle, surface.Handle);
            if (_window == IntPtr.Zero)
                throw new Exception("Unable to obtain ANativeWindow");
            ANativeWindow_Buffer buffer;
            var rc = new ARect()
            {
                right = ANativeWindow_getWidth(_window),
                bottom = ANativeWindow_getHeight(_window)
            };
            Size = new PixelSize(rc.right, rc.bottom);
            ANativeWindow_lock(_window, &buffer, &rc);

            Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
                ? PixelFormat.Rgb565 : PixelFormat.Rgba8888;

            RowBytes = buffer.stride * (Format == PixelFormat.Rgb565 ? 2 : 4);
            Address = buffer.bits;

            Dpi = new Vector(96, 96) * scaling;
        }

        public void Dispose()
        {
            ANativeWindow_unlockAndPost(_window);

Review comment (suggestion):
`InvalidationAwareSurfaceView.HandleDescriptor` should return `ANativeWindow` instead of `SurfaceView` to make it consistent with the actual handle content. But it is technically a silent breaking change.

Code after:
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Avalonia.Platform;

namespace Avalonia.Android.Platform.SkiaPlatform
{
    unsafe class AndroidFramebuffer : ILockedFramebuffer
    {
        private IntPtr _window;

        public AndroidFramebuffer(InvalidationAwareSurfaceView surface, double scaling)
        {
            if(surface == null)
                throw new ArgumentNullException(nameof(surface));
            _window = (surface as IPlatformHandle).Handle;
            if (_window == IntPtr.Zero)
                throw new Exception("Unable to obtain ANativeWindow");
            ANativeWindow_Buffer buffer;
            var rc = new ARect()
            {
                right = ANativeWindow_getWidth(_window),
                bottom = ANativeWindow_getHeight(_window)
            };
            Size = new PixelSize(rc.right, rc.bottom);
            ANativeWindow_lock(_window, &buffer, &rc);

            Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
                ? PixelFormat.Rgb565 : PixelFormat.Rgba8888;

            RowBytes = buffer.stride * (Format == PixelFormat.Rgb565 ? 2 : 4);
            Address = buffer.bits;

            Dpi = new Vector(96, 96) * scaling;
        }

        public void Dispose()
        {
            ANativeWindow_unlockAndPost(_window);
            _window = IntPtr.Zero;
            Address = IntPtr.Zero;