In-depth analysis of network latency during Android boot

Source: Internet
Author: User

In-depth analysis of network latency during Android boot

In general, the property of phone is persistent to true, and the phone process is called up earlier. Applications modified by android: presistent will be started by AM after the system is started, even if they are not running, AM also calls startProcessLocked to start the process. Start package com. android. phone, that is, phone application. This will directly call onCreate () of PhoneApp and execute the initialization action of network searching.

The source code is as follows:

Alps \ packages \ services \ Telephony \ AndroidManifest. xml

Android: persistent = "true"

......

The log that the phone is called normally should be as follows:

01-01 14:01:47. 890: I/ActivityManager (717): Start proc com. android. phone for added application com. android. phone: pid = 991 uid = 1001 gids = {41001,300 2, 3001,300 3, 1028,101 5, 1004,200 2, 1023}
From the above log, we can see that the Phone process started normally. However, when we checked the Phone with network latency to reproduce the Phone, we found that the Phone process was not started normally, but started by the components of the run in the Phone process. The reference log is as follows:

01-29 14:08:29. 842: I/ActivityManager (723): Start proc com. android. phone for service com. mediatek. cellConnService /. phoneStatesMgrService: pid = 990 uid = 1001 gids = {41001,300 2, 3001,300 3, 1028,101 5, 1004,200 2, 1023}
From the above log, we can see that the current phone process is called by the CellConnService. PhoneStatesMgrService service. We can view the PhoneStatesMgrService source code and find that the service runs in the phone process as a component of the phone. The source code is as follows:

Android: process = "com. android. phone"// Through this android: process = "com. android. phone" attribute, we can specify the process that a component runs. You can set this attribute to allow each component to run in its own process, or share only some components with one process. You can set the "android: process" attribute to run components in different applications in the same process. Com. mediatek. CellConnService runs in com. android. phone as a component.
Android: allowClearUserData = "false"
......


CELLCONNSERVICE"/>



If the phone process is called by the phone interface, You Cannot initialize the network searching operation. Instead, wait until alps \ packages \ services \ telephony \ AndroidManifest. in xml, the OtaStartUpReceiver receives BOOT_COMPLETED before calling the PhoneApp, and then executes its onCreate () to initialize the network searching operation. This will undoubtedly lead to network latency. In this case, we need to find out where to start PhoneStagtesMgrService. Here we need to take a look at the above bold marked red Action ---CELLCONNSERVICEThen, we analyze the log. See the log as follows:

01-29 14:08:29. 764: W/ContextImpl (882): Implicit intents with startService are not safe: Intent {act = android. intent. action. CELLCONNSERVICE} android. content. contextWrapper. startService: 494 com. mediatek. cellConnService. cellConnMgr. register: 159 com. android. systemui. huawei. mobileStateManager. 106
01-29 14:08:29. 852: W/ContextImpl (882): Implicit intents with startService are not safe: Intent {act = android. intent. action. CELLCONNSERVICE} android. content. contextWrapper. bindService: 517 com. mediatek. cellConnService. cellConnMgr. register: 160 com. android. systemui. huawei. mobileStateManager. 106
01-29 14:08:32. 294: W/ContextImpl (882): Implicit intents with startService are not safe: Intent {act = android. intent. action. CELLCONNSERVICE} android. content. contextWrapper. startService: 494 com. mediatek. cellConnService. cellConnMgr. register: 159 com. android. systemui. huawei. mobileStateManager. 106
01-29 14:08:32. 307: W/ContextImpl (882): Implicit intents with startService are not safe: Intent { Act = android. intent. action. CELLCONNSERVICE} Android. content. ContextWrapper. bindService: 517 com. mediatek. CellConnService. CellConnMgr. register: 160 com. android. systemui. huawei. MobileStateManager. 106

From the preceding log, we can see that MobileStateManager starts a service through Intent, and the service that receives this Intent is exactly PhoneStagtesMgrService. The reference code is as follows:

