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