Over the past two years, we have done some pretty exciting work in custom android builds. As a part of our learnings, we collated the core concepts that we have drilled down to get the expertise. We will be sharing these in a series of blog posts in details. Here is a glimpse of the topics we will cover.
Ever wondered how to make an application launch by default app on the Android device. Well, we did it. And not just the basic launcher changing and the admin-based permission stuff. We have gone deep into the system layer and have achieved customization on each level. This includes:
- Phone Startup UI
- Disabling the default launcher
A complete set of things that makes up a custom Android OS (with base code, of course) is built from the ground up. We will be posting the step-by-step process of how this can be achieved.
Ever wondered how some of the system apps do not need permissions to run some of the OS level tasks(camera, storage, etc.). We were able to pinpoint this and make sure all the required permissions are prebuilt on a custom OS for an application of our own choosing.
In Android OS we can configure an application to receive the events of each level for an OS startup. This allows applications to check for the OS startup and availability of some of the services to ensure certain aspects are available on the startup of the device. (For example, SMS service, Call service)
Service apps building
Consider a requirement where your app has to interact with other applications that enable a function (such as applying an Instagram filter on a photo, authenticating against a common authenticator). There may be other cases where you are required to split the app into services. We can take you on a deep dive into this modular approach soon.
Socket-based server for communication
We have built a custom set of classes that allows for communication to the device over TCP/IP sockets and makes communication between the app and any other system easier. With multiple connections handling and a queue-based mechanism, we were able to achieve a highly reliable communication layer.
Protobuff and TLV
Though it is an industry-standard to establish a communication protocol, we were able to design some of the systems to effectively transfer data from one app to another using Google's protobuff library and a bit of TLV (type, length, value) format of data transfer.
Multi-camera support and CameraX
There is a common notion that one cannot get access to both cameras at the same time and that various devices are not able to support this (except for, probably, Google Pixel 3). Could it be possible for an app to access both front and back cameras at the same time (either for preview or for processing)? Yes, it’s possible! We were able to achieve this using some of the intricate details in the system and bring out this multi-camera support for a device. We were also able to distinguish between various terms used in the multi-camera support space (dual camera access, multi-camera access, etc.)
Serial port communication with external hardware
Often when building custom hardware for specific needs on top of Android, you may be required to have an interaction with external hardware along with the base android device. This may be a temperature sensor, a robotic arm, a synchronous motor, or a simple LED bulb. Most of this hardware comes with an inbuilt serial port communication module that helps other systems to interface with them. However, serial port communication in Android is restricted and poses a challenge for interactions. We were able to overcome this challenge and build a methodology to interact with any kind of hardware device over serial port communication.
USB unblocking and UI customization
By default, Android USB tethering is not available on plugging in. We were able to customize this behavior to a specific mode and ensure that all other communication is blocked. Many UI customizations are also put in place for this that include:
- Overall styling
- Navigation bar customization
- Default button appearance disabling (back, home and status bar)
We were also able to customize the OS to block/unblock the adb communication with the device ensuring proper security for the end product.
Improving build time using scripts
Scripting helps when you have to integrate with all the code of your Android custom build and also execute a firmware update (OS update) that will need a lot of time to build. It also ensures that the build integrity is maintained. We were able to optimize the build times and also thin the build for specific requirements.
Apart from these, there are many other learnings we will share—such as removing unwanted apps from the android bare code, enabling RNDIS for the device by default, integrating with the custom hardware attached to the device, validating the BOM for the given requirements, ensuring crash logs are captured in the device, ensuring certain files are not deleted even with the new OS upgrade. The list is long and we are more than excited to share the details in the upcoming blog posts. Watch this space!