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 { 94ab845dee6565a8dfc384186bc8f2e801a2b087e1Ye Wen private static final String TAG = LogTag.TAG; 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(); 203a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor 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 218a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor 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 387a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor startAsyncQuery(); 388a277f438d33872b9a0f1611fb8a86a918765f04bTom 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 411a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor stopAsyncQuery(); 412a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor 413d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang DraftCache.getInstance().removeOnDraftChangedListener(this); 414f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 415a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor unbindListeners(null); 416f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor // Simply setting the choice mode causes the previous choice mode to finish and we exit 417f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor // multi-select mode (if we're in it) and remove all the selections. 418f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 419f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 4206f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen // Close the cursor in the ListAdapter if the activity stopped. 4216f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen Cursor cursor = mListAdapter.getCursor(); 4226f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen 4236f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen if (cursor != null && !cursor.isClosed()) { 4246f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen cursor.close(); 4256f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen } 4266f82efcfc934f13b7774a05c8d5ed9fafa2c4fcaRoger Chen 42759cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.changeCursor(null); 42872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 430a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor private void unbindListeners(final Collection<Long> threadIds) { 431a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor for (int i = 0; i < getListView().getChildCount(); i++) { 432a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor View view = getListView().getChildAt(i); 433a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (view instanceof ConversationListItem) { 434a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor ConversationListItem item = (ConversationListItem)view; 435a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (threadIds == null) { 436a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor item.unbind(); 437a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } else if (threadIds.contains(item.getConversation().getThreadId())) { 438a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor item.unbind(); 439a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 440a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 441a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 442a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 443a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor 444ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 445d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang public void onDraftChanged(final long threadId, final boolean hasDraft) { 44659cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick // Run notifyDataSetChanged() on the main thread. 44759cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mQueryHandler.post(new Runnable() { 448ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 44959cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick public void run() { 450d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 451d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang log("onDraftChanged: threadId=" + threadId + ", hasDraft=" + hasDraft); 452d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang } 45359cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.notifyDataSetChanged(); 45459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick } 45559cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick }); 456b530437ceaad97151be691067191f48e1e93b87eFicus Kirkpatrick } 45733a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void startAsyncQuery() { 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 460e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor ((TextView)(getListView().getEmptyView())).setText(R.string.loading_conversations); 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46270c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick Conversation.startQueryForAll(mQueryHandler, THREAD_LIST_QUERY_TOKEN); 4632426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Conversation.startQuery(mQueryHandler, UNREAD_THREADS_QUERY_TOKEN, Threads.READ + "=0"); 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (SQLiteException e) { 46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SqliteWrapper.checkSQLiteException(this, e); 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 469a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor private void stopAsyncQuery() { 470a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (mQueryHandler != null) { 471a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor mQueryHandler.cancelOperation(THREAD_LIST_QUERY_TOKEN); 472a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor mQueryHandler.cancelOperation(UNREAD_THREADS_QUERY_TOKEN); 473a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 474a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 475a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor 476e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchView.OnQueryTextListener mQueryTextListener = new SearchView.OnQueryTextListener() { 477ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 478e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner public boolean onQueryTextSubmit(String query) { 479e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner Intent intent = new Intent(); 480e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner intent.setClass(ConversationList.this, SearchActivity.class); 481e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner intent.putExtra(SearchManager.QUERY, query); 482e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner startActivity(intent); 483e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchItem.collapseActionView(); 484e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return true; 485e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 486e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner 487ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 488e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner public boolean onQueryTextChange(String newText) { 489e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return false; 490e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 491e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner }; 492b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 494136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor public boolean onCreateOptionsMenu(Menu menu) { 495b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor getMenuInflater().inflate(R.menu.conversation_list_menu, menu); 496b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 497e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchItem = menu.findItem(R.id.search); 498e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView = (SearchView) mSearchItem.getActionView(); 499b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor 500e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setOnQueryTextListener(mQueryTextListener); 501e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setQueryHint(getString(R.string.search_hint)); 502e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setIconifiedByDefault(true); 503e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 504136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor 505e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner if (searchManager != null) { 506e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner SearchableInfo info = searchManager.getSearchableInfo(this.getComponentName()); 507e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner mSearchView.setSearchableInfo(info); 508e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner } 509e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner 51078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby MenuItem cellBroadcastItem = menu.findItem(R.id.action_cell_broadcasts); 51178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (cellBroadcastItem != null) { 51278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby // Enable link to Cell broadcast activity depending on the value in config.xml. 51378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby boolean isCellBroadcastAppLinkEnabled = this.getResources().getBoolean( 51478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby com.android.internal.R.bool.config_cellBroadcastAppLinks); 51578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby try { 51678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (isCellBroadcastAppLinkEnabled) { 51778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby PackageManager pm = getPackageManager(); 51878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (pm.getApplicationEnabledSetting("com.android.cellbroadcastreceiver") 51978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) { 52078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby isCellBroadcastAppLinkEnabled = false; // CMAS app disabled 52178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 52278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 52378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } catch (IllegalArgumentException ignored) { 52478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby isCellBroadcastAppLinkEnabled = false; // CMAS app not installed 52578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 52678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby if (!isCellBroadcastAppLinkEnabled) { 52778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastItem.setVisible(false); 52878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 52978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 53078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby 531e131a53620fff000a08cf53d29313a3922328dc0Mark Wagner return true; 532136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor } 533136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor 534136fe3767b8cb5dc0575992f2f6951c8451ee5e2Tom Taylor @Override 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onPrepareOptionsMenu(Menu menu) { 536b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor MenuItem item = menu.findItem(R.id.action_delete_all); 537b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (item != null) { 538991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun item.setVisible((mListAdapter.getCount() > 0) && mIsSmsEnabled); 539991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 540991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun item = menu.findItem(R.id.action_compose_new); 541991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (item != null ){ 542a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Dim compose if SMS is disabled because it will not work (will show a toast) 543a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun item.getIcon().setAlpha(mIsSmsEnabled ? 255 : 127); 54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 545b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (!LogTag.DEBUG_DUMP) { 546b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor item = menu.findItem(R.id.action_debug_dump); 547b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor if (item != null) { 548b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor item.setVisible(false); 549b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor } 550b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor } 551331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner return true; 552331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner } 553331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 554331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner @Override 555331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner public boolean onSearchRequested() { 5564a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor if (mSearchItem != null) { 5574a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor mSearchItem.expandActionView(); 5584a0d14c517c1968c0f1e59544a54277ede9a8fa4Tom Taylor } 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onOptionsItemSelected(MenuItem item) { 56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch(item.getItemId()) { 565b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_compose_new: 566a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun if (mIsSmsEnabled) { 567a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun createNewMessage(); 568a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } else { 569a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun // Display a toast letting the user know they can not compose. 570a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun if (mComposeDisabledToast == null) { 571a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mComposeDisabledToast = Toast.makeText(this, 572a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun R.string.compose_disabled_toast, Toast.LENGTH_SHORT); 573a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 574a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun mComposeDisabledToast.show(); 575a8ec27f7ab554745e1e1c4700455fdfd6a1048e9David Braun } 57672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 577b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_delete_all: 5783e10898d774b0005fc776865216651346503024bTom Taylor // The invalid threadId of -1 means all threads here. 5793e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(-1L, mQueryHandler); 58072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 581b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_settings: 58272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = new Intent(this, MessagingPreferenceActivity.class); 58372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project startActivityIfNeeded(intent, -1); 58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 585b31f9b5666f424d4fe8551696f480be0c1f51926Tom Taylor case R.id.action_debug_dump: 586a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor LogTag.dumpInternalTables(this); 587b3217a6ddcd9455968de7078bfbc0a901b4ff705Tom Taylor break; 58878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby case R.id.action_cell_broadcasts: 58978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby Intent cellBroadcastIntent = new Intent(Intent.ACTION_MAIN); 59078e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastIntent.setComponent(new ComponentName( 59178e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby "com.android.cellbroadcastreceiver", 59278e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby "com.android.cellbroadcastreceiver.CellBroadcastListActivity")); 59378e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby cellBroadcastIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 59478e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby try { 59578e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby startActivity(cellBroadcastIntent); 59678e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } catch (ActivityNotFoundException ignored) { 59778e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby Log.e(TAG, "ActivityNotFoundException for CellBroadcastListActivity"); 59878e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby } 59978e2f412983f8f3732b87bfd794e04d3b20233bbJake Hamby return true; 60072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 60172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 60772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onListItemClick(ListView l, View v, int position, long id) { 6082426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // Note: don't read the thread id data from the ConversationListItem view passed in. 6092426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // It's unreliable to read the cached data stored in the view because the ListItem 6102426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // can be recycled, and the same view could be assigned to a different position 6112426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // if you click the list item fast enough. Instead, get the cursor at the position 6122426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // clicked and load the data from the cursor. 6132426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // (ConversationListAdapter extends CursorAdapter, so getItemAtPosition() should 6142426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // return the cursor object, which is moved to the position passed in) 6152426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Cursor cursor = (Cursor) getListView().getItemAtPosition(position); 6162426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Conversation conv = Conversation.from(this, cursor); 6172426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor long tid = conv.getThreadId(); 6182426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 6192426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (LogTag.VERBOSE) { 6202426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor Log.d(TAG, "onListItemClick: pos=" + position + ", view=" + v + ", tid=" + tid); 62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 6222426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 6232426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor openThread(tid); 62472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void createNewMessage() { 627812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang startActivity(ComposeMessageActivity.createIntent(this, 0)); 62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 630ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick private void openThread(long threadId) { 631812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang startActivity(ComposeMessageActivity.createIntent(this, threadId)); 63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6347d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor public static Intent createAddContactIntent(String address) { 6357d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor // address must be a single recipient 6361bb6975b0a9a5a4b38aef689305b1e7eb5b61b08Tom Taylor Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); 637923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.setType(Contacts.CONTENT_ITEM_TYPE); 63820b79e068c8aebff46f24fd3803cf7697df4eac4Ficus Kirkpatrick if (Mms.isEmailAddress(address)) { 639923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.putExtra(ContactsContract.Intents.Insert.EMAIL, address); 64020b79e068c8aebff46f24fd3803cf7697df4eac4Ficus Kirkpatrick } else { 641923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov intent.putExtra(ContactsContract.Intents.Insert.PHONE, address); 642012970b3d50851d147318527a9a872108b0ab9c7Tom Taylor intent.putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, 643012970b3d50851d147318527a9a872108b0ab9c7Tom Taylor ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); 6447d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 645dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 64633a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 6477d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor return intent; 6487d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 6497d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor 65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final OnCreateContextMenuListener mConvListOnCreateContextMenuListener = 65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project new OnCreateContextMenuListener() { 652ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onCreateContextMenu(ContextMenu menu, View v, 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ContextMenuInfo menuInfo) { 65559cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Cursor cursor = mListAdapter.getCursor(); 656f899bce945a70990c9511ce4d26f856d8adf1e04Tom Taylor if (cursor == null || cursor.getPosition() < 0) { 657e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor return; 658e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor } 65970c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick Conversation conv = Conversation.from(ConversationList.this, cursor); 66033a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick ContactList recipients = conv.getRecipients(); 66133a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick menu.setHeaderTitle(recipients.formatNames(",")); 66270c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick 66370c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick AdapterView.AdapterContextMenuInfo info = 66470c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick (AdapterView.AdapterContextMenuInfo) menuInfo; 6652426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_VIEW, 0, R.string.menu_view); 6662426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 6672426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // Only show if there's a single recipient 6682426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (recipients.size() == 1) { 6692426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor // do we have this recipient in contacts? 6702426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor if (recipients.get(0).existsInDatabase()) { 6712426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact); 6722426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor } else { 6732426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor menu.add(0, MENU_ADD_TO_CONTACTS, 0, R.string.menu_add_to_contacts); 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 676991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun if (mIsSmsEnabled) { 677991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun menu.add(0, MENU_DELETE, 0, R.string.menu_delete); 678991a1f3a31bd749573b4d780a3e4d01e6c1c293fDavid Braun } 67972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 68172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 68272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onContextItemSelected(MenuItem item) { 68459cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Cursor cursor = mListAdapter.getCursor(); 685f899bce945a70990c9511ce4d26f856d8adf1e04Tom Taylor if (cursor != null && cursor.getPosition() >= 0) { 686e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor Conversation conv = Conversation.from(ConversationList.this, cursor); 687e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor long threadId = conv.getThreadId(); 688e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor switch (item.getItemId()) { 68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_DELETE: { 6903e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(threadId, mQueryHandler); 69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_VIEW: { 694ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick openThread(threadId); 69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case MENU_VIEW_CONTACT: { 69833a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick Contact contact = conv.getRecipients().get(0); 69933a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick Intent intent = new Intent(Intent.ACTION_VIEW, contact.getUri()); 700dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 70133a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick startActivity(intent); 70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 7047d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor case MENU_ADD_TO_CONTACTS: { 70533a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick String address = conv.getRecipients().get(0).getNumber(); 7067d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor startActivity(createAddContactIntent(address)); 7077d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor break; 7087d3e1caa6000b0bbab0716b1815c2c7177d67948Tom Taylor } 70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 711e64a39148677dfae433185af5a63f9a9f8687b48Tom Taylor } 71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return super.onContextItemSelected(item); 71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 716923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov @Override 71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onConfigurationChanged(Configuration newConfig) { 71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // We override this method to avoid restarting the entire 71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // activity when the keyboard is opened (declared in 72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // AndroidManifest.xml). Because the only translatable text 72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // in this activity is "New Message", which has the full width 72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // of phone to work with, localization shouldn't be a problem: 72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // no abbreviated alternate words should be needed even in 72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // 'wide' languages like German or Russian. 72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onConfigurationChanged(newConfig); 72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (DEBUG) Log.v(TAG, "onConfigurationChanged: " + newConfig); 72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7303e10898d774b0005fc776865216651346503024bTom Taylor /** 7313e10898d774b0005fc776865216651346503024bTom Taylor * Start the process of putting up a dialog to confirm deleting a thread, 7323e10898d774b0005fc776865216651346503024bTom Taylor * but first start a background query to see if any of the threads or thread 7333e10898d774b0005fc776865216651346503024bTom Taylor * contain locked messages so we'll know how detailed of a UI to display. 7343e10898d774b0005fc776865216651346503024bTom Taylor * @param threadId id of the thread to delete or -1 for all threads 7353e10898d774b0005fc776865216651346503024bTom Taylor * @param handler query handler to do the background locked query 7363e10898d774b0005fc776865216651346503024bTom Taylor */ 7373e10898d774b0005fc776865216651346503024bTom Taylor public static void confirmDeleteThread(long threadId, AsyncQueryHandler handler) { 738b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ArrayList<Long> threadIds = null; 739b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (threadId != -1) { 740b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor threadIds = new ArrayList<Long>(); 741b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor threadIds.add(threadId); 742b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 743b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor confirmDeleteThreads(threadIds, handler); 744b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 745b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 746b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor /** 747b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * Start the process of putting up a dialog to confirm deleting threads, 748b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * but first start a background query to see if any of the threads 749b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * contain locked messages so we'll know how detailed of a UI to display. 750b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * @param threadIds list of threadIds to delete or null for all threads 751b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * @param handler query handler to do the background locked query 752b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor */ 753b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor public static void confirmDeleteThreads(Collection<Long> threadIds, AsyncQueryHandler handler) { 754b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor Conversation.startQueryHaveLockedMessages(handler, threadIds, 7553e10898d774b0005fc776865216651346503024bTom Taylor HAVE_LOCKED_MESSAGES_TOKEN); 75685fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 75785fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 7583e10898d774b0005fc776865216651346503024bTom Taylor /** 7593e10898d774b0005fc776865216651346503024bTom Taylor * Build and show the proper delete thread dialog. The UI is slightly different 7603e10898d774b0005fc776865216651346503024bTom Taylor * depending on whether there are locked messages in the thread(s) and whether we're 761b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor * deleting single/multiple threads or all threads. 7623e10898d774b0005fc776865216651346503024bTom Taylor * @param listener gets called when the delete button is pressed 763ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev * @param threadIds the thread IDs to be deleted (pass null for all threads) 7643e10898d774b0005fc776865216651346503024bTom Taylor * @param hasLockedMessages whether the thread(s) contain locked messages 7653e10898d774b0005fc776865216651346503024bTom Taylor * @param context used to load the various UI elements 7663e10898d774b0005fc776865216651346503024bTom Taylor */ 7673e10898d774b0005fc776865216651346503024bTom Taylor public static void confirmDeleteThreadDialog(final DeleteThreadListener listener, 768b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor Collection<Long> threadIds, 7693e10898d774b0005fc776865216651346503024bTom Taylor boolean hasLockedMessages, 7703e10898d774b0005fc776865216651346503024bTom Taylor Context context) { 7713e10898d774b0005fc776865216651346503024bTom Taylor View contents = View.inflate(context, R.layout.delete_thread_dialog_view, null); 77285fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor TextView msg = (TextView)contents.findViewById(R.id.message); 773b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 774b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (threadIds == null) { 775b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor msg.setText(R.string.confirm_delete_all_conversations); 776b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } else { 777b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor // Show the number of threads getting deleted in the confirmation dialog. 778b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor int cnt = threadIds.size(); 779b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor msg.setText(context.getResources().getQuantityString( 780b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor R.plurals.confirm_delete_conversation, cnt, cnt)); 781b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 782b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 78385fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor final CheckBox checkbox = (CheckBox)contents.findViewById(R.id.delete_locked); 78485fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor if (!hasLockedMessages) { 78585fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor checkbox.setVisibility(View.GONE); 78685fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } else { 7873e10898d774b0005fc776865216651346503024bTom Taylor listener.setDeleteLockedMessage(checkbox.isChecked()); 78885fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor checkbox.setOnClickListener(new View.OnClickListener() { 789ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 79085fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor public void onClick(View v) { 7913e10898d774b0005fc776865216651346503024bTom Taylor listener.setDeleteLockedMessage(checkbox.isChecked()); 79285fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 79385fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor }); 79485fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor } 79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7963e10898d774b0005fc776865216651346503024bTom Taylor AlertDialog.Builder builder = new AlertDialog.Builder(context); 79785fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor builder.setTitle(R.string.confirm_dialog_title) 79818d29eb95b2e692974b53655d4953accb6968570Tom Taylor .setIconAttribute(android.R.attr.alertDialogIcon) 7992426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setCancelable(true) 8002426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setPositiveButton(R.string.delete, listener) 8012426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setNegativeButton(R.string.no, null) 8022426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .setView(contents) 8032426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor .show(); 80472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 80572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 80672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private final OnKeyListener mThreadListKeyListener = new OnKeyListener() { 807ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 80872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public boolean onKey(View v, int keyCode, KeyEvent event) { 80972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (event.getAction() == KeyEvent.ACTION_DOWN) { 81072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (keyCode) { 81172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case KeyEvent.KEYCODE_DEL: { 81272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project long id = getListView().getSelectedItemId(); 81372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (id > 0) { 8143e10898d774b0005fc776865216651346503024bTom Taylor confirmDeleteThread(id, mQueryHandler); 81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return true; 81772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 82072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return false; 82172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 82272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 82372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8243e10898d774b0005fc776865216651346503024bTom Taylor public static class DeleteThreadListener implements OnClickListener { 825b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor private final Collection<Long> mThreadIds; 8266bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor private final ConversationQueryHandler mHandler; 8273e10898d774b0005fc776865216651346503024bTom Taylor private final Context mContext; 8283e10898d774b0005fc776865216651346503024bTom Taylor private boolean mDeleteLockedMessages; 82972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8306bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor public DeleteThreadListener(Collection<Long> threadIds, ConversationQueryHandler handler, 831b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor Context context) { 832b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mThreadIds = threadIds; 8333e10898d774b0005fc776865216651346503024bTom Taylor mHandler = handler; 8343e10898d774b0005fc776865216651346503024bTom Taylor mContext = context; 8353e10898d774b0005fc776865216651346503024bTom Taylor } 8363e10898d774b0005fc776865216651346503024bTom Taylor 8373e10898d774b0005fc776865216651346503024bTom Taylor public void setDeleteLockedMessage(boolean deleteLockedMessages) { 8383e10898d774b0005fc776865216651346503024bTom Taylor mDeleteLockedMessages = deleteLockedMessages; 83972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 84072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 841ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 842475d780550e0034379ed821a90fdbc96d810b72dTom Taylor public void onClick(DialogInterface dialog, final int whichButton) { 843b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor MessageUtils.handleReadReport(mContext, mThreadIds, 84472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project PduHeaders.READ_STATUS__DELETED_WITHOUT_BEING_READ, new Runnable() { 845ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 84672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void run() { 84770c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick int token = DELETE_CONVERSATION_TOKEN; 848a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (mContext instanceof ConversationList) { 849a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor ((ConversationList)mContext).unbindListeners(mThreadIds); 850a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 851b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mThreadIds == null) { 8523e10898d774b0005fc776865216651346503024bTom Taylor Conversation.startDeleteAll(mHandler, token, mDeleteLockedMessages); 8537542864dfb78a58d056e26c9f12e48842324a849Wei Huang DraftCache.getInstance().refresh(); 85470c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick } else { 8558cc338d324dc4c92b686029064882147e9054f17Tom Taylor Conversation.startDelete(mHandler, token, mDeleteLockedMessages, 8568cc338d324dc4c92b686029064882147e9054f17Tom Taylor mThreadIds); 85770c73e05a792832aa28da751cdaf3fa83a7b8113Ficus Kirkpatrick } 85872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 85972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }); 860c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor dialog.dismiss(); 86172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 86372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8645fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor private final Runnable mDeleteObsoleteThreadsRunnable = new Runnable() { 865ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 8665fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor public void run() { 8675fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { 8685fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable getSavingDraft(): " + 8695fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor DraftCache.getInstance().getSavingDraft()); 8705fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8715fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor if (DraftCache.getInstance().getSavingDraft()) { 8725fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor // We're still saving a draft. Try again in a second. We don't want to delete 8735fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor // any threads out from under the draft. 87499f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 87599f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable saving draft, trying again"); 87699f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 8775fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor mHandler.postDelayed(mDeleteObsoleteThreadsRunnable, 1000); 8785fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } else { 87999f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 88099f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("mDeleteObsoleteThreadsRunnable calling " + 88199f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor "asyncDeleteObsoleteThreads"); 88299f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 8835fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor Conversation.asyncDeleteObsoleteThreads(mQueryHandler, 8845fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor DELETE_OBSOLETE_THREADS_TOKEN); 8855fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8865fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor } 8875fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor }; 8885fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor 8896bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor private final class ThreadListQueryHandler extends ConversationQueryHandler { 89072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public ThreadListQueryHandler(ContentResolver contentResolver) { 89172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(contentResolver); 89272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 89372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 894e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // Test code used for various scenarios where its desirable to insert a delay in 895e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // responding to query complete. To use, uncomment out the block below and then 896e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor // comment out the @Override and onQueryComplete line. 897e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// @Override 898e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// protected void onQueryComplete(final int token, final Object cookie, final Cursor cursor) { 899e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// mHandler.postDelayed(new Runnable() { 900e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// public void run() { 901e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// myonQueryComplete(token, cookie, cursor); 902e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// } 903e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// }, 2000); 904e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// } 905e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// 906e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor// protected void myonQueryComplete(int token, Object cookie, Cursor cursor) { 907e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor 90872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 90972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 91059cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick switch (token) { 91159cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick case THREAD_LIST_QUERY_TOKEN: 91259cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick mListAdapter.changeCursor(cursor); 913627007213deb59ef938c80353c8f3598b01478b3Wei Huang 914e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor if (mListAdapter.getCount() == 0) { 915e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor ((TextView)(getListView().getEmptyView())).setText(R.string.no_conversations); 916e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor } 917e0dccd0713d9349dadef5f0b41ce7da5e970f541Tom Taylor 918d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor if (mDoOnceAfterFirstQuery) { 919d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor mDoOnceAfterFirstQuery = false; 920d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // Delay doing a couple of DB operations until we've initially queried the DB 921d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // for the list of conversations to display. We don't want to slow down showing 922d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // the initial UI. 923d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor 924d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // 1. Delete any obsolete threads. Obsolete threads are threads that aren't 925d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // referenced by at least one message in the pdu or sms tables. 9265fd2543851375fc764495584ddd319f5e7d13cb9Tom Taylor mHandler.post(mDeleteObsoleteThreadsRunnable); 927d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor 928d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor // 2. Mark all the conversations as seen. 929d645c8b53ae904bc059ee1ca7232916637c223e5Tom Taylor Conversation.markAllConversationsAsSeen(getApplicationContext()); 93063e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor } 9316019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor if (mSavedFirstVisiblePosition != AdapterView.INVALID_POSITION) { 9326019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor // Restore the list to its previous position. 9336019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor getListView().setSelectionFromTop(mSavedFirstVisiblePosition, 9346019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstItemOffset); 9356019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor mSavedFirstVisiblePosition = AdapterView.INVALID_POSITION; 9366019ec8bfc8df57e95ca1ca36cf76c77ca84818eTom Taylor } 93759cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick break; 93885fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 9392426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor case UNREAD_THREADS_QUERY_TOKEN: 94028af0405f300b050bed3b4649ad777bde8f28971Tom Taylor int count = 0; 94128af0405f300b050bed3b4649ad777bde8f28971Tom Taylor if (cursor != null) { 94228af0405f300b050bed3b4649ad777bde8f28971Tom Taylor count = cursor.getCount(); 94328af0405f300b050bed3b4649ad777bde8f28971Tom Taylor cursor.close(); 94428af0405f300b050bed3b4649ad777bde8f28971Tom Taylor } 9452426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor mUnreadConvCount.setText(count > 0 ? Integer.toString(count) : null); 9462426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor break; 9472426db8887f7f1c0c93dbab5a10663cb22575ccdTom Taylor 94885fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor case HAVE_LOCKED_MESSAGES_TOKEN: 949a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (ConversationList.this.isFinishing()) { 950a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor Log.w(TAG, "ConversationList is finished, do nothing "); 951a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor if (cursor != null) { 952a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor cursor.close(); 953a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 954a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor return ; 955a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor } 956ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @SuppressWarnings("unchecked") 957b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor Collection<Long> threadIds = (Collection<Long>)cookie; 958b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor confirmDeleteThreadDialog(new DeleteThreadListener(threadIds, mQueryHandler, 959b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ConversationList.this), threadIds, 9603e10898d774b0005fc776865216651346503024bTom Taylor cursor != null && cursor.getCount() > 0, 9613e10898d774b0005fc776865216651346503024bTom Taylor ConversationList.this); 96228af0405f300b050bed3b4649ad777bde8f28971Tom Taylor if (cursor != null) { 96328af0405f300b050bed3b4649ad777bde8f28971Tom Taylor cursor.close(); 96428af0405f300b050bed3b4649ad777bde8f28971Tom Taylor } 96585fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor break; 96685fbc94e34688455c3f2f36271ba65b90ceb2542Tom Taylor 96759cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick default: 96859cd1f499645badf8df9e2820b29d28fc1835e79Ficus Kirkpatrick Log.e(TAG, "onQueryComplete called with unknown token " + token); 96972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 97072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 97172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 97272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 97372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onDeleteComplete(int token, Object cookie, int result) { 9746bbfdd3cc9cbe6b31dc64f122f3308563d19e077Tom Taylor super.onDeleteComplete(token, cookie, result); 97572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (token) { 97672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DELETE_CONVERSATION_TOKEN: 9771b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor long threadId = cookie != null ? (Long)cookie : -1; // default to all threads 9782ddc2c0585fec6fca59acc115e26dc51f69aacc5Tom Taylor 9791b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor if (threadId == -1) { 9801b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // Rebuild the contacts cache now that all threads and their associated unique 9811b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // recipients have been deleted. 9821b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor Contact.init(ConversationList.this); 9831b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } else { 9841b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // Remove any recipients referenced by this single thread from the 9851b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // contacts cache. It's possible for two or more threads to reference 9861b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // the same contact. That's ok if we remove it. We'll recreate that contact 9871b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor // when we init all Conversations below. 9881b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor Conversation conv = Conversation.get(ConversationList.this, threadId, false); 9891b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor if (conv != null) { 9901b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor ContactList recipients = conv.getRecipients(); 9911b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor for (Contact contact : recipients) { 992a277f438d33872b9a0f1611fb8a86a918765f04bTom Taylor contact.removeFromCache(); 9931b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 9941b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 9951b1af7c751218e380bd119629ff9a652157fbb21Tom Taylor } 99607ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor // Make sure the conversation cache reflects the threads in the DB. 99707ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor Conversation.init(ConversationList.this); 99807ce1878a36d2df1707dd4bbd9cd7235679bdc94Tom Taylor 99972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Update the notification for new messages since they 100072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // may be deleted. 10013b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor MessagingNotification.nonBlockingUpdateNewMessageIndicator(ConversationList.this, 1002c8d727902ff6976c45285a12aab176545a7848bbTodor Kalaydjiev MessagingNotification.THREAD_NONE, false); 100372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Update the notification for failed messages since they 100472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // may be deleted. 1005b0ef8fc2738b210a2bb0490e75eedc1e7b7b491fTom Taylor MessagingNotification.nonBlockingUpdateSendFailedNotification(ConversationList.this); 100633a87f96f8c625aa10131a77a3968c97c4ec5a62Ficus Kirkpatrick 100772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Make sure the list reflects the delete 100872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project startAsyncQuery(); 1009cee64965b033733a494df675892267e109a23dd6Roger Chen 1010cee64965b033733a494df675892267e109a23dd6Roger Chen MmsWidgetProvider.notifyDatasetChanged(getApplicationContext()); 101172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 101263e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor 101363e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor case DELETE_OBSOLETE_THREADS_TOKEN: 101499f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor if (DEBUGCLEANUP) { 101599f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor LogTag.debug("onQueryComplete finished DELETE_OBSOLETE_THREADS_TOKEN"); 101699f719d1cb0c6ed68373d73427a816c4e56eb5baTom Taylor } 101763e395258ae33a101b9634a68b55ec89fac8b580Tom Taylor break; 101872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 101972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 102072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 1021812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 1022b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private class ModeCallback implements ListView.MultiChoiceModeListener { 1023b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private View mMultiSelectActionBarView; 1024b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor private TextView mSelectedConvCount; 1025b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor private HashSet<Long> mSelectedThreadIds; 1026b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1027ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1028b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onCreateActionMode(ActionMode mode, Menu menu) { 1029b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor MenuInflater inflater = getMenuInflater(); 1030b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds = new HashSet<Long>(); 1031b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor inflater.inflate(R.menu.conversation_multi_select_menu, menu); 1032b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1033b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mMultiSelectActionBarView == null) { 1034ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev mMultiSelectActionBarView = LayoutInflater.from(ConversationList.this) 1035b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .inflate(R.layout.conversation_list_multi_select_actionbar, null); 1036b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1037b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount = 1038b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor (TextView)mMultiSelectActionBarView.findViewById(R.id.selected_conv_count); 1039b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1040b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.setCustomView(mMultiSelectActionBarView); 1041b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ((TextView)mMultiSelectActionBarView.findViewById(R.id.title)) 1042b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .setText(R.string.select_conversations); 1043b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1044b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1045b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1046ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1047b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 1048b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor if (mMultiSelectActionBarView == null) { 1049b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor ViewGroup v = (ViewGroup)LayoutInflater.from(ConversationList.this) 1050b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor .inflate(R.layout.conversation_list_multi_select_actionbar, null); 1051b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.setCustomView(v); 1052b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1053b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount = (TextView)v.findViewById(R.id.selected_conv_count); 1054b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1055b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1056b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1057b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1058ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1059b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 1060b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor switch (item.getItemId()) { 1061b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor case R.id.delete: 1062b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor if (mSelectedThreadIds.size() > 0) { 1063b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor confirmDeleteThreads(mSelectedThreadIds, mQueryHandler); 1064b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1065b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mode.finish(); 1066b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor break; 1067b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1068b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor default: 1069b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor break; 1070b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1071b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor return true; 1072b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1073b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1074ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1075b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public void onDestroyActionMode(ActionMode mode) { 1076f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor ConversationListAdapter adapter = (ConversationListAdapter)getListView().getAdapter(); 1077f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor adapter.uncheckAll(); 1078b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds = null; 1079b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1080b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1081ddd31c4011b4191035bdfbba05a8edb1785f71afTodor Kalaydjiev @Override 1082b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor public void onItemCheckedStateChanged(ActionMode mode, 1083b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor int position, long id, boolean checked) { 1084f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor ListView listView = getListView(); 1085f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor final int checkedCount = listView.getCheckedItemCount(); 1086b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor mSelectedConvCount.setText(Integer.toString(checkedCount)); 1087f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor 1088f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor Cursor cursor = (Cursor)listView.getItemAtPosition(position); 1089f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor Conversation conv = Conversation.from(ConversationList.this, cursor); 1090f9d706cfd0c46a74ba3d79e5543f13a225328d30Tom Taylor conv.setIsChecked(checked); 1091b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor long threadId = conv.getThreadId(); 1092b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor 1093b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor if (checked) { 1094b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds.add(threadId); 1095b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor } else { 1096b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor mSelectedThreadIds.remove(threadId); 1097b04236e2977ac69e63cc0fa123399a584b606945Tom Taylor } 1098b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1099b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1100b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor } 1101b51ea8318ca2e4019b666d938e3e7efdf6e643b3Tom Taylor 1102812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang private void log(String format, Object... args) { 1103812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang String s = String.format(format, args); 1104812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang Log.d(TAG, "[" + Thread.currentThread().getId() + "] " + s); 1105812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang } 110672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 1107