ConversationList.java revision a8ec27f7ab554745e1e1c4700455fdfd6a1048e9
172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 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.ui; 1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 202426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylorimport android.app.ActionBar; 2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.ListActivity; 23136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylorimport android.app.SearchManager; 24e131a53620fff000a08cf53d29313a3922328dc0Mark Wagnerimport android.app.SearchableInfo; 25d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.ActivityNotFoundException; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.AsyncQueryHandler; 2778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hambyimport android.content.ComponentName; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver; 293e10898d774b0005fc776865216651346503024bTom Taylorimport android.content.Context; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface; 31d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.DialogInterface.OnClickListener; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 33f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylorimport android.content.SharedPreferences; 34a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.content.pm.ApplicationInfo; 35d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.content.pm.PackageManager; 36a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.content.pm.PackageManager.NameNotFoundException; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Configuration; 3872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor; 3972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.sqlite.SQLiteException; 40d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.database.sqlite.SqliteWrapper; 41a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.graphics.drawable.Drawable; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Bundle; 43f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylorimport android.os.Handler; 44f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylorimport android.preference.PreferenceManager; 45923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikovimport android.provider.ContactsContract; 46923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikovimport android.provider.ContactsContract.Contacts; 47a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.provider.Telephony; 48f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms; 492426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylorimport android.provider.Telephony.Threads; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 51b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylorimport android.view.ActionMode; 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.ContextMenu; 53d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.view.ContextMenu.ContextMenuInfo; 549995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylorimport android.view.Gravity; 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.KeyEvent; 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.LayoutInflater; 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.Menu; 58b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylorimport android.view.MenuInflater; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.MenuItem; 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View; 6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View.OnCreateContextMenuListener; 6272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View.OnKeyListener; 63d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport android.view.ViewGroup; 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.AdapterView; 6585fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylorimport android.widget.CheckBox; 66a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.widget.ImageView; 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ListView; 68e131a53620fff000a08cf53d29313a3922328dc0Mark Wagnerimport android.widget.SearchView; 6985fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylorimport android.widget.TextView; 70a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport android.widget.Toast; 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 72d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.LogTag; 73991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braunimport com.android.mms.MmsConfig; 74d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.R; 75d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Contact; 76d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.ContactList; 77d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Conversation; 78d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.data.Conversation.ConversationQueryHandler; 79d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.transaction.MessagingNotification; 80d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.transaction.SmsRejectedReceiver; 81d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.DraftCache; 82d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.android.mms.util.Recycler; 83cee64965b033733a494df675892267e109a23dd6Roger Chenimport com.android.mms.widget.MmsWidgetProvider; 84d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chenimport com.google.android.mms.pdu.PduHeaders; 85d64419030e1fec1e751695dab3bd7236e2fb0214Roger Chen 86a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport java.util.ArrayList; 87a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport java.util.Collection; 88a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braunimport java.util.HashSet; 89a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This activity provides a list view of existing conversations. 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 93e131a53620fff000a08cf53d29313a3922328dc0Mark Wagnerpublic class ConversationList extends ListActivity implements DraftCache.OnDraftChangedListener { 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "ConversationList"; 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final boolean DEBUG = false; 9699f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor private static final boolean DEBUGCLEANUP = true; 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9863e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor private static final int THREAD_LIST_QUERY_TOKEN = 1701; 992426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor private static final int UNREAD_THREADS_QUERY_TOKEN = 1702; 10063e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor public static final int DELETE_CONVERSATION_TOKEN = 1801; 10163e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor public static final int HAVE_LOCKED_MESSAGES_TOKEN = 1802; 10263e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor private static final int DELETE_OBSOLETE_THREADS_TOKEN = 1803; 10333a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // IDs of the context menu items for the list of conversations. 10548da875f1beea835c6771977e5bd8a9aa3d4bc10Tom Taylor public static final int MENU_DELETE = 0; 10648da875f1beea835c6771977e5bd8a9aa3d4bc10Tom Taylor public static final int MENU_VIEW = 1; 10748da875f1beea835c6771977e5bd8a9aa3d4bc10Tom Taylor public static final int MENU_VIEW_CONTACT = 2; 10848da875f1beea835c6771977e5bd8a9aa3d4bc10Tom Taylor public static final int MENU_ADD_TO_CONTACTS = 3; 10933a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ThreadListQueryHandler mQueryHandler; 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ConversationListAdapter mListAdapter; 112f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor private SharedPreferences mPrefs; 113f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor private Handler mHandler; 114d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor private boolean mDoOnceAfterFirstQuery; 1152426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor private TextView mUnreadConvCount; 116e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner private MenuItem mSearchItem; 117e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner private SearchView mSearchView; 118991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun private View mSmsPromoBannerView; 1196019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor private int mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION; 1206019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor private int mSavedFirstItemOffset; 1216019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 1226019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // keys for extras and icicles 1236019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor private final static String LAST_LIST_POS = "last_list_pos"; 1246019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor private final static String LAST_LIST_OFFSET = "last_list_offset"; 125f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor 126f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor static private final String CHECKED_MESSAGE_LIMITS = "checked_message_limits"; 12772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 128991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun // Whether or not we are currently enabled for SMS. This field is updated in onResume to make 129991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun // sure we notice if the user has changed the default SMS app. 130991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun private boolean mIsSmsEnabled; 131a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun private Toast mComposeDisabledToast; 132991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onCreate(Bundle savedInstanceState) { 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onCreate(savedInstanceState); 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project setContentView(R.layout.conversation_list_screen); 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 139991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun mSmsPromoBannerView = findViewById(R.id.banner_sms_promo); 140991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mQueryHandler = new ThreadListQueryHandler(getContentResolver()); 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ListView listView = getListView(); 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project listView.setOnCreateContextMenuListener(mConvListOnCreateContextMenuListener); 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project listView.setOnKeyListener(mThreadListKeyListener); 146b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 147b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor listView.setMultiChoiceModeListener(new ModeCallback()); 14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 149ebb3227c391ec7fd4686aadd3cb18d5f427fc17bTom Taylor // Tell the list view which view to display when the list is empty 150e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor listView.setEmptyView(findViewById(R.id.empty)); 151ebb3227c391ec7fd4686aadd3cb18d5f427fc17bTom Taylor 15259cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick initListAdapter(); 15333a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 1542426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor setupActionBar(); 1552426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 15664989ecb6d0e4bea59487bade662915317b6b54bTodor Kalaydjiev setTitle(R.string.app_label); 157f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor 158f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor mHandler = new Handler(); 159f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor mPrefs = PreferenceManager.getDefaultSharedPreferences(this); 160f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor boolean checkedMessageLimits = mPrefs.getBoolean(CHECKED_MESSAGE_LIMITS, false); 161f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (DEBUG) Log.v(TAG, "checkedMessageLimits: " + checkedMessageLimits); 1626af6c0c78aa684221f43d297e6d1ea52afa7093aRoger Chen if (!checkedMessageLimits) { 163f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor runOneTimeStorageLimitCheckForLegacyMessages(); 164f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 1656019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 1666019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor if (savedInstanceState != null) { 1676019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstVisiblePosition = savedInstanceState.getInt(LAST_LIST_POS, 1686019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor AdapterView.INVALID_POSITION); 1696019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstItemOffset = savedInstanceState.getInt(LAST_LIST_OFFSET, 0); 1706019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } else { 1716019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION; 1726019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstItemOffset = 0; 1736019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } 1746019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } 1756019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 1766019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor @Override 1776019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor public void onSaveInstanceState(Bundle outState) { 1786019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor super.onSaveInstanceState(outState); 1796019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 1806019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor outState.putInt(LAST_LIST_POS, mSavedFirstVisiblePosition); 1816019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor outState.putInt(LAST_LIST_OFFSET, mSavedFirstItemOffset); 1826019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } 1836019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 1846019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor @Override 1856019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor public void onPause() { 1866019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor super.onPause(); 1876019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor 188f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor // Don't listen for changes while we're paused. 189f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor mListAdapter.setOnContentChangedListener(null); 190f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor 1916019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // Remember where the list is scrolled to so we can restore the scroll position 1926019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // when we come back to this activity and *after* we complete querying for the 1936019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // conversations. 1946019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor ListView listView = getListView(); 1956019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstVisiblePosition = listView.getFirstVisiblePosition(); 1966019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor View firstChild = listView.getChildAt(0); 1976019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstItemOffset = (firstChild == null) ? 0 : firstChild.getTop(); 19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 200f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor @Override 201f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor protected void onResume() { 202f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor super.onResume(); 203991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun boolean isSmsEnabled = MmsConfig.isSmsEnabled(this); 204991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (isSmsEnabled != mIsSmsEnabled) { 205991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun mIsSmsEnabled = isSmsEnabled; 206991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun invalidateOptionsMenu(); 207991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 208991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun 209991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun // Multi-select is used to delete conversations. It is disabled if we are not the sms app. 210991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun ListView listView = getListView(); 211991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (mIsSmsEnabled) { 212991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 213991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } else { 214991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun listView.setChoiceMode(ListView.CHOICE_MODE_NONE); 215991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 216991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun 217991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun // Show or hide the SMS promo banner 218991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (mIsSmsEnabled || MmsConfig.isSmsPromoDismissed(this)) { 219991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun mSmsPromoBannerView.setVisibility(View.GONE); 220991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } else { 221a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun initSmsPromoBanner(); 222991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun mSmsPromoBannerView.setVisibility(View.VISIBLE); 223991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 224f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor 225f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor mListAdapter.setOnContentChangedListener(mContentChangedListener); 226f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor } 227f794f8cf5bdf72165bbed1fb3dc7f3e98b49150eTom Taylor 2282426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor private void setupActionBar() { 2292426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor ActionBar actionBar = getActionBar(); 2302426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 2312426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor ViewGroup v = (ViewGroup)LayoutInflater.from(this) 2322426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .inflate(R.layout.conversation_list_actionbar, null); 2339995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylor actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM, 2349995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylor ActionBar.DISPLAY_SHOW_CUSTOM); 2352426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor actionBar.setCustomView(v, 2369995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylor new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, 2379995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylor ActionBar.LayoutParams.WRAP_CONTENT, 2389995f7fda121bbd84a2a8a3c5edfd9d2d60870e8Tom Taylor Gravity.CENTER_VERTICAL | Gravity.RIGHT)); 2392426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 2402426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor mUnreadConvCount = (TextView)v.findViewById(R.id.unread_conv_count); 2412426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor } 2422426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 24367b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor private final ConversationListAdapter.OnContentChangedListener mContentChangedListener = 24467b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor new ConversationListAdapter.OnContentChangedListener() { 245ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 24667b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor public void onContentChanged(ConversationListAdapter adapter) { 24767b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor startAsyncQuery(); 24867b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor } 24967b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor }; 25067b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor 25159cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick private void initListAdapter() { 2521d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick mListAdapter = new ConversationListAdapter(this, null); 25367b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor mListAdapter.setOnContentChangedListener(mContentChangedListener); 25459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick setListAdapter(mListAdapter); 255d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang getListView().setRecyclerListener(mListAdapter); 25659cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick } 25733a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 258991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun private void initSmsPromoBanner() { 259a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun final PackageManager packageManager = getPackageManager(); 260a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun final String smsAppPackage = Telephony.Sms.getDefaultSmsPackage(this); 261a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun 262a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Get all the data we need about the default app to properly render the promo banner. We 263a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // try to show the icon and name of the user's selected SMS app and have the banner link 264a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // to that app. If we can't read that information for any reason we leave the fallback 265a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // text that links to Messaging settings where the user can change the default. 266a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun Drawable smsAppIcon = null; 267a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun ApplicationInfo smsAppInfo = null; 268a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun try { 269a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun smsAppIcon = packageManager.getApplicationIcon(smsAppPackage); 270a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun smsAppInfo = packageManager.getApplicationInfo(smsAppPackage, 0); 271a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } catch (NameNotFoundException e) { 272a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 273a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun final Intent smsAppIntent = packageManager.getLaunchIntentForPackage(smsAppPackage); 274a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun 275a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // If we got all the info we needed 276a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun if (smsAppIcon != null && smsAppInfo != null && smsAppIntent != null) { 277a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun ImageView defaultSmsAppIconImageView = 278a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun (ImageView)mSmsPromoBannerView.findViewById(R.id.banner_sms_default_app_icon); 279a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun defaultSmsAppIconImageView.setImageDrawable(smsAppIcon); 280a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun TextView smsPromoBannerTitle = 281a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun (TextView)mSmsPromoBannerView.findViewById(R.id.banner_sms_promo_title); 282a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun String message = getResources().getString(R.string.banner_sms_promo_title_application, 283a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun smsAppInfo.loadLabel(packageManager)); 284a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun smsPromoBannerTitle.setText(message); 285a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun 286a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mSmsPromoBannerView.setOnClickListener(new View.OnClickListener() { 287a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun @Override 288a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun public void onClick(View v) { 289a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun startActivity(smsAppIntent); 290a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 291a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun }); 292a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } else { 293a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Otherwise the banner will be left alone and will launch settings 294a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mSmsPromoBannerView.setOnClickListener(new View.OnClickListener() { 295a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun @Override 296a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun public void onClick(View v) { 297a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Launch settings 298a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun Intent settingsIntent = new Intent(ConversationList.this, 299a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun MessagingPreferenceActivity.class); 300a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun startActivityIfNeeded(settingsIntent, -1); 301a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 302a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun }); 303a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 304991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 305991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun 306f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor /** 307f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * Checks to see if the number of MMS and SMS messages are under the limits for the 308f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * recycler. If so, it will automatically turn on the recycler setting. If not, it 309f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * will prompt the user with a message and point them to the setting to manually 310f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * turn on the recycler. 311f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor */ 312f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor public synchronized void runOneTimeStorageLimitCheckForLegacyMessages() { 313f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (Recycler.isAutoDeleteEnabled(this)) { 314f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (DEBUG) Log.v(TAG, "recycler is already turned on"); 315f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // The recycler is already turned on. We don't need to check anything or warn 316f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // the user, just remember that we've made the check. 317f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor markCheckedMessageLimit(); 318f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor return; 319f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 320f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor new Thread(new Runnable() { 321ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 322f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor public void run() { 323f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (Recycler.checkForThreadsOverLimit(ConversationList.this)) { 324f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (DEBUG) Log.v(TAG, "checkForThreadsOverLimit TRUE"); 325f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // Dang, one or more of the threads are over the limit. Show an activity 326f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // that'll encourage the user to manually turn on the setting. Delay showing 327f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // this activity until a couple of seconds after the conversation list appears. 328f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor mHandler.postDelayed(new Runnable() { 329ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 330f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor public void run() { 331f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor Intent intent = new Intent(ConversationList.this, 332f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor WarnOfStorageLimitsActivity.class); 333f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor startActivity(intent); 334f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 335f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor }, 2000); 336f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } else { 337f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (DEBUG) Log.v(TAG, "checkForThreadsOverLimit silently turning on recycler"); 338f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // No threads were over the limit. Turn on the recycler by default. 339f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor runOnUiThread(new Runnable() { 340ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 341f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor public void run() { 342f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor SharedPreferences.Editor editor = mPrefs.edit(); 343f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor editor.putBoolean(MessagingPreferenceActivity.AUTO_DELETE, true); 344d4ab73b7483ba8a92a96235474070fbf5c10244cBrad Fitzpatrick editor.apply(); 345f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 346f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor }); 347f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 348f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor // Remember that we don't have to do the check anymore when starting MMS. 349f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor runOnUiThread(new Runnable() { 350ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 351f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor public void run() { 352f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor markCheckedMessageLimit(); 353f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 354f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor }); 355f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 356ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev }, "ConversationList.runOneTimeStorageLimitCheckForLegacyMessages").start(); 357f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 358f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor 359f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor /** 360f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * Mark in preferences that we've checked the user's message limits. Once checked, we'll 361f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor * never check them again, unless the user wipe-data or resets the device. 362f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor */ 363f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor private void markCheckedMessageLimit() { 364f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor if (DEBUG) Log.v(TAG, "markCheckedMessageLimit"); 365f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor SharedPreferences.Editor editor = mPrefs.edit(); 366f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor editor.putBoolean(CHECKED_MESSAGE_LIMITS, true); 367d4ab73b7483ba8a92a96235474070fbf5c10244cBrad Fitzpatrick editor.apply(); 368f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor } 369f766f33b774cfb6dd4100a6522ffa23c0a0dae35Tom Taylor 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onNewIntent(Intent intent) { 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Handle intents that occur after the activity has already been created. 37363e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor startAsyncQuery(); 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 376d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang @Override 377d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang protected void onStart() { 378d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang super.onStart(); 379dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor 380a1af734418c5578483f3387e5e0bf6128c963dfaTom Taylor MessagingNotification.cancelNotification(getApplicationContext(), 381a1af734418c5578483f3387e5e0bf6128c963dfaTom Taylor SmsRejectedReceiver.SMS_REJECTED_NOTIFICATION_ID); 382b530437ceaad97151be691067191f48e1e93b87eFicus Kirkpatrick 383d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang DraftCache.getInstance().addOnDraftChangedListener(this); 384812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 385d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor mDoOnceAfterFirstQuery = true; 38663e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor 38763e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor startAsyncQuery(); 38863e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor 389d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // We used to refresh the DraftCache here, but 390d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // refreshing the DraftCache each time we go to the ConversationList seems overly 391d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // aggressive. We already update the DraftCache when leaving CMA in onStop() and 392d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // onNewIntent(), and when we delete threads or delete all in CMA or this activity. 393d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // I hope we don't have to do such a heavy operation each time we enter here. 394598ca14f5d7d26d6d5125d8fe0d07e50f066ff98Ficus Kirkpatrick 395d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // we invalidate the contact cache here because we want to get updated presence 396d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // and any contact changes. We don't invalidate the cache by observing presence and contact 397d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // changes (since that's too untargeted), so as a tradeoff we do it here. 398445fb5abf8804279e591d1c35657c9162625135eTom Taylor // If we're in the middle of the app initialization where we're loading the conversation 399445fb5abf8804279e591d1c35657c9162625135eTom Taylor // threads, don't invalidate the cache because we're in the process of building it. 400d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // TODO: think of a better way to invalidate cache more surgically or based on actual 401d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang // TODO: changes we care about 402445fb5abf8804279e591d1c35657c9162625135eTom Taylor if (!Conversation.loadingThreads()) { 403445fb5abf8804279e591d1c35657c9162625135eTom Taylor Contact.invalidateCache(); 404445fb5abf8804279e591d1c35657c9162625135eTom Taylor } 40572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 40672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 40772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 40872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onStop() { 40972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onStop(); 41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 411d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang DraftCache.getInstance().removeOnDraftChangedListener(this); 412f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 413f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor // Simply setting the choice mode causes the previous choice mode to finish and we exit 414f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor // multi-select mode (if we're in it) and remove all the selections. 415f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 416f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 4176f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen // Close the cursor in the ListAdapter if the activity stopped. 4186f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen Cursor cursor = mListAdapter.getCursor(); 4196f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen 4206f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen if (cursor != null && !cursor.isClosed()) { 4216f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen cursor.close(); 4226f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen } 4236f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen 42459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.changeCursor(null); 42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 427ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 428d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang public void onDraftChanged(final long threadId, final boolean hasDraft) { 42959cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick // Run notifyDataSetChanged() on the main thread. 43059cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mQueryHandler.post(new Runnable() { 431ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 43259cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick public void run() { 433d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 434d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang log("onDraftChanged: threadId=" + threadId + ", hasDraft=" + hasDraft); 435d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang } 43659cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.notifyDataSetChanged(); 43759cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick } 43859cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick }); 439b530437ceaad97151be691067191f48e1e93b87eFicus Kirkpatrick } 44033a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void startAsyncQuery() { 44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 443e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor ((TextView)(getListView().getEmptyView())).setText(R.string.loading_conversations); 44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 44570c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick Conversation.startQueryForAll(mQueryHandler, THREAD_LIST_QUERY_TOKEN); 4462426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Conversation.startQuery(mQueryHandler, UNREAD_THREADS_QUERY_TOKEN, Threads.READ + "=0"); 44772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (SQLiteException e) { 44872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.checkSQLiteException(this, e); 44972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 452e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchView.OnQueryTextListener mQueryTextListener = new SearchView.OnQueryTextListener() { 453ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 454e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner public boolean onQueryTextSubmit(String query) { 455e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner Intent intent = new Intent(); 456e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner intent.setClass(ConversationList.this, SearchActivity.class); 457e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner intent.putExtra(SearchManager.QUERY, query); 458e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner startActivity(intent); 459e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchItem.collapseActionView(); 460e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return true; 461e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 462e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner 463ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 464e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner public boolean onQueryTextChange(String newText) { 465e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return false; 466e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 467e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner }; 468b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 470136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor public boolean onCreateOptionsMenu(Menu menu) { 471b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor getMenuInflater().inflate(R.menu.conversation_list_menu, menu); 472b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 473e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchItem = menu.findItem(R.id.search); 474e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView = (SearchView) mSearchItem.getActionView(); 475b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 476e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setOnQueryTextListener(mQueryTextListener); 477e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setQueryHint(getString(R.string.search_hint)); 478e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setIconifiedByDefault(true); 479e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 480136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor 481e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner if (searchManager != null) { 482e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchableInfo info = searchManager.getSearchableInfo(this.getComponentName()); 483e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setSearchableInfo(info); 484e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 485e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner 48678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby MenuItem cellBroadcastItem = menu.findItem(R.id.action_cell_broadcasts); 48778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (cellBroadcastItem != null) { 48878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby // Enable link to Cell broadcast activity depending on the value in config.xml. 48978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby boolean isCellBroadcastAppLinkEnabled = this.getResources().getBoolean( 49078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby com.android.internal.R.bool.config_cellBroadcastAppLinks); 49178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby try { 49278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (isCellBroadcastAppLinkEnabled) { 49378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby PackageManager pm = getPackageManager(); 49478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (pm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver") 49578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 49678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby isCellBroadcastAppLinkEnabled = false; // CMAS app disabled 49778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 49878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 49978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } catch (IllegalArgumentException ignored) { 50078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby isCellBroadcastAppLinkEnabled = false; // CMAS app not installed 50178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 50278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (!isCellBroadcastAppLinkEnabled) { 50378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastItem.setVisible(false); 50478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 50578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 50678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby 507e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return true; 508136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor } 509136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor 510136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor @Override 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 512b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor MenuItem item = menu.findItem(R.id.action_delete_all); 513b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (item != null) { 514991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun item.setVisible((mListAdapter.getCount() > 0) && mIsSmsEnabled); 515991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 516991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun item = menu.findItem(R.id.action_compose_new); 517991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (item != null ){ 518a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Dim compose if SMS is disabled because it will not work (will show a toast) 519a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun item.getIcon().setAlpha(mIsSmsEnabled ? 255 : 127); 52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 521b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (!LogTag.DEBUG_DUMP) { 522b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor item = menu.findItem(R.id.action_debug_dump); 523b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (item != null) { 524b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor item.setVisible(false); 525b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor } 526b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor } 527331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner return true; 528331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner } 529331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 530331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner @Override 531331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner public boolean onSearchRequested() { 5324a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor if (mSearchItem != null) { 5334a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor mSearchItem.expandActionView(); 5344a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor } 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onOptionsItemSelected(MenuItem item) { 54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch(item.getItemId()) { 541b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_compose_new: 542a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun if (mIsSmsEnabled) { 543a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun createNewMessage(); 544a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } else { 545a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Display a toast letting the user know they can not compose. 546a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun if (mComposeDisabledToast == null) { 547a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mComposeDisabledToast = Toast.makeText(this, 548a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun R.string.compose_disabled_toast, Toast.LENGTH_SHORT); 549a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 550a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mComposeDisabledToast.show(); 551a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 553b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_delete_all: 5543e10898d774b0005fc776865216651346503024bTom Taylor // The invalid threadId of -1 means all threads here. 5553e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(-1L, mQueryHandler); 55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 557b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_settings: 55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = new Intent(this, MessagingPreferenceActivity.class); 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project startActivityIfNeeded(intent, -1); 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 561b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_debug_dump: 562b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor LogTag.dumpInternalTables(this); 563b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor break; 56478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby case R.id.action_cell_broadcasts: 56578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby Intent cellBroadcastIntent = new Intent(Intent.ACTION_MAIN); 56678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastIntent.setComponent(new ComponentName( 56778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby "com.android.cellbroadcastreceiver", 56878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby "com.android.cellbroadcastreceiver.CellBroadcastListActivity")); 56978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 57078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby try { 57178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby startActivity(cellBroadcastIntent); 57278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } catch (ActivityNotFoundException ignored) { 57378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby Log.e(TAG, "ActivityNotFoundException for CellBroadcastListActivity"); 57478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 57578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby return true; 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 57772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 57872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 57972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 58172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onListItemClick(ListView l, View v, int position, long id) { 5842426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // Note: don't read the thread id data from the ConversationListItem view passed in. 5852426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // It's unreliable to read the cached data stored in the view because the ListItem 5862426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // can be recycled, and the same view could be assigned to a different position 5872426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // if you click the list item fast enough. Instead, get the cursor at the position 5882426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // clicked and load the data from the cursor. 5892426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // (ConversationListAdapter extends CursorAdapter, so getItemAtPosition() should 5902426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // return the cursor object, which is moved to the position passed in) 5912426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Cursor cursor = (Cursor) getListView().getItemAtPosition(position); 5922426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Conversation conv = Conversation.from(this, cursor); 5932426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor long tid = conv.getThreadId(); 5942426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 5952426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (LogTag.VERBOSE) { 5962426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Log.d(TAG, "onListItemClick: pos=" + position + ", view=" + v + ", tid=" + tid); 59772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 5982426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 5992426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor openThread(tid); 60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void createNewMessage() { 603812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang startActivity(ComposeMessageActivity.createIntent(this, 0)); 60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 606ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick private void openThread(long threadId) { 607812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang startActivity(ComposeMessageActivity.createIntent(this, threadId)); 60872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6107d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor public static Intent createAddContactIntent(String address) { 6117d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor // address must be a single recipient 6121bb6975b0a9a5a4b38aef689305b1e7eb5b61b08Tom Taylor Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); 613923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.setType(Contacts.CONTENT_ITEM_TYPE); 61420b79e068c8aebff46f24fd3803cf7697df4eac4Ficus Kirkpatrick if (Mms.isEmailAddress(address)) { 615923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.putExtra(ContactsContract.Intents.Insert.EMAIL, address); 61620b79e068c8aebff46f24fd3803cf7697df4eac4Ficus Kirkpatrick } else { 617923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.putExtra(ContactsContract.Intents.Insert.PHONE, address); 618012970b3d50851d147318527a9a872108b0ab9c7Tom Taylor intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, 619012970b3d50851d147318527a9a872108b0ab9c7Tom Taylor ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); 6207d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 621dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 62233a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 6237d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor return intent; 6247d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 6257d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor 62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final OnCreateContextMenuListener mConvListOnCreateContextMenuListener = 62772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new OnCreateContextMenuListener() { 628ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreateContextMenu(ContextMenu menu, View v, 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContextMenuInfo menuInfo) { 63159cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Cursor cursor = mListAdapter.getCursor(); 632f899bce945a70990c9511ce4d26f856d8adf1e04Tom Taylor if (cursor == null || cursor.getPosition() < 0) { 633e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor return; 634e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor } 63570c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick Conversation conv = Conversation.from(ConversationList.this, cursor); 63633a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick ContactList recipients = conv.getRecipients(); 63733a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick menu.setHeaderTitle(recipients.formatNames(",")); 63870c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick 63970c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick AdapterView.AdapterContextMenuInfo info = 64070c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick (AdapterView.AdapterContextMenuInfo) menuInfo; 6412426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_VIEW, 0, R.string.menu_view); 6422426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 6432426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // Only show if there's a single recipient 6442426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (recipients.size() == 1) { 6452426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // do we have this recipient in contacts? 6462426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (recipients.get(0).existsInDatabase()) { 6472426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact); 6482426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor } else { 6492426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_ADD_TO_CONTACTS, 0, R.string.menu_add_to_contacts); 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 652991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (mIsSmsEnabled) { 653991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun menu.add(0, MENU_DELETE, 0, R.string.menu_delete); 654991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 65572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onContextItemSelected(MenuItem item) { 66059cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Cursor cursor = mListAdapter.getCursor(); 661f899bce945a70990c9511ce4d26f856d8adf1e04Tom Taylor if (cursor != null && cursor.getPosition() >= 0) { 662e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor Conversation conv = Conversation.from(ConversationList.this, cursor); 663e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor long threadId = conv.getThreadId(); 664e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor switch (item.getItemId()) { 66572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_DELETE: { 6663e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(threadId, mQueryHandler); 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 66872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_VIEW: { 670ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick openThread(threadId); 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_VIEW_CONTACT: { 67433a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick Contact contact = conv.getRecipients().get(0); 67533a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick Intent intent = new Intent(Intent.ACTION_VIEW, contact.getUri()); 676dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 67733a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick startActivity(intent); 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 67972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 6807d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor case MENU_ADD_TO_CONTACTS: { 68133a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick String address = conv.getRecipients().get(0).getNumber(); 6827d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor startActivity(createAddContactIntent(address)); 6837d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor break; 6847d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 687e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor } 68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return super.onContextItemSelected(item); 69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 692923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov @Override 69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onConfigurationChanged(Configuration newConfig) { 69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // We override this method to avoid restarting the entire 69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // activity when the keyboard is opened (declared in 69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // AndroidManifest.xml). Because the only translatable text 69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // in this activity is "New Message", which has the full width 69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // of phone to work with, localization shouldn't be a problem: 69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // no abbreviated alternate words should be needed even in 70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // 'wide' languages like German or Russian. 70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onConfigurationChanged(newConfig); 70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (DEBUG) Log.v(TAG, "onConfigurationChanged: " + newConfig); 70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7063e10898d774b0005fc776865216651346503024bTom Taylor /** 7073e10898d774b0005fc776865216651346503024bTom Taylor * Start the process of putting up a dialog to confirm deleting a thread, 7083e10898d774b0005fc776865216651346503024bTom Taylor * but first start a background query to see if any of the threads or thread 7093e10898d774b0005fc776865216651346503024bTom Taylor * contain locked messages so we'll know how detailed of a UI to display. 7103e10898d774b0005fc776865216651346503024bTom Taylor * @param threadId id of the thread to delete or -1 for all threads 7113e10898d774b0005fc776865216651346503024bTom Taylor * @param handler query handler to do the background locked query 7123e10898d774b0005fc776865216651346503024bTom Taylor */ 7133e10898d774b0005fc776865216651346503024bTom Taylor public static void confirmDeleteThread(long threadId, AsyncQueryHandler handler) { 714b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ArrayList<Long> threadIds = null; 715b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (threadId != -1) { 716b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor threadIds = new ArrayList<Long>(); 717b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor threadIds.add(threadId); 718b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 719b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor confirmDeleteThreads(threadIds, handler); 720b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 721b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 722b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor /** 723b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * Start the process of putting up a dialog to confirm deleting threads, 724b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * but first start a background query to see if any of the threads 725b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * contain locked messages so we'll know how detailed of a UI to display. 726b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * @param threadIds list of threadIds to delete or null for all threads 727b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * @param handler query handler to do the background locked query 728b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor */ 729b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor public static void confirmDeleteThreads(Collection<Long> threadIds, AsyncQueryHandler handler) { 730b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor Conversation.startQueryHaveLockedMessages(handler, threadIds, 7313e10898d774b0005fc776865216651346503024bTom Taylor HAVE_LOCKED_MESSAGES_TOKEN); 73285fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 73385fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 7343e10898d774b0005fc776865216651346503024bTom Taylor /** 7353e10898d774b0005fc776865216651346503024bTom Taylor * Build and show the proper delete thread dialog. The UI is slightly different 7363e10898d774b0005fc776865216651346503024bTom Taylor * depending on whether there are locked messages in the thread(s) and whether we're 737b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * deleting single/multiple threads or all threads. 7383e10898d774b0005fc776865216651346503024bTom Taylor * @param listener gets called when the delete button is pressed 739ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev * @param threadIds the thread IDs to be deleted (pass null for all threads) 7403e10898d774b0005fc776865216651346503024bTom Taylor * @param hasLockedMessages whether the thread(s) contain locked messages 7413e10898d774b0005fc776865216651346503024bTom Taylor * @param context used to load the various UI elements 7423e10898d774b0005fc776865216651346503024bTom Taylor */ 7433e10898d774b0005fc776865216651346503024bTom Taylor public static void confirmDeleteThreadDialog(final DeleteThreadListener listener, 744b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor Collection<Long> threadIds, 7453e10898d774b0005fc776865216651346503024bTom Taylor boolean hasLockedMessages, 7463e10898d774b0005fc776865216651346503024bTom Taylor Context context) { 7473e10898d774b0005fc776865216651346503024bTom Taylor View contents = View.inflate(context, R.layout.delete_thread_dialog_view, null); 74885fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor TextView msg = (TextView)contents.findViewById(R.id.message); 749b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 750b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (threadIds == null) { 751b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor msg.setText(R.string.confirm_delete_all_conversations); 752b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } else { 753b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor // Show the number of threads getting deleted in the confirmation dialog. 754b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor int cnt = threadIds.size(); 755b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor msg.setText(context.getResources().getQuantityString( 756b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor R.plurals.confirm_delete_conversation, cnt, cnt)); 757b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 758b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 75985fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor final CheckBox checkbox = (CheckBox)contents.findViewById(R.id.delete_locked); 76085fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor if (!hasLockedMessages) { 76185fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor checkbox.setVisibility(View.GONE); 76285fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } else { 7633e10898d774b0005fc776865216651346503024bTom Taylor listener.setDeleteLockedMessage(checkbox.isChecked()); 76485fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor checkbox.setOnClickListener(new View.OnClickListener() { 765ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 76685fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor public void onClick(View v) { 7673e10898d774b0005fc776865216651346503024bTom Taylor listener.setDeleteLockedMessage(checkbox.isChecked()); 76885fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 76985fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor }); 77085fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7723e10898d774b0005fc776865216651346503024bTom Taylor AlertDialog.Builder builder = new AlertDialog.Builder(context); 77385fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor builder.setTitle(R.string.confirm_dialog_title) 77418d29eb95b2e692974b53655d4953accb6968570Tom Taylor .setIconAttribute(android.R.attr.alertDialogIcon) 7752426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setCancelable(true) 7762426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setPositiveButton(R.string.delete, listener) 7772426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setNegativeButton(R.string.no, null) 7782426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setView(contents) 7792426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .show(); 78072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 78172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final OnKeyListener mThreadListKeyListener = new OnKeyListener() { 783ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onKey(View v, int keyCode, KeyEvent event) { 78572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (event.getAction() == KeyEvent.ACTION_DOWN) { 78672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (keyCode) { 78772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DEL: { 78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long id = getListView().getSelectedItemId(); 78972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (id > 0) { 7903e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(id, mQueryHandler); 79172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 79972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8003e10898d774b0005fc776865216651346503024bTom Taylor public static class DeleteThreadListener implements OnClickListener { 801b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor private final Collection<Long> mThreadIds; 8026bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor private final ConversationQueryHandler mHandler; 8033e10898d774b0005fc776865216651346503024bTom Taylor private final Context mContext; 8043e10898d774b0005fc776865216651346503024bTom Taylor private boolean mDeleteLockedMessages; 80572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8066bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor public DeleteThreadListener(Collection<Long> threadIds, ConversationQueryHandler handler, 807b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor Context context) { 808b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mThreadIds = threadIds; 8093e10898d774b0005fc776865216651346503024bTom Taylor mHandler = handler; 8103e10898d774b0005fc776865216651346503024bTom Taylor mContext = context; 8113e10898d774b0005fc776865216651346503024bTom Taylor } 8123e10898d774b0005fc776865216651346503024bTom Taylor 8133e10898d774b0005fc776865216651346503024bTom Taylor public void setDeleteLockedMessage(boolean deleteLockedMessages) { 8143e10898d774b0005fc776865216651346503024bTom Taylor mDeleteLockedMessages = deleteLockedMessages; 81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 817ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 818475d780550e0034379ed821a90fdbc96d810b72dTom Taylor public void onClick(DialogInterface dialog, final int whichButton) { 819b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor MessageUtils.handleReadReport(mContext, mThreadIds, 82072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduHeaders.READ_STATUS__DELETED_WITHOUT_BEING_READ, new Runnable() { 821ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 82272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 82370c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick int token = DELETE_CONVERSATION_TOKEN; 824b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mThreadIds == null) { 8253e10898d774b0005fc776865216651346503024bTom Taylor Conversation.startDeleteAll(mHandler, token, mDeleteLockedMessages); 8267542864dfb78a58d056e26c9f12e48842324a849Wei Huang DraftCache.getInstance().refresh(); 82770c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick } else { 8288cc338d324dc4c92b686029064882147e9054f17Tom Taylor Conversation.startDelete(mHandler, token, mDeleteLockedMessages, 8298cc338d324dc4c92b686029064882147e9054f17Tom Taylor mThreadIds); 83070c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick } 83172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }); 833c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor dialog.dismiss(); 83472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8375fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor private final Runnable mDeleteObsoleteThreadsRunnable = new Runnable() { 838ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 8395fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor public void run() { 8405fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 8415fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable getSavingDraft(): " + 8425fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor DraftCache.getInstance().getSavingDraft()); 8435fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8445fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor if (DraftCache.getInstance().getSavingDraft()) { 8455fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor // We're still saving a draft. Try again in a second. We don't want to delete 8465fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor // any threads out from under the draft. 84799f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 84899f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable saving draft, trying again"); 84999f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 8505fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor mHandler.postDelayed(mDeleteObsoleteThreadsRunnable, 1000); 8515fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } else { 85299f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 85399f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable calling " + 85499f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor "asyncDeleteObsoleteThreads"); 85599f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 8565fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor Conversation.asyncDeleteObsoleteThreads(mQueryHandler, 8575fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor DELETE_OBSOLETE_THREADS_TOKEN); 8585fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8595fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8605fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor }; 8615fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor 8626bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor private final class ThreadListQueryHandler extends ConversationQueryHandler { 86372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ThreadListQueryHandler(ContentResolver contentResolver) { 86472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(contentResolver); 86572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 867e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // Test code used for various scenarios where its desirable to insert a delay in 868e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // responding to query complete. To use, uncomment out the block below and then 869e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // comment out the @Override and onQueryComplete line. 870e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// @Override 871e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// protected void onQueryComplete(final int token, final Object cookie, final Cursor cursor) { 872e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// mHandler.postDelayed(new Runnable() { 873e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// public void run() { 874e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// myonQueryComplete(token, cookie, cursor); 875e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// } 876e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// }, 2000); 877e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// } 878e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// 879e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// protected void myonQueryComplete(int token, Object cookie, Cursor cursor) { 880e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor 88172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 88272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 88359cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick switch (token) { 88459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick case THREAD_LIST_QUERY_TOKEN: 88559cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.changeCursor(cursor); 886627007213deb59ef938c80353c8f3598b01478b3Wei Huang 887e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor if (mListAdapter.getCount() == 0) { 888e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor ((TextView)(getListView().getEmptyView())).setText(R.string.no_conversations); 889e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor } 890e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor 891d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor if (mDoOnceAfterFirstQuery) { 892d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor mDoOnceAfterFirstQuery = false; 893d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // Delay doing a couple of DB operations until we've initially queried the DB 894d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // for the list of conversations to display. We don't want to slow down showing 895d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // the initial UI. 896d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor 897d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // 1. Delete any obsolete threads. Obsolete threads are threads that aren't 898d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // referenced by at least one message in the pdu or sms tables. 8995fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor mHandler.post(mDeleteObsoleteThreadsRunnable); 900d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor 901d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // 2. Mark all the conversations as seen. 902d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor Conversation.markAllConversationsAsSeen(getApplicationContext()); 90363e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor } 9046019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor if (mSavedFirstVisiblePosition != AdapterView.INVALID_POSITION) { 9056019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // Restore the list to its previous position. 9066019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor getListView().setSelectionFromTop(mSavedFirstVisiblePosition, 9076019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstItemOffset); 9086019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION; 9096019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } 91059cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick break; 91185fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 9122426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor case UNREAD_THREADS_QUERY_TOKEN: 91328af0405f300b050bed3b4649ad777bde8f28971Tom Taylor int count = 0; 91428af0405f300b050bed3b4649ad777bde8f28971Tom Taylor if (cursor != null) { 91528af0405f300b050bed3b4649ad777bde8f28971Tom Taylor count = cursor.getCount(); 91628af0405f300b050bed3b4649ad777bde8f28971Tom Taylor cursor.close(); 91728af0405f300b050bed3b4649ad777bde8f28971Tom Taylor } 9182426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor mUnreadConvCount.setText(count > 0 ? Integer.toString(count) : null); 9192426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor break; 9202426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 92185fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor case HAVE_LOCKED_MESSAGES_TOKEN: 922ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @SuppressWarnings("unchecked") 923b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor Collection<Long> threadIds = (Collection<Long>)cookie; 924b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor confirmDeleteThreadDialog(new DeleteThreadListener(threadIds, mQueryHandler, 925b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ConversationList.this), threadIds, 9263e10898d774b0005fc776865216651346503024bTom Taylor cursor != null && cursor.getCount() > 0, 9273e10898d774b0005fc776865216651346503024bTom Taylor ConversationList.this); 92828af0405f300b050bed3b4649ad777bde8f28971Tom Taylor if (cursor != null) { 92928af0405f300b050bed3b4649ad777bde8f28971Tom Taylor cursor.close(); 93028af0405f300b050bed3b4649ad777bde8f28971Tom Taylor } 93185fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor break; 93285fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 93359cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick default: 93459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Log.e(TAG, "onQueryComplete called with unknown token " + token); 93572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 93672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 93772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 93872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 93972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onDeleteComplete(int token, Object cookie, int result) { 9406bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor super.onDeleteComplete(token, cookie, result); 94172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (token) { 94272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DELETE_CONVERSATION_TOKEN: 9431b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor long threadId = cookie != null ? (Long)cookie : -1; // default to all threads 9442ddc2c0585fec6fca59acc115e26dc51f69aacc5Tom Taylor 9451b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor if (threadId == -1) { 9461b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // Rebuild the contacts cache now that all threads and their associated unique 9471b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // recipients have been deleted. 9481b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor Contact.init(ConversationList.this); 9491b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } else { 9501b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // Remove any recipients referenced by this single thread from the 9511b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // contacts cache. It's possible for two or more threads to reference 9521b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // the same contact. That's ok if we remove it. We'll recreate that contact 9531b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // when we init all Conversations below. 9541b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor Conversation conv = Conversation.get(ConversationList.this, threadId, false); 9551b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor if (conv != null) { 9561b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor ContactList recipients = conv.getRecipients(); 9571b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor for (Contact contact : recipients) { 9581b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor contact.removeFromCache(); 9591b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 9601b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 9611b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 96207ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor // Make sure the conversation cache reflects the threads in the DB. 96307ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor Conversation.init(ConversationList.this); 96407ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor 96572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Update the notification for new messages since they 96672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // may be deleted. 9673b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor MessagingNotification.nonBlockingUpdateNewMessageIndicator(ConversationList.this, 968c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.THREAD_NONE, false); 96972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Update the notification for failed messages since they 97072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // may be deleted. 971b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor MessagingNotification.nonBlockingUpdateSendFailedNotification(ConversationList.this); 97233a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 97372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Make sure the list reflects the delete 97472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project startAsyncQuery(); 975cee64965b033733a494df675892267e109a23dd6Roger Chen 976cee64965b033733a494df675892267e109a23dd6Roger Chen MmsWidgetProvider.notifyDatasetChanged(getApplicationContext()); 97772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 97863e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor 97963e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor case DELETE_OBSOLETE_THREADS_TOKEN: 98099f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 98199f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("onQueryComplete finished DELETE_OBSOLETE_THREADS_TOKEN"); 98299f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 98363e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor break; 98472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 98572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 98672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 987812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 988b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private class ModeCallback implements ListView.MultiChoiceModeListener { 989b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private View mMultiSelectActionBarView; 990b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private TextView mSelectedConvCount; 991b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor private HashSet<Long> mSelectedThreadIds; 992b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 993ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 994b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onCreateActionMode(ActionMode mode, Menu menu) { 995b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor MenuInflater inflater = getMenuInflater(); 996b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds = new HashSet<Long>(); 997b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor inflater.inflate(R.menu.conversation_multi_select_menu, menu); 998b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 999b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mMultiSelectActionBarView == null) { 1000ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev mMultiSelectActionBarView = LayoutInflater.from(ConversationList.this) 1001b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .inflate(R.layout.conversation_list_multi_select_actionbar, null); 1002b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1003b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount = 1004b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor (TextView)mMultiSelectActionBarView.findViewById(R.id.selected_conv_count); 1005b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1006b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.setCustomView(mMultiSelectActionBarView); 1007b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ((TextView)mMultiSelectActionBarView.findViewById(R.id.title)) 1008b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .setText(R.string.select_conversations); 1009b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1010b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1011b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1012ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1013b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 1014b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mMultiSelectActionBarView == null) { 1015b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ViewGroup v = (ViewGroup)LayoutInflater.from(ConversationList.this) 1016b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .inflate(R.layout.conversation_list_multi_select_actionbar, null); 1017b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.setCustomView(v); 1018b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1019b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount = (TextView)v.findViewById(R.id.selected_conv_count); 1020b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1021b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1022b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1023b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1024ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1025b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 1026b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor switch (item.getItemId()) { 1027b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor case R.id.delete: 1028b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor if (mSelectedThreadIds.size() > 0) { 1029b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor confirmDeleteThreads(mSelectedThreadIds, mQueryHandler); 1030b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1031b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.finish(); 1032b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor break; 1033b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1034b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor default: 1035b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor break; 1036b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1037b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1038b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1039b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1040ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1041b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public void onDestroyActionMode(ActionMode mode) { 1042f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor ConversationListAdapter adapter = (ConversationListAdapter)getListView().getAdapter(); 1043f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor adapter.uncheckAll(); 1044b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds = null; 1045b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1046b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1047ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1048b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public void onItemCheckedStateChanged(ActionMode mode, 1049b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor int position, long id, boolean checked) { 1050f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor ListView listView = getListView(); 1051f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor final int checkedCount = listView.getCheckedItemCount(); 1052b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount.setText(Integer.toString(checkedCount)); 1053f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 1054f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor Cursor cursor = (Cursor)listView.getItemAtPosition(position); 1055f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor Conversation conv = Conversation.from(ConversationList.this, cursor); 1056f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor conv.setIsChecked(checked); 1057b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor long threadId = conv.getThreadId(); 1058b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor 1059b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor if (checked) { 1060b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds.add(threadId); 1061b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor } else { 1062b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds.remove(threadId); 1063b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor } 1064b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1065b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1066b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1067b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1068812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang private void log(String format, Object... args) { 1069812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang String s = String.format(format, args); 1070812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang Log.d(TAG, "[" + Thread.currentThread().getId() + "] " + s); 1071812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang } 107272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 1073