Skip to content

This PR implements the command_screen_off notification command, all… - #6973

Closed
rvroon wants to merge 4 commits into
home-assistant:mainfrom
rvroon:command_screen_off
Closed

This PR implements the command_screen_off notification command, all…#6973
rvroon wants to merge 4 commits into
home-assistant:mainfrom
rvroon:command_screen_off

Conversation

@rvroon

@rvroon rvroon commented Jun 5, 2026

Copy link
Copy Markdown

…owing users to remotely lock their Android device screen via Home Assistant notifications.

Summary

This PR implements the command_screen_off notification command, allowing users to remotely lock their Android device screen via Home Assistant notifications.

Checklist

  • New or updated tests have been added to cover the changes following the testing guidelines.
    • Note: MessagingManager currently has no unit tests. This feature follows the exact same pattern as existing device commands (command_ble_transmitter, command_bluetooth, etc.). Testing requires extensive Android system mocking (DevicePolicyManager, Context, AlertDialog) that is not currently in place for this class.
  • The code follows the project's code style and best_practices.
  • The changes have been thoroughly tested, and edge cases have been considered.
  • Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Link to pull request in documentation repositories

User Documentation: home-assistant/companion.home-assistant#

Any other notes

  • This command requires Device Administrator permission, which is a sensitive permission. Users will see a system dialog explaining the permission and must explicitly approve it.
  • The implementation includes clear user messaging explaining why this permission is needed.
  • Follows the same architectural patterns as other device commands in the codebase.
  • Comprehensive Timber logging added for debugging purposes.
  • The feature is non-breaking and opt-in (only activates when the specific command is sent).

…owing users to remotely lock their Android device screen via Home Assistant notifications.
Copilot AI review requested due to automatic review settings June 5, 2026 19:19

@home-assistant home-assistant Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hi @rvroon

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@home-assistant
home-assistant Bot marked this pull request as draft June 5, 2026 19:19
@home-assistant

home-assistant Bot commented Jun 5, 2026

Copy link
Copy Markdown

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

Copilot AI left a comment

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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for remotely locking the device screen via a new command_screen_off notification command, powered by Android Device Administrator.

Changes:

  • Introduces a DeviceAdminReceiver and device admin policy XML to enable DevicePolicyManager.lockNow().
  • Adds command_screen_off handling, permission request flow, and user-facing explanation text.
  • Registers the device admin receiver in the app manifest.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
common/src/main/res/values/strings.xml Adds user-facing explanation shown during device-admin activation.
app/src/main/res/xml/device_admin.xml Declares the device admin policy (force-lock).
app/src/main/kotlin/io/homeassistant/companion/android/notifications/ScreenOffAdminReceiver.kt Adds the required DeviceAdminReceiver implementation.
app/src/main/kotlin/io/homeassistant/companion/android/notifications/MessagingManager.kt Adds new command constant, dispatch, lockNow execution, and permission request intent.
app/src/main/AndroidManifest.xml Registers the admin receiver and links it to the policy XML.

Comment on lines +839 to +849
COMMAND_SCREEN_OFF -> {
val devicePolicyManager = context.getSystemService<DevicePolicyManager>()
val adminComponent = ComponentName(context, ScreenOffAdminReceiver::class.java)

if (devicePolicyManager?.isAdminActive(adminComponent) == true) {
Timber.d("Locking device screen")
devicePolicyManager.lockNow()
} else {
notifyMissingPermission(message, serverId)
}
}

@rvroon rvroon Jun 5, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Resolved

Comment on lines +1067 to +1077
<receiver
android:name=".notifications.ScreenOffAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN"
android:exported="true">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Resolved

Comment thread common/src/main/res/values/strings.xml Outdated
<string name="delete_shortcut">Delete shortcut</string>
<string name="description">Description</string>
<string name="details">Details</string>
<string name="device_admin_explanation">Home Assistant requires device administrator permission to lock your screen remotely using the command_screen_off notification command.</string>

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Resolved

@rvroon
rvroon requested a review from Copilot June 5, 2026 19:33

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment on lines +1842 to +1849
private fun requestDeviceAdminPermission() {
val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).apply {
putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, ComponentName(context, ScreenOffAdminReceiver::class.java))
putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, context.getString(commonR.string.device_admin_explanation))
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Valid concern, but already a pre-existing pattern in this file — not a new risk introduced by this code.

Looking at the code around lines 1801–1834, there are already 5 other functions using the exact same pattern of context.startActivity(intent) with FLAG_ACTIVITY_NEW_TASK:

  • requestDNDPermission() (line 1801)
  • requestSystemAlertPermission() (line 1808)
  • requestNotificationPermission() (line 1817)
  • navigateAppDetails() (line 1823)
  • requestWriteSystemPermission() (line 1829)

Comment on lines +543 to +545
COMMAND_SCREEN_OFF -> {
handleDeviceCommands(jsonData)
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Each command may diverge in behavior in the future (e.g., adding validation like COMMAND_MEDIA has)

@jpelgrom

jpelgrom commented Jun 5, 2026

Copy link
Copy Markdown
Member

We previously rejected this due to requiring the device admin role, as it is quite 'heavy': #2520. I believe Google Play is also quite strict in when apps are allowed to use this, with multiple reports online (example).

My opinion hasn't really changed on this subject but I'm interested to know what @TimoPtr thinks.

In case you were not aware, as a workaround of sorts, you can adjust the screen off timeout to a very low setting to quickly turn off the device.

@rvroon
rvroon marked this pull request as ready for review June 5, 2026 19:42
@home-assistant
home-assistant Bot dismissed their stale review June 5, 2026 19:42

Stale

@rvroon

rvroon commented Jun 5, 2026

Copy link
Copy Markdown
Author

We previously rejected this due to requiring the device admin role, as it is quite 'heavy': #2520. I believe Google Play is also quite strict in when apps are allowed to use this, with multiple reports online (example).

My opinion hasn't really changed on this subject but I'm interested to know what @TimoPtr thinks.

In case you were not aware, as a workaround of sorts, you can adjust the screen off timeout to a very low setting to quickly turn off the device.

@jpelgrom Thanks for your suggestion. I tried this, also following this thread: https://community.home-assistant.io/t/turn-off-screen-of-android-device/338013
But I couldn't get it to work properly on my Android Tablet (the screen refuses to turn off within a respectable time). The only workaround for me was using "fully kiosk", but I would prefer to use the native companion app.

@TimoPtr

TimoPtr commented Jun 8, 2026

Copy link
Copy Markdown
Member

I'm sharing the same feeling than @jpelgrom here. I'm not feeling confident for the app to get the ADMIN device permission. Also I would like to push back a little on adding new command until we come up with a refactor on the mobile_app integration to make the usage of these commands user friendly.

This feature could be quite invasive for secondary users for instance. Lastly I would not call screen_off but more screen_lock.

With both of us @jpelgrom not being confident at the moment I'm closing the PR until we have a plan how to deliver this properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants