Implement command_volume_level_step notification command for relative volume adjustments - #7112
Draft
marazmarci wants to merge 6 commits into
Draft
Conversation
…nly getting AudioManager at its usage site
…sagingManager::processStreamVolume
… volume adjustments
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends the Android companion app’s notification “device command” handling to support relative volume adjustments by introducing a new command_volume_level_step command, enabling faster volume up/down automations without relying on sensor round-trips.
Changes:
- Added
command_volume_level_stepto the supported notification command set and permission request flow - Implemented step-based volume adjustment behavior alongside existing absolute volume setting
- Updated the user-facing changelog entry for the new command
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| app/src/main/res/xml/changelog_master.xml | Adds a changelog entry for the new relative volume notification command |
| app/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt | Adds new command constant and routes it through volume handling with “step vs absolute” behavior |
| app/src/main/kotlin/io/homeassistant/companion/android/ApplicationModule.kt | Provides AudioManager via Hilt for use by MessagingManager |
Comments suppressed due to low confidence (1)
app/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt:707
audioManageris injected as nullable but is force-unwrapped here. SinceApplicationModulecurrently providesAudioManager?, this can crash at runtime if the service is unavailable (or in certain test/preview contexts). Consider guarding for null before callingprocessRingerMode.
if (notificationManager?.isNotificationPolicyAccessGranted == false) {
notifyMissingPermission(message, serverId)
} else {
processRingerMode(audioManager!!, command)
}
Comment on lines
+1958
to
1965
| private fun setStreamVolume(streamType: Int, volume: Int) { | ||
| val maxVolume = audioManager!!.getStreamMaxVolume(streamType) | ||
| val clampedVolume = volume.coerceIn(0, maxVolume) | ||
|
|
||
| audioManager.setStreamVolume( | ||
| stream, | ||
| volumeLevel, | ||
| streamType, | ||
| clampedVolume, | ||
| AudioManager.FLAG_SHOW_UI, |
Comment on lines
744
to
750
| processStreamVolume( | ||
| audioManager!!, | ||
| data[NotificationData.MEDIA_STREAM].toString(), | ||
| command!!.toInt(), | ||
| serverId, | ||
| stream = data[NotificationData.MEDIA_STREAM].toString(), | ||
| volume = command!!.toInt(), | ||
| step = message == COMMAND_VOLUME_LEVEL_STEP, | ||
| serverId = serverId, | ||
| message = message, | ||
| ) |
Member
|
@marazmarci thanks for pushing this through. I've made some changes that you'll have to add to your PR. Is it an option to extend the existing command with more parameters to achieve the same goals as what you are trying to achieve? |
TimoPtr
marked this pull request as draft
July 3, 2026 15:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a new
command_volume_level_stepnotification command (alongside the existingcommand_volume_level) to add support for relative volume adjustments. It enables users to create responsive volume up/down control automations, for example for physical media control buttons through HA (eg. this Zigbee device). Currently the best option for implementing such automation is to first read the current state of the music volume sensor, then add/subtract the desired adjustment value, and then fire acommand_volume_levelnotification command to set the new volume. The problem with this approach is slowness. Quick successive button presses would result in most of the button presses to be seemingly ignored, because the music volume sensor doesn't update quickly enough.The parameters of the new command are exactly the same as for
command_volume_level. The only difference is in behavior of thecommandkey. Here's an example service call YAML to decrease music volume by 2 steps:Checklist
New or updated tests have been added to cover the changes following the testing guidelines.MessagingManagerdidn't have any unit tests to begin with.Link to pull request in documentation repositories
Documentation: home-assistant/companion.home-assistant#
I'll open the doc update PR and the PR for adding the new notification command in the mobile-apps-fcm-push repo when this PR is getting close to be merged ⏳
Any other notes
This is a reworked & rethought version of a PR I opened (and abandoned) a while ago: #4056 (closed without merging)
In that PR, I implemented the same functionality with a different approach: I extended the existing
command_volume_levelnotification command with arelative: true/falseproperty. Now I changed my mind, because I think adding a separate notification command feels cleaner, expresses the distinction more clearly, and is more similar to existing patterns in HA, like thebrightness_stepkey for thelight.turn_oncommand.