adn进程JAVA_ADN加载流程

ADN加载流程:

f5925ef3b1b6e46b52a71f4b380a1042.png

IccProvider.java

IccProvider定义在/packages/services/Telephony/AndroidManifest.xml

android:authorities="icc"

android:multiprocess="true"

android:exported="true"

android:readPermission="android.permission.READ_CONTACTS"

android:writePermission="android.permission.WRITE_CONTACTS" />

public class IccProvider extends com.android.internal.telephony.IccProvider {

public IccProvider() {

super();

}

}

从上面可以看到,真正的ICCProvider是在framework中继承ContentProvider,处理ADN/FDN/SDN的query/insert/update/delete等操作,和SIM卡交互完成后,将数据改变信息通知给ContentObserver,然后ContentObserver将数据变化的发送给注册监听的应用,Contacts应用做相应的同步动作。

Contacts数据库和SIM卡联系的同步后面继续分析。

关于ContentProvider和ContentResolver以及ContentObserver的介绍,可以参考:

http://blog.csdn.net/dmk877/a...

IccProvider重写ContentProvider的方法:

8ad023c120ee3730e4fbc97f09245dba.png

UiccPhoneBookController.java

UiccPhoneBookController在ProxyController的构造方法中初始化。

mUiccPhoneBookController = new UiccPhoneBookController(mPhones);

UiccPhoneBookController的构造方法:

