diff options
Diffstat (limited to 'src')
17 files changed, 345 insertions, 67 deletions
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java index 94c2f0018..db4abe73c 100644 --- a/src/com/android/dialer/CallDetailActivity.java +++ b/src/com/android/dialer/CallDetailActivity.java @@ -283,10 +283,12 @@ public class CallDetailActivity extends AppCompatActivity if (TextUtils.isEmpty(mNumber)) { return; } - mContext.startActivity( - new CallIntentBuilder(getDialableNumber()) - .setCallInitiationType(LogState.INITIATION_CALL_DETAILS) - .build()); + Intent dialIntent = new CallIntentBuilder(getDialableNumber()) + .setCallInitiationType(LogState.INITIATION_CALL_DETAILS).build(); + if (DialerUtils.isConferenceURICallLog(mNumber, mPostDialDigits)) { + dialIntent.putExtra("org.codeaurora.extra.DIAL_CONFERENCE_URI", true); + } + mContext.startActivity(dialIntent); } }); diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java index 6142d52c3..2ae567f62 100644 --- a/src/com/android/dialer/DialtactsActivity.java +++ b/src/com/android/dialer/DialtactsActivity.java @@ -1223,10 +1223,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O setConferenceDialButtonImage(false); setConferenceDialButtonVisibility(true); boolean mIsRecipientsShown = mDialpadFragment.isRecipientsShown(); - if(mIsRecipientsShown) { - mDialpadFragment.hideAndClearDialConference(); - } - if (mIsDialpadShown || mIsRecipientsShown) { if (TextUtils.isEmpty(mSearchQuery) || (mSmartDialSearchFragment != null && mSmartDialSearchFragment.isVisible() diff --git a/src/com/android/dialer/SpeedDialListActivity.java b/src/com/android/dialer/SpeedDialListActivity.java index 2d6cef2ec..e979151b0 100644 --- a/src/com/android/dialer/SpeedDialListActivity.java +++ b/src/com/android/dialer/SpeedDialListActivity.java @@ -111,6 +111,11 @@ public class SpeedDialListActivity extends ListActivity implements private static final int COLUMN_NORMALIZED = 4; private static final int MENU_REPLACE = 1001; private static final int MENU_DELETE = 1002; + private int mItemPosition; + private static String SPEAD_DIAL_NUMBER = "SpeedDialNumber"; + private static String SAVE_CLICKED_POS = "Clicked_pos"; + private String mInputNumber; + private boolean mConfigChanged; private static final String PROPERTY_RADIO_ATEL_CARRIER = "persist.radio.atel.carrier"; private static final String CARRIER_ONE_DEFAULT_MCC_MNC = "405854"; @@ -177,6 +182,29 @@ public class SpeedDialListActivity extends ListActivity implements } @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (mAddSpeedDialDialog == null || !mAddSpeedDialDialog.isShowing()) { + outState.clear(); + return; + } + outState.putInt(SAVE_CLICKED_POS, mItemPosition); + outState.putString(SPEAD_DIAL_NUMBER, mEditNumber.getText().toString()); + } + + @Override + protected void onRestoreInstanceState(Bundle state) { + super.onRestoreInstanceState(state); + if (state.isEmpty()) { + return; + } + mConfigChanged = true; + int number = state.getInt(SAVE_CLICKED_POS, mItemPosition); + mInputNumber = state.getString(SPEAD_DIAL_NUMBER, ""); + showAddSpeedDialDialog(number); + } + + @Override protected void onResume() { super.onResume(); @@ -239,6 +267,7 @@ public class SpeedDialListActivity extends ListActivity implements private void showAddSpeedDialDialog(final int number) { mPickNumber = number; + mItemPosition = number; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.speed_dial_settings); View contentView = LayoutInflater.from(this).inflate( @@ -257,6 +286,11 @@ public class SpeedDialListActivity extends ListActivity implements if (null != mRecords.get(number)) { mEditNumber.setText(SpeedDialUtils.getNumber(this, number)); } + if (mConfigChanged && !mInputNumber.isEmpty()) { + mEditNumber.setText(mInputNumber); + mConfigChanged = false; + mInputNumber = ""; + } Button cancelButton = (Button) contentView .findViewById(R.id.btn_cancel); cancelButton.setOnClickListener(new View.OnClickListener() { @@ -333,6 +367,7 @@ public class SpeedDialListActivity extends ListActivity implements Toast.LENGTH_SHORT).show(); return; } + mItemPosition = number; final Record record = mRecords.get(number); if (record == null) { showAddSpeedDialDialog(number); diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 48b4f5564..6a447a667 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -60,6 +60,7 @@ import com.android.dialer.filterednumber.BlockNumberDialogFragment.Callback; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; import com.android.dialer.service.ExtendedBlockingButtonRenderer; +import com.android.dialer.util.DialerUtils; import com.android.dialer.util.PhoneNumberUtil; import com.android.dialer.voicemail.VoicemailPlaybackPresenter; @@ -182,7 +183,9 @@ public class CallLogAdapter extends GroupingListAdapter if (viewHolder.callType == CallLog.Calls.MISSED_TYPE) { CallLogAsyncTaskUtil.markCallAsRead(mContext, viewHolder.callIds); if (mActivityType == ACTIVITY_TYPE_DIALTACTS) { - ((DialtactsActivity) v.getContext()).updateTabUnreadCounts(); + if (v.getContext() instanceof DialtactsActivity) { + ((DialtactsActivity) v.getContext()).updateTabUnreadCounts(); + } } } expandViewHolderActions(viewHolder); @@ -379,6 +382,13 @@ public class CallLogAdapter extends GroupingListAdapter } } + public void onStop () { + pauseCache(); + if (mHiddenItemUri != null) { + CallLogAsyncTaskUtil.deleteVoicemail(mContext, mHiddenItemUri, null); + } + } + @VisibleForTesting /* package */ void pauseCache() { mContactInfoCache.stop(); @@ -497,15 +507,15 @@ public class CallLogAdapter extends GroupingListAdapter } int count = getGroupSize(position); - final String phoneNumber = c.getString(CallLogQuery.NUMBER); Pattern pattern = Pattern.compile("[,;]"); String[] num = pattern.split(phoneNumber); - final String number = num.length > 0 ? num[0] : ""; final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO); final String postDialDigits = CompatUtils.isNCompatible() && mActivityType != ACTIVITY_TYPE_ARCHIVE ? c.getString(CallLogQuery.POST_DIAL_DIGITS) : ""; + final String number = DialerUtils.isConferenceURICallLog(phoneNumber, postDialDigits) ? + phoneNumber : num.length > 0 ? num[0] : ""; final String viaNumber = CompatUtils.isNCompatible() && mActivityType != ACTIVITY_TYPE_ARCHIVE ? c.getString(CallLogQuery.VIA_NUMBER) : ""; @@ -524,8 +534,11 @@ public class CallLogAdapter extends GroupingListAdapter ContactInfo info = ContactInfo.EMPTY; if (PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemailNumber) { // Lookup contacts with this number - info = mContactInfoCache.getValue(number + postDialDigits, - countryIso, cachedContactInfo); + boolean isConfCallLog = num != null && num.length > 1 + && DialerUtils.isConferenceURICallLog(phoneNumber, postDialDigits); + String queryNumber = isConfCallLog ? phoneNumber : number; + info = mContactInfoCache.getValue(queryNumber, postDialDigits, + countryIso, cachedContactInfo, isConfCallLog); } CharSequence formattedNumber = info.formattedNumber == null ? null : PhoneNumberUtilsCompat.createTtsSpannable(info.formattedNumber); diff --git a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java index 34b2f0ea9..667d6b98b 100644 --- a/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java +++ b/src/com/android/dialer/calllog/CallLogAsyncTaskUtil.java @@ -41,11 +41,13 @@ import com.android.dialer.database.VoicemailArchiveContract; import com.android.dialer.util.AsyncTaskExecutor; import com.android.dialer.util.AsyncTaskExecutors; import com.android.dialer.util.PhoneNumberUtil; +import com.android.dialer.util.DialerUtils; import com.android.dialer.util.TelecomUtil; import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; +import java.util.regex.Pattern; public class CallLogAsyncTaskUtil { private static String TAG = CallLogAsyncTaskUtil.class.getSimpleName(); @@ -208,13 +210,20 @@ public class CallLogAsyncTaskUtil { PhoneNumberUtil.canPlaceCallsTo(number, numberPresentation) && !isVoicemail; ContactInfo info = ContactInfo.EMPTY; + Pattern pattern = Pattern.compile("[,;]"); + String[] num = pattern.split(number); + boolean isConf = num != null && num.length > 1 + && DialerUtils.isConferenceURICallLog(number, postDialDigits); + String phoneNumber = num != null && num.length > 0 ? num[0] : ""; + String queryNumber = isConf ? number : phoneNumber; if (shouldLookupNumber) { - ContactInfo lookupInfo = contactInfoHelper.lookupNumber(number, countryIso); + ContactInfo lookupInfo = contactInfoHelper.lookupNumber(queryNumber, postDialDigits, + countryIso, isConf); info = lookupInfo != null ? lookupInfo : ContactInfo.EMPTY; } PhoneCallDetails details = new PhoneCallDetails( - context, number, numberPresentation, info.formattedNumber, + context, queryNumber, numberPresentation, info.formattedNumber, postDialDigits, isVoicemail); details.viaNumber = viaNumber; diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java index b44d8ca6b..96551a4b4 100644 --- a/src/com/android/dialer/calllog/CallLogFragment.java +++ b/src/com/android/dialer/calllog/CallLogFragment.java @@ -354,14 +354,13 @@ public class CallLogFragment extends Fragment implements CallLogQueryHandler.Lis @Override public void onPause() { cancelDisplayUpdate(); - mAdapter.onPause(); super.onPause(); } @Override public void onStop() { updateOnTransition(); - + mAdapter.onStop(); super.onStop(); } diff --git a/src/com/android/dialer/calllog/CallLogGroupBuilder.java b/src/com/android/dialer/calllog/CallLogGroupBuilder.java index aa45029c0..ab9d5354d 100644 --- a/src/com/android/dialer/calllog/CallLogGroupBuilder.java +++ b/src/com/android/dialer/calllog/CallLogGroupBuilder.java @@ -27,6 +27,9 @@ import com.android.contacts.common.compat.CompatUtils; import com.android.contacts.common.util.DateUtils; import com.android.contacts.common.util.PhoneNumberHelper; import com.android.dialer.util.AppCompatConstants; +import com.android.dialer.util.DialerUtils; + +import java.util.regex.Pattern; /** * Groups together calls in the call log. The primary grouping attempts to group together calls @@ -130,6 +133,8 @@ public class CallLogGroupBuilder { int groupCallType = cursor.getInt(CallLogQuery.CALL_TYPE); String groupAccountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME); String groupAccountId = cursor.getString(CallLogQuery.ACCOUNT_ID); + boolean isGroupConfCallLog = DialerUtils.isConferenceURICallLog(groupNumber, + groupPostDialDigits); int groupSize = 1; String number; @@ -138,6 +143,7 @@ public class CallLogGroupBuilder { int callType; String accountComponentName; String accountId; + boolean isNumberConfCallLog = false; while (cursor.moveToNext()) { // Obtain the values for the current call to group. @@ -149,8 +155,10 @@ public class CallLogGroupBuilder { callType = cursor.getInt(CallLogQuery.CALL_TYPE); accountComponentName = cursor.getString(CallLogQuery.ACCOUNT_COMPONENT_NAME); accountId = cursor.getString(CallLogQuery.ACCOUNT_ID); + isNumberConfCallLog = DialerUtils.isConferenceURICallLog(number, numberPostDialDigits); - final boolean isSameNumber = equalNumbers(groupNumber, number); + final boolean isSameNumber = equalNumbers(groupNumber, isGroupConfCallLog, + number, isNumberConfCallLog); final boolean isSamePostDialDigits = groupPostDialDigits.equals(numberPostDialDigits); final boolean isSameViaNumbers = groupViaNumbers.equals(numberViaNumbers); final boolean isSameAccount = isSameAccount( @@ -184,6 +192,8 @@ public class CallLogGroupBuilder { groupCallType = callType; groupAccountComponentName = accountComponentName; groupAccountId = accountId; + isGroupConfCallLog = DialerUtils.isConferenceURICallLog(groupNumber, + groupPostDialDigits); } // Save the day group associated with the current call. @@ -224,8 +234,27 @@ public class CallLogGroupBuilder { @VisibleForTesting boolean equalNumbers(String number1, String number2) { + return equalNumbers(number1, false, number2, false); + } + + boolean equalNumbers(String number1, boolean isConf1, String number2, boolean isConf2) { if (PhoneNumberHelper.isUriNumber(number1) || PhoneNumberHelper.isUriNumber(number2)) { return compareSipAddresses(number1, number2); + } else if (isConf1 && isConf2) { + Pattern pattern = Pattern.compile("[,;]"); + String[] num1 = pattern.split(number1); + String[] num2 = pattern.split(number2); + if (num1 == null || num2 == null || num1.length != num2.length) { + return false; + } + for (int i = 0; i < num1.length; i++) { + if (!PhoneNumberUtils.compare(num1[i], num2[i])) { + return false; + } + } + return true; + } else if (isConf1 != isConf2) { + return false; } else { return PhoneNumberUtils.compare(number1, number2); } diff --git a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java index 4036f10f9..d63531bd7 100644 --- a/src/com/android/dialer/calllog/CallLogListItemViewHolder.java +++ b/src/com/android/dialer/calllog/CallLogListItemViewHolder.java @@ -710,6 +710,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder if (intentProvider != null) { final Intent intent = intentProvider.getIntent(mContext); // See IntentProvider.getCallDetailIntentProvider() for why this may be null. + if (DialerUtils.isConferenceURICallLog(number, postDialDigits)) { + intent.putExtra("org.codeaurora.extra.DIAL_CONFERENCE_URI", true); + } if (intent != null) { DialerUtils.startActivityWithErrorToast(mContext, intent); } diff --git a/src/com/android/dialer/calllog/ContactInfoHelper.java b/src/com/android/dialer/calllog/ContactInfoHelper.java index b0ef0abf4..ea39d037d 100644 --- a/src/com/android/dialer/calllog/ContactInfoHelper.java +++ b/src/com/android/dialer/calllog/ContactInfoHelper.java @@ -43,6 +43,8 @@ import com.android.dialer.service.CachedNumberLookupService.CachedContactInfo; import com.android.dialer.util.TelecomUtil; import com.android.dialerbind.ObjectFactory; +import java.util.regex.Pattern; + import org.json.JSONException; import org.json.JSONObject; @@ -76,6 +78,26 @@ public class ContactInfoHelper { */ @Nullable public ContactInfo lookupNumber(String number, String countryIso) { + return lookupNumber(number, null, countryIso, false); + } + + /** + * Returns the contact information for the given number. + * <p> + * If the number does not match any contact, returns a contact info containing only the number + * and the formatted number. + * <p> + * If an error occurs during the lookup, it returns null. + * + * @param number the number to look up + * @param postDialString append into number if required + * @param countryIso the country associated with this number + * @param isConfUrlLog whether call log is for Conference URL call + */ + @Nullable + public ContactInfo lookupNumber(String number, String postDialString, String countryIso, + boolean isConfUrlCallLog) { + if (TextUtils.isEmpty(number)) { return null; } @@ -89,12 +111,14 @@ public class ContactInfoHelper { // If lookup failed, check if the "username" of the SIP address is a phone number. String username = PhoneNumberHelper.getUsernameFromUriNumber(number); if (PhoneNumberUtils.isGlobalPhoneNumber(username)) { - info = queryContactInfoForPhoneNumber(username, countryIso, true); + info = queryContactInfoForPhoneNumber(username, null, countryIso, true, + isConfUrlCallLog); } } } else { // Look for a contact that has the given phone number. - info = queryContactInfoForPhoneNumber(number, countryIso, false); + info = queryContactInfoForPhoneNumber(number, postDialString, countryIso, + false, isConfUrlCallLog); } final ContactInfo updatedInfo; @@ -106,6 +130,9 @@ public class ContactInfoHelper { if (info == ContactInfo.EMPTY) { // Did not find a matching contact. updatedInfo = new ContactInfo(); + if (!isConfUrlCallLog && !TextUtils.isEmpty(postDialString)) { + number += postDialString; + } updatedInfo.number = number; updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso); updatedInfo.normalizedNumber = PhoneNumberUtils.formatNumberToE164( @@ -244,14 +271,47 @@ public class ContactInfoHelper { * <p> * If the lookup fails for some other reason, it returns null. */ - private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso, - boolean isSip) { + private ContactInfo queryContactInfoForPhoneNumber(String number, String postDialString, + String countryIso, boolean isSip, boolean isConfUrlLog) { if (TextUtils.isEmpty(number)) { return null; } ContactInfo info = lookupContactFromUri(getContactInfoLookupUri(number), isSip); + if (isConfUrlLog) { + Pattern pattern = Pattern.compile("[,;]"); + String[] nums = pattern.split(number); + if (nums != null && nums.length > 1) { + if (info == null || info == ContactInfo.EMPTY) { + info = new ContactInfo(); + info.number = number; + info.formattedNumber = formatPhoneNumber(number, null, countryIso); + info.lookupUri = createTemporaryContactUri(info.formattedNumber); + info.normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, + countryIso); + } + String combName = ""; + for (String num : nums) { + ContactInfo singleCi = lookupContactFromUri(getContactInfoLookupUri(num), + isSip); + // If contact does not exist, need to avoid changing static empty-contact. + if (singleCi == ContactInfo.EMPTY) { + singleCi = new ContactInfo(); + } + if (TextUtils.isEmpty(singleCi.name)) { + singleCi.name = formatPhoneNumber(num, null, countryIso); + } + combName += singleCi.name + ";"; + } + if (!TextUtils.isEmpty(combName) && combName.length() > 1) { + info.name = combName.substring(0, combName.length() - 1); + } + } + } if (info != null && info != ContactInfo.EMPTY) { + if (!isConfUrlLog && TextUtils.isEmpty(postDialString)) { + number += postDialString; + } info.formattedNumber = formatPhoneNumber(number, null, countryIso); } else if (mCachedNumberLookupService != null) { CachedContactInfo cacheInfo = diff --git a/src/com/android/dialer/contactinfo/ContactInfoCache.java b/src/com/android/dialer/contactinfo/ContactInfoCache.java index 1e2457957..4fd30133c 100644 --- a/src/com/android/dialer/contactinfo/ContactInfoCache.java +++ b/src/com/android/dialer/contactinfo/ContactInfoCache.java @@ -76,7 +76,8 @@ public class ContactInfoCache { if (req != null) { // Process the request. If the lookup succeeds, schedule a redraw. - needRedraw |= queryContactInfo(req.number, req.countryIso, req.callLogInfo); + needRedraw |= queryContactInfo(req.number, req.postDialString, req.countryIso, + req.callLogInfo, req.isConf); } else { // Throttle redraw rate by only sending them when there are // more requests. @@ -130,6 +131,7 @@ public class ContactInfoCache { private final LinkedList<ContactInfoRequest> mRequests; private ExpirableCache<NumberWithCountryIso, ContactInfo> mCache; + private ExpirableCache<NumberWithCountryIso, ContactInfo> mCacheFor4gConfCall; private ContactInfoHelper mContactInfoHelper; private QueryThread mContactInfoQueryThread; @@ -142,32 +144,52 @@ public class ContactInfoCache { mRequests = new LinkedList<ContactInfoRequest>(); mCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE); + mCacheFor4gConfCall = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE); } public ContactInfo getValue(String number, String countryIso, ContactInfo cachedContactInfo) { - NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso); - ExpirableCache.CachedValue<ContactInfo> cachedInfo = - mCache.getCachedValue(numberCountryIso); + return getValue(number, null, countryIso, cachedContactInfo, false); + } + + public ContactInfo getValue(String number, String postDialString, String countryIso, + ContactInfo cachedContactInfo, boolean isConf) { + String phoneNumber = number; + if (!isConf && !TextUtils.isEmpty(postDialString)) { + phoneNumber += postDialString; + } + NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(phoneNumber, countryIso); + ExpirableCache.CachedValue<ContactInfo> cachedInfo = null; + if (isConf) { + cachedInfo = mCacheFor4gConfCall.getCachedValue(numberCountryIso); + } else { + cachedInfo = mCache.getCachedValue(numberCountryIso); + } ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue(); if (cachedInfo == null) { - mCache.put(numberCountryIso, ContactInfo.EMPTY); + if (isConf) { + mCacheFor4gConfCall.put(numberCountryIso, ContactInfo.EMPTY); + } else { + mCache.put(numberCountryIso, ContactInfo.EMPTY); + } // Use the cached contact info from the call log. info = cachedContactInfo; // The db request should happen on a non-UI thread. // Request the contact details immediately since they are currently missing. - enqueueRequest(number, countryIso, cachedContactInfo, true); + enqueueRequest(number, postDialString, countryIso, cachedContactInfo, true, isConf); // We will format the phone number when we make the background request. } else { if (cachedInfo.isExpired()) { // The contact info is no longer up to date, we should request it. However, we // do not need to request them immediately. - enqueueRequest(number, countryIso, cachedContactInfo, false); + enqueueRequest(number, postDialString, countryIso, + cachedContactInfo, false, isConf); } else if (!callLogInfoMatches(cachedContactInfo, info)) { // The call log information does not match the one we have, look it up again. // We could simply update the call log directly, but that needs to be done in a // background thread, so it is easier to simply request a new lookup, which will, as // a side-effect, update the call log. - enqueueRequest(number, countryIso, cachedContactInfo, false); + enqueueRequest(number, postDialString, countryIso, + cachedContactInfo, false, isConf); } if (info == ContactInfo.EMPTY) { @@ -186,11 +208,15 @@ public class ContactInfoCache { * * The number might be either a SIP address or a phone number. * + * @param postDialString if required, append into number + * @param isConf determine whether it is a 4g conf call log * It returns true if it updated the content of the cache and we should therefore tell the * view to update its content. */ - private boolean queryContactInfo(String number, String countryIso, ContactInfo callLogInfo) { - final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso); + private boolean queryContactInfo(String number, String postDialString, String countryIso, + ContactInfo callLogInfo, boolean isConf) { + final ContactInfo info = mContactInfoHelper.lookupNumber(number, postDialString, + countryIso, isConf); if (info == null) { // The lookup failed, just return without requesting to update the view. @@ -199,8 +225,17 @@ public class ContactInfoCache { // Check the existing entry in the cache: only if it has changed we should update the // view. - NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso); - ContactInfo existingInfo = mCache.getPossiblyExpired(numberCountryIso); + String phoneNumber = number; + if (!isConf && !TextUtils.isEmpty(postDialString)) { + phoneNumber += postDialString; + } + NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(phoneNumber, countryIso); + ContactInfo existingInfo = null; + if (isConf) { + existingInfo = mCacheFor4gConfCall.getPossiblyExpired(numberCountryIso); + } else { + existingInfo = mCache.getPossiblyExpired(numberCountryIso); + } final boolean isRemoteSource = info.sourceType != 0; @@ -215,11 +250,21 @@ public class ContactInfoCache { // Store the data in the cache so that the UI thread can use to display it. Store it // even if it has not changed so that it is marked as not expired. - mCache.put(numberCountryIso, info); + if (isConf) { + mCacheFor4gConfCall.put(numberCountryIso, info); + } else { + mCache.put(numberCountryIso, info); + } // Update the call log even if the cache it is up-to-date: it is possible that the cache // contains the value from a different call log entry. - mContactInfoHelper.updateCallLogContactInfo(number, countryIso, info, callLogInfo); + if (isConf) { + mContactInfoHelper.updateCallLogContactInfo(number, countryIso, + info, callLogInfo); + } else { + mContactInfoHelper.updateCallLogContactInfo(phoneNumber, countryIso, + info, callLogInfo); + } return updated; } @@ -264,6 +309,7 @@ public class ContactInfoCache { public void invalidate() { mCache.expireAll(); + mCacheFor4gConfCall.expireAll(); stopRequestProcessing(); } @@ -293,7 +339,24 @@ public class ContactInfoCache { */ protected void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo, boolean immediate) { - ContactInfoRequest request = new ContactInfoRequest(number, countryIso, callLogInfo); + enqueueRequest(number, null, countryIso, callLogInfo, immediate, false); + } + + /** + * Enqueues a request to look up the contact details for the given phone number. + * <p> + * It also provides the current contact info stored in the call log for this number. + * <p> + * If the {@code immediate} parameter is true, it will start immediately the thread that looks + * up the contact information (if it has not been already started). Otherwise, it will be + * started with a delay. See {@link #START_PROCESSING_REQUESTS_DELAY_MILLIS}. + * @param postDialString if required, append into number + * @param isConf indicate whether call log is for Conference Url call + */ + protected void enqueueRequest(String number, String postDialString, String countryIso, + ContactInfo callLogInfo, boolean immediate, boolean isConf) { + ContactInfoRequest request = new ContactInfoRequest(number, postDialString, countryIso, + callLogInfo, isConf); synchronized (mRequests) { if (!mRequests.contains(request)) { mRequests.add(request); diff --git a/src/com/android/dialer/contactinfo/ContactInfoRequest.java b/src/com/android/dialer/contactinfo/ContactInfoRequest.java index ec5c1198e..98208bc40 100644 --- a/src/com/android/dialer/contactinfo/ContactInfoRequest.java +++ b/src/com/android/dialer/contactinfo/ContactInfoRequest.java @@ -31,11 +31,20 @@ public final class ContactInfoRequest { public final String countryIso; /** The cached contact information stored in the call log. */ public final ContactInfo callLogInfo; + public final boolean isConf; + public final String postDialString; public ContactInfoRequest(String number, String countryIso, ContactInfo callLogInfo) { + this(number, null, countryIso, callLogInfo, false); + } + + public ContactInfoRequest(String number, String postDialString, String countryIso, + ContactInfo callLogInfo, boolean isConf) { this.number = number; + this.postDialString = postDialString; this.countryIso = countryIso; this.callLogInfo = callLogInfo; + this.isConf = isConf; } @Override @@ -47,6 +56,7 @@ public final class ContactInfoRequest { ContactInfoRequest other = (ContactInfoRequest) obj; if (!TextUtils.equals(number, other.number)) return false; + if (!TextUtils.equals(postDialString, other.postDialString)) return false; if (!TextUtils.equals(countryIso, other.countryIso)) return false; if (!Objects.equal(callLogInfo, other.callLogInfo)) return false; @@ -60,6 +70,7 @@ public final class ContactInfoRequest { result = prime * result + ((callLogInfo == null) ? 0 : callLogInfo.hashCode()); result = prime * result + ((countryIso == null) ? 0 : countryIso.hashCode()); result = prime * result + ((number == null) ? 0 : number.hashCode()); + result = prime * result + ((postDialString == null) ? 0 : postDialString.hashCode()); return result; } } diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java index 13661a425..85be75448 100644 --- a/src/com/android/dialer/dialpad/DialpadFragment.java +++ b/src/com/android/dialer/dialpad/DialpadFragment.java @@ -100,6 +100,9 @@ import com.android.phone.common.animation.AnimUtils; import com.android.phone.common.dialpad.DialpadKeyButton; import com.android.phone.common.dialpad.DialpadView; +import static android.Manifest.permission.READ_CALL_LOG; +import static android.Manifest.permission.WRITE_CALL_LOG; + import java.util.HashSet; import java.util.List; @@ -114,8 +117,9 @@ public class DialpadFragment extends Fragment DialpadKeyButton.OnPressedListener { private static final String TAG = "DialpadFragment"; - /* define for Activity permission request for Android6.0 */ + /* define for Activity permission request for Android >= 6.0 */ private static final int PERMISSION_REQUEST_CODE_LOCATION = 2; + private static final int READ_WRITE_CALL_LOG_PERMISSION_REQUEST_CODE = 3; /** * LinearLayout with getter and setter methods for the translationY property using floats, * for animation purposes. @@ -196,7 +200,6 @@ public class DialpadFragment extends Fragment private static final String PROPERTY_RADIO_ATEL_CARRIER = "persist.radio.atel.carrier"; private static final String CARRIER_ONE_DEFAULT_MCC_MNC = "405854"; - private OnDialpadQueryChangedListener mDialpadQueryListener; private DialpadView mDialpadView; @@ -269,6 +272,8 @@ public class DialpadFragment extends Fragment private CallStateReceiver mCallStateReceiver; + private boolean mHasReadAndWriteCallLogPermission = false; + private class CallStateReceiver extends BroadcastReceiver { /** * Receive call state changes so that we can take down the @@ -649,11 +654,16 @@ public class DialpadFragment extends Fragment private void setFormattedDigits(String data, String normalizedNumber) { final String formatted = getFormattedDigits(data, normalizedNumber, mCurrentCountryIso); if (!TextUtils.isEmpty(formatted)) { - Editable digits = mDigits.getText(); - digits.replace(0, digits.length(), formatted); - // for some reason this isn't getting called in the digits.replace call above.. - // but in any case, this will make sure the background drawable looks right - afterTextChanged(digits); + if (isRecipientsShown()) { + mRecipients.setText(formatted); + afterTextChanged(mRecipients.getText()); + } else { + Editable digits = mDigits.getText(); + digits.replace(0, digits.length(), formatted); + // for some reason this isn't getting called in the digits.replace call above.. + // but in any case, this will make sure the background drawable looks right + afterTextChanged(digits); + } } } @@ -756,8 +766,16 @@ public class DialpadFragment extends Fragment final StopWatch stopWatch = StopWatch.start("Dialpad.onResume"); // Query the last dialed number. Do it first because hitting + mHasReadAndWriteCallLogPermission = + PermissionsUtil.hasPermission(getActivity(), READ_CALL_LOG) && + PermissionsUtil.hasPermission(getActivity(), WRITE_CALL_LOG); // the DB is 'slow'. This call is asynchronous. - queryLastOutgoingCall(); + if (mHasReadAndWriteCallLogPermission){ + queryLastOutgoingCall(); + } else { + ActivityCompat.requestPermissions(getActivity(), new String[] {READ_CALL_LOG, + WRITE_CALL_LOG}, READ_WRITE_CALL_LOG_PERMISSION_REQUEST_CODE); + } stopWatch.lap("qloc"); @@ -2086,6 +2104,15 @@ public class DialpadFragment extends Fragment handleDialButtonPressed(); } break; + case READ_WRITE_CALL_LOG_PERMISSION_REQUEST_CODE: + for (int i = 0; i < grantResults.length; i++) { + mHasReadAndWriteCallLogPermission &= + PackageManager.PERMISSION_GRANTED == grantResults[i]; + } + if (mHasReadAndWriteCallLogPermission) { + queryLastOutgoingCall(); + } + break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } diff --git a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java b/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java index 3c60a967b..6255dec87 100644 --- a/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java +++ b/src/com/android/dialer/filterednumber/BlockNumberDialogFragment.java @@ -238,7 +238,9 @@ public class BlockNumberDialogFragment extends DialogFragment { final OnUnblockNumberListener onUndoListener = new OnUnblockNumberListener() { @Override public void onUnblockComplete(int rows, ContentValues values) { - Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); + if (mParentView != null) { + Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); + } if (callback != null) { callback.onChangeFilteredNumberUndo(); } @@ -256,12 +258,12 @@ public class BlockNumberDialogFragment extends DialogFragment { mHandler.unblock(onUndoListener, uri); } }; - - Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) - .setActionTextColor(actionTextColor) - .show(); - + if (mParentView != null) { + Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) + .setAction(R.string.block_number_undo, undoListener) + .setActionTextColor(actionTextColor) + .show(); + } if (callback != null) { callback.onFilterNumberSuccess(); } @@ -287,7 +289,9 @@ public class BlockNumberDialogFragment extends DialogFragment { final OnBlockNumberListener onUndoListener = new OnBlockNumberListener() { @Override public void onBlockComplete(final Uri uri) { - Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); + if (mParentView != null) { + Snackbar.make(mParentView, undoMessage, Snackbar.LENGTH_LONG).show(); + } if (callback != null) { callback.onChangeFilteredNumberUndo(); } @@ -305,12 +309,12 @@ public class BlockNumberDialogFragment extends DialogFragment { mHandler.blockNumber(onUndoListener, values); } }; - - Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) - .setAction(R.string.block_number_undo, undoListener) - .setActionTextColor(actionTextColor) - .show(); - + if (mParentView != null) { + Snackbar.make(mParentView, message, Snackbar.LENGTH_LONG) + .setAction(R.string.block_number_undo, undoListener) + .setActionTextColor(actionTextColor) + .show(); + } if (callback != null) { callback.onUnfilterNumberSuccess(); } diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java index 1c814555c..303c73a26 100644 --- a/src/com/android/dialer/settings/DialerSettingsActivity.java +++ b/src/com/android/dialer/settings/DialerSettingsActivity.java @@ -63,10 +63,12 @@ public class DialerSettingsActivity extends AppCompatPreferenceActivity { @Override public void onBuildHeaders(List<Header> target) { - Header displayOptionsHeader = new Header(); - displayOptionsHeader.titleRes = R.string.display_options_title; - displayOptionsHeader.fragment = DisplayOptionsSettingsFragment.class.getName(); - target.add(displayOptionsHeader); + if (showDisplayOptions()) { + Header displayOptionsHeader = new Header(); + displayOptionsHeader.titleRes = R.string.display_options_title; + displayOptionsHeader.fragment = DisplayOptionsSettingsFragment.class.getName(); + target.add(displayOptionsHeader); + } Header soundSettingsHeader = new Header(); soundSettingsHeader.titleRes = R.string.sounds_and_vibration_title; @@ -158,6 +160,18 @@ public class DialerSettingsActivity extends AppCompatPreferenceActivity { } } + /** + * Returns {@code true} or {@code false} based on whether the display options setting should be + * shown. For languages such as Chinese, Japanese, or Korean, display options aren't useful + * since contacts are sorted and displayed family name first by default. + * + * @return {@code true} if the display options should be shown, {@code false} otherwise. + */ + private boolean showDisplayOptions() { + return getResources().getBoolean(R.bool.config_display_order_user_changeable) + && getResources().getBoolean(R.bool.config_sort_order_user_changeable); + } + @Override public void onHeaderClick(Header header, int position) { if (header.id == R.id.settings_header_sounds_and_vibration) { diff --git a/src/com/android/dialer/util/DialerUtils.java b/src/com/android/dialer/util/DialerUtils.java index a71e287cc..f2b04f928 100644 --- a/src/com/android/dialer/util/DialerUtils.java +++ b/src/com/android/dialer/util/DialerUtils.java @@ -232,4 +232,13 @@ public class DialerUtils { PREFS_MESSAGE, Context.MODE_PRIVATE); prefs.edit().putBoolean(KEY_STATE, show).apply(); } + + /** + * @return true if calllog inserted earlier when dial a ConfURI call. + */ + public static boolean isConferenceURICallLog(String number, String postDialDigits) { + return (number == null || number.contains(";") || number.contains(",")) && + (postDialDigits == null || postDialDigits.equals("")); + } + } diff --git a/src/com/android/dialer/util/IntentUtil.java b/src/com/android/dialer/util/IntentUtil.java index 8d47075e7..bb87a49cf 100644 --- a/src/com/android/dialer/util/IntentUtil.java +++ b/src/com/android/dialer/util/IntentUtil.java @@ -177,7 +177,8 @@ public class IntentUtil { if (subRes.getBoolean(R.bool.config_enable_conference_dialer)) { TelephonyManager telephonyMgr = (TelephonyManager) context. getSystemService(Context.TELEPHONY_SERVICE); - isEnabled = telephonyMgr.isImsRegistered(); + isEnabled = telephonyMgr.isImsRegisteredForSubscriber(subInfo + .getSubscriptionId()); if (isEnabled) { break; } diff --git a/src/com/android/dialer/util/TelecomUtil.java b/src/com/android/dialer/util/TelecomUtil.java index bd201c459..69c7334b9 100644 --- a/src/com/android/dialer/util/TelecomUtil.java +++ b/src/com/android/dialer/util/TelecomUtil.java @@ -95,11 +95,14 @@ public class TelecomUtil { } public static boolean handleMmi(Context context, String dialString, - PhoneAccountHandle handle) { + @Nullable PhoneAccountHandle handle) { if (hasModifyPhoneStatePermission(context)) { try { - return TelecomManagerCompat.handleMmi( - getTelecomManager(context), dialString, handle); + if (handle == null) { + return getTelecomManager(context).handleMmi(dialString); + } else { + return getTelecomManager(context).handleMmi(dialString, handle); + } } catch (SecurityException e) { Log.w(TAG, "TelecomManager.handleMmi called without permission."); } |