Skip to content

Native AA again, more small things from issues#328

Closed
andreknieriem wants to merge 12 commits intomainfrom
native-aa-new
Closed

Native AA again, more small things from issues#328
andreknieriem wants to merge 12 commits intomainfrom
native-aa-new

Conversation

@andreknieriem
Copy link
Copy Markdown
Owner

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a 'Native Android Auto' wireless mode, implementing the official Bluetooth handshake protocol for seamless phone discovery. Key additions include the NativeAaHandshakeManager for RFCOMM server management, updated WiFi Direct logic to exchange credentials, and a new WirelessConnectionFragment for configuration. The feedback highlights several critical issues, including undefined variables (msgType) in AapMessageHandlerType, compilation errors in NativeAaHandshakeManager due to missing Short conversions, and potential crashes from malformed MAC addresses or null network interfaces. Additionally, improvements are suggested for coroutine dispatcher usage and Android 8.0+ service compatibility.

.setStatus(0)
.build()
sendProtobuf(output, request.toByteArray(), 1)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Kotlin does not perform implicit narrowing conversions from Int to Short. Since sendProtobuf expects a Short for the type parameter, passing 1 (an Int) will cause a compilation error.

        sendProtobuf(output, request.toByteArray(), 1.toShort())

.setAccessPointType(Wireless.AccessPointType.STATIC)
.build()
sendProtobuf(output, response.toByteArray(), 3)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Passing an Int literal where a Short is expected will result in a compilation error in Kotlin. Please cast the type ID to Short.

        sendProtobuf(output, response.toByteArray(), 3.toShort())

delay(2000) // Give the servers time to start