public class UiccPhoneBookController extends IIccPhoneBook.Stub {

private static final String TAG = "UiccPhoneBookController";

private Phone[] mPhone;

/* only one UiccPhoneBookController exists */

public UiccPhoneBookController(Phone[] phone) {

if (ServiceManager.getService("simphonebook") == null) {

ServiceManager.addService("simphonebook", this);

}

mPhone = phone;

IccProvider通过AIDL调用UiccPhoneBookController:

try {

IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(

ServiceManager.getService("simphonebook"));

if (iccIpb != null) {

success = iccIpb.updateAdnRecordsInEfBySearchForSubscriber(subId, efType,

"", "", name, number, pin2);

}

} catch (RemoteException ex) {

// ignore it

} catch (SecurityException ex) {

if (DBG) log(ex.toString());

}

关于AIDL的实现后面详细学习

IccPhoneBookInterfaceManager.java

IccPhoneBookInterfaceManager是在Phone的初始化时完成实例化:

在GsmCdmaPhone构造方法initOnce()中:

mIccPhoneBookIntManager = mTelephonyComponentFactory.makeIccPhoneBookInterfaceManager(this);

SimPhoneBookAdnRecordCache.java

SimPhoneBookAdnRecordCache在IccPhoneBookInterfaceManager构造方法中完成初始化:

public IccPhoneBookInterfaceManager(Phone phone) {

this.mPhone = phone;

IccRecords r = phone.getIccRecords();

if (r != null) {

mAdnCache = r.getAdnCache();

}

if(isSimPhoneBookEnabled()){

if(mSimPbAdnCache == null) {

mSimPbAdnCache = new SimPhoneBookAdnRecordCache(

phone.getContext(), phone.getPhoneId(), phone.mCi);

}

}

}

查询SIM卡联系人流程

1 IccProvider

private static final UriMatcher URL_MATCHER =

new UriMatcher(UriMatcher.NO_MATCH);

static {

URL_MATCHER.addURI("icc", "adn", ADN);

URL_MATCHER.addURI("icc", "adn/subId/#", ADN_SUB);

URL_MATCHER.addURI("icc", "fdn", FDN);

URL_MATCHER.addURI("icc", "fdn/subId/#", FDN_SUB);

URL_MATCHER.addURI("icc", "sdn", SDN);

URL_MATCHER.addURI("icc", "sdn/subId/#", SDN_SUB);

}

支持ADN/FDN/SDN的URL

private MatrixCursor loadFromEf(int efType, int subId) {

if (DBG) log("loadFromEf: efType=0x" +

Integer.toHexString(efType).toUpperCase() + ", subscription=" + subId);

List adnRecords = null;

try {

IIccPhoneBook iccIpb = IIccPhoneBook.Stub.asInterface(

ServiceManager.getService("simphonebook"));

if (iccIpb != null) {

adnRecords = iccIpb.getAdnRecordsInEfForSubscriber(subId, efType);

}

} catch (RemoteException ex) {

// ignore it

} catch (SecurityException ex) {

if (DBG) log(ex.toString());

}

//获取adn list转换成cursor

if (adnRecords != null) {

// Load the results

final int N = adnRecords.size();

final MatrixCursor cursor = new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES, N);

if (DBG) log("adnRecords.size=" + N);

for (int i = 0; i < N ; i++) {

loadRecord(adnRecords.get(i), cursor, i);

}

return cursor;

} else {

// No results to load

Rlog.w(TAG, "Cannot load ADN records");

return new MatrixCursor(ADDRESS_BOOK_COLUMN_NAMES);

}

}

UiccPhoneBookController时一个Binder服务类,接口是IIccPhoneBook,服务名"simphonebook"

2.UiccPhoneBookController

getAdnRecordsInEfForSubscriber方法:

@Override

public List getAdnRecordsInEfForSubscriber(int subId, int efid)

throws android.os.RemoteException {

//获取实例,实例在文章开始Phone初始化时设置

IccPhoneBookInterfaceManager iccPbkIntMgr =

getIccPhoneBookInterfaceManager(subId);

if (iccPbkIntMgr != null) {

//调用getAdnRecordsInEf方法

return iccPbkIntMgr.getAdnRecordsInEf(efid);

} else {

Rlog.e(TAG,"getAdnRecordsInEf iccPbkIntMgr is" +

"null for Subscription:"+subId);

return null;

}

}

3.IccPhoneBookInterfaceManager

/**

* Loads the AdnRecords in efid and returns them as a

* List of AdnRecords

*

* throws SecurityException if no READ_CONTACTS permission

*

* @param efid the EF id of a ADN-like ICC

* @return List of AdnRecord

*/

public List getAdnRecordsInEf(int efid) {

//检查权限

if (mPhone.getContext().checkCallingOrSelfPermission(

android.Manifest.permission.READ_CONTACTS)

!= PackageManager.PERMISSION_GRANTED) {

throw new SecurityException(

"Requires android.permission.READ_CONTACTS permission");

}

//根据SIM卡类型设定EF_ID

efid = updateEfForIccType(efid);

if (DBG) logd("getAdnRecordsInEF: efid=0x" + Integer.toHexString(efid).toUpperCase());

//线程同步

synchronized(mLock) {

checkThread();

AtomicBoolean status = new AtomicBoolean(false);

//回调message

Message response = mBaseHandler.obtainMessage(EVENT_LOAD_DONE, status);

if (isSimPhoneBookEnabled() &&

(efid == IccConstants.EF_PBR || efid == IccConstants.EF_ADN)) {

if (mSimPbAdnCache != null) {

//查询联系人,通过message返回

mSimPbAdnCache.requestLoadAllAdnLike(response);

//此处线程wait(),mBaseHandler 获取mRecords后notifyPending(),代码才能继续往下执行

waitForResult(status);

} else {

loge("Failure while trying to load from SIM due to uninit sim pb adncache");

}

} else {

if (mAdnCache != null) {

mAdnCache.requestLoadAllAdnLike(

efid, mAdnCache.extensionEfForEf(efid), response);

waitForResult(status);

} else {

loge("Failure while trying to load from SIM due to uninitialised adncache");

}

}

}

return mRecords;

}

看看Handler的处理:

protected class IccPbHandler extends Handler {

public IccPbHandler(Looper looper) {

super(looper);

}

@Override

public void handleMessage(Message msg) {

AsyncResult ar;

switch (msg.what) {

case EVENT_GET_SIZE_DONE:

ar = (AsyncResult) msg.obj;

synchronized (mLock) {

if (ar.exception == null) {

mRecordSize = (int[])ar.result;

// recordSize[0] is the record length

// recordSize[1] is the total length of the EF file

// recordSize[2] is the number of records in the EF file

logd("GET_RECORD_SIZE Size " + mRecordSize[0] +

" total " + mRecordSize[1] +

" #record " + mRecordSize[2]);

}

notifyPending(ar);

}

break;

case EVENT_UPDATE_DONE:

ar = (AsyncResult) msg.obj;

if(ar.exception != null) {

if(DBG) logd("exception of EVENT_UPDATE_DONE is" + ar.exception );

}

synchronized (mLock) {

mSuccess = (ar.exception == null);

notifyPending(ar);

}

break;

case EVENT_LOAD_DONE://查询完成

ar = (AsyncResult)msg.obj;

synchronized (mLock) {

if (ar.exception == null) {

if(DBG) logd("Load ADN records done");

//返回adn list

mRecords = (List) ar.result;

} else {

if(DBG) logd("Cannot load ADN records");

mRecords = null;

}

//notify()唤醒

notifyPending(ar);

}

break;

}

}

4.SimPhoneBookAdnRecordCache查询,requestLoadAllAdnLike()方法

public void requestLoadAllAdnLike(Message response) {

//加入message list

if (mAdnLoadingWaiters != null) {

mAdnLoadingWaiters.add(response);

}

//线程同步

synchronized (mLock) {

if (!mSimPbRecords.isEmpty()) {

log("ADN cache has already filled in");

if (mRefreshAdnCache) {

mRefreshAdnCache = false;

refreshAdnCache();

} else {

notifyAndClearWaiters();

}

return;

}

//查询adn

queryAdnRecord();

}

}

queryAdnRecord方法:

public void queryAdnRecord () {

mRecCount = 0;

mAdnCount = 0;

mValidAdnCount = 0;

mEmailCount = 0;

mAddNumCount = 0;

log("start to queryAdnRecord");

//查询ADN record,返回容量

mCi.getAdnRecord(obtainMessage(EVENT_QUERY_ADN_RECORD_DONE));

//向RIL注册ADN records info监听

mCi.registerForAdnRecordsInfo(this, EVENT_LOAD_ADN_RECORD_DONE, null);

try {

//线程等待,EVENT_LOAD_ADN_RECORD_DONE消息处理完(实际是EVENT_LOAD_ALL_ADN_LIKE_DONE)后notify唤醒

mLock.wait();

} catch (InterruptedException e) {

Rlog.e(LOG_TAG, "Interrupted Exception in queryAdnRecord");

}

//取消监听

mCi.unregisterForAdnRecordsInfo(this);

}

handlerMessage中的处理:

case EVENT_QUERY_ADN_RECORD_DONE:

log("Querying ADN record done");

if (ar.exception != null) {

synchronized (mLock) {

mLock.notify();

}

for (Message response : mAdnLoadingWaiters) {

sendErrorResponse(response, "Query adn record failed" + ar.exception);

}

mAdnLoadingWaiters.clear();

break;

}

mAdnCount = ((int[]) (ar.result))[0];

mValidAdnCount = ((int[]) (ar.result))[1];

mEmailCount = ((int[]) (ar.result))[2];

mValidEmailCount = ((int[]) (ar.result))[3];

mAddNumCount = ((int[]) (ar.result))[4];

mValidAddNumCount = ((int[]) (ar.result))[5];

log("Max ADN count is: " + mAdnCount

+ ", Valid ADN count is: " + mValidAdnCount

+ ", Email count is: " + mEmailCount

+ ", Valid Email count is: " + mValidEmailCount

+ ", Add number count is: " + mAddNumCount

+ ", Valid Add number count is: " + mValidAddNumCount);

if(mValidAdnCount == 0 || mRecCount == mValidAdnCount) {

sendMessage(obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE));

}

break;

case EVENT_LOAD_ADN_RECORD_DONE:

log("Loading ADN record done");

if (ar.exception != null) {

break;

}

SimPhoneBookAdnRecord[] AdnRecordsGroup = (SimPhoneBookAdnRecord[])(ar.result);

for (int i = 0 ; i < AdnRecordsGroup.length ; i++) {

if (AdnRecordsGroup[i] != null) {

mSimPbRecords.add(new AdnRecord(0,

AdnRecordsGroup[i].getRecordIndex(),

AdnRecordsGroup[i].getAlphaTag(),

AdnRecordsGroup[i].getNumber(),

AdnRecordsGroup[i].getEmails(),

AdnRecordsGroup[i].getAdNumbers()));

mRecCount ++;

}

}

if(mRecCount == mValidAdnCount) {

sendMessage(obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE));

}

