-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add option for alternate head tracking packets #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option for alternate head tracking packets #176
Conversation
Co-authored-by: kavishdevar <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds an optional configuration setting for users experiencing issues with the default head tracking implementation. The feature provides an alternate packet format for AirPods head tracking requests.
- Added new toggle setting "Use alternate head tracking packets" in Advanced Options with proper UI integration
- Implemented alternate head tracking packet creation methods with different data formats
- Modified head tracking service methods to conditionally use alternate packets based on user preference
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| AACPManager.kt | Added methods to create alternate start/stop head tracking packets with different data formats |
| AirPodsService.kt | Modified head tracking methods to check user preference and use alternate packets when enabled |
| AppSettingsScreen.kt | Added toggle switch UI for the new setting with proper state management and persistence |
| fun createAlternateStartHeadTrackingPacket(): ByteArray { | ||
| val opcode = byteArrayOf(Opcodes.HEADTRACKING, 0x00) | ||
| val data = byteArrayOf( | ||
| 0x00, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x08, 0x73, 0x42, 0x0B, 0x08, 0x10, 0x10, 0x02, 0x1A, 0x05, 0x01, 0x40, 0x9C.toByte(), 0x00, 0x00 |
Copilot
AI
Jul 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded hex values should be documented or extracted to constants with meaningful names to improve code maintainability and explain their purpose.
| fun createAlternateStopHeadTrackingPacket(): ByteArray { | ||
| val opcode = byteArrayOf(Opcodes.HEADTRACKING, 0x00) | ||
| val data = byteArrayOf( | ||
| 0x00, 0x00, 0x10, 0x00, 0x0F, 0x00, 0x08, 0x75, 0x42, 0x0B, 0x08, 0x10, 0x10, 0x02, 0x1A, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00 |
Copilot
AI
Jul 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded hex values should be documented or extracted to constants with meaningful names to improve code maintainability and explain their purpose.
| fun startHeadTracking() { | ||
| isHeadTrackingActive = true | ||
| aacpManager.sendStartHeadTracking() | ||
| val useAlternatePackets = sharedPreferences.getBoolean("use_alternate_head_tracking_packets", false) |
Copilot
AI
Jul 11, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The preference key string is duplicated in multiple places. Consider extracting it to a constant to avoid inconsistencies and improve maintainability.
| val useAlternatePackets = sharedPreferences.getBoolean("use_alternate_head_tracking_packets", false) | |
| val useAlternatePackets = sharedPreferences.getBoolean(USE_ALTERNATE_HEAD_TRACKING_PACKETS_KEY, false) |
android/app/src/main/java/me/kavishdevar/librepods/services/AirPodsService.kt
Show resolved
Hide resolved
|
@kavishdevar , alternative way for head tracking? Is this documented anywhere (I would like to play around a bit) |
|
The existing packets stopped working after I updated to the beta firmware released this year. These are the new packets:
|
This PR adds a new customization option to enable alternate head tracking packets for users experiencing issues with the default head tracking implementation.
Changes Made
New Setting
use_alternate_head_tracking_packets(boolean, default: false)Implementation Details
AACPManager.kt:
createAlternateStartHeadTrackingPacket()methodcreateAlternateStopHeadTrackingPacket()method040004001700000010000F000873420B081010021A0501409C0000040004001700000010000F000875420B081010021A050100000000AirPodsService.kt:
startHeadTracking()andstopHeadTracking()to check the preference settingAppSettingsScreen.kt:
Technical Notes
Testing
The implementation has been verified to:
This addresses cases where users may experience head tracking issues with the default packet format by providing an alternative implementation.
Warning
Firewall rules blocked me from connecting to one or more addresses
I tried to connect to the following addresses, but was blocked by firewall rules:
dl.google.com/usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant -cp /home/REDACTED/.gradle/wrapper/dists/gradle-8.11.1-bin/bpt9gzteqjrbo1mjrsomdt32c/gradle-8.11.1/lib/gradle-daemon-main-8.11.1.jar -javaagent:/home/REDACTED/.gradle/wrapper/dists/gradle-8.11.1-bin/bpt9gzteqjrbo1mjrsomdt32c/gradle-8.11.1/lib/agents/gradle-instrumentation-agent-8.11.1.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.11.1(dns block)If you need me to access, download, or install something from one of these locations, you can either:
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.