RIL
public RIL(Context context, int preferredNetworkType, int cdmaSubscription,int phoneId) {
super(context);
mCdmaSubscription = cdmaSubscription;
mPreferredNetworkType = preferredNetworkType;
mPhoneType = RILConstants.NO_PHONE;
mPhoneId = phoneId;
if (mPhoneId != PhoneFactory.DEFAULT_PHONE_ID) {
SOCKET_NAME_RIL = SOCKET_NAME_RIL + phoneId;
}
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
mWakeLock.setReferenceCounted(false);
mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,DEFAULT_WAKE_LOCK_TIMEOUT);
mRequestMessagesPending = 0;
mRequestMessagesWaiting = 0;
//创建ril发送线程
mSenderThread = new HandlerThread("RILSender");
mSenderThread.start();
Looper looper = mSenderThread.getLooper();
mSender = new RILSender(looper);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
riljLog("Not starting RILReceiver: wifi-only");
} else {
riljLog("Starting RILReceiver");
//创建接收线程
mReceiver = new RILReceiver();
mReceiverThread = new Thread(mReceiver, "RILReceiver");
mReceiverThread.start();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
context.registerReceiver(mIntentReceiver, filter);
}
}
RIL线程模型:
RILSender
当上层需要向rild服务发送请求时,通过RIL的send函数来完成。
public void handleMessage(Message msg) {
RILRequest rr = (RILRequest) (msg.obj);
RILRequest req = null;
switch (msg.what) {
case EVENT_SEND:
boolean alreadySubtracted = false;
try {
LocalSocket s;
s = mSocket;
if (s == null) {
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
if (mRequestMessagesPending > 0)
mRequestMessagesPending--;
alreadySubtracted = true;
return;
}
synchronized (mRequestsList) {
mRequestsList.add(rr);
mRequestMessagesWaiting++;
}
if (mRequestMessagesPending > 0)
mRequestMessagesPending--;
alreadySubtracted = true;
byte[] data;
data = rr.mp.marshall();
rr.mp.recycle();
rr.mp = null;
if (data.length > RIL_MAX_COMMAND_BYTES) {
throw new RuntimeException("Parcel larger than max bytes allowed! "+ data.length);
}
// parcel length in big endian
dataLength[0] = dataLength[1] = 0;
dataLength[2] = (byte) ((data.length >> 8) & 0xff);
dataLength[3] = (byte) ((data.length) & 0xff);
s.getOutputStream().write(dataLength);
s.getOutputStream().write(data);
} catch (IOException ex) {
Log.e(LOG_TAG, "IOException", ex);
req = findAndRemoveRequestFromList(rr.mSerial);
if (req != null || !alreadySubtracted) {
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
}
} catch (RuntimeException exc) {
Log.e(LOG_TAG, "Uncaught exception ", exc);
req = findAndRemoveRequestFromList(rr.mSerial);
if (req != null || !alreadySubtracted) {
rr.onError(GENERIC_FAILURE, null);
rr.release();
}
} finally {
releaseWakeLockIfDone();
}
if (!alreadySubtracted && mRequestMessagesPending > 0) {
mRequestMessagesPending--;
}
break;
case EVENT_WAKE_LOCK_TIMEOUT:
synchronized (mWakeLock) {
if (mWakeLock.isHeld()) {
if (mRequestMessagesWaiting != 0) {
mRequestMessagesWaiting = 0;
}
if (mRequestMessagesPending != 0) {
mRequestMessagesPending = 0;
}
mWakeLock.release();
}
}
break;
}
}
写入rild套接字的数据为:
发送步骤:
1.生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中
2.使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler
3.RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回。
RILReceiver
public void run() {
int retryCount = 0;
try {
for (;;) {
LocalSocket s = null;
LocalSocketAddress l;
try {
//创建socket并连接到rild
s = new LocalSocket();
l = new LocalSocketAddress(SOCKET_NAME_RIL,LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
} catch (IOException ex) {
try {
if (s != null) {
s.close();
}
} catch (IOException ex2) {
// ignore failure to close after failure to connect
}
if (retryCount == 8) {
Log.e(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL
+ "' socket after " + retryCount
+ " times, continuing to retry silently");
} else if (retryCount > 0 && retryCount < 8) {
Log.i(LOG_TAG, "Couldn't find '" + SOCKET_NAME_RIL
+ "' socket; retrying after timeout");
}
try {
Thread.sleep(SOCKET_OPEN_RETRY_MILLIS);
} catch (InterruptedException er) {
}
retryCount++;
continue;
}
retryCount = 0;
mSocket = s;
Log.i(LOG_TAG, "Connected to '" + SOCKET_NAME_RIL + "' socket");
int length = 0;
try {
InputStream is = mSocket.getInputStream();
//循环从socket中读取消息
for (;;) {
Parcel p;
length = readRilMessage(is, buffer);
if (length < 0) {
break;
}
p = Parcel.obtain();
p.unmarshall(buffer, 0, length);
p.setDataPosition(0);
processResponse(p);
p.recycle();
}
} catch (java.io.IOException ex) {
Log.i(LOG_TAG, "'" + SOCKET_NAME_RIL + "' socket closed",ex);
} catch (Throwable tr) {
Log.e(LOG_TAG, "Uncaught exception read length=" + length+ "Exception:" + tr.toString());
}
//socket连接断开,请求所有请求并重新连接
Log.i(LOG_TAG, "Disconnected from '" + SOCKET_NAME_RIL+ "' socket");
setRadioState(RadioState.RADIO_UNAVAILABLE);
try {
mSocket.close();
} catch (IOException ex) {
}
mSocket = null;
RILRequest.resetSerial();
clearRequestsList(RADIO_NOT_AVAILABLE, false);
}
} catch (Throwable tr) {
Log.e(LOG_TAG, "Uncaught exception", tr);
}
notifyRegistrantsRilConnectionChanged(-1);
}
接收步骤
1.分析接收到的Parcel,根据类型不同进行处理。
2.根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息。
3.将是接收到的数据转换成结果数据。
4.将结果放在RequestMessage中发回到请求的发起者。
分享到:
相关推荐
android_phone_模块分析 针对Phone模块进行分析
3、猫相关的各种状态的监听和通知机制。 4、通话相关的图标变换的工作原理。 5、gprs拨号上网的通路原理。 6、通话相关的语音通路切换原理、震动接口。 7、通话相关的notification服务。 8、通话相关的各种...
Android4.2.2_r1版本Phone电话模块源代码
Android 从contacts 到 phone的总结 比较详细
Phone服务:是指 Phone所能提供的各种服务(来电去电,短信,SIM的锁定,数据连结传输等)与 service不是同一个概念。
android系统模块源码:音乐播放器,BasicSmsReceiver,Bluetooth,VideoEditor,Phone,Camera,Gallery等
主要对android系统的phone模块的框架介绍,清晰,明朗,简单入手
android整个Phone模块的应用层源代码,供大家学习。
压缩包内是android4.0的电话模块源代码
android中phone原理详解,参照流程图,详见该类源码
从以下四层介绍phone模块的框架: App应用程序 Frameworks中间层 Hardware 硬件抽象层 Kernel驱动层
1、此ROM是移植CyanogenMod7.1而来, Android版本为2.3.7, 内核版本为2.6.32 2、解决了之前原生2.3.2的断网和亮度的BUG,并且开启了自动亮度调节功能 3、运行商中文显示) f5 z L3 F9 x: @8 h 4、多媒体源码采用谷.歌的...
1、此ROM是移植CyanogenMod7.1而来, Android版本为2.3.7, 内核版本为2.6.32 2、解决了之前原生2.3.2的断网和亮度的BUG,并且开启了自动亮度调节功能 3、运行商中文显示) f5 z L3 F9 x: @8 h 4、多媒体源码采用谷.歌的...
对于android的phone模块的各种状态,在此备份一下
支持基于AP的网络(Infrastructure)/对等网络Ad-Hoc (IBSS))/ 虚拟AP 模式 ,IPHONE/ IPAD/Android 设备也能不用AP/路由器而直接连接 支持802.11i加密方式:WEP-64/128, TKIP (WPA-PSK) and AES (WPA2-PSK) ...
我对kotlin原生的第一次体验我对kotlin原生的第一次体验如何构建只需运行./gradlew构建它将生成kotlin通用模块我的中等故事的样本示例:我对kotlin的首次体验我对kotlin的第一次体验如何构建只需运行./gradlew...
� 由于采用了 Java 作为应用开发语言,目前可用的传统第三方应用还很少,但由于 Android 是一款完全 开 源的移动计算平台,相信第三方应用会很快的丰富起来。 � Google 提供了一套 Java 核心包 (J2SE 5,J2SE 6) 的...
本书是在分析Android源码的基础上展开的,而源码文件所在的路径一般都很长,例如,文件AndroidRuntime.cpp的真实路径就是framework/base/core/jni/AndroidRuntime.cpp。为了书 写方便起见,我们在各章节开头把该...
1.3 机器一直不断重启6 2.1 BT 打不开7 2.2 BT 工作不稳定14 3.2 ANDROID 4.2 解决 IPHONE 热点连接上后无法上网问题
1、此ROM是移植CyanogenMod7.1而来, Android版本为2.3.7, 内核版本为2.6.32 2、解决了之前原生2.3.2的断网和亮度的BUG,并且开启了自动亮度调节功能 3、运行商中文显示) f5 z L3 F9 x: @8 h 4、多媒体源码采用谷.歌的...