break;

case EVENT_LOAD_ALL_ADN_LIKE_DONE:

log("Loading all ADN records done");

synchronized (mLock) {

mLock.notify();

}

notifyAndClearWaiters();

break;

RIL先返回RIL_UNSOL_RESPONSE_ADN_RECORDS,在EVENT_LOAD_ADN_RECORD_DONE事件中处理,更新mSimPbRecords和MRecount;

然后RIL返回getAdnRecord的请求RIL_REQUEST_GET_ADN_RECORD,在EVENT_QUERY_ADN_RECORD_DONE消息处理,获得Max ADN count/Valid ADN count等数据;

然后发送EVENT_LOAD_ALL_ADN_LIKE_DONE消息,在该消息中mLock.notify()(queryAdnRecord 方法继续执行解除注册);

notifyAndClearWaiters方法将之前requestLoadAllAdnLike方法中记录的messaage消息发出去,发给IccPhoneBookInterfaceManager处理;

IccPhoneBookInterfaceManager的getAdnRecordsInEf方法此时走到waitForResult(),线程wait,在mBaseHandler处理完 message后获取mRecords,然后唤醒等待线程,getAdnRecordsInEf方法执行完毕获得返回and list。

开机加载ADN log解析:

//通过ContentResolver调用provider查询

3793:09-22 15:52:44.114 2230 2311 D IccProvider: [IccProvider] query

