From 04ac93d3c9d2f3f4c157bfa1d23d225aa34db9df Mon Sep 17 00:00:00 2001 From: erfanian Date: Mon, 9 Oct 2017 15:12:22 -0700 Subject: Add assisted dialing to outbound calls that qualify. * Add missing assisted dialing to calls from contacts in the call log. * Add missing assisted dialing to calls from dialpad and normal search. Bug: 63995025,63995261 Test: unit test PiperOrigin-RevId: 171593967 Change-Id: I4e63ef1dcd7ee1b2b5cbb8ecb4d8da744d90bd66 --- java/com/android/dialer/app/DialtactsActivity.java | 19 +++--- .../app/calllog/CallLogListItemViewHolder.java | 34 ++++++----- .../android/dialer/app/calllog/IntentProvider.java | 15 +++++ .../assisteddialing/AssistedDialingMediator.java | 57 +----------------- .../AssistedDialingMediatorImpl.java | 70 ++++++++++++++++++++++ .../AssistedDialingMediatorStub.java | 34 +++++++++++ .../dialer/assisteddialing/ConcreteCreator.java | 16 ++++- .../dialer/assisteddialing/Constraints.java | 26 ++++++-- .../dialer/assisteddialing/TransformationInfo.java | 10 ++-- .../dialer/callintent/CallIntentBuilder.java | 41 +++++++++++-- .../compat/telephony/TelephonyManagerCompat.java | 5 ++ .../interactions/PhoneNumberInteraction.java | 8 ++- .../dialer/searchfragment/list/SearchAdapter.java | 19 ++++-- 13 files changed, 253 insertions(+), 101 deletions(-) create mode 100644 java/com/android/dialer/assisteddialing/AssistedDialingMediatorImpl.java create mode 100644 java/com/android/dialer/assisteddialing/AssistedDialingMediatorStub.java diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index 04f1431e4..5f3620b1c 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -43,7 +43,7 @@ import android.support.v4.app.ActivityCompat; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; import android.telecom.PhoneAccount; -import android.telecom.TelecomManager; +import android.telephony.TelephonyManager; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -90,6 +90,7 @@ import com.android.dialer.app.list.SmartDialSearchFragment; import com.android.dialer.app.settings.DialerSettingsActivity; import com.android.dialer.app.widget.ActionBarController; import com.android.dialer.app.widget.SearchEditTextLayout; +import com.android.dialer.assisteddialing.ConcreteCreator; import com.android.dialer.callcomposer.CallComposerActivity; import com.android.dialer.calldetails.CallDetailsActivity; import com.android.dialer.callintent.CallInitiationType; @@ -97,7 +98,6 @@ import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.dialer.compat.telephony.TelephonyManagerCompat; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.contactsfragment.ContactsFragment; @@ -1488,13 +1488,14 @@ public class DialtactsActivity extends TransactionSafeActivity } Intent intent = - new CallIntentBuilder(phoneNumber, callSpecificAppData).setIsVideoCall(isVideoCall).build(); - - if (callSpecificAppData.getAllowAssistedDialing()) { - Bundle extras = new Bundle(); - extras.putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true); - intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); - } + new CallIntentBuilder(phoneNumber, callSpecificAppData) + .setIsVideoCall(isVideoCall) + .setAllowAssistedDial( + callSpecificAppData.getAllowAssistedDialing(), + ConcreteCreator.createNewAssistedDialingMediator( + getApplication().getSystemService(TelephonyManager.class), + getApplicationContext())) + .build(); DialerUtils.startActivityWithErrorToast(this, intent); mClearSearchOnPause = true; diff --git a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java index 60acb55fc..f0eee112b 100644 --- a/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +++ b/java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java @@ -23,7 +23,6 @@ import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.AsyncTask; -import android.os.Bundle; import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; @@ -38,6 +37,7 @@ import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.text.BidiFormatter; import android.text.TextDirectionHeuristics; import android.text.TextUtils; @@ -69,7 +69,6 @@ import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.compat.CompatUtils; -import com.android.dialer.compat.telephony.TelephonyManagerCompat; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.contactphoto.ContactPhotoManager; @@ -532,8 +531,16 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder // Call to generic voicemail number, in case there are multiple accounts. primaryActionButtonView.setTag(IntentProvider.getReturnVoicemailCallIntentProvider()); } else { - primaryActionButtonView.setTag( - IntentProvider.getReturnCallIntentProvider(number + postDialDigits)); + if (this.info != null && this.info.lookupKey != null) { + primaryActionButtonView.setTag( + IntentProvider.getAssistedDialIntentProvider( + number + postDialDigits, + mContext, + mContext.getSystemService(TelephonyManager.class))); + } else { + primaryActionButtonView.setTag( + IntentProvider.getReturnCallIntentProvider(number + postDialDigits)); + } } primaryActionButtonView.setContentDescription( @@ -592,8 +599,14 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder ((TextView) callButtonView.findViewById(R.id.call_type_or_location_text)); if (canPlaceCallToNumber) { - callButtonView.setTag(IntentProvider.getReturnCallIntentProvider(number)); - callTypeOrLocationView.setVisibility(View.GONE); + if (this.info != null && this.info.lookupKey != null) { + callButtonView.setTag( + IntentProvider.getAssistedDialIntentProvider( + number, mContext, mContext.getSystemService(TelephonyManager.class))); + } else { + callButtonView.setTag(IntentProvider.getReturnCallIntentProvider(number)); + callTypeOrLocationView.setVisibility(View.GONE); + } } if (!TextUtils.isEmpty(voicemailUri) && canPlaceCallToNumber) { @@ -911,15 +924,6 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder return; } - if (info != null && info.lookupKey != null) { - Bundle extras = new Bundle(); - if (intent.hasExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS)) { - extras = intent.getParcelableExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS); - } - extras.putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true); - intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); - } - // We check to see if we are starting a Lightbringer intent. The reason is Lightbringer // intents need to be started using startActivityForResult instead of the usual startActivity String packageName = intent.getPackage(); diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java index 55fdbbace..52a7b0faf 100644 --- a/java/com/android/dialer/app/calllog/IntentProvider.java +++ b/java/com/android/dialer/app/calllog/IntentProvider.java @@ -22,8 +22,10 @@ import android.content.Intent; import android.net.Uri; import android.provider.ContactsContract; import android.telecom.PhoneAccountHandle; +import android.telephony.TelephonyManager; import com.android.contacts.common.model.Contact; import com.android.contacts.common.model.ContactLoader; +import com.android.dialer.assisteddialing.ConcreteCreator; import com.android.dialer.calldetails.CallDetailsActivity; import com.android.dialer.calldetails.CallDetailsEntries; import com.android.dialer.callintent.CallInitiationType; @@ -59,6 +61,19 @@ public abstract class IntentProvider { }; } + public static IntentProvider getAssistedDialIntentProvider( + final String number, final Context context, final TelephonyManager telephonyManager) { + return new IntentProvider() { + @Override + public Intent getIntent(Context context) { + return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) + .setAllowAssistedDial( + true, ConcreteCreator.createNewAssistedDialingMediator(telephonyManager, context)) + .build(); + } + }; + } + public static IntentProvider getReturnVideoCallIntentProvider(final String number) { return getReturnVideoCallIntentProvider(number, null); } diff --git a/java/com/android/dialer/assisteddialing/AssistedDialingMediator.java b/java/com/android/dialer/assisteddialing/AssistedDialingMediator.java index 3d027296c..4dc87a772 100644 --- a/java/com/android/dialer/assisteddialing/AssistedDialingMediator.java +++ b/java/com/android/dialer/assisteddialing/AssistedDialingMediator.java @@ -19,63 +19,12 @@ package com.android.dialer.assisteddialing; import android.annotation.TargetApi; import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; -import com.android.dialer.common.LogUtil; import java.util.Optional; -/** - * The Mediator for Assisted Dialing. - * - *

