Use off-the-shelf components
TomTom Digital Cockpit comes standard with a comprehensive set of automotive grade services and applications, ready to be used for commercial purposes. We call these the off-the-shelf or stock components.
Off-the-shelf applications can be used "plug-and-play" or they can be customized to the car maker’s needs. Performing customization is not limited to visual changes, but may also include modified or added features. By using the extensive set of TomTom Digital Cockpit platform APIs, which extend the standard Android Automotive APIs, new applications can be added with much less effort compared to standard Android Automotive development.
Reuse TomTom's UI controls
TomTom provides a reusable UI controls library TomTom Android Tools that developers can use to build the user interface of their frontend. These controls are optimized for use in cars and have additional features compared to their built-in Android equivalents to allow developers to build a consistent look-and-feel across their whole IVI system and to minimize implementation effort. The controls also support various forms of user interaction. The system wide appearance of the UI controls can be customized through theming.
Avoid blocking of the UI thread
The whole UI of the IVI system runs in a single UI thread. Prevent IO and CPU intensive calculations from blocking the UI thread. Put anything that is not UI related in services instead.
Avoid a monolithic Gradle module
When you start your first project, you will likely start with a single Gradle module for building the APK. Avoid adding everything to this single module. Define smaller library modules per service and frontend. See the Create a frontend plugin and Create an IVI service tutorials as examples.
Smaller modules allow you to avoid unnecessary dependencies between the modules. This makes it easier to isolate relevant modules when analyzing issues. Smaller modules also have advantages during development. Their class path will contain fewer classes so the code completion will be faster. Smaller modules also allow for faster rebuilds.
Apply secure design, code, test standards, and processes
Here at TomTom we follow secure design, code, and test standards and processes. These standards and processes help us to deliver high-quality software quickly. We encourage you to do the same. Our recommendation is to set up the standards and processes and write high quality code from the start. Keeping the code organized is much easier if done right from the start.
Here are some good practices and tools we use:
Implement a Secure Development Lifecycle
In TomTom, we have implemented a Secure Development Lifecycle (SDL). The SDL standardizes TomTom's approach to security. The SDL helps developers build more secure software by reducing the number and severity of vulnerabilities in software, while reducing development cost.
See Secure Development Lifecycle: The essential guide to safe software pipelines for more information about SDL.
We follow Google's official Kotlin style guide, falling back to Kotlin's style guide if something isn't covered.
We apply the SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion) principles.
To make sure code is written in a consistent way, our coding standard is updated by developers whenever a decision is made to do either A or B.
Code formatting tools
We avoid lengthy discussions about things that really do not matter. For Kotlin code we use ktlint.
Use static and dynamic code analysis
Static and dynamic code analysis tools prevent bugs. We require all issues reported by these tools to be addressed before code can be merged. This helps detecting bugs before the software is published, or even before testing the software. We use various tools, for example, static code analysis, linters and vulnerability scanning tools.
Treat warnings as errors
In a lot of cases, a warning is or can become a bug in the feature. For this reason we simply consider every warning a bug. Better safe than sorry. Warnings must be resolved before code can be merged. It also helps in making sure the code is easier to maintain.
Secure code reviews
All code is reviewed by at least two other developers before code is merged. Responsibilities of both reviewers and the author of the change are clearly defined. Check lists are available for reviewers. Authors have to address all comments, in a constructive way. For example: If a reviewer raises a question, it is the responsibility of the author to improve the code to make sure anybody else reading the code later will not raise the same question.
We require all our code to be covered by automated tests and we require all our tests to pass before any change is merged. This allows us to release at any time. This approach also ensures that developers are not getting blocked by other developers.
Automated testing implies designing for testability. One test may not affect another, so avoid using singletons in your code. They are an anti-pattern in the first place. Since a singleton can keep state, they can easily affect the next test. See Testing for more information.
Reflect and improve
If something goes wrong we take actions to prevent it from happening again. For example, for a bug fix, we also add a test that covers the problem.
Integrate new versions as soon as available
New versions of TomTom Digital Cockpit are released continuously. Newer versions include new functionality, bug fixes, and performance improvements. Update to the latest release as soon as it becomes available. More and smaller increments make integrating a newer version much easier compared to big bang integrations. The sooner you use a newer version, the quicker you can provide us feedback and the quicker you benefit from newly provided functionality or bug fixes.
Integrating a newer version of TomTom Digital Cockpit can result in disruptions. TomTom tries to avoid disruptions as much as possible. However it is an illusion to think that they will never happen. A common pit-fall is to think that delaying integrations results in fewer disruptions. The opposite is true. Finding the cause of disruptions and finding a solution is much faster if only a smaller change set has to be considered.
Use release builds for performance testing
Only release builds are suitable for performance testing. Android has various optimizations that are only applied on release builds.
The sooner we can help you, the better it is for everybody involved. Report issues with reproduced steps, the expected outcome, the actual outcome, the affected TomTom Digital Cockpit version, and always provide logcat logging.