Document the multi-user adaptation issue:
The background is that there are two new APIKs under the system/app, one is our business scenario apk and the other is the virtual car CarService service apk, our apk needs to link the CarService service to communicate through AITL.
The following two pictures are not roo situation (the current car user is user14, the userid of the virtual car is 0): the virtual car cannot be found, and the virtual car in the log has been crashing: ServiceManager.addService check failed
The next log after opening root is:
It’s amazing, this article is to talk about why you can communicate normally after opening Root:
The car technology we used in the past was a single user, so there is no problem of different users not sharing data; But recently a new project to use the car machine is a multi-user system, about the multi-user I summarized some information, you can see the following statement:
1. In the multi-user state, the user’s new process is system/app directory sharing only modified parameters (its userid defaults to 0), and the data/app directory is reinstalled (its userid is determined during installation, and the same is true for multi-user installation)
2. The four major components need to specify the corresponding accepted user (the current user of the default system) to start.
3.systemServer’s Binder communication will carry UserId, if there is no service in the current UserId, the corresponding Binder cannot be found (because the current user is 10, but the user under systemapp is 0 and needs to be rooted before communication)
4. Multi-open is the use of this multi-user way, uid as long as it is different (userid*10000 + appid). The appid is the same, but the userid is not the same, so the uid is not the same, you can open more. But how do different users communicate?
5.app read the storage sd card path and the app’s private directory, in fact, they will be soft-connected to the partition of the corresponding user directory.
Therefore, multi-user switching is essentially to change the data/app’s stored reading information to a directory; For the system app, only some parameters have been modified, and some properties of the system have been changed; For the servicemanager, it is to switch to the binder thread pool used by another user (which is why the virtual car can be added to the servicemanager after root)
6. Therefore, one of the points we need to consider when using multi-user is how to make our app communicate with the system app, which are two different users. The default of the car machine startup is userid10, but the app below the system is user0. The premise of communication is that the binder of the system service must have the binder of the system service in the binder thread pool of the app under the current car user. This leads to a conflict that the car machine user is 10 system users do 0 after explaining how to solve
7. The system can be restricted, and the userid to which the corresponding APP must belong. (This is also the knowledge that this article focuses on because this knowledge point is our solution)
The first problem is that our process has been reconnecting when it rebinds the Service
The default user of the car boot system is user10, and the service we need to link is under user0, even if our APK and virtual car are user0, it cannot be connected, according to the third point listed above:
In the Binder that we need to link is the current system user that is bound, that is, user10, so when using the service, an exception is reported that the service cannot be found. Because this service is not under user10 at all, he is under user0, and the natural link fails.
The second problem is that the virtual car has been reporting ServiceManager.addService’s validation without passing the exception
This is also well understood, when adding system services, ServiceManager will verify that the current system user and the corresponding service user to be added are consistent, and if it is not consistent (it cannot be found), it will not be added.
Here are the answers to the questions raised in the sixth knowledge point above:
The simplest way is to switch the ROOT user, use adb root to switch to the system user user0 can normally link services, and the virtual car can also be added to the ServiceManager normally
The reason is that the servicemanager under user0 can retrieve this virtual car service.
After switching users, remember to kill the process, the process of switching users AMS although killing the process but the data will still be retained, the use of user10 data
But the problem can never be so simple to bring, test students need to test when you must manually root this is fine, if it is a user? Users can’t root, so they’ll have to find other solutions, but thankfully this afternoon I noticed a particularly weird phenomenon:
Another colleague in our department, his APP is also under the system/app, but the userid is always user10. I have a question: shouldn’t the system/app be all user0 below? How could he be 10, and later chatted with their leader and found that their APP was communicated with the ROM side in advance and could limit their userid, so their userid has always been 10
Therefore, our communication with the virtual car also has a solution, yes: it is to tell the ROM manufacturer to limit the userid of the virtual car to 10, so that our app can connect to the service normally under the user10 user who is started by default by the system, and the virtual car service can also be added to the SystemServer under user10.
The problem was solved, but there was a serious sequelae that plagued me:
Let’s put the conclusion first: APP1 after the ROM restricts userid10 above, he can only pull up the process of userid10
The question points out: the other process APP2 is also the system below the system, although he is not restricted by the ROM userid, but his userid is also 10, why is this??? The only difference is that this App2 will be pulled up again by APP1
After knowing this unique difference, exclude all constants, and the only variable is the userid of this APP1. Or more broadly, which userid your app is, then the process you pull up is also which userid
Because different users are isolated, if he is the APP of user10, then he can only pull up the APP of user10. This sequelae is what I have been wondering about since then, and only here I suddenly became enlightened, and then I will end this article with a summary of knowledge points:
I forgot to mention an important point in the above knowledge points:
When APP1 pulls up another APP2, what is the userid of the APP2 pulled up?
The answer is that it has nothing to do with the current user of the system, different users are isolated between each other, and the userid of APP2 and the userid of APP1 are the same.
That is to say, if the same APP1 under different users wants to communicate with another APP2, then the basis for whether he pulls up another APP2 is to determine whether there is an APP2 process under the userid of APP1 If there is one, it does not need to be pulled up, and if not, it is necessary to re-create the process.
Here’s a concrete example:
The default user of the system is still user10, and our process userid is 0 (under system/app). An APP with a userid of 10 needs to pull up our process, he will judge that the APP’s usreid found to be 10, and then retrieve userid10 below and find that there is no process for us, so he will pull up a userid of 10 of our process again.
At this point, our process has two, one is the user0 that the system starts by default, and the other is pulled up by the userid10 process.
(Mainly introduces the difference between userid, uid and appid)
Retention and rebuilding of multi-user processes:
(These two articles are still mainly looking at the multi-user switch creation and deletion process is better, the basic point is not as good as the first link)
Author: Beiyang Link: https://juejin.cn/post/7152449135902195749
Follow me to get more knowledge or contribute