This class is responsible for mediating location discovery of the user, determining if the - * call is eligible for assisted dialing, and performing the transformation of numbers eligible for - * assisted dialing. - */ -public final class AssistedDialingMediator { - - private final LocationDetector locationDetector; - private final NumberTransformer numberTransformer; - - protected AssistedDialingMediator( - @NonNull LocationDetector locationDetector, @NonNull NumberTransformer numberTransformer) { - if (locationDetector == null) { - throw new NullPointerException("locationDetector was null"); - } +/** The core interface for the AssistedDialingMediator. */ +public interface AssistedDialingMediator { - if (numberTransformer == null) { - throw new NullPointerException("numberTransformer was null"); - } - this.locationDetector = locationDetector; - this.numberTransformer = numberTransformer; - } - - /** - * Returns a boolean for callers to quickly determine whether or not the AssistedDialingMediator - * thinks an attempt at assisted dialing is likely to succeed. - */ - public boolean conditionsEligibleForAssistedDialing( - @NonNull String numberToCheck, - @NonNull String userHomeCountryCode, - @NonNull String userRoamingCountryCode) { - return numberTransformer.canDoAssistedDialingTransformation( - numberToCheck, userHomeCountryCode, userRoamingCountryCode); - } - - /** - * Returns an Optional of type String containing the transformed number that was provided. The - * transformed number should be capable of dialing out of the User's current country and - * successfully connecting with a contact in the User's home country. - */ @SuppressWarnings("AndroidApiChecker") // Use of optional @TargetApi(VERSION_CODES.N) - public Optional attemptAssistedDial(@NonNull String numberToTransform) { - Optional userHomeCountryCode = locationDetector.getUpperCaseUserHomeCountry(); - Optional userRoamingCountryCode = locationDetector.getUpperCaseUserRoamingCountry(); - - if (!userHomeCountryCode.isPresent() || !userRoamingCountryCode.isPresent()) { - LogUtil.i("AssistedDialingMediator.attemptAssistedDial", "Unable to determine country codes"); - return Optional.empty(); - } - - return numberTransformer.doAssistedDialingTransformation( - numberToTransform, userHomeCountryCode.get(), userRoamingCountryCode.get()); - } + public Optional attemptAssistedDial(@NonNull String numberToTransform); } diff --git a/java/com/android/dialer/assisteddialing/AssistedDialingMediatorImpl.java b/java/com/android/dialer/assisteddialing/AssistedDialingMediatorImpl.java new file mode 100644 index 000000000..1692614bb --- /dev/null +++ b/java/com/android/dialer/assisteddialing/AssistedDialingMediatorImpl.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.assisteddialing; + +import android.annotation.TargetApi; +import android.os.Build.VERSION_CODES; +import android.support.annotation.NonNull; +import com.android.dialer.common.LogUtil; +import java.util.Optional; + +/** + * The Mediator for Assisted Dialing. + * + *

This class is responsible for mediating location discovery of the user, determining if the + * call is eligible for assisted dialing, and performing the transformation of numbers eligible for + * assisted dialing. + */ +final class AssistedDialingMediatorImpl implements AssistedDialingMediator { + + private final LocationDetector locationDetector; + private final NumberTransformer numberTransformer; + + AssistedDialingMediatorImpl( + @NonNull LocationDetector locationDetector, @NonNull NumberTransformer numberTransformer) { + if (locationDetector == null) { + throw new NullPointerException("locationDetector was null"); + } + + if (numberTransformer == null) { + throw new NullPointerException("numberTransformer was null"); + } + this.locationDetector = locationDetector; + this.numberTransformer = numberTransformer; + } + + /** + * Returns an Optional of type String containing the transformed number that was provided. The + * transformed number should be capable of dialing out of the User's current country and + * successfully connecting with a contact in the User's home country. + */ + @SuppressWarnings("AndroidApiChecker") // Use of optional + @TargetApi(VERSION_CODES.N) + @Override + public Optional attemptAssistedDial(@NonNull String numberToTransform) { + Optional userHomeCountryCode = locationDetector.getUpperCaseUserHomeCountry(); + Optional userRoamingCountryCode = locationDetector.getUpperCaseUserRoamingCountry(); + + if (!userHomeCountryCode.isPresent() || !userRoamingCountryCode.isPresent()) { + LogUtil.i("AssistedDialingMediator.attemptAssistedDial", "Unable to determine country codes"); + return Optional.empty(); + } + + return numberTransformer.doAssistedDialingTransformation( + numberToTransform, userHomeCountryCode.get(), userRoamingCountryCode.get()); + } +} diff --git a/java/com/android/dialer/assisteddialing/AssistedDialingMediatorStub.java b/java/com/android/dialer/assisteddialing/AssistedDialingMediatorStub.java new file mode 100644 index 000000000..c7a821214 --- /dev/null +++ b/java/com/android/dialer/assisteddialing/AssistedDialingMediatorStub.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.dialer.assisteddialing; + +import android.annotation.TargetApi; +import android.os.Build.VERSION_CODES; +import android.support.annotation.NonNull; +import java.util.Optional; + +/** A stub assisted dialing implementation. */ +public final class AssistedDialingMediatorStub implements AssistedDialingMediator { + + /** Always returns an empty Optional. */ + @Override + @SuppressWarnings("AndroidApiChecker") // Use of optional + @TargetApi(VERSION_CODES.N) + public Optional attemptAssistedDial(@NonNull String numberToTransform) { + return Optional.empty(); + } +} diff --git a/java/com/android/dialer/assisteddialing/ConcreteCreator.java b/java/com/android/dialer/assisteddialing/ConcreteCreator.java index f51216a69..49d3b1f87 100644 --- a/java/com/android/dialer/assisteddialing/ConcreteCreator.java +++ b/java/com/android/dialer/assisteddialing/ConcreteCreator.java @@ -18,10 +18,12 @@ package com.android.dialer.assisteddialing; import android.annotation.TargetApi; import android.content.Context; +import android.os.Build; import android.os.Build.VERSION_CODES; import android.support.annotation.NonNull; import android.telephony.TelephonyManager; import com.android.dialer.common.LogUtil; +import com.android.dialer.configprovider.ConfigProviderBindings; /** * A Creator for AssistedDialingMediators. @@ -32,6 +34,11 @@ import com.android.dialer.common.LogUtil; @TargetApi(VERSION_CODES.N) public final class ConcreteCreator { + // Floor set at N due to use of Optional. + protected static final int BUILD_CODE_FLOOR = Build.VERSION_CODES.N; + // Ceiling set at O because this feature will ship as part of the framework in P. + protected static final int BUILD_CODE_CEILING = Build.VERSION_CODES.O; + /** * Creates a new AssistedDialingMediator * @@ -42,6 +49,7 @@ public final class ConcreteCreator { */ public static AssistedDialingMediator createNewAssistedDialingMediator( @NonNull TelephonyManager telephonyManager, @NonNull Context context) { + if (telephonyManager == null) { LogUtil.i( "ConcreteCreator.createNewAssistedDialingMediator", "provided TelephonyManager was null"); @@ -51,8 +59,14 @@ public final class ConcreteCreator { LogUtil.i("ConcreteCreator.createNewAssistedDialingMediator", "provided context was null"); throw new NullPointerException("Provided context was null"); } + + if ((Build.VERSION.SDK_INT < BUILD_CODE_FLOOR || Build.VERSION.SDK_INT > BUILD_CODE_CEILING) + || !ConfigProviderBindings.get(context).getBoolean("assisted_dialing_enabled", false)) { + return new AssistedDialingMediatorStub(); + } + Constraints constraints = new Constraints(context); - return new AssistedDialingMediator( + return new AssistedDialingMediatorImpl( new LocationDetector(telephonyManager), new NumberTransformer(constraints)); } } diff --git a/java/com/android/dialer/assisteddialing/Constraints.java b/java/com/android/dialer/assisteddialing/Constraints.java index 6bcab9963..023be1c4c 100644 --- a/java/com/android/dialer/assisteddialing/Constraints.java +++ b/java/com/android/dialer/assisteddialing/Constraints.java @@ -62,7 +62,7 @@ final class Constraints { "GB" /* United Kingdom */, "JP" /* Japan */, "MX" /* Mexico */, - "US" /* United States*/, + "US" /* United States */, }; private final Set supportedCountryCodes = @@ -115,7 +115,8 @@ final class Constraints { && isUserRoaming(userHomeCountryCode, userRoamingCountryCode) && isNotInternationalNumber(parsedPhoneNumber) && isNotEmergencyNumber(numberToCheck, context) - && isValidNumber(parsedPhoneNumber); + && isValidNumber(parsedPhoneNumber) + && doesNotHaveExtension(parsedPhoneNumber); } /** Returns a boolean indicating the value equivalence of the provided country codes. */ @@ -165,10 +166,7 @@ final class Constraints { } } - /** - * Returns a boolean indicating if the provided number and home country code are already - * internationally formatted. - */ + /** Returns a boolean indicating if the provided number is already internationally formatted. */ private boolean isNotInternationalNumber(@NonNull Optional parsedPhoneNumber) { if (parsedPhoneNumber.get().hasCountryCode() @@ -181,6 +179,22 @@ final class Constraints { return true; } + /** + * Returns a boolean indicating if the provided number has an extension. + * + *

Extensions are currently stripped when formatting a number for mobile dialing, so we don't + * want to purposefully truncate a number. + */ + private boolean doesNotHaveExtension(@NonNull Optional parsedPhoneNumber) { + + if (parsedPhoneNumber.get().hasExtension() + && !TextUtils.isEmpty(parsedPhoneNumber.get().getExtension())) { + LogUtil.i("Constraints.doesNotHaveExtension", "phone number has an extension"); + return false; + } + return true; + } + /** Returns a boolean indicating if the provided number is considered to be a valid number. */ private boolean isValidNumber(@NonNull Optional parsedPhoneNumber) { boolean result = PhoneNumberUtil.getInstance().isValidNumber(parsedPhoneNumber.get()); diff --git a/java/com/android/dialer/assisteddialing/TransformationInfo.java b/java/com/android/dialer/assisteddialing/TransformationInfo.java index 7149d71cc..03e565c51 100644 --- a/java/com/android/dialer/assisteddialing/TransformationInfo.java +++ b/java/com/android/dialer/assisteddialing/TransformationInfo.java @@ -43,15 +43,15 @@ public abstract class TransformationInfo { private static final String TRANSFORMED_NUMBER_COUNTRY_CALLING_CODE_KEY = "TRANSFORMED_NUMBER_COUNTRY_CALLING_CODE"; - abstract String originalNumber(); + public abstract String originalNumber(); - abstract String transformedNumber(); + public abstract String transformedNumber(); - abstract String userHomeCountryCode(); + public abstract String userHomeCountryCode(); - abstract String userRoamingCountryCode(); + public abstract String userRoamingCountryCode(); - abstract int transformedNumberCountryCallingCode(); + public abstract int transformedNumberCountryCallingCode(); public static Builder builder() { return new AutoValue_TransformationInfo.Builder(); diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java index b5b680e48..dc239dc6b 100644 --- a/java/com/android/dialer/callintent/CallIntentBuilder.java +++ b/java/com/android/dialer/callintent/CallIntentBuilder.java @@ -16,21 +16,27 @@ package com.android.dialer.callintent; +import android.annotation.TargetApi; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; +import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telecom.VideoProfile; import android.text.TextUtils; +import com.android.dialer.assisteddialing.AssistedDialingMediator; +import com.android.dialer.assisteddialing.TransformationInfo; import com.android.dialer.common.Assert; import com.android.dialer.compat.telephony.TelephonyManagerCompat; import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.util.CallUtil; +import java.util.Optional; /** Creates an intent to start a new outgoing call. */ public class CallIntentBuilder { @@ -40,6 +46,7 @@ public class CallIntentBuilder { private boolean isVideoCall; private String callSubject; private boolean allowAssistedDial; + private AssistedDialingMediator assistedDialingMediator; private static int lightbringerButtonAppearInExpandedCallLogItemCount = 0; private static int lightbringerButtonAppearInCollapsedCallLogItemCount = 0; @@ -103,7 +110,9 @@ public class CallIntentBuilder { return this; } - public CallIntentBuilder setAllowAssistedDial(boolean allowAssistedDial) { + public CallIntentBuilder setAllowAssistedDial( + boolean allowAssistedDial, @NonNull AssistedDialingMediator assistedDialingMediator) { + this.assistedDialingMediator = Assert.isNotNull(assistedDialingMediator); this.allowAssistedDial = allowAssistedDial; return this; } @@ -115,18 +124,18 @@ public class CallIntentBuilder { public Intent build() { Intent intent = new Intent(Intent.ACTION_CALL, uri); + Bundle extras = new Bundle(); + + if (allowAssistedDial && this.assistedDialingMediator != null) { + intent = buildAssistedDialingParameters(intent, extras); + } intent.putExtra( TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, isVideoCall ? VideoProfile.STATE_BIDIRECTIONAL : VideoProfile.STATE_AUDIO_ONLY); - Bundle extras = new Bundle(); extras.putLong(Constants.EXTRA_CALL_CREATED_TIME_MILLIS, SystemClock.elapsedRealtime()); CallIntentParser.putCallSpecificAppData(extras, callSpecificAppData); - if (allowAssistedDial) { - extras.putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true); - } - intent.putExtra(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras); if (phoneAccountHandle != null) { @@ -140,6 +149,26 @@ public class CallIntentBuilder { return intent; } + @SuppressWarnings("AndroidApiChecker") // Use of optional + @TargetApi(Build.VERSION_CODES.N) + private Intent buildAssistedDialingParameters(Intent intent, Bundle extras) { + extras.putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true); + String phoneNumber = + uri.getScheme().equals(PhoneAccount.SCHEME_TEL) ? uri.getSchemeSpecificPart() : ""; + Optional transformedNumber = + assistedDialingMediator.attemptAssistedDial(phoneNumber); + if (transformedNumber.isPresent()) { + Bundle assistedDialingExtras = transformedNumber.get().toBundle(); + extras.putBoolean(TelephonyManagerCompat.IS_ASSISTED_DIALED, true); + extras.putBundle(TelephonyManagerCompat.ASSISTED_DIALING_EXTRAS, assistedDialingExtras); + intent = + new Intent( + Intent.ACTION_CALL, + CallUtil.getCallUri(Assert.isNotNull(transformedNumber.get().transformedNumber()))); + } + return intent; + } + private static @NonNull CallSpecificAppData createCallSpecificAppData( CallInitiationType.Type callInitiationType) { CallSpecificAppData callSpecificAppData = diff --git a/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java b/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java index ecd36d359..61c44b9f4 100644 --- a/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java +++ b/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java @@ -68,6 +68,11 @@ public class TelephonyManagerCompat { */ public static final String IS_ASSISTED_DIALED = "android.telecom.extra.IS_ASSISTED_DIALED"; + // TODO(erfanian): b/63995261 Replace with the platform/telecom API when available. + /** Additional information relating to the assisted dialing transformation. */ + public static final String ASSISTED_DIALING_EXTRAS = + "android.telecom.extra.ASSISTED_DIALING_EXTRAS"; + /** * Returns the number of phones available. Returns 1 for Single standby mode (Single SIM * functionality) Returns 2 for Dual standby mode.(Dual SIM functionality) diff --git a/java/com/android/dialer/interactions/PhoneNumberInteraction.java b/java/com/android/dialer/interactions/PhoneNumberInteraction.java index c42be42ec..9692dae0f 100644 --- a/java/com/android/dialer/interactions/PhoneNumberInteraction.java +++ b/java/com/android/dialer/interactions/PhoneNumberInteraction.java @@ -40,6 +40,7 @@ import android.provider.ContactsContract.RawContacts; import android.support.annotation.IntDef; import android.support.annotation.VisibleForTesting; import android.support.v4.app.ActivityCompat; +import android.telephony.TelephonyManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -51,6 +52,7 @@ import com.android.contacts.common.Collapser; import com.android.contacts.common.Collapser.Collapsible; import com.android.contacts.common.MoreContactUtils; import com.android.contacts.common.util.ContactDisplayUtils; +import com.android.dialer.assisteddialing.ConcreteCreator; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.callintent.CallIntentParser; @@ -83,6 +85,7 @@ public class PhoneNumberInteraction implements OnLoadCompleteListener { private static final String TAG = PhoneNumberInteraction.class.getSimpleName(); /** The identifier for a permissions request if one is generated. */ public static final int REQUEST_READ_CONTACTS = 1; + public static final int REQUEST_CALL_PHONE = 2; @VisibleForTesting @@ -183,7 +186,10 @@ public class PhoneNumberInteraction implements OnLoadCompleteListener { intent = new CallIntentBuilder(phoneNumber, callSpecificAppData) .setIsVideoCall(isVideoCall) - .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()) + .setAllowAssistedDial( + callSpecificAppData.getAllowAssistedDialing(), + ConcreteCreator.createNewAssistedDialingMediator( + context.getSystemService(TelephonyManager.class), context)) .build(); break; } diff --git a/java/com/android/dialer/searchfragment/list/SearchAdapter.java b/java/com/android/dialer/searchfragment/list/SearchAdapter.java index 22bfa6dbd..1ca29e072 100644 --- a/java/com/android/dialer/searchfragment/list/SearchAdapter.java +++ b/java/com/android/dialer/searchfragment/list/SearchAdapter.java @@ -21,11 +21,13 @@ import android.content.Intent; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import com.android.dialer.assisteddialing.ConcreteCreator; import com.android.dialer.callcomposer.CallComposerActivity; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; @@ -209,23 +211,32 @@ public final class SearchAdapter extends RecyclerView.Adapter @Override public void placeVoiceCall(String phoneNumber, int ranking) { - placeCall(phoneNumber, ranking, false); + placeCall(phoneNumber, ranking, false, true); } @Override public void placeVideoCall(String phoneNumber, int ranking) { - placeCall(phoneNumber, ranking, true); + placeCall(phoneNumber, ranking, true, false); } - private void placeCall(String phoneNumber, int position, boolean isVideoCall) { + private void placeCall( + String phoneNumber, int position, boolean isVideoCall, boolean allowAssistedDial) { CallSpecificAppData callSpecificAppData = CallSpecificAppData.newBuilder() .setCallInitiationType(callInitiationType) .setPositionOfSelectedSearchResult(position) .setCharactersInSearchString(query == null ? 0 : query.length()) + .setAllowAssistedDialing(allowAssistedDial) .build(); Intent intent = - new CallIntentBuilder(phoneNumber, callSpecificAppData).setIsVideoCall(isVideoCall).build(); + new CallIntentBuilder(phoneNumber, callSpecificAppData) + .setIsVideoCall(isVideoCall) + .setAllowAssistedDial( + allowAssistedDial, + ConcreteCreator.createNewAssistedDialingMediator( + activity.getSystemService(TelephonyManager.class), + activity.getApplicationContext())) + .build(); DialerUtils.startActivityWithErrorToast(activity, intent); } -- cgit v1.2.3