Looks like in this case it was Android libc too, so they actually went out of their way to match glibc semantics.. that or it came from one of the other BSDs, FreeBSD or NetBSD.
Android's reallocarray passes through to the underlying malloc implementation. The behavior comes from jemalloc:
https://github.com/jemalloc/jemalloc/blob/5.2.1/src/jemalloc.c#L2662-L2683…
I think jemalloc chose to copy the non-standards-compliant glibc behavior due to applications depending on it to avoid memory leaks...
In hardened_malloc, I chose to have realloc of size 0 work the same way as malloc of size 0 for standards compliance and much safer handling of bugs leading to this happening. IIRC, the current C standard forbids what glibc is doing but also declares realloc of size 0 deprecated.
Android actually has a test for this as part of the CTS to make sure the glibc/jemalloc behavior is used, and it's one of the intentional test failures in GrapheneOS. So, for example, search for 'realloc' in this 10 month old comparison of CTS results: