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