I was working with the Android File System recently when one of my colleagues pushed a thing into my mind. The blog is all about the answer to that question.
The thought
Remember those days when we were using the chmod (777 🙂↔️)command to a directory in our Linux sub-system as I didn’t have the write permission to the specific directory? Don’t be offended, we’re still doing the same things. If I can remember it correctly, the permission is granted to the user. After that, I (user id: 12345) have permission to write to the specific directory. This means if I run 4 more apps, the 4 apps now have the permission to write to that directory.
In a Unix-like File System, the permission is granted to the user. Android is Linux (not actually, but the Android kernel shares lots of common behaviors), so how come APP1 doesn’t have access to the download directory but APP2 has when I am the same user with the same user ID (with the same face as well) running the same application.
In Unix derivatives, if I am logged in as user 12345 and, run 5 apps, the 5 apps’ UID is most likely to be the 12345. Android is based on Linux and the file system is a core part of the kernel. Android didn’t want to disobey its ancestors and rewrite things. So.. Android had to think a little here (maybe more). If the user is me and I have read, and write permission to the /data/custom directory, this means if I am running the APP1, it has the same permission, if I am running the APP2, it has the same permissions as well. But we don’t want that. What’s the solution here then? MAKE EVERY APP AN USER!!!
The Food
When an app is launched a UID and PID are bonded with the process. The File System determines the permission from the user ID which in my case is showing the name against the user ID. This is done so that we don’t mess up the file system. By default, we don’t have permission to the system directories. When we change the permission for a user, we have to go through a little hassle kept intentionally to validate we know what we are doing (I once deleted the /boot directory 🤭).
Sharing the same kernel Android is no different from other Linux-based distros in choosing the file system! So, every Android App is running with a different user. This is a snap from a third-party app:
The user id is different for each app. If you kill the app and re-launch it, it will be launched with the same UID as you can see here. The UID might be different in your device than mine. Every app has a unique (here is a but) user ID and the user has permission to the directory. Your app doesn’t have permission, the user for the app has permission.
Food for thought!
The conclusion is one line, but the digging took tera flops of my dual-core single-threaded brain. The question is “how do they (Android) do it?”
It starts with the installation. When you install an apk, the Android System will hand over the installation process to a system service called “Package Manager Service” which will have the apk in its queue for app installation. The Package Manager communicates with a helper daemon (I like this name, I am gonna name my daughter DAY-MOON) process named “installd”.
installd will create a directory for the apk in the /data/app/<pkg>* location. The apk will be copied to the /data/app/<pkg>*/base.apk location. After that, It will read the manifest first, then it will create a user unique to that app unless we have the catch.
The catch?
Did you know you could set a user ID in the Android Manifest? If you have two apps and, you set the same user ID for both apps, both of your apps will get the same access to the files/directory. The attribute was deprecated in API level 29. This is when you can set the user ID for your app (ref: android manifest).
It looks fascinating to me that if I have two apps, granting permission to APP1 would provide permission to APP2. Not just file permissions, but other permissions as well!!!
Also, system apps, pre-installed with the device, are typically assigned a system-level UID (often 0 or 1000). This grants them broader system access.
It feels great to be around great colleagues, they’re awesome, and I keep learning from fantastic leaders.
Note: This is based on the information that I could have gathered. There could be lots of grey areas and areas where I could be wrong. Cross-validate these before using this post as a reference.