收到通知,返回通知确认
下载彩信
1.onReceive
packages\apps\Mms\src\com\android\mms\transaction\PushReceiver.java
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WAP_PUSH_DELIVER_ACTION) && ContentType.MMS_MESSAGE.equals(intent.getType())) {
// Hold a wake lock for 5 seconds, enough to give any
// services we start time to take their own wake locks.
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
//PARTIAL_WAKE_LOCK:Wake lock level: Ensures that the CPU is running; the screen and keyboard backlight will be allowed
//to go off.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MMS PushReceiver");
wl.acquire(5000);
new ReceivePushTask(context).execute(intent);
}
}
2.doInBackground
packages\apps\Mms\src\com\android\mms\transaction\PushReceiver.java
private class ReceivePushTask extends AsyncTask {
protected Void doInBackground(Intent... intents) {
Intent intent = intents[0];
// Get raw PDU push-data from the message and parse it
byte[] pushData = intent.getByteArrayExtra("data"); //获得数据
PduParser parser = new PduParser(pushData, PduParserUtil.shouldParseContentDisposition());
GenericPdu pdu = parser.parse(); //解析成pdu
PduPersister p = PduPersister.getPduPersister(mContext);
ContentResolver cr = mContext.getContentResolver();
int type = pdu.getMessageType();
long threadId = -1;
switch (type) {
case MESSAGE_TYPE_NOTIFICATION_IND: {
NotificationInd nInd = (NotificationInd) pdu;
if (!isDuplicateNotification(mContext, nInd)) { //不存在相同的通知
// Save the pdu. If we can start downloading the real pdu immediately,
// don't allow persist() to create a thread for the notificationInd
// because it causes UI jank.
//如果是自动下载彩信的,这里存入数据库的时候不创建threadId
Uri uri = p.persist(pdu, Inbox.CONTENT_URI, !NotificationTransaction.allowAutoDownload(),
MessagingPreferenceActivity.getIsGroupMmsEnabled(mContext), null);
// Start service to finish the notification transaction.
Intent svc = new Intent(mContext, TransactionService.class);
svc.putExtra(TransactionBundle.URI, uri.toString());
svc.putExtra(TransactionBundle.TRANSACTION_TYPE, Transaction.NOTIFICATION_TRANSACTION);
mContext.startService(svc);
}
}
}
}
}
3.onStartCommand
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
Message msg = mServiceHandler.obtainMessage(EVENT_NEW_INTENT);
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
return Service.START_NOT_STICKY;
}
4.handleMessage
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private final class ServiceHandler extends Handler {
public void handleMessage(Message msg) {
Transaction transaction = null;
switch (msg.what) {
case EVENT_NEW_INTENT:
onNewIntent((Intent)msg.obj, msg.arg1);
break;
}
}
}
5.onNewIntent
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
public void onNewIntent(Intent intent, int serviceId) {
String action = intent.getAction();
if (ACTION_ONALARM.equals(action) || ACTION_ENABLE_AUTO_RETRIEVE.equals(action) ||
(intent.getExtras() == null)) {
} else{//彩信通知走这里
// For launching NotificationTransaction and test purpose.
TransactionBundle args = new TransactionBundle(intent.getExtras());
launchTransaction(serviceId, args, noNetwork);
}
}
6.launchTransaction
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private void launchTransaction(int serviceId, TransactionBundle txnBundle, boolean noNetwork) {
if (noNetwork) {
Log.w(TAG, "launchTransaction: no network error!");
onNetworkUnavailable(serviceId, txnBundle.getTransactionType());
return;
}
Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST);
msg.arg1 = serviceId;
msg.obj = txnBundle;
if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
Log.v(TAG, "launchTransaction: sending message " + msg);
}
mServiceHandler.sendMessage(msg);
}
7.handleMessage
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private final class ServiceHandler extends Handler {
public void handleMessage(Message msg) {
Transaction transaction = null;
switch (msg.what) {
case EVENT_TRANSACTION_REQUEST:
int transactionType = args.getTransactionType();
switch (transactionType) {
case Transaction.NOTIFICATION_TRANSACTION:
String uri = args.getUri();
if (uri != null) {
transaction = new NotificationTransaction(TransactionService.this, serviceId, transactionSettings, uri);
}
}
if (!processTransaction(transaction)) {
transaction = null;
return;
}
}
}
}
8.processTransaction
packages\apps\Mms\src\com\android\mms\transaction\TransactionService.java
private boolean processTransaction(Transaction transaction) throws IOException {
transaction.attach(TransactionService.this);
transaction.process();
return true;
}
9.process
packages\apps\Mms\src\com\android\mms\transaction\NotificationTransaction.java
public void process() {
new Thread(this, "NotificationTransaction").start();
}
10.run
packages\apps\Mms\src\com\android\mms\transaction\NotificationTransaction.java
public void run() {
DownloadManager downloadManager = DownloadManager.getInstance();
boolean autoDownload = allowAutoDownload(); //是否自动下载
try {
// By default, we set status to STATUS_DEFERRED because we
// should response MMSC with STATUS_DEFERRED when we cannot
// download a MM immediately.
int status = STATUS_DEFERRED;
// Don't try to download when data is suspended, as it will fail, so defer download
if (!autoDownload) { //如果不是自动下载
downloadManager.markState(mUri, DownloadManager.STATE_UNSTARTED);
sendNotifyRespInd(status); //发送 M-NotifyResp.ind
return;
}
downloadManager.markState(mUri, DownloadManager.STATE_DOWNLOADING);
byte[] retrieveConfData = null;
// We should catch exceptions here to response MMSC
// with STATUS_DEFERRED.
try {
retrieveConfData = getPdu(mContentLocation); //下载彩信
} catch (IOException e) {
mTransactionState.setState(FAILED);
}
if (retrieveConfData != null) {
//解析
GenericPdu pdu = new PduParser(retrieveConfData, PduParserUtil.shouldParseContentDisposition()).parse();
if ((pdu == null) || (pdu.getMessageType() != MESSAGE_TYPE_RETRIEVE_CONF)) {//如果下载的类型不对
mTransactionState.setState(FAILED);
status = STATUS_UNRECOGNIZED;
} else{ //下载到正确的M-Retrieve.conf pdu
// Save the received PDU (must be a M-RETRIEVE.CONF).
PduPersister p = PduPersister.getPduPersister(mContext);
//存储彩信
Uri uri = p.persist(pdu, Inbox.CONTENT_URI, true, MessagingPreferenceActivity.getIsGroupMmsEnabled(mContext), null);
// We have successfully downloaded the new MM. Delete the
// M-NotifyResp.ind from Inbox.
//删除通知 M-Notification.ind
SqliteWrapper.delete(mContext, mContext.getContentResolver(), mUri, null, null);
mUri = uri;
status = STATUS_RETRIEVED;
}
}
sendNotifyRespInd(status); //发送 M-NotifyResp.ind
} finally {
mTransactionState.setContentUri(mUri);
if (!autoDownload) {
// Always mark the transaction successful for deferred
// download since any error here doesn't make sense.
mTransactionState.setState(SUCCESS);
}
if (mTransactionState.getState() != SUCCESS) {
mTransactionState.setState(FAILED);
Log.e(TAG, "NotificationTransaction failed.");
}
notifyObservers(); //执行TransactionService的update
}
}