194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/* 294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Copyright (C) 2009 The Android Open Source Project 394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * you may not use this file except in compliance with the License. 694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * You may obtain a copy of the License at 794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 1094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Unless required by applicable law or agreed to in writing, software 1194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 1294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * See the License for the specific language governing permissions and 1494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * limitations under the License. 1594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 1694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpackage com.android.dialer; 1894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 1994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.app.Activity; 2094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.ContentResolver; 2194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.ContentUris; 2294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.ContentValues; 2394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.Context; 2494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.Intent; 2594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.content.res.Resources; 2694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.database.Cursor; 2794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.graphics.drawable.Drawable; 2894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.net.Uri; 2994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.os.AsyncTask; 3094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.os.Bundle; 3194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.CallLog; 3294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.CallLog.Calls; 3394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.Contacts.Intents.Insert; 3494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.CommonDataKinds.Phone; 3594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.ContactsContract.Contacts; 3694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.provider.VoicemailContract.Voicemails; 3794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.PhoneNumberUtils; 3894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.telephony.TelephonyManager; 3994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.text.TextUtils; 4094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.util.Log; 4194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.ActionMode; 4294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.KeyEvent; 4394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.LayoutInflater; 4494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.Menu; 4594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.MenuItem; 4694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.view.View; 4794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.ImageButton; 4894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.ImageView; 4994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.ListView; 5094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.TextView; 5194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport android.widget.Toast; 5294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 5335071c06d1587942f5a66c8f12e6247e8f904d26Chiao Chengimport com.android.contacts.common.ContactPhotoManager; 549d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Chengimport com.android.contacts.common.CallUtil; 559d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Chengimport com.android.contacts.common.ClipboardUtils; 5635071c06d1587942f5a66c8f12e6247e8f904d26Chiao Chengimport com.android.contacts.common.GeoUtil; 5758ebe5d3fac837625b69fe1565427f17025bd780Yorke Leeimport com.android.contacts.common.util.UriUtils; 5891197049c458f07092b31501d2ed512180b13d58Chiao Chengimport com.android.dialer.BackScrollManager.ScrollableHeader; 5994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.CallDetailHistoryAdapter; 6094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.CallTypeHelper; 6194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.ContactInfo; 6294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.ContactInfoHelper; 6394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.calllog.PhoneNumberHelper; 64fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Chengimport com.android.dialer.calllog.PhoneNumberUtilsWrapper; 6591197049c458f07092b31501d2ed512180b13d58Chiao Chengimport com.android.dialer.util.AsyncTaskExecutor; 6691197049c458f07092b31501d2ed512180b13d58Chiao Chengimport com.android.dialer.util.AsyncTaskExecutors; 6794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.voicemail.VoicemailPlaybackFragment; 6894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.voicemail.VoicemailStatusHelper; 6994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.voicemail.VoicemailStatusHelper.StatusMessage; 7094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport com.android.dialer.voicemail.VoicemailStatusHelperImpl; 7194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 7294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengimport java.util.List; 7394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 7494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng/** 7594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Displays the details of a specific call log entry. 7694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 7794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * This activity can be either started with the URI of a single call log entry, or with the 7894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries. 7994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 8094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Chengpublic class CallDetailActivity extends Activity implements ProximitySensorAware { 8194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private static final String TAG = "CallDetail"; 8294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 8335071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng private static final char LEFT_TO_RIGHT_EMBEDDING = '\u202A'; 8435071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng private static final char POP_DIRECTIONAL_FORMATTING = '\u202C'; 8535071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng 8694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The time to wait before enabling the blank the screen due to the proximity sensor. */ 8794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private static final long PROXIMITY_BLANK_DELAY_MILLIS = 100; 8894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The time to wait before disabling the blank the screen due to the proximity sensor. */ 8994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private static final long PROXIMITY_UNBLANK_DELAY_MILLIS = 500; 9094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The enumeration of {@link AsyncTask} objects used in this class. */ 9294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public enum Tasks { 9394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng MARK_VOICEMAIL_READ, 9494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng DELETE_VOICEMAIL_AND_FINISH, 9594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng REMOVE_FROM_CALL_LOG_AND_FINISH, 9694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng UPDATE_PHONE_CALL_DETAILS, 9794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 9894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 9994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** A long array extra containing ids of call log entries to display. */ 10094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public static final String EXTRA_CALL_LOG_IDS = "EXTRA_CALL_LOG_IDS"; 10194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** If we are started with a voicemail, we'll find the uri to play with this extra. */ 10294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public static final String EXTRA_VOICEMAIL_URI = "EXTRA_VOICEMAIL_URI"; 10394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** If we should immediately start playback of the voicemail, this extra will be set to true. */ 10494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public static final String EXTRA_VOICEMAIL_START_PLAYBACK = "EXTRA_VOICEMAIL_START_PLAYBACK"; 10594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** If the activity was triggered from a notification. */ 10694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION"; 10794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 10894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private CallTypeHelper mCallTypeHelper; 10994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private PhoneNumberHelper mPhoneNumberHelper; 11094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private PhoneCallDetailsHelper mPhoneCallDetailsHelper; 11194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private TextView mHeaderTextView; 11294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private View mHeaderOverlayView; 11394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ImageView mMainActionView; 11494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ImageButton mMainActionPushLayerView; 11594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ImageView mContactBackgroundView; 11694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private AsyncTaskExecutor mAsyncTaskExecutor; 11794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ContactInfoHelper mContactInfoHelper; 11894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 11994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private String mNumber = null; 12094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private String mDefaultCountryIso; 12194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 12294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /* package */ LayoutInflater mInflater; 12394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /* package */ Resources mResources; 12494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Helper to load contact photos. */ 12594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ContactPhotoManager mContactPhotoManager; 12694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Helper to make async queries to content resolver. */ 12794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private CallDetailActivityQueryHandler mAsyncQueryHandler; 12894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Helper to get voicemail status messages. */ 12994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private VoicemailStatusHelper mVoicemailStatusHelper; 13094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Views related to voicemail status message. 13194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private View mStatusMessageView; 13294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private TextView mStatusMessageText; 13394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private TextView mStatusMessageAction; 13494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 13594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Whether we should show "edit number before call" in the options menu. */ 13694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean mHasEditNumberBeforeCallOption; 13794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Whether we should show "trash" in the options menu. */ 13894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean mHasTrashOption; 13994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Whether we should show "remove from call log" in the options menu. */ 14094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean mHasRemoveFromCallLogOption; 14194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 14294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ProximitySensorManager mProximitySensorManager; 14394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener(); 14494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 14594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 14694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * The action mode used when the phone number is selected. This will be non-null only when the 14794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * phone number is selected. 14894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 14994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private ActionMode mPhoneNumberActionMode; 15094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private CharSequence mPhoneNumberLabelToCopy; 15294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private CharSequence mPhoneNumberToCopy; 15394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 15494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Listener to changes in the proximity sensor state. */ 15594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private class ProximitySensorListener implements ProximitySensorManager.Listener { 15694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Used to show a blank view and hide the action bar. */ 15794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final Runnable mBlankRunnable = new Runnable() { 15894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 15994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void run() { 16094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View blankView = findViewById(R.id.blank); 16194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng blankView.setVisibility(View.VISIBLE); 16294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getActionBar().hide(); 16394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 16494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 16594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Used to remove the blank view and show the action bar. */ 16694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final Runnable mUnblankRunnable = new Runnable() { 16794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 16894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void run() { 16994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View blankView = findViewById(R.id.blank); 17094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng blankView.setVisibility(View.GONE); 17194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getActionBar().show(); 17294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 17394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 17494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 17594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 17694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public synchronized void onNear() { 17794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng clearPendingRequests(); 17894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng postDelayed(mBlankRunnable, PROXIMITY_BLANK_DELAY_MILLIS); 17994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 18194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 18294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public synchronized void onFar() { 18394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng clearPendingRequests(); 18494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng postDelayed(mUnblankRunnable, PROXIMITY_UNBLANK_DELAY_MILLIS); 18594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 18694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 18794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Removed any delayed requests that may be pending. */ 18894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public synchronized void clearPendingRequests() { 18994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View blankView = findViewById(R.id.blank); 19094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng blankView.removeCallbacks(mBlankRunnable); 19194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng blankView.removeCallbacks(mUnblankRunnable); 19294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 19394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 19494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Post a {@link Runnable} with a delay on the main thread. */ 19594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private synchronized void postDelayed(Runnable runnable, long delayMillis) { 19694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Post these instead of executing immediately so that: 19794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // - They are guaranteed to be executed on the main thread. 19894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // - If the sensor values changes rapidly for some time, the UI will not be 19994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // updated immediately. 20094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View blankView = findViewById(R.id.blank); 20194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng blankView.postDelayed(runnable, delayMillis); 20294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 20394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 20494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 20594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final String[] CALL_LOG_PROJECTION = new String[] { 20694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.DATE, 20794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.DURATION, 20894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.NUMBER, 20994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.TYPE, 21094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.COUNTRY_ISO, 21194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng CallLog.Calls.GEOCODED_LOCATION, 212719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner CallLog.Calls.NUMBER_PRESENTATION, 21394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 21494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 21594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int DATE_COLUMN_INDEX = 0; 21694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int DURATION_COLUMN_INDEX = 1; 21794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int NUMBER_COLUMN_INDEX = 2; 21894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int CALL_TYPE_COLUMN_INDEX = 3; 21994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int COUNTRY_ISO_COLUMN_INDEX = 4; 22094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final int GEOCODED_LOCATION_COLUMN_INDEX = 5; 221719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner static final int NUMBER_PRESENTATION_COLUMN_INDEX = 6; 22294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 22394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() { 22494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 22594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onClick(View view) { 22694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (finishPhoneNumerSelectedActionModeIfShown()) { 22794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 22894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 22994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startActivity(((ViewEntry) view.getTag()).primaryIntent); 23094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 23194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 23294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 23394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() { 23494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 23594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onClick(View view) { 23694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (finishPhoneNumerSelectedActionModeIfShown()) { 23794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 23894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 23994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startActivity(((ViewEntry) view.getTag()).secondaryIntent); 24094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 24194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 24294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 24394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final View.OnLongClickListener mPrimaryLongClickListener = 24494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new View.OnLongClickListener() { 24594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 24694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onLongClick(View v) { 24794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (finishPhoneNumerSelectedActionModeIfShown()) { 24894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 24994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 25094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startPhoneNumberSelectedActionMode(v); 25194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 25294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 25394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }; 25494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 25594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 25694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng protected void onCreate(Bundle icicle) { 25794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng super.onCreate(icicle); 25894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 25994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng setContentView(R.layout.call_detail); 26094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 26194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor(); 26294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 26394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mResources = getResources(); 26494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 26594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallTypeHelper = new CallTypeHelper(getResources()); 26694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberHelper = new PhoneNumberHelper(mResources); 26794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(mResources, mCallTypeHelper, 268fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng new PhoneNumberUtilsWrapper()); 26994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mVoicemailStatusHelper = new VoicemailStatusHelperImpl(); 27094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncQueryHandler = new CallDetailActivityQueryHandler(this); 27194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderTextView = (TextView) findViewById(R.id.header_text); 27294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderOverlayView = findViewById(R.id.photo_text_bar); 27394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageView = findViewById(R.id.voicemail_status); 27494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message); 27594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action); 27694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionView = (ImageView) findViewById(R.id.main_action); 27794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionPushLayerView = (ImageButton) findViewById(R.id.main_action_push_layer); 27894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContactBackgroundView = (ImageView) findViewById(R.id.contact_background); 27935071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng mDefaultCountryIso = GeoUtil.getCurrentCountryIso(this); 28094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContactPhotoManager = ContactPhotoManager.getInstance(this); 28194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mProximitySensorManager = new ProximitySensorManager(this, mProximitySensorListener); 28235071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng mContactInfoHelper = new ContactInfoHelper(this, GeoUtil.getCurrentCountryIso(this)); 283adb742ca30da01a3f09be5551f0844f170eaa5d8Chiao Cheng getActionBar().setDisplayHomeAsUpEnabled(true); 28494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng optionallyHandleVoicemail(); 28594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) { 28694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng closeSystemDialogs(); 28794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 28894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 28994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 29094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 29194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onResume() { 29294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng super.onResume(); 29394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng updateData(getCallLogEntryUris()); 29494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 29594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 29694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 29794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Handle voicemail playback or hide voicemail ui. 29894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 29994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If the Intent used to start this Activity contains the suitable extras, then start voicemail 30094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * playback. If it doesn't, then hide the voicemail ui. 30194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 30294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void optionallyHandleVoicemail() { 30394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View voicemailContainer = findViewById(R.id.voicemail_container); 30494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (hasVoicemail()) { 30594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Has voicemail: add the voicemail fragment. Add suitable arguments to set the uri 30694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // to play and optionally start the playback. 30794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Do a query to fetch the voicemail status messages. 30894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng VoicemailPlaybackFragment playbackFragment = new VoicemailPlaybackFragment(); 30994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Bundle fragmentArguments = new Bundle(); 31094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng fragmentArguments.putParcelable(EXTRA_VOICEMAIL_URI, getVoicemailUri()); 31194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (getIntent().getBooleanExtra(EXTRA_VOICEMAIL_START_PLAYBACK, false)) { 31294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng fragmentArguments.putBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, true); 31394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 31494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng playbackFragment.setArguments(fragmentArguments); 31594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng voicemailContainer.setVisibility(View.VISIBLE); 31694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getFragmentManager().beginTransaction() 317aa536fd9b7a3b144aaa74aa50e88f3d05bde0dd1Yorke Lee .add(R.id.voicemail_container, playbackFragment) 318aa536fd9b7a3b144aaa74aa50e88f3d05bde0dd1Yorke Lee .commitAllowingStateLoss(); 31994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncQueryHandler.startVoicemailStatusQuery(getVoicemailUri()); 32094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng markVoicemailAsRead(getVoicemailUri()); 32194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 32294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // No voicemail uri: hide the status view. 32394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageView.setVisibility(View.GONE); 32494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng voicemailContainer.setVisibility(View.GONE); 32594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 32694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 32794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 32894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean hasVoicemail() { 32994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return getVoicemailUri() != null; 33094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 33194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 33294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private Uri getVoicemailUri() { 33394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return getIntent().getParcelableExtra(EXTRA_VOICEMAIL_URI); 33494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 33594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 33694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void markVoicemailAsRead(final Uri voicemailUri) { 33794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncTaskExecutor.submit(Tasks.MARK_VOICEMAIL_READ, new AsyncTask<Void, Void, Void>() { 33894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 33994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public Void doInBackground(Void... params) { 34094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContentValues values = new ContentValues(); 34194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng values.put(Voicemails.IS_READ, true); 34294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getContentResolver().update(voicemailUri, values, 34394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Voicemails.IS_READ + " = 0", null); 34494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return null; 34594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 34694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }); 34794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 34894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 34994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 35094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Returns the list of URIs to show. 35194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 35294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * There are two ways the URIs can be provided to the activity: as the data on the intent, or as 35394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * a list of ids in the call log added as an extra on the URI. 35494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * <p> 35594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If both are available, the data on the intent takes precedence. 35694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 35794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private Uri[] getCallLogEntryUris() { 35894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Uri uri = getIntent().getData(); 35994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (uri != null) { 36094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If there is a data on the intent, it takes precedence over the extra. 36194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return new Uri[]{ uri }; 36294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 36394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng long[] ids = getIntent().getLongArrayExtra(EXTRA_CALL_LOG_IDS); 36494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Uri[] uris = new Uri[ids.length]; 36594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng for (int index = 0; index < ids.length; ++index) { 36694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng uris[index] = ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, ids[index]); 36794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 36894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return uris; 36994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 37094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 37194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 37294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onKeyDown(int keyCode, KeyEvent event) { 37394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng switch (keyCode) { 37494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng case KeyEvent.KEYCODE_CALL: { 37594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Make sure phone isn't already busy before starting direct call 37694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng TelephonyManager tm = (TelephonyManager) 37794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getSystemService(Context.TELEPHONY_SERVICE); 37894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) { 3799d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Cheng startActivity(CallUtil.getCallIntent( 3809d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Cheng Uri.fromParts(CallUtil.SCHEME_TEL, mNumber, null))); 38194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 38294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 38394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 38494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 38594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 38694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return super.onKeyDown(keyCode, event); 38794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 38894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 38994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 39094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Update user interface with details of given call. 39194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * 39294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * @param callUris URIs into {@link CallLog.Calls} of the calls to be displayed 39394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 39494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void updateData(final Uri... callUris) { 39594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng class UpdateContactDetailsTask extends AsyncTask<Void, Void, PhoneCallDetails[]> { 39694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 39794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public PhoneCallDetails[] doInBackground(Void... params) { 39894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // TODO: All phone calls correspond to the same person, so we can make a single 39994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // lookup. 40094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final int numCalls = callUris.length; 40194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng PhoneCallDetails[] details = new PhoneCallDetails[numCalls]; 40294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng try { 40394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng for (int index = 0; index < numCalls; ++index) { 40494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng details[index] = getPhoneCallDetailsForUri(callUris[index]); 40594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 40694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return details; 40794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } catch (IllegalArgumentException e) { 40894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Something went wrong reading in our primary data. 40994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Log.w(TAG, "invalid URI starting call details", e); 41094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return null; 41194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 41294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 41394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 41494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 41594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onPostExecute(PhoneCallDetails[] details) { 41694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (details == null) { 41794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Somewhere went wrong: we're going to bail out and show error to users. 41894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Toast.makeText(CallDetailActivity.this, R.string.toast_call_detail_error, 41994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Toast.LENGTH_SHORT).show(); 42094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng finish(); 42194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 42294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 42394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 42494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // We know that all calls are from the same number and the same contact, so pick the 42594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // first. 42694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng PhoneCallDetails firstDetails = details[0]; 42794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mNumber = firstDetails.number.toString(); 428719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final int numberPresentation = firstDetails.numberPresentation; 42994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Uri contactUri = firstDetails.contactUri; 43094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Uri photoUri = firstDetails.photoUri; 43194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 43294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Set the details header, based on the first phone call. 43394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneCallDetailsHelper.setCallDetailsHeader(mHeaderTextView, firstDetails); 43494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 43594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Cache the details about the phone number. 436719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final boolean canPlaceCallsTo = 437fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng PhoneNumberUtilsWrapper.canPlaceCallsTo(mNumber, numberPresentation); 438fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng final PhoneNumberUtilsWrapper phoneUtils = new PhoneNumberUtilsWrapper(); 439fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng final boolean isVoicemailNumber = phoneUtils.isVoicemailNumber(mNumber); 440fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng final boolean isSipNumber = phoneUtils.isSipNumber(mNumber); 44194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 44294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Let user view contact details if they exist, otherwise add option to create new 44394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // contact from this number. 44494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Intent mainActionIntent; 44594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final int mainActionIcon; 44694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String mainActionDescription; 44794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 44894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence nameOrNumber; 44994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (!TextUtils.isEmpty(firstDetails.name)) { 45094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameOrNumber = firstDetails.name; 45194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 45294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameOrNumber = firstDetails.number; 45394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 45494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 45558ebe5d3fac837625b69fe1565427f17025bd780Yorke Lee if (contactUri != null && !UriUtils.isEncodedContactUri(contactUri)) { 45694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent = new Intent(Intent.ACTION_VIEW, contactUri); 45794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This will launch People's detail contact screen, so we probably want to 45894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // treat it as a separate People task. 45994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent.setFlags( 46094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 46194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIcon = R.drawable.ic_contacts_holo_dark; 46294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionDescription = 46394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getString(R.string.description_view_contact, nameOrNumber); 46494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else if (isVoicemailNumber) { 46594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent = null; 46694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIcon = 0; 46794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionDescription = null; 46894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else if (isSipNumber) { 46994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // TODO: This item is currently disabled for SIP addresses, because 47094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // the Insert.PHONE extra only works correctly for PSTN numbers. 47194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // 47294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // To fix this for SIP addresses, we need to: 47394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // - define ContactsContract.Intents.Insert.SIP_ADDRESS, and use it here if 47494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // the current number is a SIP address 47594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // - update the contacts UI code to handle Insert.SIP_ADDRESS by 47694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // updating the SipAddress field 47794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // and then we can remove the "!isSipNumber" check above. 47894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent = null; 47994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIcon = 0; 48094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionDescription = null; 48194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else if (canPlaceCallsTo) { 48294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT); 48394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent.setType(Contacts.CONTENT_ITEM_TYPE); 48494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent.putExtra(Insert.PHONE, mNumber); 48594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIcon = R.drawable.ic_add_contact_holo_dark; 48694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionDescription = getString(R.string.description_add_contact); 48794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 48894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If we cannot call the number, when we probably cannot add it as a contact either. 48994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This is usually the case of private, unknown, or payphone numbers. 49094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIntent = null; 49194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionIcon = 0; 49294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainActionDescription = null; 49394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 49494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 49594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (mainActionIntent == null) { 49694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionView.setVisibility(View.INVISIBLE); 49794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionPushLayerView.setVisibility(View.GONE); 49894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderTextView.setVisibility(View.INVISIBLE); 49994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderOverlayView.setVisibility(View.INVISIBLE); 50094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 50194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionView.setVisibility(View.VISIBLE); 50294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionView.setImageResource(mainActionIcon); 50394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionPushLayerView.setVisibility(View.VISIBLE); 50494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionPushLayerView.setOnClickListener(new View.OnClickListener() { 50594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 50694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onClick(View v) { 50794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startActivity(mainActionIntent); 50894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 50994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }); 51094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mMainActionPushLayerView.setContentDescription(mainActionDescription); 51194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderTextView.setVisibility(View.VISIBLE); 51294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHeaderOverlayView.setVisibility(View.VISIBLE); 51394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 51494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 51594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This action allows to call the number that places the call. 51694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (canPlaceCallsTo) { 51794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence displayNumber = 51894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberHelper.getDisplayNumber( 519719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner firstDetails.number, 520719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner firstDetails.numberPresentation, 521719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner firstDetails.formattedNumber); 52294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 52394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ViewEntry entry = new ViewEntry( 52494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getString(R.string.menu_callNumber, 52535071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng forceLeftToRight(displayNumber)), 5269d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Cheng CallUtil.getCallIntent(mNumber), 52794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getString(R.string.description_call, nameOrNumber)); 52894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 52994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Only show a label if the number is shown and it is not a SIP address. 53094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (!TextUtils.isEmpty(firstDetails.name) 53194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng && !TextUtils.isEmpty(firstDetails.number) 53294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng && !PhoneNumberUtils.isUriNumber(firstDetails.number.toString())) { 53394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng entry.label = Phone.getTypeLabel(mResources, firstDetails.numberType, 53494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng firstDetails.numberLabel); 53594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 53694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 53794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // The secondary action allows to send an SMS to the number that placed the 53894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // call. 539fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng if (phoneUtils.canSendSmsTo(mNumber, numberPresentation)) { 54094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng entry.setSecondaryAction( 541aa536fd9b7a3b144aaa74aa50e88f3d05bde0dd1Yorke Lee R.drawable.ic_text_holo_light, 54294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new Intent(Intent.ACTION_SENDTO, 54394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Uri.fromParts("sms", mNumber, null)), 54494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getString(R.string.description_send_text_message, nameOrNumber)); 54594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 54694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 54794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng configureCallButton(entry); 54894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberToCopy = displayNumber; 54994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberLabelToCopy = entry.label; 55094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 55194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng disableCallButton(); 55294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberToCopy = null; 55394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberLabelToCopy = null; 55494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 55594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 55694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHasEditNumberBeforeCallOption = 55794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng canPlaceCallsTo && !isSipNumber && !isVoicemailNumber; 55894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHasTrashOption = hasVoicemail(); 55994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mHasRemoveFromCallLogOption = !hasVoicemail(); 56094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng invalidateOptionsMenu(); 56194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 56294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ListView historyList = (ListView) findViewById(R.id.history); 56394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng historyList.setAdapter( 56494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new CallDetailHistoryAdapter(CallDetailActivity.this, mInflater, 56594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mCallTypeHelper, details, hasVoicemail(), canPlaceCallsTo, 56694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng findViewById(R.id.controls))); 56794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng BackScrollManager.bind( 56894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new ScrollableHeader() { 56994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private View mControls = findViewById(R.id.controls); 57094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private View mPhoto = findViewById(R.id.contact_background_sizer); 57194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private View mHeader = findViewById(R.id.photo_text_bar); 572ac09b51a171ab53c893b5facc6399c4b973a1d75Yorke Lee private View mSeparator = findViewById(R.id.separator); 57394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 57494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 57594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void setOffset(int offset) { 57694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mControls.setY(-offset); 57794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 57894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 57994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 58094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public int getMaximumScrollableHeaderOffset() { 58194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // We can scroll the photo out, but we should keep the header if 58294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // present. 58394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (mHeader.getVisibility() == View.VISIBLE) { 58494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return mPhoto.getHeight() - mHeader.getHeight(); 58594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 58694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If the header is not present, we should also scroll out the 58794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // separator line. 58894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return mPhoto.getHeight() + mSeparator.getHeight(); 58994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 59094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 59194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }, 59294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng historyList); 59394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng loadContactPhotos(photoUri); 59494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng findViewById(R.id.call_detail).setVisibility(View.VISIBLE); 59594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 59694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 59794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncTaskExecutor.submit(Tasks.UPDATE_PHONE_CALL_DETAILS, new UpdateContactDetailsTask()); 59894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 59994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 60094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Return the phone call details for a given call log URI. */ 60194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private PhoneCallDetails getPhoneCallDetailsForUri(Uri callUri) { 60294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContentResolver resolver = getContentResolver(); 60394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null); 60494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng try { 60594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (callCursor == null || !callCursor.moveToFirst()) { 60694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng throw new IllegalArgumentException("Cannot find content: " + callUri); 60794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 60894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 60994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Read call log specifics. 610719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final String number = callCursor.getString(NUMBER_COLUMN_INDEX); 611719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final int numberPresentation = callCursor.getInt( 612719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner NUMBER_PRESENTATION_COLUMN_INDEX); 613719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final long date = callCursor.getLong(DATE_COLUMN_INDEX); 614719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final long duration = callCursor.getLong(DURATION_COLUMN_INDEX); 615719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner final int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX); 61694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX); 61794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX); 61894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 61994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(countryIso)) { 62094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng countryIso = mDefaultCountryIso; 62194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 62294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 62394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Formatted phone number. 62494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence formattedNumber; 62594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Read contact specifics. 62694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence nameText; 62794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final int numberType; 62894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final CharSequence numberLabel; 62994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Uri photoUri; 63094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Uri lookupUri; 63194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // If this is not a regular number, there is no point in looking it up in the contacts. 63294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ContactInfo info = 633fb0a934ad90f1855787563eb80f2c8fff7f640acChiao Cheng PhoneNumberUtilsWrapper.canPlaceCallsTo(number, numberPresentation) 6341a7c1963ba99548d15eb179beb4026b890d1fb62Yorke Lee && !new PhoneNumberUtilsWrapper().isVoicemailNumber(number) 63594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ? mContactInfoHelper.lookupNumber(number, countryIso) 63694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng : null; 63794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (info == null) { 638719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner formattedNumber = mPhoneNumberHelper.getDisplayNumber(number, 639719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner numberPresentation, null); 64094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = ""; 64194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberType = 0; 64294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberLabel = ""; 64394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng photoUri = null; 64494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng lookupUri = null; 64594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 64694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng formattedNumber = info.formattedNumber; 64794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText = info.name; 64894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberType = info.type; 64994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng numberLabel = info.label; 65094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng photoUri = info.photoUri; 65194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng lookupUri = info.lookupUri; 65294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 653719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner return new PhoneCallDetails(number, numberPresentation, 654719a7adde25e0a717816b00668c16c3a1e3c5518Jay Shrauner formattedNumber, countryIso, geocode, 65594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new int[]{ callType }, date, duration, 65694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng nameText, numberType, numberLabel, lookupUri, photoUri); 65794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } finally { 65894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (callCursor != null) { 65994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callCursor.close(); 66094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 66194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 66294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 66394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 66494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Load the contact photos and places them in the corresponding views. */ 66594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void loadContactPhotos(Uri photoUri) { 66694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri, 66794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mContactBackgroundView.getWidth(), true); 66894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 66994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 67094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng static final class ViewEntry { 67194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public final String text; 67294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public final Intent primaryIntent; 67394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The description for accessibility of the primary action. */ 67494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public final String primaryDescription; 67594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 67694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public CharSequence label = null; 67794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Icon for the secondary action. */ 67894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public int secondaryIcon = 0; 67994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Intent for the secondary action. If not null, an icon must be defined. */ 68094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public Intent secondaryIntent = null; 68194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** The description for accessibility of the secondary action. */ 68294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public String secondaryDescription = null; 68394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 68494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public ViewEntry(String text, Intent intent, String description) { 68594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng this.text = text; 68694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng primaryIntent = intent; 68794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng primaryDescription = description; 68894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 68994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 69094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void setSecondaryAction(int icon, Intent intent, String description) { 69194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng secondaryIcon = icon; 69294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng secondaryIntent = intent; 69394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng secondaryDescription = description; 69494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 69594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 69694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 69794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Disables the call button area, e.g., for private numbers. */ 69894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void disableCallButton() { 69994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng findViewById(R.id.call_and_sms).setVisibility(View.GONE); 70094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 70194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 70294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Configures the call button area using the given entry. */ 70394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void configureCallButton(ViewEntry entry) { 70494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View convertView = findViewById(R.id.call_and_sms); 70594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng convertView.setVisibility(View.VISIBLE); 70694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 70794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ImageView icon = (ImageView) convertView.findViewById(R.id.call_and_sms_icon); 70894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View divider = convertView.findViewById(R.id.call_and_sms_divider); 70994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng TextView text = (TextView) convertView.findViewById(R.id.call_and_sms_text); 71094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 71194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng View mainAction = convertView.findViewById(R.id.call_and_sms_main_action); 71294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainAction.setOnClickListener(mPrimaryActionListener); 71394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainAction.setTag(entry); 71494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainAction.setContentDescription(entry.primaryDescription); 71594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mainAction.setOnLongClickListener(mPrimaryLongClickListener); 71694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 71794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (entry.secondaryIntent != null) { 71894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setOnClickListener(mSecondaryActionListener); 71994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setImageResource(entry.secondaryIcon); 72094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setVisibility(View.VISIBLE); 72194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setTag(entry); 72294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setContentDescription(entry.secondaryDescription); 72394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng divider.setVisibility(View.VISIBLE); 72494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 72594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng icon.setVisibility(View.GONE); 72694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng divider.setVisibility(View.GONE); 72794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 72894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng text.setText(entry.text); 72994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 73094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng TextView label = (TextView) convertView.findViewById(R.id.call_and_sms_label); 73194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(entry.label)) { 73294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng label.setVisibility(View.GONE); 73394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 73494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng label.setText(entry.label); 73594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng label.setVisibility(View.VISIBLE); 73694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 73794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 73894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 73994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng protected void updateVoicemailStatusMessage(Cursor statusCursor) { 74094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (statusCursor == null) { 74194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageView.setVisibility(View.GONE); 74294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 74394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 74494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final StatusMessage message = getStatusMessage(statusCursor); 74594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (message == null || !message.showInCallDetails()) { 74694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageView.setVisibility(View.GONE); 74794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return; 74894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 74994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 75094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageView.setVisibility(View.VISIBLE); 75194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageText.setText(message.callDetailsMessageId); 75294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (message.actionMessageId != -1) { 75394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageAction.setText(message.actionMessageId); 75494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 75594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (message.actionUri != null) { 75694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageAction.setClickable(true); 75794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageAction.setOnClickListener(new View.OnClickListener() { 75894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 75994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onClick(View v) { 76094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startActivity(new Intent(Intent.ACTION_VIEW, message.actionUri)); 76194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 76294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }); 76394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } else { 76494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mStatusMessageAction.setClickable(false); 76594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 76694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 76794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 76894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private StatusMessage getStatusMessage(Cursor statusCursor) { 76994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor); 77094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (messages.size() == 0) { 77194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return null; 77294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 77394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // There can only be a single status message per source package, so num of messages can 77494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // at most be 1. 77594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (messages.size() > 1) { 77694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Log.w(TAG, String.format("Expected 1, found (%d) num of status messages." + 77794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng " Will use the first one.", messages.size())); 77894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 77994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return messages.get(0); 78094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 78194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 78294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 78394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onCreateOptionsMenu(Menu menu) { 78494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getMenuInflater().inflate(R.menu.call_details_options, menu); 78594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return super.onCreateOptionsMenu(menu); 78694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 78794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 78894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 78994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onPrepareOptionsMenu(Menu menu) { 79094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This action deletes all elements in the group from the call log. 79194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // We don't have this action for voicemails, because you can just use the trash button. 79294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng menu.findItem(R.id.menu_remove_from_call_log).setVisible(mHasRemoveFromCallLogOption); 79394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng menu.findItem(R.id.menu_edit_number_before_call).setVisible(mHasEditNumberBeforeCallOption); 79494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng menu.findItem(R.id.menu_trash).setVisible(mHasTrashOption); 79594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return super.onPrepareOptionsMenu(menu); 79694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 79794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 79894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onMenuRemoveFromCallLog(MenuItem menuItem) { 79994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final StringBuilder callIds = new StringBuilder(); 80094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng for (Uri callUri : getCallLogEntryUris()) { 80194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (callIds.length() != 0) { 80294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callIds.append(","); 80394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 80494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng callIds.append(ContentUris.parseId(callUri)); 80594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 80694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncTaskExecutor.submit(Tasks.REMOVE_FROM_CALL_LOG_AND_FINISH, 80794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new AsyncTask<Void, Void, Void>() { 80894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 80994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public Void doInBackground(Void... params) { 81094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getContentResolver().delete(Calls.CONTENT_URI_WITH_VOICEMAIL, 81194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Calls._ID + " IN (" + callIds + ")", null); 81294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return null; 81394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 81494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 81594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 81694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onPostExecute(Void result) { 81794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng finish(); 81894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 81994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }); 82094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 82194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 82294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onMenuEditNumberBeforeCall(MenuItem menuItem) { 8239d4f3b20793a007b4489547aa40fc1049d0d8fefChiao Cheng startActivity(new Intent(Intent.ACTION_DIAL, CallUtil.getCallUri(mNumber))); 82494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 82594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 82694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onMenuTrashVoicemail(MenuItem menuItem) { 82794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng final Uri voicemailUri = getVoicemailUri(); 82894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mAsyncTaskExecutor.submit(Tasks.DELETE_VOICEMAIL_AND_FINISH, 82994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng new AsyncTask<Void, Void, Void>() { 83094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 83194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public Void doInBackground(Void... params) { 83294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getContentResolver().delete(voicemailUri, null, null); 83394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return null; 83494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 83594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 83694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onPostExecute(Void result) { 83794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng finish(); 83894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 83994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng }); 84094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 84194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 84294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** Invoked when the user presses the home button in the action bar. */ 84394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void onHomeSelected() { 84494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng Intent intent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI); 84594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // This will open the call log even if the detail view has been opened directly. 84694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 84794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng startActivity(intent); 84894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng finish(); 84994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 85094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 85194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 85294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng protected void onPause() { 85394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Immediately stop the proximity sensor. 85494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng disableProximitySensor(false); 85594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mProximitySensorListener.clearPendingRequests(); 85694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng super.onPause(); 85794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 85894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 85994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 86094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void enableProximitySensor() { 86194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mProximitySensorManager.enable(); 86294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 86394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 86494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 86594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void disableProximitySensor(boolean waitForFarState) { 86694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mProximitySensorManager.disable(waitForFarState); 86794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 86894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 86994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng /** 87094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * If the phone number is selected, unselect it and return {@code true}. 87194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng * Otherwise, just {@code false}. 87294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng */ 87394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private boolean finishPhoneNumerSelectedActionModeIfShown() { 87494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (mPhoneNumberActionMode == null) return false; 87594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberActionMode.finish(); 87694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 87794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 87894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 87994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void startPhoneNumberSelectedActionMode(View targetView) { 88094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberActionMode = startActionMode(new PhoneNumberActionModeCallback(targetView)); 88194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 88294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 88394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private void closeSystemDialogs() { 88494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); 88594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 88694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 88794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private class PhoneNumberActionModeCallback implements ActionMode.Callback { 88894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final View mTargetView; 88994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng private final Drawable mOriginalViewBackground; 89094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 89194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public PhoneNumberActionModeCallback(View targetView) { 89294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mTargetView = targetView; 89394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 89494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Highlight the phone number view. Remember the old background, and put a new one. 89594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mOriginalViewBackground = mTargetView.getBackground(); 89694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mTargetView.setBackgroundColor(getResources().getColor(R.color.item_selected)); 89794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 89894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 89994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 90094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onCreateActionMode(ActionMode mode, Menu menu) { 90194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng if (TextUtils.isEmpty(mPhoneNumberToCopy)) return false; 90294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 90394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng getMenuInflater().inflate(R.menu.call_details_cab, menu); 90494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 90594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 90694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 90794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 90894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 90994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 91094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 91194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 91294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 91394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 91494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng switch (item.getItemId()) { 91594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng case R.id.copy_phone_number: 91694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng ClipboardUtils.copyText(CallDetailActivity.this, mPhoneNumberLabelToCopy, 91794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberToCopy, true); 91894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mode.finish(); // Close the CAB 91994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return true; 92094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 92194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng return false; 92294b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 92394b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 92494b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng @Override 92594b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng public void onDestroyActionMode(ActionMode mode) { 92694b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mPhoneNumberActionMode = null; 92794b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng 92894b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng // Restore the view background. 92994b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng mTargetView.setBackground(mOriginalViewBackground); 93094b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 93194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng } 93235071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng 93335071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng /** Returns the given text, forced to be left-to-right. */ 93435071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng private static CharSequence forceLeftToRight(CharSequence text) { 93535071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng StringBuilder sb = new StringBuilder(); 93635071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng sb.append(LEFT_TO_RIGHT_EMBEDDING); 93735071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng sb.append(text); 93835071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng sb.append(POP_DIRECTIONAL_FORMATTING); 93935071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng return sb.toString(); 94035071c06d1587942f5a66c8f12e6247e8f904d26Chiao Cheng } 94194b10b530c0fc297e2974e57e094c500d3ee6003Chiao Cheng} 942