Create a Frontend Coordination Rule

Last edit: 2024.02.02

Knowledge of the system UI will help you to understand this guide. If you are not yet familiar with it, feel free to take a look at the system UI overview.

A system UI in the TomTom Digital Cockpit can use frontend coordination rules to apply business logic that coordinates frontends. Such rules commonly trigger a Panel within a Frontend to open, close or update services with information derived from frontends and their panels. For example, CloseModalPanelsOnTaskPanelChangeFrontendCoordinationRule ensures a ModalPanel is closed when the active TaskPanel changes; ToggleTaskPanelsOnMenuItemClickFrontendCoordinationRule responds to system UI menu items being clicked by opening or closing a TaskPanel. More examples can be found in com.tomtom.ivi.platform.systemui.api.common.frontendcoordinator.frontendcoordination.

These rules have a direct impact on the look and feel of the Digital Cockpit and it's possible to create custom rules to customize the behavior of the system UI. The following section explains how to create a custom FrontendCoordinationRule to hide the DebugPanel when a main menu item is clicked. Code snippets only show significant parts for this example, the full code is provided in the examples/customization/frontendcoordinationrule directory.

Create a frontend coordination rule

Create a CloseDebugPanelOnMenuItemClickFrontendCoordinationRule.kt.

1internal class CloseDebugPanelOnMenuItemClickFrontendCoordinationRule(
2 private val debugPanelService: DebugPanelServiceApi?
3) : FrontendCoordinationRule {
4 override fun activate(
5 lifecycleOwner: LifecycleOwner,
6 iviServiceProvider: IviInstanceBoundIviServiceProvider,
7 frontends: LiveData<out Collection<Frontend>>
8 ) {
9
10 SystemUiMenuItemsService.createApi(lifecycleOwner, iviServiceProvider)
11 .addMenuItemEventListener(
12 lifecycleOwner,
13 object : SystemUiMenuItemsService.MenuItemEventListener {
14 override fun onMenuItemClicked(id: MenuItem.Id) {
15 debugPanelService?.showDebugPanelAsync(false)
16 }
17 }
18 )
19 }
20}

Create a view model with the frontend coordination rule

Create a CustomSystemUiViewModel that includes the new rule. Note how the frontendCoordinator property is used to provide a collection of rules used by the system UI.

1internal class CustomSystemUiViewModel(
2 coreViewModel: CoreSystemUiViewModel
3) : LifecycleViewModel() {
4
5 val frontendCoordinator = FrontendCoordinator.createDefault(
6 lifecycleOwner = this,
7 iviServiceProvider = coreViewModel.iviServiceProvider,
8 frontendMetadata = coreViewModel.frontendMetadata,
9 frontendContextFactory = coreViewModel.defaultFrontendContextFactory,
10 frontendCoordinationRulesFactory = { frontendRegistry, panelRegistry ->
11 val defaultRules = DefaultFrontendCoordinationRules.create(
12 frontendRegistry,
13 panelRegistry
14 )
15 defaultRules + CloseDebugPanelOnMenuItemClickFrontendCoordinationRule(debugPanelService)
16 }
17 )
18}

Create a custom system UI host for the view model

Create a CustomSystemUiHost that uses the CustomSystemUiViewModel.

1internal class CustomSystemUiHost(systemUiHostContext: SystemUiHostContext) :
2 SystemUiHost(systemUiHostContext) {
3
4 private lateinit var viewModel: CustomSystemUiViewModel
5
6 override fun onCreate() {
7 viewModel = ViewModelProvider(
8 viewModelStoreOwner,
9 FixedConstructorFactory(coreViewModel)
10 )[CustomSystemUiViewModel::class.java]
11 }
12
13 override fun onSystemUiPresented() {
14 viewModel.frontendCoordinator.onSystemUiPresented()
15 }
16
17 private fun bindSystemUiView(binding: TtiviFrontendcoordinationruleCustomsystemuiBinding) {
18 binding.viewModel = viewModel
19 binding.panelRegistry = viewModel.panelRegistry
20
21 setIviOnBackPressedCallbacks(listOf(binding.exampleCustomizationTaskPanelStackContainer))
22 }
23}

Create a custom activity for the system UI host

Create a CustomActivity that uses the CustomSystemUiHost.

1class CustomActivity : DefaultActivity() {
2 override fun createSystemUiHost(iviInstanceId: IviInstanceId): SystemUiHost =
3 CustomSystemUiHost(getDefaultSystemUiHostContext(iviInstanceId))
4}

Try the custom frontend coordination rule

After the application is built and deployed to a target device, follow these steps to see the new behavior of the system UI:

  • Long press the 'volume down' hardware button.
  • The debug menu appears on the right of the screen.
  • Tap a main menu item.
  • The debug menu is automatically closed.

Debug tabs are normally only included in debug builds. In this example debug tabs are explicitly included.