偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.
全部博文(1751)
分类: LINUX
2010-01-13 17:46:54
一、总览 1、从java端发送at命令的处理流程。 2、unsolicited 消息从modem上报到java的流程。 3、猫相关的各种状态的监听和通知机制。 4、通话相关的图标变换的工作原理。 5、gprs拨号上网的通路原理。 6、通话相关的语音通路切换原理、震动接口。 7、通话相关的notification服务。 8、通话相关的各种server。 第一部分:从java端发送at命令的处理流程。 拨出电话流程: 1、contacts的androidmanifest.xml android:process="android.process.acore"说明此应用程序运行在acore进程中。 DialtactsActivity的intent-filter的action属性设置为main,catelog属性设置为launcher,所以此activity能出现 在主菜单中,并且是点击此应用程序的第一个界面。dialtactsactivity包含四个tab,分别由TwelveKeyDialer、 RecentCallsListActivity,两个activity-alias DialtactsContactsEntryActivity和DialtactsFavoritesEntryActivity分别 表示联系人和收藏tab,但是正真的联系人列表和收藏是由ContactsListActivity负责。 2、进入TwelveKeyDialer OnClick方法,按住的按钮id为: R.id.digits,执行 placecall() Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, Uri.fromParts("tel", number, null)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 3、intert.ACTION_CALL_PRIVILEGED实际字符串为android.intent.action.CALL_PRIVILEGED,通过查找知道了packegs/phone 下面的androidmanifest.xml中PrivilegedOutgoingCallBroadcaster activity-alias设置了intent-filter,所以需要找到其 targetactivity为OutgoingCallBroadcaster。所以进入OutgoingCallBroadcaster的 onCreate() //如果为紧急号码马上启动intent.setClass(this, InCallScreen.class); startActivity(intent); Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL); if (number != null) broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow); broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, intent.getData().toString()); if (LOGV) Log.v(TAG, "Broadcasting intent " + broadcastIntent + "."); sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null, Activity.RESULT_OK, number, null); 4、Intent.ACTION_NEW_OUTGOING_CALL实际字符串为android.intent.action.NEW_OUTGOING_CALL,通过查找知道了packegs/phone 下面的androidmanifest.xml中OutgoingCallReceiver Receiver接收此intent消息。找到OutgoingCallReceiver,执行 onReceive()函数 Intent newIntent = new Intent(Intent.ACTION_CALL, uri); newIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number); newIntent.setClass(context, InCallScreen.class); newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 5、请求拨号的java部分流程 onCreate(第一次)/onNewIntent(非第一次) internalResolveIntent placeCall(intent); PhoneUtils.placeCall(mPhone, number, intent.getData()); phone.dial(number); mCT.dial(newDialString); dial(dialString, CommandsInterface.CLIR_DEFAULT); cm.dial(pendingMO.address, clirMode, obtainCompleteMessage());//obtainCompleteMessage(EVENT_OPERATION_COMPLETE); send(rr); msg = mSender.obtainMessage(EVENT_SEND, rr); acquireWakeLock(); msg.sendToTarget(); RILSender.handleMessage() case EVENT_SEND: ... s.getOutputStream().write(dataLength); s.getOutputStream().write(data);//从这里流程跑到下面ril.cpp中监听部份 6、请求拨号的c/c++部分流程 6.1、初始化事件循环,启动串口监听,注册socket监听。 rild.c->main() (1)、RIL_startEventLoop //建立事件循环线程 ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL); //注册进程唤醒事件回调 ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, processWakeupCallback, NULL); rilEventAddWakeup (&s_wakeupfd_event); //建立事件循环 ril_event_loop for (;;) { ... n = select(nfds, &rfds, NULL, NULL, ptv); // Check for timeouts processTimeouts(); // Check for read-ready processReadReadies(&rfds, n); // Fire away firePending(); } (2)、funcs = rilInit(&s_rilEnv, argc, rilArgv);//实际是通过动态加载动态库的方式执行reference-ril.c中的RIL_Init //单独启动一个线程读取串口数据 ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL); fd = open (s_device_path, O_RDWR); ret = at_open(fd, onUnsolicited); ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr); RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0); 在initializeCallback中执行的程序: setRadioState (RADIO_STATE_OFF); at_handshake(); /* note: we don't check errors here. Everything important will be handled in onATTimeout and onATReaderClosed */ /* atchannel is tolerant of echo but it must */ /* have verbose result codes */ at_send_command("ATE0Q0V1", NULL); /* No auto-answer */ at_send_command("ATS0=0", NULL); ... //注册rild socket端口事件监听到事件循环中 (3)、RIL_register(funcs); s_fdListen = android_get_control_socket(SOCKET_NAME_RIL); ret = listen(s_fdListen, 4); ril_event_set (&s_listen_event, s_fdListen, false, listenCallback, NULL);//将此端口加入事件select队列 rilEventAddWakeup (&s_listen_event); 如果rild socket端口有数据来了将执行listencallback函数 listencallback //为此客户端连接创建新的监听句柄,s_fdListen继续监听其他客户端的连接。 s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen); ril_event_set (&s_commands_event, s_fdCommand, 1, processCommandsCallback, p_rs);//将此端口加入事件select队列 rilEventAddWakeup (&s_commands_event); 6.2、socket监听,收到dial的socket请求 processCommandsCallback //读数据到p_record中 ret = record_stream_get_next(p_rs, &p_record, &recordlen); processCommandBuffer(p_record, recordlen); p.setData((uint8_t *) buffer, buflen); // status checked at end status = p.readInt32(&request); status = p.readInt32 (&token);//请求队列中的序号 pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo)); pRI->token = token; /* 包含#include "ril_commands.h"语句,结构体如下: typedef struct { int requestNumber; void (*dispatchFunction) (Parcel &p, struct RequestInfo *pRI); int(*responseFunction) (Parcel &p, void *response, size_t responselen); } CommandInfo; */ pRI->pCI = &(s_commands[request]); pRI->p_next = s_pendingRequests; s_pendingRequests = pRI; pRI->pCI->dispatchFunction(p, pRI); //假设是接收了dial指令,pRI->PCI->dispatchFunction(p,pRI),调用dispatchDial (p,pRI) dispatchDial (p,pRI) s_callbacks.onRequest(pRI->pCI->requestNumber, &dial, sizeof(dial), pRI); in reference-ril.c onRequest() ... switch (request) { case RIL_REQUEST_DIAL: requestDial(data, datalen, t); asprintf(&cmd, "ATD%s%s;", p_dial->address, clir); ret = at_send_command(cmd, NULL); err = at_send_command_full (command, NO_RESULT, NULL, NULL, 0, pp_outResponse); err = at_send_command_full_nolock(command, type, responsePrefix, smspdu,timeoutMsec, sponse); err = writeline (command); //此处等待,直到收到成功应答或失败的应答,如:ok,connect,error cme等 err = pthread_cond_wait(&s_commandcond, &s_commandmutex); waiting.... waiting.... /* success or failure is ignored by the upper layer here. it will call GET_CURRENT_CALLS and determine success that way */ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); p.writeInt32 (RESPONSE_SOLICITED); p.writeInt32 (pRI->token); errorOffset = p.dataPosition(); p.writeInt32 (e); if (e == RIL_E_SUCCESS) { /* process response on success */ ret = pRI->pCI->responseFunction(p, response, responselen); if (ret != 0) { p.setDataPosition(errorOffset); p.writeInt32 (ret); } } sendResponse(p); sendResponseRaw(p.data(), p.dataSize()); blockingWrite(fd, (void *)&header, sizeof(header)); blockingWrite(fd, data, dataSize); 6.4、串口监听收到atd命令的应答"OK"或"no carrier"等 readerLoop() line = readline(); processLine(line); handleFinalResponse(line); pthread_cond_signal(&s_commandcond);//至此,前面的等待结束,接着执行RIL_onRequestComplete函数 6.5、java层收到应答后的处理,以dial为例子. ril.java->RILReceiver.run() for(;;) { ... length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); type = p.readInt(); if (type == RESPONSE_SOLICITED) { processSolicited (p); serial = p.readInt(); rr = findAndRemoveRequestFromList(serial); rr.mResult.sendToTarget(); ...... } CallTracker.java->handleMessage (Message msg) switch (msg.what) { case EVENT_OPERATION_COMPLETE: ar = (AsyncResult)msg.obj; operationComplete(); cm.getCurrentCalls(lastRelevantPoll); 第二部分:unsolicited 消息从modem上报到java的流程。 c++部份 readerLoop() line = readline(); processLine(line); handleUnsolicited(line); if (s_unsolHandler != NULL) { s_unsolHandler (line1, line2);//实际执行的是void onUnsolicited (const char *s, const char *sms_pdu) if (strStartsWith(s,"+CRING:") || strStartsWith(s,"RING") || strStartsWith(s,"NO CARRIER") || strStartsWith(s,"+CCWA") ) RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, NULL, 0); p.writeInt32 (RESPONSE_UNSOLICITED); p.writeInt32 (unsolResponse); ret = s_unsolResponses[unsolResponseIndex].responseFunction(p, data, datalen); ret = sendResponse(p); sendResponseRaw(p.data(), p.dataSize()); ret = blockingWrite(fd, (void *)&header, sizeof(header)); blockingWrite(fd, data, dataSize); java部份 ril.java->RILReceiver.run() for(;;) { ... length = readRilMessage(is, buffer); p = Parcel.obtain(); p.unmarshall(buffer, 0, length); p.setDataPosition(0); processResponse(p); processUnsolicited (p); response = p.readInt(); switch(response) { ... case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: ret = responseVoid(p); break; ... } switch(response) { case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: if (RILJ_LOGD) unsljLog(response); mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null)); ... } 第三部分、第四部分:猫相关的各种状态的监听和通知机制/通话相关的图标变换的工作原理。 网络状态,edge,gprs图标的处理 第五部分:gprs拨号上网的通路原理。 上层java程序调用gprs流程: =>DataConnectionTracker.java 第六部分:通话相关的语音通路切换原理、震动接口 6、语音通路 6.1、设置语音通路的路由 目前我们有两处处理: a、CallTracker.java中的 handlePollCalls() 检测到+clcc返回的电话列表中有状态为DriverCall.State.ALERTING(表示拨打电话后,对方已经振铃),此时需要设置语音通路为MODE_IN_CALL b、PhoneUtils.java中setAudioMode()函数 c、调用通路分析 AudioManager audioManager = (AudioManager) context.getSystemService (Context.AUDIO_SERVICE); audioManager.setMode(mode); AudioManager.setMode(mode); AudioService.setMode(mode); AudioSystem.setMode(mode);(native function) android_media_AudioSystem.cpp==>android_media_AudioSystem_setMode() AudioSystem.cpp==>setMode() const sp binder = sm->getService(String16("media.audio_flinger")); ... gAudioFlinger = interface_cast ... return gAudioFlinger; 通过查找“media.audio_flinger”发现AudioFlinger.cpp==>instantiate()//Main_mediaserver.cpp中被实例化。 defaultServiceManager()->addService(String16("media.audio_flinger"), new AudioFlinger()); mAudioHardware = AudioHardwareInterface::create(); LOGV("Creating Vendor Specific AudioHardware"); hw = createAudioHardware(); return new AudioHardwareMarvell(); return af->setMode(mode); AudioHardwareLittle.cpp==>setMode(mode) doRouting(); enable_incall_headphone()//or others... system("alsactl -f /etc/alsactl/asound.state_none restore"); system("alsactl -f /etc/alsactl/asound.state_headset_r_s restore"); 6.2、来电播放振铃,挂断或接听停止振铃。 ==>Phone.app onCreate() ringer = new Ringer(phone); Vibrator mVibrator = new Vibrator(); mService = IHardwareService.Stub.asInterface(ServiceManager.getService("hardware")); notifier = new CallNotifier(this, phone, ringer, mBtHandsfree); mPhone.registerForIncomingRing(this, PHONE_INCOMING_RING, null); mPhone.registerForPhoneStateChanged(this, PHONE_STATE_CHANGED, null); mPhone.registerForDisconnect(this, PHONE_DISCONNECT, null); ... case PHONE_INCOMING_RING: mRinger.ring(); mHardwareService.setAttentionLight(true); mVibratorThread.start(); while (mContinueVibrating) { mVibrator.vibrate(VIBRATE_LENGTH); SystemClock.sleep(VIBRATE_LENGTH + PAUSE_LENGTH); } ... makeLooper(); mRingHandler.sendEmptyMessage(PLAY_RING_ONCE); ... case PLAY_RING_ONCE: PhoneUtils.setAudioMode(mContext, AudioManager.MODE_RINGTONE); r.play(); ... case PHONE_DISCONNECT: case PHONE_STATE_CHANGED: ... mRinger.stopRing(); Message msg = mRingHandler.obtainMessage(STOP_RING); msg.obj = mRingtone; mRingHandler.sendMessage(msg); case STOP_RING: r.stop(); getLooper().quit(); ... mVibrator.cancel(); 第七部分:通话相关的notification服务 7、通话相关的notification服务。 7.1、NotificationMgr ==>PhoneApp.java onCreate() NotificationMgr.init(this)//NotificationMgr.java//此类主要负责电话通知的具体表现(通知和取消通知),未接图标、通话中、蓝牙激活中、保持中,静音、免提等。封装了简单的瞬间显示文本消息的功能。提供漫游数据连接禁止的通知封装和漫游数据连接允许时取消通知 sMe = new NotificationMgr(context); mNotificationMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mStatusBar = (StatusBarManager) context.getSystemService(Context.STATUS_BAR_SERVICE); //主要用于显示静音和speaker状态的图表(在状态条右边显示) sMe.updateNotifications();//主要功能是: 1、查询是否有未读的未接听电话,并显示到状态栏图标,和通知列表 2、根据是否是电话状态,更新状态栏图表和通知列表(可能是激活,蓝牙,保持等) 7.2、CallNotifier ==>PhoneApp.java onCreate() notifier = new CallNotifier(this, phone, ringer, mBtHandsfree);//此类主要是监听通话相关的事件,然后进行例如来电播放铃声,震动。挂断、接听停止振铃等(调用Ringer类实现此功能),根据不同的状态调用调用NotificationMgr进行具体的通知和取消通知。 第八部分: 通话相关的各种server 电话通信相关的服务:
a、注册监听部分
==>SystemServer.java
init2()
Thread thr = new ServerThread();
thr.setName("android.server.ServerThread");
thr.start();
ServerThread.run()
com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
sInstance = new StatusBarPolicy(context, service);
// phone_signal
mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneData = IconData.makeIcon("phone_signal",
null, com.android.internal.R.drawable.stat_sys_signal_null, 0, 0);
mPhoneIcon = service.addIcon(mPhoneData, null);
// register for phone state notifications.
((TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE))
.listen(mPhoneStateListener,
PhoneStateListener.LISTEN_SERVICE_STATE
| PhoneStateListener.LISTEN_SIGNAL_STRENGTH
| PhoneStateListener.LISTEN_CALL_STATE
| PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
| PhoneStateListener.LISTEN_DATA_ACTIVITY);
//实际是调用的是TelephonyRegistry.listen,此listen函数会将Iphonestatelistener添加到对应的的handler数组中,到时来了事件会轮询回调。
// data_connection
mDataData = IconData.makeIcon("data_connection",
null, com.android.internal.R.drawable.stat_sys_data_connected_g, 0, 0);
mDataIcon = service.addIcon(mDataData, null);
service.setIconVisibility(mDataIcon, false);
b、事件通知部分
==>PhoneFactory.java
makeDefaultPhones()
sPhoneNotifier = new DefaultPhoneNotifier();
useNewRIL(context);
phone = new GSMPhone(context, new RIL(context), sPhoneNotifier);
for example
==>DataConnectionTracker.java
notifyDefaultData(String reason)
phone.notifyDataConnection(reason);
mNotifier.notifyDataConnection(this, reason);
==>DefaultPhoneNotifier.java
mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
sender.getInterfaceName(null));
=>PhoneApp.java
onCreate()
PhoneFactory.makeDefaultPhones(this);
phone = new GSMPhone(context, new SimulatedCommands(), sPhoneNotifier);
mDataConnection = new DataConnectionTracker (this);
createAllPdpList();//建立缺省pdpconnection
pdp = new PdpConnection(phone);
dataLink = new PppLink(phone.mDataConnection);
dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null);
//某个条件触发执行
trySetupData(String reason)
setupData(reason);
pdp = findFreePdp();
Message msg = obtainMessage();
msg.what = EVENT_DATA_SETUP_COMPLETE;
msg.obj = reason;
pdp.connect(apn, msg);
phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
obtainMessage(EVENT_SETUP_PDP_DONE));
//收到EVENT_SETUP_PDP_DONE消息
=>pdpconnection.java
handleMessage()
case EVENT_SETUP_PDP_DONE:
dataLink.connect();//dataLink是pppLink.java
SystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务
poll.what = EVENT_POLL_DATA_CONNECTION;
sendMessageDelayed(poll, POLL_SYSFS_MILLIS);//启动轮询,看是否成功连接gprs
checkPPP()//每隔5秒轮询,看是否连接成功,或断开
//如果已经连接
mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);
//执行到pdpconnection.handleMessage()
case EVENT_LINK_STATE_CHANGED
onLinkStateChanged(ls);
case LINK_UP:
notifySuccess(onConnectCompleted);
onCompleted.sendToTarget();
//执行dataConnectionTracker.java的handleMessage()
case EVENT_DATA_SETUP_COMPLETE
notifyDefaultData(reason);
setupDnsProperties();
setState(State.CONNECTED);
phone.notifyDataConnection(reason);
startNetStatPoll();
resetPollStats();
1、读取发送出去的包数和接受到的包数
2、如果发送的数据包且没有收到应答包数n大于等于看门狗追踪的限定包数。
2.1、开始轮询pdp context list,尝试恢复网络连接
2.2、如果轮询24次后还没有联通网络则停止网络状态轮询,进行一次ping实验。
2.2.1、如果ping成功则,重新进行网络状态轮询,否则发送EVENT_START_RECOVERY事件。
// reset reconnect timer
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
着重c++部分代码的角度分析
trySetupData(String reason)
setupData(reason);
=>PdpConnection.java
pdp.connect(apn, msg);
=>RIL.JAVA
phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
obtainMessage(EVENT_SETUP_PDP_DONE));
send(rr);
//send socket to RIL
//enter c++ layer
=>ril.cpp
processCommandsCallback (int fd, short flags, void *param)
processCommandBuffer(p_record, recordlen);
status = p.readInt32(&request);
pRI->pCI = &(s_commands[request]);
pRI->pCI->dispatchFunction(p, pRI);
dispatchStrings();
s_callbacks.onRequest(pRI->pCI->requestNumber, pStrings, datalen, pRI);
=>reference-ril.c
onRequest();
requestSetupDefaultPDP(data, datalen, t);
err = write_at_to_data_channel("ATD*99***1#",1);
//after a while.get "connect" from data channel,so need to send socket message to java layer.
p.writeInt32 (RESPONSE_SOLICITED);
p.writeInt32 (pRI->token);//the serial No in the request list.
errorOffset = p.dataPosition();
p.writeInt32 (e);
if (e == RIL_E_SUCCESS) {
/* process response on success */
ret = pRI->pCI->responseFunction(p, response, responselen);
/* if an error occurred, rewind and mark it */
if (ret != 0) {
p.setDataPosition(errorOffset);
p.writeInt32 (ret);
}
}
sendResponse(p);
sendResponseRaw(p.data(), p.dataSize());
ret = blockingWrite(fd, (void *)&header, sizeof(header));
blockingWrite(fd, data, dataSize);
=>RIL.JAVA
RILReceiver.run();
length = readRilMessage(is, buffer);
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
processResponse(p);
processSolicited (p);
serial = p.readInt();
error = p.readInt();
rr = findAndRemoveRequestFromList(serial);
ret = responseStrings(p);
if (rr.mResult != null) {
AsyncResult.forMessage(rr.mResult, ret, null);
rr.mResult.sendToTarget();
}
=>pdpConnection.java
handleMessage()
case EVENT_SETUP_PDP_DONE:
...
dataLink.connect();
=>pppLink.java
SystemProperties.set(PROPERTY_PPPD_EXIT_CODE, "");
SystemService.start(SERVICE_PPPD_GPRS);//启动pppd_grps服务
poll.what = EVENT_POLL_DATA_CONNECTION;
sendMessageDelayed(poll, POLL_SYSFS_MILLIS);
dataConnection.state = State.CONNECTING;
handleMessage()
case EVENT_POLL_DATA_CONNECTION
checkPPP();
if (ArrayUtils.equals(mCheckPPPBuffer, UP_ASCII_STRING, UP_ASCII_STRING.length)
|| ArrayUtils.equals(mCheckPPPBuffer, UNKNOWN_ASCII_STRING,
UNKNOWN_ASCII_STRING.length)
&& dataConnection.state == State.CONNECTING)
if (mLinkChangeRegistrant != null) {
mLinkChangeRegistrant.notifyResult(LinkState.LINK_UP);
=>pdpConnection.java
handleMessage()
case EVENT_LINK_STATE_CHANGED:
DataLink.LinkState ls = (DataLink.LinkState) ar.result;
onLinkStateChanged(ls);
case LINK_UP:
notifySuccess(onConnectCompleted);
AsyncResult.forMessage(onCompleted);
onCompleted.sendToTarget();
=>DataConnectionTracker.java
handleMessage()
case EVENT_DATA_SETUP_COMPLETE:
...
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
notifyDefaultData(reason);
setupDnsProperties();//设置dns,gw,我们的实现方式是在pppd中设置的,不用pppd拨号的适用。
setState(State.CONNECTED);
phone.notifyDataConnection(reason);
mNotifier.notifyDataConnection(this, reason);
=>DefaultPhoneNotifier.java
//mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));构造函数中初始化了mRegistry
mRegistry.notifyDataConnection(convertDataState(sender.getDataConnectionState()),
sender.isDataConnectivityPossible(), reason, sender.getActiveApn(),
sender.getInterfaceName(null));
startNetStatPoll();
}
(1)、从ServiceManager得到的:
a、wifiService
b、PhoneInterfaceManager
c、PhoneSubInfo
d、SimPhoneBookInterfaceManager
e、SimSmsInterfaceManager
f、TelephonyRegistry
g、NetStatService
h、ConnectivityService
(2)、从ApplicationContext得到的:
a、TelephonyManager