172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2007-2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.io.IOException; 21d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport java.util.ArrayList; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Service; 2415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylorimport android.content.BroadcastReceiver; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris; 26c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylorimport android.content.ContentValues; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 2915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylorimport android.content.IntentFilter; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 31c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylorimport android.database.sqlite.SqliteWrapper; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.ConnectivityManager; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.NetworkInfo; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.HandlerThread; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.IBinder; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Looper; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.PowerManager; 41d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.provider.Telephony.Mms; 42d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.provider.Telephony.MmsSms; 43c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylorimport android.provider.Telephony.Mms.Sent; 44d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.provider.Telephony.MmsSms.PendingMessages; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 49d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.internal.telephony.Phone; 50d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.internal.telephony.PhoneConstants; 51d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.LogTag; 529dc65e65a3968cfdca8d4611eba93cf2e0a1df05David Braunimport com.android.mms.MmsConfig; 53d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 542c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylorimport com.android.mms.util.DownloadManager; 55d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.RateController; 56d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.GenericPdu; 57d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.NotificationInd; 58d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduHeaders; 59d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduParser; 60d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduPersister; 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The TransactionService of the MMS Client is responsible for handling requests 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to initiate client-transactions sent from: 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <ul> 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>The Proxy-Relay (Through Push messages)</li> 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>The composer/viewer activities of the MMS Client (Through intents)</li> 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * </ul> 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The TransactionService runs locally in the same process as the application. 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * It contains a HandlerThread to which messages are posted from the 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * intent-receivers of this application. 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <p/> 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <b>IMPORTANT</b>: This is currently the only instance in the system in 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * which simultaneous connectivity to both the mobile data network and 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * a Wi-Fi network is allowed. This makes the code for handling network 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * connectivity somewhat different than it is in other applications. In 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * particular, we want to be able to send or receive MMS messages when 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * a Wi-Fi connection is active (which implies that there is no connection 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to the mobile data network). This has two main consequences: 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <ul> 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Testing for current network connectivity ({@link android.net.NetworkInfo#isConnected()} is 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * not sufficient. Instead, the correct test is for network availability 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * ({@link android.net.NetworkInfo#isAvailable()}).</li> 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>If the mobile data network is not in the connected state, but it is available, 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * we must initiate setup of the mobile data connection, and defer handling 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * the MMS transaction until the connection is established.</li> 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * </ul> 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class TransactionService extends Service implements Observer { 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "TransactionService"; 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used to identify notification intents broadcasted by the 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionService when a Transaction is completed. 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String TRANSACTION_COMPLETED_ACTION = 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "android.intent.action.TRANSACTION_COMPLETED_ACTION"; 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Action for the Intent which is sent by Alarm service to launch 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionService. 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String ACTION_ONALARM = "android.intent.action.ACTION_ONALARM"; 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 10656e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor * Action for the Intent which is sent when the user turns on the auto-retrieve setting. 10756e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor * This service gets started to auto-retrieve any undownloaded messages. 10856e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor */ 10956e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor public static final String ACTION_ENABLE_AUTO_RETRIEVE 11056e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor = "android.intent.action.ACTION_ENABLE_AUTO_RETRIEVE"; 11156e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor 11256e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor /** 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used as extra key in notification intents broadcasted by the TransactionService 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * when a Transaction is completed (TRANSACTION_COMPLETED_ACTION intents). 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Allowed values for this key are: TransactionState.INITIALIZED, 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionState.SUCCESS, TransactionState.FAILED. 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String STATE = "state"; 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used as extra key in notification intents broadcasted by the TransactionService 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * when a Transaction is completed (TRANSACTION_COMPLETED_ACTION intents). 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Allowed values for this key are any valid content uri. 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String STATE_URI = "uri"; 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_TRANSACTION_REQUEST = 1; 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_CONTINUE_MMS_CONNECTIVITY = 3; 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_HANDLE_NEXT_PENDING_TRANSACTION = 4; 13049a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor private static final int EVENT_NEW_INTENT = 5; 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_QUIT = 100; 13235de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_MSG_QUEUED = 1; 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_DOWNLOAD_LATER = 2; 135c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor private static final int TOAST_NO_APN = 3; 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_NONE = -1; 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // How often to extend the use of the MMS APN while a transaction 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // is still being processed. 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int APN_EXTENSION_WAIT = 30 * 1000; 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ServiceHandler mServiceHandler; 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Looper mServiceLooper; 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final ArrayList<Transaction> mProcessing = new ArrayList<Transaction>(); 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final ArrayList<Transaction> mPending = new ArrayList<Transaction>(); 14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ConnectivityManager mConnMgr; 14715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor private ConnectivityBroadcastReceiver mReceiver; 14815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private PowerManager.WakeLock mWakeLock; 15082f5492b211f51e71c7089eb7779384ff03c0d89Tom Taylor 15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public Handler mToastHandler = new Handler() { 15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleMessage(Message msg) { 15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String str = null; 15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (msg.what == TOAST_MSG_QUEUED) { 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project str = getString(R.string.message_queued); 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (msg.what == TOAST_DOWNLOAD_LATER) { 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project str = getString(R.string.download_later); 160c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor } else if (msg.what == TOAST_NO_APN) { 161c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor str = getString(R.string.no_apn); 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (str != null) { 16549a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Toast.makeText(TransactionService.this, str, 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Toast.LENGTH_LONG).show(); 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreate() { 173812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Creating TransactionService"); 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Start up the thread running the service. Note that we create a 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // separate thread because the service normally runs in the process's 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // main thread, which we don't want to block. 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HandlerThread thread = new HandlerThread("TransactionService"); 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project thread.start(); 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper = thread.getLooper(); 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler = new ServiceHandler(mServiceLooper); 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18615c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor mReceiver = new ConnectivityBroadcastReceiver(); 18715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor IntentFilter intentFilter = new IntentFilter(); 18815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 18915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor registerReceiver(mReceiver, intentFilter); 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19135de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 19335de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor public int onStartCommand(Intent intent, int flags, int startId) { 19449a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor if (intent != null) { 19549a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Message msg = mServiceHandler.obtainMessage(EVENT_NEW_INTENT); 19649a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor msg.arg1 = startId; 19749a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor msg.obj = intent; 19849a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor mServiceHandler.sendMessage(msg); 19935de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor } 20049a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor return Service.START_NOT_STICKY; 20149a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor } 20249a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor 20349a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor public void onNewIntent(Intent intent, int serviceId) { 2046dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 2059dc65e65a3968cfdca8d4611eba93cf2e0a1df05David Braun if (mConnMgr == null || !mConnMgr.getMobileDataEnabled() 2069dc65e65a3968cfdca8d4611eba93cf2e0a1df05David Braun || !MmsConfig.isSmsEnabled(getApplicationContext())) { 207ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor endMmsConnectivity(); 208ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor stopSelf(serviceId); 209ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor return; 210ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor } 211ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor NetworkInfo ni = mConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS); 212ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor boolean noNetwork = ni == null || !ni.isAvailable(); 21335de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 214812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 21549a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Log.v(TAG, "onNewIntent: serviceId: " + serviceId + ": " + intent.getExtras() + 21649a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor " intent=" + intent); 2176dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, " networkAvailable=" + !noNetwork); 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 22056e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor String action = intent.getAction(); 22156e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor if (ACTION_ONALARM.equals(action) || ACTION_ENABLE_AUTO_RETRIEVE.equals(action) || 22256e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor (intent.getExtras() == null)) { 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Scan database to find all pending operations. 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = PduPersister.getPduPersister(this).getPendingMessages( 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project System.currentTimeMillis()); 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 228ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang int count = cursor.getCount(); 229ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang 230ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2312c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: cursor.count=" + count + " action=" + action); 232ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang } 233ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang 234ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang if (count == 0) { 235812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 23649a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Log.v(TAG, "onNewIntent: no pending messages. Stopping service."); 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RetryScheduler.setRetryAlarm(this); 23949a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor stopSelfIfIdle(serviceId); 24049a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor return; 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 243ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang int columnIndexOfMsgId = cursor.getColumnIndexOrThrow(PendingMessages.MSG_ID); 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int columnIndexOfMsgType = cursor.getColumnIndexOrThrow( 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingMessages.MSG_TYPE); 24635de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project while (cursor.moveToNext()) { 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int msgType = cursor.getInt(columnIndexOfMsgType); 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int transactionType = getTransactionType(msgType); 2502c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2512c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: msgType=" + msgType + " transactionType=" + 2522c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor transactionType); 2532c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (noNetwork) { 25549a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor onNetworkUnavailable(serviceId, transactionType); 25649a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor return; 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (transactionType) { 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case -1: 26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If it's a transiently failed transaction, 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // we should retry it in spite of current 26456e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor // downloading mode. If the user just turned on the auto-retrieve 26556e8095ef2e82f8db5fd4a04fa0a67c91cc7fbd3Tom Taylor // option, we also retry those messages that don't have any errors. 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int failureType = cursor.getInt( 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.getColumnIndexOrThrow( 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingMessages.ERROR_TYPE)); 2692c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor DownloadManager downloadManager = DownloadManager.getInstance(); 2702c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor boolean autoDownload = downloadManager.isAuto(); 2712c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2722c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: failureType=" + failureType + 2732c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor " action=" + action + " isTransientFailure:" + 2742c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor isTransientFailure(failureType) + " autoDownload=" + 2752c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor autoDownload); 2762c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 2772c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (!autoDownload) { 2782c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // If autodownload is turned off, don't process the 2792c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // transaction. 2802c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2812c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: skipping - autodownload off"); 2822c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 2852c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // Logic is twisty. If there's no failure or the failure 2862c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // is a non-permanent failure, we want to process the transaction. 2872c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // Otherwise, break out and skip processing this transaction. 2882c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (!(failureType == MmsSms.NO_ERROR || 2892c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor isTransientFailure(failureType))) { 2902c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2912c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: skipping - permanent error"); 2922c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 2932c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor break; 2942c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 2952c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 2962c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: falling through and processing"); 2972c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 2982c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor // fall-through 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri uri = ContentUris.withAppendedId( 30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.CONTENT_URI, 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.getLong(columnIndexOfMsgId)); 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = new TransactionBundle( 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionType, uri.toString()); 30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // FIXME: We use the same startId for all MMs. 3062c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 3072c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor Log.v(TAG, "onNewIntent: launchTransaction uri=" + uri); 3082c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor } 30949a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor launchTransaction(serviceId, args, false); 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 317812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 31849a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Log.v(TAG, "onNewIntent: no pending messages. Stopping service."); 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RetryScheduler.setRetryAlarm(this); 32149a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor stopSelfIfIdle(serviceId); 32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 324812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 32549a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor Log.v(TAG, "onNewIntent: launch transaction..."); 3265d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project } 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // For launching NotificationTransaction and test purpose. 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = new TransactionBundle(intent.getExtras()); 32949a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor launchTransaction(serviceId, args, noNetwork); 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void stopSelfIfIdle(int startId) { 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.isEmpty() && mPending.isEmpty()) { 336812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 3375d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project Log.v(TAG, "stopSelfIfIdle: STOP!"); 3385d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project } 33982f5492b211f51e71c7089eb7779384ff03c0d89Tom Taylor 34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(startId); 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static boolean isTransientFailure(int type) { 3462c8593aa4b05933df5c766af1827a11578dc37e3Tom Taylor return type > MmsSms.NO_ERROR && type < MmsSms.ERR_TYPE_GENERIC_PERMANENT; 34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int getTransactionType(int msgType) { 35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msgType) { 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.RETRIEVE_TRANSACTION; 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.READREC_TRANSACTION; 35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_SEND_REQ: 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.SEND_TRANSACTION; 35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Unrecognized MESSAGE_TYPE: " + msgType); 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return -1; 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void launchTransaction(int serviceId, TransactionBundle txnBundle, boolean noNetwork) { 36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (noNetwork) { 3655d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project Log.w(TAG, "launchTransaction: no network error!"); 36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project onNetworkUnavailable(serviceId, txnBundle.getTransactionType()); 36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST); 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.arg1 = serviceId; 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.obj = txnBundle; 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 373812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 3746dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "launchTransaction: sending message " + msg); 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void onNetworkUnavailable(int serviceId, int transactionType) { 380ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 381ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang Log.v(TAG, "onNetworkUnavailable: sid=" + serviceId + ", type=" + transactionType); 382ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang } 383ad98c6b8428b6b9a328244054a7293f4bec320e0Wei Huang 38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int toastType = TOAST_NONE; 38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transactionType == Transaction.RETRIEVE_TRANSACTION) { 38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project toastType = TOAST_DOWNLOAD_LATER; 38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (transactionType == Transaction.SEND_TRANSACTION) { 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project toastType = TOAST_MSG_QUEUED; 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (toastType != TOAST_NONE) { 39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mToastHandler.sendEmptyMessage(toastType); 39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onDestroy() { 398812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Destroying TransactionService"); 40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!mPending.isEmpty()) { 4025d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project Log.w(TAG, "TransactionService exiting with transaction still pending"); 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project releaseWakeLock(); 40635de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 40715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor unregisterReceiver(mReceiver); 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendEmptyMessage(EVENT_QUIT); 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public IBinder onBind(Intent intent) { 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle status change of Transaction (The Observable). 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void update(Observable observable) { 42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Transaction transaction = (Transaction) observable; 42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = transaction.getServiceId(); 4236dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 424812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 4256dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "update transaction " + serviceId); 4266dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 4276dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.remove(transaction); 43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mPending.size() > 0) { 432812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 4336dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "update: handle next pending transaction..."); 4346dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage( 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project EVENT_HANDLE_NEXT_PENDING_TRANSACTION, 43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.getConnectionSettings()); 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 440310a878485369829f93709544b718008b2f623c2Tom Taylor else if (mProcessing.isEmpty()) { 441812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 4426dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "update: endMmsConnectivity"); 4436dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 445310a878485369829f93709544b718008b2f623c2Tom Taylor } else { 446310a878485369829f93709544b718008b2f623c2Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 447310a878485369829f93709544b718008b2f623c2Tom Taylor Log.v(TAG, "update: mProcessing is not empty"); 448310a878485369829f93709544b718008b2f623c2Tom Taylor } 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = new Intent(TRANSACTION_COMPLETED_ACTION); 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionState state = transaction.getState(); 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = state.getState(); 45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project intent.putExtra(STATE, result); 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (result) { 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TransactionState.SUCCESS: 459812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction complete: " + serviceId); 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project intent.putExtra(STATE_URI, state.getContentUri()); 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Notify user in the system-wide notification area. 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (transaction.getType()) { 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.NOTIFICATION_TRANSACTION: 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 4693b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // We're already in a non-UI thread called from 4703b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor // NotificationTransacation.run(), so ok to block here. 471c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev long threadId = MessagingNotification.getThreadId( 472c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev this, state.getContentUri()); 473c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.blockingUpdateNewMessageIndicator(this, 474c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev threadId, 4753b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor false); 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MessagingNotification.updateDownloadFailedNotification(this); 47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.SEND_TRANSACTION: 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RateController.getInstance().update(); 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TransactionState.FAILED: 484812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction failed: " + serviceId); 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 489812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction state unknown: " + 49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project serviceId + " " + result); 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 496812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 4976dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "update: broadcast transaction result " + result); 4986dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Broadcast the result of the transaction. 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendBroadcast(intent); 50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.detach(this); 503310a878485369829f93709544b718008b2f623c2Tom Taylor stopSelfIfIdle(serviceId); 50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void createWakeLock() { 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Create a new wake lock if we haven't made one yet. 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mWakeLock == null) { 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MMS Connectivity"); 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.setReferenceCounted(false); 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51535de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void acquireWakeLock() { 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // It's okay to double-acquire this because we are not using it 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // in reference-counted mode. 519c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor Log.v(TAG, "mms acquireWakeLock"); 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.acquire(); 52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52235de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void releaseWakeLock() { 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Don't release the wake lock if it hasn't been created and acquired. 52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mWakeLock != null && mWakeLock.isHeld()) { 526c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor Log.v(TAG, "mms releaseWakeLock"); 52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.release(); 52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected int beginMmsConnectivity() throws IOException { 532ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 533ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor Log.v(TAG, "beginMmsConnectivity"); 534ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor } 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Take a wake lock so we don't fall asleep before the message is downloaded. 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project createWakeLock(); 53735de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = mConnMgr.startUsingNetworkFeature( 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS); 5406dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 541812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 5426dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "beginMmsConnectivity: result=" + result); 5436dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 5446dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (result) { 54609fb57c41102b5e10beb7081f203d5b5ed8fa71eWink Saville case PhoneConstants.APN_ALREADY_ACTIVE: 54709fb57c41102b5e10beb7081f203d5b5ed8fa71eWink Saville case PhoneConstants.APN_REQUEST_STARTED: 5486dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang acquireWakeLock(); 5496dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang return result; 55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new IOException("Cannot establish MMS connectivity"); 55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void endMmsConnectivity() { 55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 557812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 5586dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "endMmsConnectivity"); 5596dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 56035de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // cancel timer for renewal of lease 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.removeMessages(EVENT_CONTINUE_MMS_CONNECTIVITY); 56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mConnMgr != null) { 56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnMgr.stopUsingNetworkFeature( 5654485565b0141038f65f8f1de5cccc2bafc55dcfaRobert Greenwalt ConnectivityManager.TYPE_MOBILE, 5664485565b0141038f65f8f1de5cccc2bafc55dcfaRobert Greenwalt Phone.FEATURE_ENABLE_MMS); 56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project releaseWakeLock(); 57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final class ServiceHandler extends Handler { 57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ServiceHandler(Looper looper) { 57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(looper); 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 57815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor private String decodeMessage(Message msg) { 57915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (msg.what == EVENT_QUIT) { 58015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "EVENT_QUIT"; 58115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (msg.what == EVENT_CONTINUE_MMS_CONNECTIVITY) { 58215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "EVENT_CONTINUE_MMS_CONNECTIVITY"; 58315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (msg.what == EVENT_TRANSACTION_REQUEST) { 58415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "EVENT_TRANSACTION_REQUEST"; 58515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (msg.what == EVENT_HANDLE_NEXT_PENDING_TRANSACTION) { 58615c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "EVENT_HANDLE_NEXT_PENDING_TRANSACTION"; 5873dde4a0552dc6365002071cbf7dbbdfce8570112Tom Taylor } else if (msg.what == EVENT_NEW_INTENT) { 5883dde4a0552dc6365002071cbf7dbbdfce8570112Tom Taylor return "EVENT_NEW_INTENT"; 58915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 59015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "unknown message.what"; 59115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 59215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 59315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor private String decodeTransactionType(int transactionType) { 59415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (transactionType == Transaction.NOTIFICATION_TRANSACTION) { 59515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "NOTIFICATION_TRANSACTION"; 59615c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (transactionType == Transaction.RETRIEVE_TRANSACTION) { 59715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "RETRIEVE_TRANSACTION"; 59815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (transactionType == Transaction.SEND_TRANSACTION) { 59915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "SEND_TRANSACTION"; 60015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } else if (transactionType == Transaction.READREC_TRANSACTION) { 60115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "READREC_TRANSACTION"; 60215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 60315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return "invalid transaction type"; 60415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 60515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 60672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle incoming transaction requests. 60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The incoming requests are initiated by the MMSC Server or by the 60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * MMS Client itself. 61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleMessage(Message msg) { 613812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 61415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor Log.v(TAG, "Handling incoming message: " + msg + " = " + decodeMessage(msg)); 61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Transaction transaction = null; 6186dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msg.what) { 62049a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor case EVENT_NEW_INTENT: 62149a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor onNewIntent((Intent)msg.obj, msg.arg1); 62249a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor break; 62349a12964d03ed83e9f0e2d8c88e51e66ec1e771cTom Taylor 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_QUIT: 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project getLooper().quit(); 62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 62735de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_CONTINUE_MMS_CONNECTIVITY: 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.isEmpty()) { 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 635812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 6366dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "handle EVENT_CONTINUE_MMS_CONNECTIVITY event..."); 63772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = beginMmsConnectivity(); 64109fb57c41102b5e10beb7081f203d5b5ed8fa71eWink Saville if (result != PhoneConstants.APN_ALREADY_ACTIVE) { 6426dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "Extending MMS connectivity returned " + result + 64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project " instead of APN_ALREADY_ACTIVE"); 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Just wait for connectivity startup without 64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // any new request of APN switch. 64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 64772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IOException e) { 64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Attempt to extend use of MMS connectivity failed"); 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Restart timer 6541e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor renewMmsConnectivity(); 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_TRANSACTION_REQUEST: 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = msg.arg1; 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = (TransactionBundle) msg.obj; 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionSettings transactionSettings; 66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66336cb4bcc16e6d395e03d365a066bcad78e9d25c4Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 66436cb4bcc16e6d395e03d365a066bcad78e9d25c4Tom Taylor Log.v(TAG, "EVENT_TRANSACTION_REQUEST MmscUrl=" + 66536cb4bcc16e6d395e03d365a066bcad78e9d25c4Tom Taylor args.getMmscUrl() + " proxy port: " + args.getProxyAddress()); 66636cb4bcc16e6d395e03d365a066bcad78e9d25c4Tom Taylor } 66736cb4bcc16e6d395e03d365a066bcad78e9d25c4Tom Taylor 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set the connection settings for this transaction. 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If these have not been set in args, load the default settings. 67072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String mmsc = args.getMmscUrl(); 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mmsc != null) { 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings = new TransactionSettings( 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mmsc, args.getProxyAddress(), args.getProxyPort()); 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings = new TransactionSettings( 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, null); 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6796dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang int transactionType = args.getTransactionType(); 6806dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 681812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 6826dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "handle EVENT_TRANSACTION_REQUEST: transactionType=" + 68315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor transactionType + " " + decodeTransactionType(transactionType)); 6846dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 6856dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Create appropriate transaction 6876dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang switch (transactionType) { 68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.NOTIFICATION_TRANSACTION: 68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String uri = args.getUri(); 69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (uri != null) { 69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new NotificationTransaction( 69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, uri); 69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Now it's only used for test purpose. 69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] pushData = args.getPushData(); 69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduParser parser = new PduParser(pushData); 69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project GenericPdu ind = parser.parse(); 69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int type = PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; 70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((ind != null) && (ind.getMessageType() == type)) { 70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new NotificationTransaction( 70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, (NotificationInd) ind); 70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Invalid PUSH data."); 70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new RetrieveTransaction( 71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.SEND_TRANSACTION: 71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new SendTransaction( 71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.READREC_TRANSACTION: 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new ReadRecTransaction( 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Invalid transaction type: " + serviceId); 72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!processTransaction(transaction)) { 73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 738812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Started processing of incoming message: " + msg); 74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (Exception ex) { 7425d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project Log.w(TAG, "Exception occurred while handling message: " + msg, ex); 74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction != null) { 74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.detach(TransactionService.this); 74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.contains(transaction)) { 74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.remove(transaction); 75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (Throwable t) { 75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Unexpected Throwable.", t); 75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set transaction to null to allow stopping the 75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // transaction service. 75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction == null) { 762812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction was null. Stopping self: " + serviceId); 76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_HANDLE_NEXT_PENDING_TRANSACTION: 77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project processPendingTransaction(transaction, (TransactionSettings) msg.obj); 77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "what=" + msg.what); 77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 779c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor public void markAllPendingTransactionsAsFailed() { 780c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor synchronized (mProcessing) { 781c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor while (mPending.size() != 0) { 782c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor Transaction transaction = mPending.remove(0); 783c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor transaction.mTransactionState.setState(TransactionState.FAILED); 784c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor if (transaction instanceof SendTransaction) { 785c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor Uri uri = ((SendTransaction)transaction).mSendReqURI; 786c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor transaction.mTransactionState.setContentUri(uri); 787c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor int respStatus = PduHeaders.RESPONSE_STATUS_ERROR_NETWORK_PROBLEM; 788c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor ContentValues values = new ContentValues(1); 789c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor values.put(Mms.RESPONSE_STATUS, respStatus); 790c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor 791c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor SqliteWrapper.update(TransactionService.this, 792c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor TransactionService.this.getContentResolver(), 793c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor uri, values, null, null); 794c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor } 795c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor transaction.notifyObservers(); 796c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor } 797c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor } 798c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor } 799c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor 80015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor public void processPendingTransaction(Transaction transaction, 8016dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang TransactionSettings settings) { 80235de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 803812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8046dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processPendingTxn: transaction=" + transaction); 8056dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 8066dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 80772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int numProcessTransaction = 0; 80872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 80972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mPending.size() != 0) { 81072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = mPending.remove(0); 81172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project numProcessTransaction = mProcessing.size(); 81372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction != null) { 81672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (settings != null) { 81772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.setConnectionSettings(settings); 81872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81935de139283bfeca8b2360c8b13b9cd8dee8e039bTom Taylor 82072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 82172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Process deferred transaction 82272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 82372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 82472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = transaction.getServiceId(); 8256dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 826812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8276dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processPendingTxn: process " + serviceId); 8286dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 8296dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 83072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (processTransaction(transaction)) { 831812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8326dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "Started deferred processing of transaction " 83372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + transaction); 83472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 83672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 83772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 83872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IOException e) { 8405d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project Log.w(TAG, e.getMessage(), e); 84172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 8426dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } else { 84372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (numProcessTransaction == 0) { 844812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8456dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processPendingTxn: no more transaction, endMmsConnectivity"); 8466dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 84772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 84872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 84972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 85072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 85172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 85272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 85372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Internal method to begin processing a transaction. 85472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param transaction the transaction. Must not be {@code null}. 85572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @return {@code true} if process has begun or will begin. {@code false} 85672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * if the transaction should be discarded. 85772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @throws IOException if connectivity for MMS traffic could not be 85872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * established. 85972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 86072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private boolean processTransaction(Transaction transaction) throws IOException { 86172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Check if transaction already processing 86272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 86372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (Transaction t : mPending) { 86472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (t.isEquivalent(transaction)) { 865812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 86672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction already pending: " + 86772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.getServiceId()); 86872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 87072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 87172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 87272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (Transaction t : mProcessing) { 87372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (t.isEquivalent(transaction)) { 874812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 87572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Duplicated transaction: " + transaction.getServiceId()); 87672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 87772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 87872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 87972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 88072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 88172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 88272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Make sure that the network connectivity necessary 88372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * for MMS traffic is enabled. If it is not, we need 88472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to defer processing the transaction until 88572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * connectivity is established. 88672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 887812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8886dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processTransaction: call beginMmsConnectivity..."); 8896dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 89072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int connectivityResult = beginMmsConnectivity(); 89109fb57c41102b5e10beb7081f203d5b5ed8fa71eWink Saville if (connectivityResult == PhoneConstants.APN_REQUEST_STARTED) { 89272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mPending.add(transaction); 893812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 8946dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processTransaction: connResult=APN_REQUEST_STARTED, " + 8956dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang "defer transaction pending MMS connectivity"); 89672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 89772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 89872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 89972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 900812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 9016dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "Adding transaction to 'mProcessing' list: " + transaction); 90272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 90372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.add(transaction); 90472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 90572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 90672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set a timer to keep renewing our "lease" on the MMS connection 90772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendMessageDelayed(obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), 90872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project APN_EXTENSION_WAIT); 90972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 910812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 9116dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang Log.v(TAG, "processTransaction: starting transaction " + transaction); 9126dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang } 9136dabb09aaf6386d6501e4165c0530bd11c2fe2a0Wei Huang 91472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Attach to transaction and process it 91572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.attach(TransactionService.this); 91672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.process(); 91772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 91872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 91972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 92015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 9211e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor private void renewMmsConnectivity() { 9221e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor // Set a timer to keep renewing our "lease" on the MMS connection 9231e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor mServiceHandler.sendMessageDelayed( 9241e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor mServiceHandler.obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), 9251e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor APN_EXTENSION_WAIT); 9261e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor } 9271e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor 92815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor private class ConnectivityBroadcastReceiver extends BroadcastReceiver { 92915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor @Override 93015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor public void onReceive(Context context, Intent intent) { 93115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor String action = intent.getAction(); 93215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 93315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor Log.w(TAG, "ConnectivityBroadcastReceiver.onReceive() action: " + action); 93415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 93515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 93615c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 93715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor return; 93815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 93915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 940e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen NetworkInfo mmsNetworkInfo = null; 94115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 942ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor if (mConnMgr != null && mConnMgr.getMobileDataEnabled()) { 943e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen mmsNetworkInfo = mConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS); 944e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } else { 945e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 946e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen Log.v(TAG, "mConnMgr is null, bail"); 947e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 948e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 94915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 95015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor /* 95115c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor * If we are being informed that connectivity has been established 95215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor * to allow MMS traffic, then proceed with processing the pending 95315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor * transaction, if any. 95415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor */ 95515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 95615c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 957e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen Log.v(TAG, "Handle ConnectivityBroadcastReceiver.onReceive(): " + mmsNetworkInfo); 95815c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 95915c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 96015c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor // Check availability of the mobile network. 961ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor if (mmsNetworkInfo == null) { 96215c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 963ed022ca79d681650142b1a89dcd76d38603fa9b8Tom Taylor Log.v(TAG, "mms type is null or mobile data is turned off, bail"); 96415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 965e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } else { 9661e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor // This is a very specific fix to handle the case where the phone receives an 9671e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor // incoming call during the time we're trying to setup the mms connection. 9681e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor // When the call ends, restart the process of mms connectivity. 969e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (Phone.REASON_VOICE_CALL_ENDED.equals(mmsNetworkInfo.getReason())) { 9701e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 9711e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor Log.v(TAG, " reason is " + Phone.REASON_VOICE_CALL_ENDED + 9721e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor ", retrying mms connectivity"); 9731e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor } 9741e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor renewMmsConnectivity(); 975e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen return; 9761e0d005e0e460a479a04535a606ad9ce94b2959dTom Taylor } 97715c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 978e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (mmsNetworkInfo.isConnected()) { 979e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen TransactionSettings settings = new TransactionSettings( 980e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen TransactionService.this, mmsNetworkInfo.getExtraInfo()); 981c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor // If this APN doesn't have an MMSC, mark everything as failed and bail. 982e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (TextUtils.isEmpty(settings.getMmscUrl())) { 983e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen Log.v(TAG, " empty MMSC url, bail"); 984c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor mToastHandler.sendEmptyMessage(TOAST_NO_APN); 985c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor mServiceHandler.markAllPendingTransactionsAsFailed(); 986c65a9fdb8e1c936a2b8ce9312c125d4046fbae46Tom Taylor endMmsConnectivity(); 987e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen return; 988e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 989e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen mServiceHandler.processPendingTransaction(null, settings); 990e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } else { 991e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 992e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen Log.v(TAG, " TYPE_MOBILE_MMS not connected, bail"); 993e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 99415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor 995e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen // Retry mms connectivity once it's possible to connect 996e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (mmsNetworkInfo.isAvailable()) { 997e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 998e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen Log.v(TAG, " retrying mms connectivity for it's available"); 999e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 1000e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen renewMmsConnectivity(); 1001e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 1002e90d18fb3e32c77a08708f1473331f269a5ee932Roger Chen } 100315c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 100415c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor } 100515c2190d6910032fa01fa9245159f0ce8e78729bTom Taylor }; 100672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 1007