//查询URL

3800:09-22 15:52:44.115 2230 2311 D IccProvider: [IccProvider] getRequestSubId url: content://icc/adn/subId/1

3801:09-22 15:52:44.115 2230 2311 D IccProvider: [IccProvider] loadFromEf: efType=0x6F3A, subscription=1

//调用IccPbInterfaceManager getAdnRecordsInEF方法查询

3802:09-22 15:52:44.116 2230 2311 D IccPhoneBookIM: [IccPbInterfaceManager] getAdnRecordsInEF: efid=0x4F30

//调用SimPhoneBookAdnRecordCache requestLoadAllAdnLike方法

3803:09-22 15:52:44.116 2230 2311 D SimPhoneBookAdnRecordCache: start to queryAdnRecord

//queryAdnRecord方法通过RIL查询

3804:09-22 15:52:44.117 2230 2311 D RILJ : [3884]> RIL_REQUEST_GET_ADN_RECORD [SUB1]

//此处queryAdnRecord方法wait

//RIL查询

3806:09-22 15:52:44.135 2230 2293 D RILJ : Unsol response received for RIL_UNSOL_RESPONSE_ADN_RECORDS Sending ack to ril.cpp [SUB1]

3807:09-22 15:52:44.136 2230 2293 D RILJ : [SimPhoneBookAdnRecord{index =1, name = Bbbbbbbbb, number = 123456789, email count = 1, email = [zzzzz@huaqin.com], ad number count = 0, ad number = null}] [SUB1]

3808:09-22 15:52:44.136 2230 2293 D RILJ : [UNSL]< RIL_UNSOL_RESPONSE_ADN_RECORDS [SUB1]

//RIL先返回RIL_UNSOL_RESPONSE_ADN_RECORDS

3809:09-22 15:52:44.136 2230 2230 D SimPhoneBookAdnRecordCache: Loading ADN record done

3810:09-22 15:52:44.136 2230 2293 D RILJ : [3884]< RIL_REQUEST_GET_ADN_RECORD {500, 1, 100, 1, 500, 0} [SUB1]

//RIL然后返回RIL_REQUEST_GET_ADN_RECORD

3811:09-22 15:52:44.137 2230 2230 D SimPhoneBookAdnRecordCache: Querying ADN record done

3812:09-22 15:52:44.137 2230 2230 D SimPhoneBookAdnRecordCache: Max ADN count is: 500, Valid ADN count is: 1, Email count is: 100, Valid Email count is: 1, Add number count is: 500, Valid Add number count is: 0

//sendMessage(obtainMessage(EVENT_LOAD_ALL_ADN_LIKE_DONE))

3817:09-22 15:52:44.147 2230 2230 D SimPhoneBookAdnRecordCache: Loading all ADN records done

//此处notify

3818:09-22 15:52:44.147 2230 2230 D SimPhoneBookAdnRecordCache: Loading all ADN records done mLock.notify

//此处解除注册

3819:09-22 15:52:44.147 2230 2311 D SimPhoneBookAdnRecordCache: unregisterForAdnRecordsInfo

//此处getAdnRecordsInEF方法wait

3820:09-22 15:52:44.147 2230 2311 D IccPhoneBookIM: [IccPbInterfaceManager] getAdnRecordsInEF: start wait

3821:09-22 15:52:44.148 2230 2311 D IccPhoneBookIM: [IccPbInterfaceManager] mLock.wait()

//IccPbInterfaceManager处理EVENT_LOAD_DONE消息

3822:09-22 15:52:44.148 2230 2303 D IccPhoneBookIM: [IccPbInterfaceManager] Load ADN records done

//处理完消息后唤醒

3823:09-22 15:52:44.148 2230 2303 D IccPhoneBookIM: [IccPbInterfaceManager] mLock.notifyAll

//查询执行结束

3824:09-22 15:52:44.148 2230 2311 D IccPhoneBookIM: [IccPbInterfaceManager] getAdnRecordsInEF: end

3825:09-22 15:52:44.149 2230 2311 D IccProvider: [IccProvider] adnRecords.size=1

3826:09-22 15:52:44.149 2230 2311 D IccProvider: [IccProvider] loadRecord: Bbbbbbbbb, [98O8HYCOBHMq32eZZczDTKeuNEE]

3827:09-22 15:52:44.149 2230 2311 D IccProvider: [IccProvider] Adding email:[27d4JpidP9pzDQRt2hPJU82D-UA]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值