val devicesToPoke = if (lastMac.isNotEmpty()) {
listOf(adapter.getRemoteDevice(lastMac))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

BluetoothAdapter.getRemoteDevice() throws an IllegalArgumentException if the MAC address string is malformed. Since lastMac comes from persistent settings, it should be validated or the call should be wrapped in a try-catch block to prevent application crashes.

Suggested change
listOf(adapter.getRemoteDevice(lastMac))
try { listOf(adapter.getRemoteDevice(lastMac)) } catch (e: IllegalArgumentException) { emptyList() }

}
// Fallback pass: return any valid IPv4 that isn't loopback
val interfaces2 = java.net.NetworkInterface.getNetworkInterfaces()
while (interfaces2.hasMoreElements()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the MAC retrieval method, getNetworkInterfaces() should be checked for null before use to avoid potential crashes.

            val interfaces2 = java.net.NetworkInterface.getNetworkInterfaces() ?: return null

val clientSocket = serverSocket?.accept() ?: break
AppLog.i("Wireless client connected: ${clientSocket.inetAddress}")
AppLog.i("WirelessServer: Incoming connection detected from ${clientSocket.inetAddress}")
serviceScope.launch {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

serviceScope.launch without a specified dispatcher defaults to Dispatchers.Main (assuming the scope was initialized for the UI thread). commManager.connect(clientSocket) performs blocking network I/O and should be executed on Dispatchers.IO to avoid blocking the main thread.

Suggested change
serviceScope.launch {
serviceScope.launch(Dispatchers.IO) {

scope.launch(Dispatchers.IO) {
try {
val buf = ByteArray(1024)
socket.inputStream.read(buf)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This read() call on the Bluetooth socket's input stream is blocking and does not have a timeout. If the remote device connects but never sends data, this coroutine will hang indefinitely. Consider setting a timeout or using a non-blocking approach.

Comment on lines 824 to +828
Thread {
AppLog.i("AapService: Auto-enabling hotspot...")
HotspotManager.setHotspotEnabled(this, true)
}.start()
} else {
val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as android.net.wifi.WifiManager
if (wifiManager.isWifiEnabled) {
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid creating raw Thread objects. Since serviceScope is available, use serviceScope.launch(Dispatchers.IO) to perform background operations. This ensures better resource management and integration with the service lifecycle.

            if ((mode == 1 || mode == 2) && settings.autoEnableHotspot) {
                serviceScope.launch(Dispatchers.IO) {
                    AppLog.i("AapService: Auto-enabling hotspot...")
                    HotspotManager.setHotspotEnabled(this@AapService, true)
                }
            }

AapService.ACTION_START_WIRELESS else AapService.ACTION_STOP_WIRELESS
}
requireContext().startService(intent)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using startService() directly can lead to IllegalStateException on Android 8.0+ if the app is in the background. Since AapService is a foreground service, use ContextCompat.startForegroundService() to ensure compatibility.

            androidx.core.content.ContextCompat.startForegroundService(requireContext(), intent)

@andreknieriem andreknieriem changed the title Native aa new Native AA again, more small things from issues Mar 31, 2026
@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 1, 2026

I ran the test here and the connection starts, Android Auto appears on the head unit, but seconds later the connection is disconnected and the screen displays:

Android Auto disconnected: If using wireless AA, disable Switch between networks or Network acceleration in phone WiFi settings

I disabled this option in the phone settings, but the connection keeps dropping.

HUR_Log_20260401_100458.txt

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 1, 2026

While talking to Gemini, I informed her that the connection happens, but it drops after 10 to 20 seconds.

She analyzed the code and found a detail: the time the connection ends is precisely the time you defined to terminate the Bluetooth socket.

I changed the code from (NativeAaHandshakeManager.kt)

AppLog.i("NativeAA: Keeping Bluetooth socket alive for 20s to allow WiFi transition...")
                
                // Keep the socket open for 20 seconds so the phone feels "stable" 
                // during the WiFi switch
                delay(20000)

to

AppLog.i("NativeAA: Handshake completed! Keeping Bluetooth socket alive indefinitely...")
                
                // Instead of closing after 20 seconds, keep the socket open indefinitely.
               while (isRunning && isActive) {
                    delay(1000)
                }

And after this change, the connection became stable; it starts and doesn't drop anymore.

HUR_Log_20260401_120221.txt

@andreknieriem
Copy link
Copy Markdown
Owner Author

Uhh good find. So Bluetooth Socket must be enabled. I will add this and try it myself. I only have a real bad chinese test tablet which allows this type pf bluetooth and I thought it is the device. Thank you!

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 1, 2026

I tested it without much hope on my Chinese head unit because it runs that very restrictive ROM.

I was surprised when it worked (even if only for a few seconds).

I tested it using a Galaxy S8+ as if it were a head unit and the same thing happened, working for a few seconds.

Both devices are completely different, but they worked the same way, only for a few seconds. So I investigated why the connection was dropping, and after long conversations with Gemini, I arrived at this part of the code.

It's perfect now, I no longer need the Wireless Helper installed, the connection is much faster. I tested it several times and it worked perfectly every time.

apk https://thiagosabaia.net/downloads/nativeaa_2.2.0-beta1_debug.apk

@andreknieriem
Copy link
Copy Markdown
Owner Author

This is so awesome! The Wifi Helper is only for those, where the bluetooth does not work this way. But I really hope it will help many people :)

@adc103
Copy link
Copy Markdown

adc103 commented Apr 2, 2026

I tested the above APK and it does natively initiate connection now without the helper app which is going to be an amazing improvement! However, I could not get a stable connection to happen between my devices. I would always see the android auto is starting message and my head unit would immedielty restart itself and begin booting. Below are my logs!

HUR_Log_20260401_173101[1].txt

@adc103
Copy link
Copy Markdown

adc103 commented Apr 2, 2026

Also for clarity, I have been using WiFi direct connection with success over the last few weeks

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 2, 2026

I tested the above APK and it does natively initiate connection now without the helper app which is going to be an amazing improvement! However, I could not get a stable connection to happen between my devices. I would always see the android auto is starting message and my head unit would immedielty restart itself and begin booting. Below are my logs!

HUR_Log_20260401_173101[1].txt

Try this version here; it's without the code I mentioned above.

https://thiagosabaia.net/downloads/nativeaaoriginal_2.2.0-beta1_debug.apk

@adc103
Copy link
Copy Markdown

adc103 commented Apr 2, 2026

Hmmm I actually am having much worse behaviour at this point.

After uninstalling that version and reinstalling the other it won't even attempt to connect like before, the phone simply shows it is attempting to connect to wirless android auto when connected via bluetooth. I then reinstalled the one that atleast attempted and nothing. I tried wiping bluetooth pairing, wiped previous connected vehicle in android auto and wiped previous wifi direct on both sides.

It is worth noting, even when the Headunit Revived app is uninstalled the phone still sees the headunit as wireless android auto when connected via bluetooth. Could the inital install have set any unique identifiers that need to be set again/updated on the new install?

Here are the logs on the new install

HUR_Log_20260401_204208[1].txt

@adc103
Copy link
Copy Markdown

adc103 commented Apr 2, 2026

After some additional testing, on this second install it seems the issue spawns from the phone not connecting to the wifi being output by the headunit. I was unable to resolve this by reinstalling headunit revived or by forgetting/removing all connection history (wifi/wifi-direct/android auto vehicles).

So, all in all, here was my testing:

On my first install the devices successfully paired and would attempt to connect to eachother causing the headunit to crash and reboot. The logs do not provide too much info, just the NsdManager losing channel and the sensorsrvice dying. I can only assume this is related to MediaTek issues?

On all subsequent installs, I was unable to get the phone to pair correctly to the headunit to do further testing.

@andreknieriem
Copy link
Copy Markdown
Owner Author

Thank you very much for your testing. This is a highly experimental feature and not even a beta release. I will add the fix from @tsabaia soon and after that I may release this beta and hopefully some user come up with a log or a great idea or asks AI the right questions :D I did use the help of AI to reverse engineer it. So there can be some trouble.

@adc103
Copy link
Copy Markdown

adc103 commented Apr 2, 2026

No worries! I will be following closely and happy to do some more testing along the way.

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 2, 2026

Hmmm I actually am having much worse behaviour at this point.

After uninstalling that version and reinstalling the other it won't even attempt to connect like before, the phone simply shows it is attempting to connect to wirless android auto when connected via bluetooth. I then reinstalled the one that atleast attempted and nothing. I tried wiping bluetooth pairing, wiped previous connected vehicle in android auto and wiped previous wifi direct on both sides.

It is worth noting, even when the Headunit Revived app is uninstalled the phone still sees the headunit as wireless android auto when connected via bluetooth. Could the inital install have set any unique identifiers that need to be set again/updated on the new install?

Here are the logs on the new install

HUR_Log_20260401_204208[1].txt

In this second log, the following line appears:

AapService: Initializing WiFi Mode: 1

This line means that the application is trying to initialize in normal mode instead of native mode. Another indication is that nowhere in the log is there a call to the UUID, which is fundamental for native Android Auto.


Access the HURev settings and change to Native Android Auto.

If Native Android Auto is already selected, change to any other mode, save, restart the app, then open it and switch back to Native Android Auto.

@hectorlf
Copy link
Copy Markdown

hectorlf commented Apr 2, 2026

Today I took @tsabaia's APK for a test in my car radio replacement, which is a chinese tablet with some extra cables and plastic parts, and got an error that I didn't expect: "Your device's Bluetooth stack does not support the required service registration for native Android Auto Wireless".

This is weird to me because the tablet comes with some pre-installed software (most of it pirated, I assume), and it has a copy of an app called Car Link 2.0 which provides wireless AA using a bluetooth handshake like this pull request.

Unfortunately, my Pixel 9a crashes with Car Link after some minutes while HURev works perfectly fine, which makes this error extra frustrating.

Would the logs from my unit help in any way or is that a lost cause?

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 3, 2026

Many Chinese multimedia systems have a separate Bluetooth chip controlled by the MCU, unlike a cell phone or tablet where it's integrated into the processor. This is why Bluetooth doesn't appear in Android settings; a specific app is needed to connect via Bluetooth.

Depending on how the ROM was developed, user-level applications may not have full control over the Bluetooth chip, which is why HURev cannot function in native mode on these devices.

Apps like TLink, Zlink, Car Link, etc., have root access because they are already integrated into the system.

The native Android Auto feature of HURev will only support a small percentage of devices due to these limitations of Chinese multimedia systems.

@andreknieriem
Copy link
Copy Markdown
Owner Author

This is weird to me because the tablet comes with some pre-installed software (most of it pirated, I assume), and it has a copy of an app called Car Link 2.0 which provides wireless AA using a bluetooth handshake like this pull request.

Unfortunately, my Pixel 9a crashes with Car Link after some minutes while HURev works perfectly fine, which makes this error extra frustrating.

Would the logs from my unit help in any way or is that a lost cause?

This is really interesting. I thought it worked or not. I maybe remove the check or just send a Warning and it may work.
New APK is on the way.

@andreknieriem
Copy link
Copy Markdown
Owner Author

https://github.com/andreknieriem/headunit-revived/releases/download/v0.0.1-pre/com.andrerinas.headunitrevived_2.2.0-beta2_debug.apk Here is the new apk. It says now it might not be supported. Would be great if it works for you :)

@hectorlf
Copy link
Copy Markdown

hectorlf commented Apr 7, 2026

Thank you very much! Unfortunately, now it simply fails with the message: "Bluetooth is not enabled", which is obviously not true but tracks with what @tsabaia was explaining above. Not the end of the world, HURev still works!

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 7, 2026

Thank you very much! Unfortunately, now it simply fails with the message: "Bluetooth is not enabled", which is obviously not true but tracks with what @tsabaia was explaining above. Not the end of the world, HURev still works!

Another option to get the native Android Auto experience is to buy a wireless Android Auto adapter. This way you can use HURev natively, without needing the Wireless Helper.

https://www.google.com/search?q=android+auto+wireless+adapter

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 7, 2026

I tested it without much hope on my Chinese head unit because it runs that very restrictive ROM.

I was surprised when it worked (even if only for a few seconds).

I tested it using a Galaxy S8+ as if it were a head unit and the same thing happened, working for a few seconds.

Both devices are completely different, but they worked the same way, only for a few seconds. So I investigated why the connection was dropping, and after long conversations with Gemini, I arrived at this part of the code.

It's perfect now, I no longer need the Wireless Helper installed, the connection is much faster. I tested it several times and it worked perfectly every time.

My Android Auto updated yesterday to 16.5.661214 and so far the native connection with HURev 2.2.0-beta2 is working normally.

@HeyPortal
Copy link
Copy Markdown

I currently have a generic Chinese headunit UIS8581a I can use for testing. I'm running DUDUOS on it and have logs from the most recent Beta 2 release in trying to use the Native AA mode.

HUR_Log_20260408_164547.txt

Currently the app doesn't see any Bluetooth devices connected when using the regular bluetooth connection menu. It appears as no device found.

My Device: Pixel 10 Pro XL
Android Auto firmware: 16.5.661214-release
HUR: 2.2.0 beta2

@tsabaia
Copy link
Copy Markdown
Contributor

tsabaia commented Apr 8, 2026

Currently the app doesn't see any Bluetooth devices connected when using the regular bluetooth connection menu. It appears as no device found.

Open Headunit Revived, wait a few seconds, then leave it running in the background and go to your headunit's Bluetooth settings.

This way you can get your phone and headunit to find each other.

@HeyPortal
Copy link
Copy Markdown

Open Headunit Revived, wait a few seconds, then leave it running in the background and go to your headunit's Bluetooth settings.

This way you can get your phone and headunit to find each other.

Here's the logs for this try.
HUR_Log_20260408_172902.txt

I normally connect via the DUDUAUTO Bluetooth connection, but this time I went into the Android settings and connected to FYT-Android instead. It connected briefly, but didn't respect my display sizing preferences. Once I exited Android Auto, I wasn't able to reconnect even though my phone/headunit still showed as connected, the app never relaunched Android Auto

@andreknieriem
Copy link
Copy Markdown
Owner Author

There seems to be an issue when you disconnect Android Auto. For me it works, if I close the app via exit button and start it again. It instantly connects.

@andreknieriem
Copy link
Copy Markdown
Owner Author

This is added in branch 2.2.0 and will be merged/released soon.

@andreknieriem andreknieriem deleted the native-aa-new branch April 13, 2026 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants