【目标】
在上一篇 Android6.0 源码增加黑名单功能 的基础上增加黑名单和短信拦截记录
【实现】
黑名单数据库和拦截记录数据库上一篇已经增加完成,这就需要我们在电话和短信分发的地方去判断号码是否属于黑名单,我们先来看电话拦截
电话分发拦截
涉及到的源码有
packages/services/Telecomm/src/com/android/server/telecom/callfiltering/AsyncBlockCheckFilter.java
packages/services/Telecomm/src/com/android/server/telecom/callfiltering/BlockCheckerAdapter.java
packages/services/Telecomm/src/com/android/server/telecom/callfiltering/CallFilteringResult.java
packages/services/Telecomm/src/com/android/server/telecom/callfiltering/CallFilterResultCallback.java
packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java
前 4 个是我们新增加的,下载地址6.0 telecom 电话拦截 主要修改在 CallsManager.java 中
import com.android.server.telecom.callfiltering.AsyncBlockCheckFilter;
import com.android.server.telecom.callfiltering.BlockCheckerAdapter;
import com.android.server.telecom.callfiltering.CallFilterResultCallback;
import com.android.server.telecom.callfiltering.CallFilteringResult;
public class CallsManager extends Call.ListenerBase
implements VideoProviderProxy.Listener, CallFilterResultCallback {
....
@Override
public void onSuccessfulIncomingCall(Call incomingCall) {
Log.d(this, "onSuccessfulIncomingCall");
setCallState(incomingCall, CallState.RINGING, "successful incoming call");
/// M: [ALPS01833793]when ECC in progress, should reject incoming call, like sip call.
// Add for 3G VT: video call and voice call could not exist at the same time.
// Add prevent dialing + ringing co-exist: Dialing + Ringing => two active if both answered.
if (hasEmergencyCall() || hasMaximumRingingCalls() || hasMaximumDialingCalls()
|| shouldBlockFor3GVT(incomingCall.isVideoCall())) {
/// @}
incomingCall.reject(false, null);
// since the call was not added to the list of calls, we have to call the missed
// call notifier and the call logger manually.
mMissedCallNotifier.showMissedCallNotification(incomingCall);
mCallLogManager.logCall(incomingCall, Calls.MISSED_TYPE);
} else {
//addCall(incomingCall);
//cczheng add
new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter()).startFilterLookup(incomingCall, this);
}
}
//cczheng add
@Override
public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) {
android.util.Log.i("InterceptInfos", "onCallFilteringComplete....");
if (result.shouldReject) {
android.util.Log.e("InterceptInfos", "onCallFilteringCompleted: blocked call, rejecting.");
incomingCall.reject(false, null);
}else{
addCall(incomingCall);
}
}
....
CallsManager 增加 CallFilterResultCallback 接口实现,覆盖 onCallFilteringComplete() 方法,
收到来电 Call 后,新增的 4 个类开启 AsyncTask 去查询是否是黑名单,是黑名单则写入拦截记录表,并回调到 onCallFilteringComplete() 中,
如果是黑名单则挂断电话。
简单说下来电流程,RIL 层收到来电消息,通知到 telecom 中,
onSuccessfulIncomingCall() 收到来电 call(响铃在 Ringer 中处理),通过 addCall() 将 call 通知到 Dialer 中,进行 UI 显示
短信分发拦截
涉及到的源码
frameworks/opt/telephony/src/java/com/android/internal/telephony/InboundSmsHandler.java
先来看下 InboundSmsHandler
// cczheng add
import com.android.internal.telephony.BlockChecker;
/**
* This class broadcasts incoming SMS messages to interested apps after storing them in
@@ -811,10 812,16 @@ public abstract class InboundSmsHandler extends StateMachine {
int messageCount = tracker.getMessageCount();
byte[][] pdus;
int destPort = tracker.getDestPort();
boolean block = false;
if (messageCount == 1) {
// single-part message
pdus = new byte[][]{tracker.getPdu()};
20190920 cczheng add for check blocking message
String addressNumber = parseDisplayAddress(pdus, tracker.getFormat());
block = BlockChecker.isBlocked(mContext, addressNumber);
android.util.Log.e("InterceptInfos","address=" addressNumber " block1="block);
E
} else {
// MTK-START
@@ -905,6 912,27 @@ public abstract class InboundSmsHandler extends StateMachine {
destPort = port;
}
}
// //20190920 cczheng add for check blocking message
// add check if display address should be blocked or not
if (!block) {
// Depending on the nature of the gateway,
// the display origination address
// is either derived from the content of the SMS TP-OA field,
// or the TP-OA field contains a generic gateway address and
// the from address is added at the beginning in the message body.
// In that case only the first SMS (part of Multi-SMS) comes with
// the display originating address which could be used for block
// checking purpose.
String addressNumber = parseDisplayAddress(pdus, tracker.getFormat());
block = BlockChecker.isBlocked(mContext, addressNumber);
//addressNumber = cursor.getString(DESTINATION_PORT_COLUMN.get(DISPLAY_ADDRESS_COLUMN));
android.util.Log.e("InterceptInfos", "addressNumber==" addressNumber " block2="block);
}
E
}
} catch (SQLException e) {
loge("Can't access multipart SMS database", e);
@@ -921,6 949,12 @@ public abstract class InboundSmsHandler extends StateMachine {
SmsBroadcastReceiver resultReceiver = new SmsBroadcastReceiver(tracker);
//20190920 cczheng add for check blocking message
if (block) {
deleteFromRawTable(tracker.getDeleteWhere(), tracker.getDeleteWhereArgs());
isFilterOutByPpl(pdus, tracker.getFormat());
return false;
}
E
if (destPort == SmsHeader.PORT_WAP_PUSH) {
// Build up the data stream
ByteArrayOutputStream output = new ByteArrayOutputStream();
@@ -1019,6 1053,48 @@ public abstract class InboundSmsHandler extends StateMachine {
return true;
}
20190920 cczheng add for check blocking message S
private String parseDisplayAddress(byte[][] pdus, String format){
try{
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i) {
msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
}
return msgs[0].getOriginatingAddress();
}catch(Exception e){
e.printStackTrace();
}
return "";
}
protected void isFilterOutByPpl(byte[][] pdus, String format) {
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i) {
msgs[i] = SmsMessage.createFromPdu(pdus[i], format);
}
String content = msgs[0].getMessageBody();
String addressNumber = msgs[0].getOriginatingAddress();
addInterceptSms(content, addressNumber);
}
public void addInterceptSms(String content, String addressNumber){
android.content.ContentResolver contentResolver = mContext.getContentResolver();
android.content.ContentValues newValues = new android.content.ContentValues();
newValues.put("type", 0);//sms
newValues.put("number", addressNumber);
newValues.put("content", content);
java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
java.util.Date date = new java.util.Date(System.currentTimeMillis());
String time = simpleDateFormat.format(date);
newValues.put("time", time);
contentResolver.insert(android.net.Uri.parse("content://com.android.blockeddata/intercept"), newValues);
android.util.Log.e("InterceptInfos","add db end sms...");
}
20190920 cczheng add for check blocking message E
短信分发后会进入到 processMessagePart() 中,分为单条短信和多条短信的情况,增加解析短信发送者号码的方法 parseDisplayAddress(),得到号码后判断是否在黑名单列表中,
然后插入拦截数据库