Code 1: Start the PhoneStatesMgrService interface here, which is located in the CellConnMgr class under CellConnServic.
Public void register (Context ctx ){
Log. d (TAG, "register ");


MCtx = ctx;


Intent it = new Intent ("android. intent. action. CELLCONNSERVICE ");
MCtx. startService (it );
MCtx. bindService (it, mConnection, Context. BIND_AUTO_CREATE );
}
Code 2: Call the constructor in MobileStateManager under systemui
Public MobileStateManager (Context context ){
MContext = context;
MCellConnMgr = new CellConnMgr (null );
// MCellConnMgr. register (mContext); // The interface for starting the PhoneStatesMgrService is called.
MITelephony = getITelephony ();
MConnManager = (ConnectivityManager) mContext. getSystemService (Context. CONNECTIVITY_SERVICE );
UpdateSIMInfoList ();
}

Therefore, we will optimize the code here to solve the problem.

It should be noted that as a component run in com. android. not only com. mediatek. cellConnService, such as com. android. providers. telephony, etc. Here I also set com. android. providers. telephony calls com. android. let's share with you the analysis method of phone.

The following describes how to call com. android. providers. telephony to call the log of the com. android. phone process:

01-30 11:02:44. 750: I/ActivityManager (714): Start proc com. android. phone for content provider com. android. providers. telephony /. telephonyProvider: pid = 999 uid = 1001 gids = {41001,300 2, 3001,300 3, 1028,101 5, 1004,200 2, 1023}
From the above log, we can see that the phone process is called by com. android. providers. telephony/. TelephonyProvider. The following describes how TelephonyProvider calls the Phone process.
First, check the source code to see the following:
Com. android. phone"
Android: allowClearUserData = "false"
Android: allowBackup = "false"
Android: label = "@ string/app_label"
Android: icon = "@ drawable/ic_launcher_phone">


Android: authorities = "telephony"
Android: exported = "true"
Android: multiprocess = "false"/>

Android: authorities =" Cb"
Android: exported = "true"
Android: multiprocess = "false"/>

Android: authorities =" Sms"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS"/>

Android: authorities =" Wappush"
Android: exported = "true"
Android: multiprocess = "false"/>

Android: authorities =" Mms"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS">



Android: authorities =" Mms-sms"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS"/>

Android: authorities =" Usersms"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS"/>
Android: authorities =" Usercb"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS"/>
Android: authorities =" Usermms"
Android: exported = "true"
Android: multiprocess = "false"
Android: readPermission = "android. permission. READ_SMS"
Android: writePermission = "android. permission. WRITE_SMS">






