TransactionService.java revision 72735c62aba8fd2a9420a0f9f83d22543e3c164f
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 2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.internal.telephony.Phone; 2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.R; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.android.mms.util.RateController; 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.GenericPdu; 2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.NotificationInd; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduHeaders; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduParser; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport com.google.android.mms.pdu.PduPersister; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Service; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.ConnectivityManager; 3572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.NetworkConnectivityListener; 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.NetworkInfo; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.HandlerThread; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.IBinder; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Looper; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.PowerManager; 4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.Mms; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.MmsSms; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Telephony.MmsSms.PendingMessages; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Config; 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException; 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.ArrayList; 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The TransactionService of the MMS Client is responsible for handling requests 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to initiate client-transactions sent from: 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <ul> 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>The Proxy-Relay (Through Push messages)</li> 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>The composer/viewer activities of the MMS Client (Through intents)</li> 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * </ul> 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The TransactionService runs locally in the same process as the application. 6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * It contains a HandlerThread to which messages are posted from the 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * intent-receivers of this application. 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <p/> 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <b>IMPORTANT</b>: This is currently the only instance in the system in 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * which simultaneous connectivity to both the mobile data network and 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * a Wi-Fi network is allowed. This makes the code for handling network 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * connectivity somewhat different than it is in other applications. In 7072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * particular, we want to be able to send or receive MMS messages when 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * a Wi-Fi connection is active (which implies that there is no connection 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to the mobile data network). This has two main consequences: 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <ul> 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>Testing for current network connectivity ({@link android.net.NetworkInfo#isConnected()} is 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * not sufficient. Instead, the correct test is for network availability 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * ({@link android.net.NetworkInfo#isAvailable()}).</li> 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * <li>If the mobile data network is not in the connected state, but it is available, 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * we must initiate setup of the mobile data connection, and defer handling 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * the MMS transaction until the connection is established.</li> 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * </ul> 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class TransactionService extends Service implements Observer { 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "TransactionService"; 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean DEBUG = false; 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used to identify notification intents broadcasted by the 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionService when a Transaction is completed. 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String TRANSACTION_COMPLETED_ACTION = 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "android.intent.action.TRANSACTION_COMPLETED_ACTION"; 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Action for the Intent which is sent by Alarm service to launch 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionService. 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String ACTION_ONALARM = "android.intent.action.ACTION_ONALARM"; 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used as extra key in notification intents broadcasted by the TransactionService 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * when a Transaction is completed (TRANSACTION_COMPLETED_ACTION intents). 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Allowed values for this key are: TransactionState.INITIALIZED, 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * TransactionState.SUCCESS, TransactionState.FAILED. 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String STATE = "state"; 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used as extra key in notification intents broadcasted by the TransactionService 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * when a Transaction is completed (TRANSACTION_COMPLETED_ACTION intents). 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Allowed values for this key are any valid content uri. 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String STATE_URI = "uri"; 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Used as extra key in notification intents broadcasted by the TransactionService 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * when a Transaction is completed (TRANSACTION_COMPLETED_ACTION intents). 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Allowed values for this key are the Uri's of stored messages relevant 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * for the completed Transaction, 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * i.e.: Uri of DeliveryInd for DeliveryTransaction, 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * NotificationInd for NotificationTransaction, 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * ReadOrigInd for ReadOrigTransaction, 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * null for ReadRecTransaction, 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * RetrieveConf for RetrieveTransaction, 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * SendReq for SendTransaction. 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String CONTENT_URI = "content_uri"; 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_TRANSACTION_REQUEST = 1; 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_DATA_STATE_CHANGED = 2; 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_CONTINUE_MMS_CONNECTIVITY = 3; 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_HANDLE_NEXT_PENDING_TRANSACTION = 4; 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int EVENT_QUIT = 100; 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_MSG_QUEUED = 1; 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_DOWNLOAD_LATER = 2; 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int TOAST_NONE = -1; 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // How often to extend the use of the MMS APN while a transaction 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // is still being processed. 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final int APN_EXTENSION_WAIT = 30 * 1000; 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ServiceHandler mServiceHandler; 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Looper mServiceLooper; 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final ArrayList<Transaction> mProcessing = new ArrayList<Transaction>(); 14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final ArrayList<Transaction> mPending = new ArrayList<Transaction>(); 14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ConnectivityManager mConnMgr; 14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private NetworkConnectivityListener mConnectivityListener; 14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private PowerManager.WakeLock mWakeLock; 15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 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); 16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (str != null) { 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Toast.makeText(TransactionService.this, str, 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Toast.LENGTH_LONG).show(); 16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 16872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreate() { 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Creating TransactionService"); 17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Start up the thread running the service. Note that we create a 17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // separate thread because the service normally runs in the process's 17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // main thread, which we don't want to block. 17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HandlerThread thread = new HandlerThread("TransactionService"); 17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project thread.start(); 18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceLooper = thread.getLooper(); 18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler = new ServiceHandler(mServiceLooper); 18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener = new NetworkConnectivityListener(); 18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener.registerHandler(mServiceHandler, EVENT_DATA_STATE_CHANGED); 18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener.startListening(this); 18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onStart(Intent intent, int startId) { 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Starting #" + startId + ": " + intent.getExtras()); 19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean noNetwork = !isNetworkAvailable(); 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (ACTION_ONALARM.equals(intent.getAction()) || (intent.getExtras() == null)) { 19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Scan database to find all pending operations. 20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Cursor cursor = PduPersister.getPduPersister(this).getPendingMessages( 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project System.currentTimeMillis()); 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor != null) { 20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (cursor.getCount() == 0) { 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "No pending messages. Stopping service."); 20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RetryScheduler.setRetryAlarm(this); 20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelfIfIdle(startId); 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int columnIndexOfMsgId = cursor.getColumnIndexOrThrow( 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingMessages.MSG_ID); 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int columnIndexOfMsgType = cursor.getColumnIndexOrThrow( 21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingMessages.MSG_TYPE); 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project while (cursor.moveToNext()) { 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int msgType = cursor.getInt(columnIndexOfMsgType); 22072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int transactionType = getTransactionType(msgType); 22172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (noNetwork) { 22272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project onNetworkUnavailable(startId, transactionType); 22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (transactionType) { 22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case -1: 22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If it's a transiently failed transaction, 23072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // we should retry it in spite of current 23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // downloading mode. 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int failureType = cursor.getInt( 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.getColumnIndexOrThrow( 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PendingMessages.ERROR_TYPE)); 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!isTransientFailure(failureType)) { 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // fall-through 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Uri uri = ContentUris.withAppendedId( 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Mms.CONTENT_URI, 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.getLong(columnIndexOfMsgId)); 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = new TransactionBundle( 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionType, uri.toString()); 24572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // FIXME: We use the same startId for all MMs. 24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project launchTransaction(startId, args, false); 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 24972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 25172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project cursor.close(); 25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "No pending messages. Stopping service."); 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RetryScheduler.setRetryAlarm(this); 25872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelfIfIdle(startId); 25972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 26172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // For launching NotificationTransaction and test purpose. 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = new TransactionBundle(intent.getExtras()); 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project launchTransaction(startId, args, noNetwork); 26472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void stopSelfIfIdle(int startId) { 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.isEmpty() && mPending.isEmpty()) { 27072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(startId); 27172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static boolean isTransientFailure(int type) { 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return (type < MmsSms.ERR_TYPE_GENERIC_PERMANENT) && (type > MmsSms.NO_ERROR); 27772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private boolean isNetworkAvailable() { 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NetworkInfo networkInfo = mConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return networkInfo.isAvailable(); 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private int getTransactionType(int msgType) { 28572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msgType) { 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.RETRIEVE_TRANSACTION; 28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_READ_REC_IND: 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.READREC_TRANSACTION; 29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_SEND_REQ: 29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return Transaction.SEND_TRANSACTION; 29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Unrecognized MESSAGE_TYPE: " + msgType); 29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return -1; 29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void launchTransaction(int serviceId, TransactionBundle txnBundle, boolean noNetwork) { 29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (noNetwork) { 30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project onNetworkUnavailable(serviceId, txnBundle.getTransactionType()); 30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage(EVENT_TRANSACTION_REQUEST); 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.arg1 = serviceId; 30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project msg.obj = txnBundle; 30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Sending: " + msg); 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void onNetworkUnavailable(int serviceId, int transactionType) { 31472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int toastType = TOAST_NONE; 31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transactionType == Transaction.RETRIEVE_TRANSACTION) { 31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project toastType = TOAST_DOWNLOAD_LATER; 31772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (transactionType == Transaction.SEND_TRANSACTION) { 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project toastType = TOAST_MSG_QUEUED; 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (toastType != TOAST_NONE) { 32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mToastHandler.sendEmptyMessage(toastType); 32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onDestroy() { 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Destroying TransactionService"); 33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!mPending.isEmpty()) { 33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.i(TAG, "TransactionService exiting with transaction still pending"); 33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project releaseWakeLock(); 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener.unregisterHandler(mServiceHandler); 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener.stopListening(); 33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnectivityListener = null; 34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendEmptyMessage(EVENT_QUIT); 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public IBinder onBind(Intent intent) { 34672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle status change of Transaction (The Observable). 35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void update(Observable observable) { 35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Transaction transaction = (Transaction) observable; 35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = transaction.getServiceId(); 35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.remove(transaction); 35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mPending.size() > 0) { 35972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Message msg = mServiceHandler.obtainMessage( 36072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project EVENT_HANDLE_NEXT_PENDING_TRANSACTION, 36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.getConnectionSettings()); 36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.sendMessage(msg); 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project else { 36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = new Intent(TRANSACTION_COMPLETED_ACTION); 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionState state = transaction.getState(); 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = state.getState(); 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project intent.putExtra(STATE, result); 37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (result) { 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TransactionState.SUCCESS: 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 37772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction complete: " + serviceId); 37872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project intent.putExtra(STATE_URI, state.getContentUri()); 38172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 38272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Notify user in the system-wide notification area. 38372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (transaction.getType()) { 38472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.NOTIFICATION_TRANSACTION: 38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 38672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MessagingNotification.updateNewMessageIndicator(this, true); 38772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project MessagingNotification.updateDownloadFailedNotification(this); 38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 38972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.SEND_TRANSACTION: 39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project RateController.getInstance().update(); 39172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case TransactionState.FAILED: 39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction failed: " + serviceId); 39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 40072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 40172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction state unknown: " + 40272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project serviceId + " " + result); 40372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Broadcast the result of the transaction. 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendBroadcast(intent); 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.detach(this); 41172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private synchronized void createWakeLock() { 41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Create a new wake lock if we haven't made one yet. 41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mWakeLock == null) { 41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MMS Connectivity"); 42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.setReferenceCounted(false); 42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void acquireWakeLock() { 42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // It's okay to double-acquire this because we are not using it 42772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // in reference-counted mode. 42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.acquire(); 42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void releaseWakeLock() { 43272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Don't release the wake lock if it hasn't been created and acquired. 43372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mWakeLock != null && mWakeLock.isHeld()) { 43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mWakeLock.release(); 43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 43672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 43772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected int beginMmsConnectivity() throws IOException { 43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Take a wake lock so we don't fall asleep before the message is downloaded. 44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project createWakeLock(); 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = mConnMgr.startUsingNetworkFeature( 44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS); 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (result) { 44672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Phone.APN_ALREADY_ACTIVE: 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Phone.APN_REQUEST_STARTED: 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project acquireWakeLock(); 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return result; 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new IOException("Cannot establish MMS connectivity"); 45372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 45572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void endMmsConnectivity() { 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // cancel timer for renewal of lease 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mServiceHandler.removeMessages(EVENT_CONTINUE_MMS_CONNECTIVITY); 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mConnMgr != null) { 46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mConnMgr.stopUsingNetworkFeature( 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS); 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project releaseWakeLock(); 46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final class ServiceHandler extends Handler { 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ServiceHandler(Looper looper) { 47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(looper); 47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Handle incoming transaction requests. 47572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * The incoming requests are initiated by the MMSC Server or by the 47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * MMS Client itself. 47772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void handleMessage(Message msg) { 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Handling incoming message: " + msg); 48272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Transaction transaction = null; 48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msg.what) { 48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_QUIT: 48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project getLooper().quit(); 48872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 48972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_CONTINUE_MMS_CONNECTIVITY: 49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.isEmpty()) { 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Extending MMS connectivity - still processing txn"); 49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int result = beginMmsConnectivity(); 50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (result != Phone.APN_ALREADY_ACTIVE) { 50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.i(TAG, "Extending MMS connectivity returned " + result + 50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project " instead of APN_ALREADY_ACTIVE"); 50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Just wait for connectivity startup without 50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // any new request of APN switch. 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IOException e) { 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Attempt to extend use of MMS connectivity failed"); 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 51572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Restart timer 51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendMessageDelayed(obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), 51772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project APN_EXTENSION_WAIT); 51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_DATA_STATE_CHANGED: 52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * If we are being informed that connectivity has been established 52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to allow MMS traffic, then proceed with processing the pending 52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * transaction, if any. 52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mConnectivityListener == null) { 52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project NetworkInfo info = mConnectivityListener.getNetworkInfo(); 53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Got DATA_STATE_CHANGED event: " + info); 53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Check availability of the mobile network. 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((info == null) || (info.getType() != ConnectivityManager.TYPE_MOBILE)) { 53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!info.isConnected()) { 54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionSettings settings = new TransactionSettings( 54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, info.getExtraInfo()); 54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (TextUtils.isEmpty(settings.getMmscUrl())) { 54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Invalid APN setting: MMSC URL is empty"); 54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set a timer to keep renewing our "lease" on the MMS connection 55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendMessageDelayed(obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), 55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project APN_EXTENSION_WAIT); 55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project processPendingTransaction(transaction, settings); 55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_TRANSACTION_REQUEST: 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = msg.arg1; 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionBundle args = (TransactionBundle) msg.obj; 56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionSettings transactionSettings; 56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 56572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set the connection settings for this transaction. 56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // If these have not been set in args, load the default settings. 56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String mmsc = args.getMmscUrl(); 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mmsc != null) { 56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings = new TransactionSettings( 57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mmsc, args.getProxyAddress(), args.getProxyPort()); 57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 57272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings = new TransactionSettings( 57372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, null); 57472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Create appropriate transaction 57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (args.getTransactionType()) { 57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.NOTIFICATION_TRANSACTION: 57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String uri = args.getUri(); 58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (uri != null) { 58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new NotificationTransaction( 58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, uri); 58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Now it's only used for test purpose. 58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] pushData = args.getPushData(); 58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduParser parser = new PduParser(pushData); 58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project GenericPdu ind = parser.parse(); 58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int type = PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND; 59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if ((ind != null) && (ind.getMessageType() == type)) { 59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new NotificationTransaction( 59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 59472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, (NotificationInd) ind); 59572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 59672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Invalid PUSH data."); 59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 59872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 59972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.RETRIEVE_TRANSACTION: 60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new RetrieveTransaction( 60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 60672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.SEND_TRANSACTION: 60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new SendTransaction( 60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 61072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 61172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 61272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case Transaction.READREC_TRANSACTION: 61372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = new ReadRecTransaction( 61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TransactionService.this, serviceId, 61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transactionSettings, args.getUri()); 61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "Invalid transaction type: " + serviceId); 61972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!processTransaction(transaction)) { 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Started processing of incoming message: " + msg); 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (Exception ex) { 63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Exception occurred while handling message: " + msg, ex); 63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 63672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction != null) { 63772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.detach(TransactionService.this); 63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mProcessing.contains(transaction)) { 64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.remove(transaction); 64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (Throwable t) { 64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Unexpected Throwable.", t); 64672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 64772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set transaction to null to allow stopping the 64872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // transaction service. 64972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction == null) { 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction was null. Stopping self: " + serviceId); 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case EVENT_HANDLE_NEXT_PENDING_TRANSACTION: 66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project processPendingTransaction(transaction, (TransactionSettings) msg.obj); 66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 66572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 66672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.w(TAG, "what=" + msg.what); 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return; 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void processPendingTransaction(Transaction transaction, TransactionSettings settings) { 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int numProcessTransaction = 0; 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mPending.size() != 0) { 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = mPending.remove(0); 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project numProcessTransaction = mProcessing.size(); 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 68072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (transaction != null) { 68172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (settings != null) { 68272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.setConnectionSettings(settings); 68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Process deferred transaction 68772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int serviceId = transaction.getServiceId(); 69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (processTransaction(transaction)) { 69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Started deferred processing of transaction: " 69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + transaction); 69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction = null; 69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project stopSelf(serviceId); 69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IOException e) { 70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, e.getMessage(), e); 70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project else { 70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (numProcessTransaction == 0) { 70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project endMmsConnectivity(); 70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Internal method to begin processing a transaction. 71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param transaction the transaction. Must not be {@code null}. 71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @return {@code true} if process has begun or will begin. {@code false} 71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * if the transaction should be discarded. 71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @throws IOException if connectivity for MMS traffic could not be 71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * established. 71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private boolean processTransaction(Transaction transaction) throws IOException { 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Check if transaction already processing 72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project synchronized (mProcessing) { 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (Transaction t : mPending) { 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (t.isEquivalent(transaction)) { 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Transaction already pending: " + 72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.getServiceId()); 72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project for (Transaction t : mProcessing) { 73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (t.isEquivalent(transaction)) { 73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Duplicated transaction: " + transaction.getServiceId()); 73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /* 74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Make sure that the network connectivity necessary 74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * for MMS traffic is enabled. If it is not, we need 74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * to defer processing the transaction until 74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * connectivity is established. 74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project int connectivityResult = beginMmsConnectivity(); 74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (connectivityResult == Phone.APN_REQUEST_STARTED) { 74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mPending.add(transaction); 75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Defer txn processing pending MMS connectivity"); 75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Adding transaction to list: " + transaction); 75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mProcessing.add(transaction); 76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (LOCAL_LOGV) { 76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "Starting transaction: " + transaction); 76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set a timer to keep renewing our "lease" on the MMS connection 76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project sendMessageDelayed(obtainMessage(EVENT_CONTINUE_MMS_CONNECTIVITY), 76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project APN_EXTENSION_WAIT); 76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Attach to transaction and process it 77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.attach(TransactionService.this); 77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project transaction.process(); 77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 777