From the source code above, TelephonyProvider belongs to com. android. phone process. You can call TelephonyProvider to start the phone process. For more information, see the following log. mediatek. in systemui, ActivityManager calls TelephonyProvider to Run TelephonyProvider in the phone process, and then starts com. andorid. phone process. That is to say, we call TelephonyProvider to indirectly call the phone process. The conventional method of calling TelephonyProvider is through "content: // telephony ". Android: authorities = "telephony";
01-30 11:02:44. 640: D/SignalClusterView (878): setWifiIndicators, visible = false, strengthIcon = com. mediatek. systemui. ext. iconIdWrapper @ listen 584f0, activityIcon = com. mediatek. systemui. ext. iconIdWrapper @ 42658508, contentDescription = wi-fi connection disconnected
01-30 11:02:44. 643: V/PhoneStatusBar (878): carrierlabel for Gemini = android. widget. linearLayout {201763b40 I. E ........... i. 0, 0-0, 0 #7f080013 app: id/carrier_label_gemini} show = true
01-30 11:02:44. 658: D/ActivityManager (714): getContentProviderImpl: from callerandroid. app. ApplicationThreadProxy @ 42ab1f60 (pid = 878) to get content provider telephony
01-30 11:02:44. 750: I/ActivityManager (714): Start proc com. android. phone for content provider com. android. providers. telephony /. telephonyProvider: pid = 999 uid = 1001 gids = {41001,300 2, 3001,300 3, 1028,101 5, 1004,200 2, 1023}
The above log shows that the 878 process (systemui) calls com. android. providers. telephony /. telephonyProvider (process id is 999), that is, systemui calls TelephonyProvider and com. android. phone process. Refer to log as follows:

01-30 11:02:42. 133: I/SurfaceFlinger (146): EventThread Client Pid (714) created

Therefore, we need to check the code in systemui. Refer to the troubleshooting method as follows:

01-30 11:02:44. 640: D/SignalClusterView (878): setWifiIndicators, visible = false, strengthIcon = com. mediatek. systemui. ext. iconIdWrapper @ listen 584f0, activityIcon = com. mediatek. systemui. ext. iconIdWrapper @ 42658508, contentDescription = wi-fi connection disconnected
01-30 11:02:44. 643: V/PhoneStatusBar (878): carrierlabel for Gemini = android. widget. linearLayout {201763b40 I. E ........... i. 0, 0-0, 0 #7f080013 app: id/carrier_label_gemini} show = true
01-30 11:02:44. 658: D/ActivityManager (714): getContentProviderImpl: from callerandroid. app. ApplicationThreadProxy @ 42ab1f60 (pid = 878) to get content provider telephony
01-30 11:02:44. 750: I/ActivityManager (714): Start proc com. android. phone for content provider com. android. providers. telephony /. telephonyProvider: pid = 999 uid = 1001 gids = {41001,300 2, 3001,300 3, 1028,101 5, 1004,200 2, 1023}
The above log shows that the 878 process (systemui) calls com. android. providers. telephony /. telephonyProvider (the process id is 999), that is, the systemui still calls TelephonyProvider, and then calls com. android. phone process.
Then, according to the log, we can see that before the TelephonyProvider process was called, the above marked red (878 is the systemui process) was operated. below is the call relationship in the source code, from the source code below, TelephonyProvider is called in many places, such as javasweiquicksettingscontroller. You need to check why these locations are called.

In the SimInfoManager class
Public static final Uri CONTENT_URI =
Uri. parse ("content: // telephony/siminfo ");
......
Public static List GetInsertedSimInfoList (Context ctx ){
Logd ("[getInsertedSimInfoList] + ");
ArrayList SimList = new ArrayList ();
Cursor cursor = ctx. getContentResolver (). query (CONTENT_URI,
Null, SLOT + "! = "+ SLOT_NONE, null, null); // TelephonyProvider is called here
Try {
If (cursor! = Null ){
While (cursor. moveToNext ()){
SimList. add (fromCursor (cursor ));
}
}
} Finally {
If (cursor! = Null ){
Cursor. close ();
}
}
Logd ("[getInsertedSimInfoList]-" + simList. size () + "infos return ");
Return simList;
}

In the SIMHelper class
Private static List GetSortedSIMInfoList (Context context ){
List SimInfoList = SimInfoManager. getInsertedSimInfoList (context );
Collections. sort (simInfoList, new Comparator (){
.....
In the PhoneStatusBar class

Public void showSimIndicator (String businessType ){
If (mIsSimIndicatorShowing ){
HideSimIndicator ();
}
MBusinessType = businessType;
Long simId = SIMHelper. getdefasim SIM (mContext, businessType );
Xlog. d (TAG, "showSimIndicator, show SIM indicator which business is" + businessType + "simId =" + simId + ".");
If (simId = android. provider. Settings. System. DEFAULT_SIM_SETTING_ALWAYS_ASK ){
List SimInfos = SIMHelper. getSIMInfoList (mContext );
....
There are a lot of calls in the source code, maybe TelephonyProvider is called to get the sim status. The specific tedious log and code will not be explained.

The entire analysis process is here. If you have any questions, send a message to me and discuss it together.



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.