From 73d995ff88b3a8894c7463a21a24dcec3f8d68e4 Mon Sep 17 00:00:00 2001 From: Zachary Heidepriem Date: Sat, 11 Nov 2017 15:03:26 -0800 Subject: Implement CallingAccountSelector and AssistedDialAction CallingAccountSelector examines the CallIntentBuilder, and if the PhoneAccountHandle is missing on a multi-SIM device while the default is not set, it will show a dialog to let the user select it. This step used to be after the in call UI is launched and telecom wants dialer to disambiguate. This step is moved to pre call as dialer need more control, like voicemail calls should always prompt, or the preferred SIM info might be available. This also allows telecom to send the selected PhoneAccountHandle to other apps so they have more information on how to rewrite numbers. AssistedDialAction replaces the step previously in CallIntentBuilder.build(), and rewrites the URI. Pre-call actions are not hooked up for dialing in this CL yet, assisted dialing will still be broken. Bug: 64216442 Test: CallingAccountSelectorTest, AssistedDialActionTest PiperOrigin-RevId: 174917321 Change-Id: Iba2e9092f83c036b402d4044a48ff5c44e806210 --- Android.mk | 7 +- .../widget/SelectPhoneAccountDialogFragment.java | 7 ++ .../dialer/assisteddialing/ConcreteCreator.java | 3 +- .../dialer/precall/impl/AssistedDialAction.java | 73 +++++++++++++ .../precall/impl/CallingAccountSelector.java | 114 +++++++++++++++++++++ .../android/dialer/precall/impl/PreCallImpl.java | 2 +- .../dialer/precall/impl/res/values/strings.xml | 22 ++++ 7 files changed, 225 insertions(+), 3 deletions(-) create mode 100644 java/com/android/dialer/precall/impl/AssistedDialAction.java create mode 100644 java/com/android/dialer/precall/impl/CallingAccountSelector.java create mode 100644 java/com/android/dialer/precall/impl/res/values/strings.xml diff --git a/Android.mk b/Android.mk index 9defc7e45..e9841d9dc 100644 --- a/Android.mk +++ b/Android.mk @@ -81,6 +81,8 @@ EXCLUDE_EXTRA_PACKAGES := \ # We specify each package explicitly to glob resource files. # find . -type f -name "AndroidManifest.xml" | uniq | sort | cut -c 8- | rev | cut -c 21- | rev | sed 's/\//./g' | sed 's/$/ \\/' LOCAL_AAPT_FLAGS := \ + com.android.assets.product \ + com.android.assets.quantum \ com.android.bubble \ com.android.contacts.common \ com.android.dialer.about \ @@ -116,8 +118,11 @@ LOCAL_AAPT_FLAGS := \ com.android.dialer.main.impl \ com.android.dialer.notification \ com.android.dialer.oem \ + com.android.dialer.phonelookup.database \ com.android.dialer.phonenumberutil \ com.android.dialer.postcall \ + com.android.dialer.precall.impl \ + com.android.dialer.preferredsim.impl \ com.android.dialer.searchfragment.common \ com.android.dialer.searchfragment.cp2 \ com.android.dialer.searchfragment.list \ @@ -129,7 +134,7 @@ LOCAL_AAPT_FLAGS := \ com.android.dialer.theme \ com.android.dialer.util \ com.android.dialer.voicemail.listui \ - com.android.dialer.voicemail.settings \ + com.android.dialer.voicemail.settings \ com.android.dialer.voicemailstatus \ com.android.dialer.widget \ com.android.incallui \ diff --git a/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java b/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java index 8156d97cf..6c6aebc0b 100644 --- a/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java +++ b/java/com/android/contacts/common/widget/SelectPhoneAccountDialogFragment.java @@ -26,6 +26,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; @@ -116,6 +117,12 @@ public class SelectPhoneAccountDialogFragment extends DialogFragment { mListener = listener; } + @Nullable + @VisibleForTesting + public SelectPhoneAccountListener getListener() { + return mListener; + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); diff --git a/java/com/android/dialer/assisteddialing/ConcreteCreator.java b/java/com/android/dialer/assisteddialing/ConcreteCreator.java index c3721a7a8..806764567 100644 --- a/java/com/android/dialer/assisteddialing/ConcreteCreator.java +++ b/java/com/android/dialer/assisteddialing/ConcreteCreator.java @@ -22,6 +22,7 @@ import android.os.Build; import android.os.Build.VERSION_CODES; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import android.support.v4.os.UserManagerCompat; import android.telephony.TelephonyManager; import com.android.dialer.assisteddialing.ui.R; @@ -41,7 +42,7 @@ 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; + @VisibleForTesting public static final int BUILD_CODE_CEILING = Build.VERSION_CODES.O; /** * Creates a new AssistedDialingMediator diff --git a/java/com/android/dialer/precall/impl/AssistedDialAction.java b/java/com/android/dialer/precall/impl/AssistedDialAction.java new file mode 100644 index 000000000..edf97cce3 --- /dev/null +++ b/java/com/android/dialer/precall/impl/AssistedDialAction.java @@ -0,0 +1,73 @@ +/* + * 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.precall.impl; + +import android.annotation.TargetApi; +import android.os.Build; +import android.os.Bundle; +import android.telecom.PhoneAccount; +import android.telephony.TelephonyManager; +import com.android.dialer.assisteddialing.AssistedDialingMediator; +import com.android.dialer.assisteddialing.ConcreteCreator; +import com.android.dialer.assisteddialing.TransformationInfo; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.common.Assert; +import com.android.dialer.compat.telephony.TelephonyManagerCompat; +import com.android.dialer.precall.PreCallAction; +import com.android.dialer.precall.PreCallCoordinator; +import com.android.dialer.util.CallUtil; +import java.util.Optional; + +/** Rewrites the call URI with country code. TODO(erfanian): use phone account for multi SIM */ +public class AssistedDialAction implements PreCallAction { + + @SuppressWarnings("AndroidApiChecker") // Use of optional + @TargetApi(Build.VERSION_CODES.N) + @Override + public void run(PreCallCoordinator coordinator) { + CallIntentBuilder builder = coordinator.getBuilder(); + if (!builder.isAssistedDialAllowed()) { + return; + } + AssistedDialingMediator assistedDialingMediator = + ConcreteCreator.createNewAssistedDialingMediator( + coordinator.getActivity().getSystemService(TelephonyManager.class), + coordinator.getActivity()); + if (!assistedDialingMediator.isPlatformEligible()) { + return; + } + builder.getOutgoingCallExtras().putBoolean(TelephonyManagerCompat.ALLOW_ASSISTED_DIAL, true); + String phoneNumber = + builder.getUri().getScheme().equals(PhoneAccount.SCHEME_TEL) + ? builder.getUri().getSchemeSpecificPart() + : ""; + Optional transformedNumber = + assistedDialingMediator.attemptAssistedDial(phoneNumber); + if (transformedNumber.isPresent()) { + Bundle assistedDialingExtras = transformedNumber.get().toBundle(); + builder.getOutgoingCallExtras().putBoolean(TelephonyManagerCompat.IS_ASSISTED_DIALED, true); + builder + .getOutgoingCallExtras() + .putBundle(TelephonyManagerCompat.ASSISTED_DIALING_EXTRAS, assistedDialingExtras); + builder.setUri( + CallUtil.getCallUri(Assert.isNotNull(transformedNumber.get().transformedNumber()))); + } + } + + @Override + public void onDiscard() {} +} diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java new file mode 100644 index 000000000..ca8798c5d --- /dev/null +++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java @@ -0,0 +1,114 @@ +/* + * 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.precall.impl; + +import android.app.Activity; +import android.support.annotation.MainThread; +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 com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; +import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; +import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.common.Assert; +import com.android.dialer.precall.PreCallAction; +import com.android.dialer.precall.PreCallCoordinator; +import java.util.List; + +/** PreCallAction to select which phone account to call with. Ignored if there's only one account */ +@SuppressWarnings("MissingPermission") +public class CallingAccountSelector implements PreCallAction { + + @VisibleForTesting static final String TAG_CALLING_ACCOUNT_SELECTOR = "CallingAccountSelector"; + + private SelectPhoneAccountDialogFragment selectPhoneAccountDialogFragment; + + private boolean isDiscarding; + + @Override + public void run(PreCallCoordinator coordinator) { + CallIntentBuilder builder = coordinator.getBuilder(); + if (builder.getPhoneAccountHandle() != null) { + return; + } + Activity activity = coordinator.getActivity(); + TelecomManager telecomManager = activity.getSystemService(TelecomManager.class); + List accounts = telecomManager.getCallCapablePhoneAccounts(); + if (accounts.size() <= 1) { + return; + } + boolean isVoicemail = builder.getUri().getScheme().equals(PhoneAccount.SCHEME_VOICEMAIL); + + if (!isVoicemail) { + PhoneAccountHandle defaultPhoneAccount = + telecomManager.getDefaultOutgoingPhoneAccount(builder.getUri().getScheme()); + if (defaultPhoneAccount != null) { + builder.setPhoneAccountHandle(defaultPhoneAccount); + return; + } + } + + selectPhoneAccountDialogFragment = + SelectPhoneAccountDialogFragment.newInstance( + R.string.pre_call_select_phone_account, + false /* canSetDefault */, // TODO(twyen): per contact defaults + accounts, + new SelectedListener(coordinator, coordinator.startPendingAction()), + null /* call ID */); + selectPhoneAccountDialogFragment.show( + activity.getFragmentManager(), TAG_CALLING_ACCOUNT_SELECTOR); + } + + @Override + public void onDiscard() { + isDiscarding = true; + selectPhoneAccountDialogFragment.dismiss(); + } + + private class SelectedListener extends SelectPhoneAccountListener { + + private final PreCallCoordinator coordinator; + private final PreCallCoordinator.PendingAction listener; + + public SelectedListener( + @NonNull PreCallCoordinator builder, @NonNull PreCallCoordinator.PendingAction listener) { + this.coordinator = Assert.isNotNull(builder); + this.listener = Assert.isNotNull(listener); + } + + @MainThread + @Override + public void onPhoneAccountSelected( + PhoneAccountHandle selectedAccountHandle, boolean setDefault, @Nullable String callId) { + coordinator.getBuilder().setPhoneAccountHandle(selectedAccountHandle); + listener.finish(); + } + + @MainThread + @Override + public void onDialogDismissed(@Nullable String callId) { + if (isDiscarding) { + return; + } + coordinator.abortCall(); + listener.finish(); + } + } +} diff --git a/java/com/android/dialer/precall/impl/PreCallImpl.java b/java/com/android/dialer/precall/impl/PreCallImpl.java index ac9750ef2..fc2eff8b1 100644 --- a/java/com/android/dialer/precall/impl/PreCallImpl.java +++ b/java/com/android/dialer/precall/impl/PreCallImpl.java @@ -33,7 +33,7 @@ public class PreCallImpl implements PreCall { @Override public ImmutableList getActions() { - return ImmutableList.of(); + return ImmutableList.of(new CallingAccountSelector(), new AssistedDialAction()); } @NonNull diff --git a/java/com/android/dialer/precall/impl/res/values/strings.xml b/java/com/android/dialer/precall/impl/res/values/strings.xml new file mode 100644 index 000000000..894394662 --- /dev/null +++ b/java/com/android/dialer/precall/impl/res/values/strings.xml @@ -0,0 +1,22 @@ + + + + + Call with + + \ No newline at end of file -- cgit v1.2.3 From 0efc840171da8739359b326249978d0a44df540b Mon Sep 17 00:00:00 2001 From: twyen Date: Tue, 7 Nov 2017 15:39:15 -0800 Subject: Hook up pre-call actions This CL replaces all instance of CallIntentBuilder.build() with PreCall.getIntent(), which when run as an activity, will finish building the intent with user interaction. Bug: 64216442 Test: manual PiperOrigin-RevId: 174924323 Change-Id: If41868df4c7ed078d03bd3431fa85b8947056a01 --- .../contacts/common/dialog/CallSubjectDialog.java | 8 +++--- java/com/android/dialer/app/DialtactsActivity.java | 9 +++---- .../android/dialer/app/calllog/IntentProvider.java | 29 +++++++++++++--------- .../dialer/app/calllog/MissedCallNotifier.java | 6 +++-- .../app/voicemail/error/VoicemailErrorMessage.java | 7 +++--- .../dialer/callcomposer/CallComposerActivity.java | 6 ++--- .../dialer/calldetails/CallDetailsActivity.java | 9 +++---- .../dialer/callintent/CallIntentBuilder.java | 5 ++++ .../dialer/calllog/ui/NewCallLogViewHolder.java | 2 +- .../dialer/calllog/ui/menu/PrimaryAction.java | 2 +- .../dialer/calllogutils/CallLogIntents.java | 16 ++++++------ .../dialer/contactactions/IntentModule.java | 17 +++++++------ .../dialer/dialpadview/DialpadFragment.java | 11 +++----- .../interactions/PhoneNumberInteraction.java | 12 +++++---- java/com/android/dialer/precall/PreCall.java | 9 +++++++ .../android/dialer/precall/PreCallCoordinator.java | 3 +++ .../precall/impl/PreCallCoordinatorImpl.java | 2 -- .../android/dialer/precall/impl/PreCallImpl.java | 3 ++- .../searchfragment/list/NewSearchFragment.java | 8 +++--- .../list/SearchActionViewHolder.java | 5 ++-- .../nearbyplaces/NearbyPlaceViewHolder.java | 5 ++-- .../remote/RemoteContactViewHolder.java | 5 ++-- .../VideoCallNotAvailablePrompt.java | 10 +++----- .../voicemail/impl/sms/LegacyModeSmsHandler.java | 8 +++--- 24 files changed, 111 insertions(+), 86 deletions(-) diff --git a/java/com/android/contacts/common/dialog/CallSubjectDialog.java b/java/com/android/contacts/common/dialog/CallSubjectDialog.java index 5c2ae2fa5..2ba2476a6 100644 --- a/java/com/android/contacts/common/dialog/CallSubjectDialog.java +++ b/java/com/android/contacts/common/dialog/CallSubjectDialog.java @@ -50,6 +50,7 @@ import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.LogUtil; import com.android.dialer.contactphoto.ContactPhotoManager; import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.precall.PreCall; import com.android.dialer.util.ViewUtil; import java.nio.charset.Charset; import java.util.ArrayList; @@ -148,13 +149,12 @@ public class CallSubjectDialog extends Activity { @Override public void onClick(View v) { String subject = mCallSubjectView.getText().toString(); - Intent intent = + PreCall.start( + CallSubjectDialog.this, new CallIntentBuilder(mNumber, CallInitiationType.Type.CALL_SUBJECT_DIALOG) .setPhoneAccountHandle(mPhoneAccountHandle) - .setCallSubject(subject) - .build(); + .setCallSubject(subject)); - getSystemService(TelecomManager.class).placeCall(intent.getData(), intent.getExtras()); mSubjectHistory.add(subject); saveSubjectHistory(mSubjectHistory); finish(); diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index 089ffd389..3087a1768 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -121,6 +121,7 @@ import com.android.dialer.p13n.logging.P13nLogger; import com.android.dialer.p13n.logging.P13nLogging; import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; +import com.android.dialer.precall.PreCall; import com.android.dialer.proguard.UsedByReflection; import com.android.dialer.searchfragment.list.NewSearchFragment; import com.android.dialer.searchfragment.list.NewSearchFragment.SearchFragmentListener; @@ -1515,14 +1516,12 @@ public class DialtactsActivity extends TransactionSafeActivity // an error message. phoneNumber = ""; } - - Intent intent = + PreCall.start( + this, new CallIntentBuilder(phoneNumber, callSpecificAppData) .setIsVideoCall(isVideoCall) - .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()) - .build(); + .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing())); - DialerUtils.startActivityWithErrorToast(this, intent); mClearSearchOnPause = true; } diff --git a/java/com/android/dialer/app/calllog/IntentProvider.java b/java/com/android/dialer/app/calllog/IntentProvider.java index 5180651da..0835d894c 100644 --- a/java/com/android/dialer/app/calllog/IntentProvider.java +++ b/java/com/android/dialer/app/calllog/IntentProvider.java @@ -32,6 +32,7 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.duo.DuoComponent; +import com.android.dialer.precall.PreCall; import com.android.dialer.util.IntentUtil; import java.util.ArrayList; @@ -53,9 +54,10 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) - .setPhoneAccountHandle(accountHandle) - .build(); + return PreCall.getIntent( + context, + new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) + .setPhoneAccountHandle(accountHandle)); } }; } @@ -65,9 +67,10 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) - .setAllowAssistedDial(true) - .build(); + return PreCall.getIntent( + context, + new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) + .setAllowAssistedDial(true)); } }; } @@ -81,10 +84,11 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) - .setPhoneAccountHandle(accountHandle) - .setIsVideoCall(true) - .build(); + return PreCall.getIntent( + context, + new CallIntentBuilder(number, CallInitiationType.Type.CALL_LOG) + .setPhoneAccountHandle(accountHandle) + .setIsVideoCall(true)); } }; } @@ -103,8 +107,9 @@ public abstract class IntentProvider { return new IntentProvider() { @Override public Intent getIntent(Context context) { - return CallIntentBuilder.forVoicemail(phoneAccountHandle, CallInitiationType.Type.CALL_LOG) - .build(); + return PreCall.getIntent( + context, + CallIntentBuilder.forVoicemail(phoneAccountHandle, CallInitiationType.Type.CALL_LOG)); } }; } diff --git a/java/com/android/dialer/app/calllog/MissedCallNotifier.java b/java/com/android/dialer/app/calllog/MissedCallNotifier.java index 8e09cf8df..dd92bb4e2 100644 --- a/java/com/android/dialer/app/calllog/MissedCallNotifier.java +++ b/java/com/android/dialer/app/calllog/MissedCallNotifier.java @@ -60,6 +60,7 @@ import com.android.dialer.notification.NotificationChannelId; import com.android.dialer.notification.NotificationManagerUtils; import com.android.dialer.phonenumbercache.ContactInfo; import com.android.dialer.phonenumberutil.PhoneNumberHelper; +import com.android.dialer.precall.PreCall; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; import java.util.Iterator; @@ -438,8 +439,9 @@ public class MissedCallNotifier implements Worker, Void> { cancelSingleMissedCallNotification(context, callUri); DialerUtils.startActivityWithErrorToast( context, - new CallIntentBuilder(number, CallInitiationType.Type.MISSED_CALL_NOTIFICATION) - .build() + PreCall.getIntent( + context, + new CallIntentBuilder(number, CallInitiationType.Type.MISSED_CALL_NOTIFICATION)) .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java index 7cc6cda45..be7dccda8 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java @@ -31,6 +31,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.PerAccountSharedPreferences; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.precall.PreCall; import com.android.dialer.voicemail.settings.VoicemailChangePinActivity; import com.android.voicemail.VoicemailClient; import com.android.voicemail.VoicemailComponent; @@ -165,10 +166,10 @@ public class VoicemailErrorMessage { @Override public void onClick(View v) { Logger.get(context).logImpression(DialerImpression.Type.VVM_CALL_VOICEMAIL_CLICKED); - context.startActivity( + PreCall.start( + context, CallIntentBuilder.forVoicemail( - phoneAccountHandle, CallInitiationType.Type.VOICEMAIL_ERROR_MESSAGE) - .build()); + phoneAccountHandle, CallInitiationType.Type.VOICEMAIL_ERROR_MESSAGE)); } }); } diff --git a/java/com/android/dialer/callcomposer/CallComposerActivity.java b/java/com/android/dialer/callcomposer/CallComposerActivity.java index cd0c74124..0d47c7007 100644 --- a/java/com/android/dialer/callcomposer/CallComposerActivity.java +++ b/java/com/android/dialer/callcomposer/CallComposerActivity.java @@ -72,6 +72,7 @@ import com.android.dialer.enrichedcall.extensions.StateExtension; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.multimedia.MultimediaData; +import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; import com.android.dialer.storage.StorageComponent; import com.android.dialer.telecom.TelecomUtil; @@ -479,9 +480,8 @@ public class CallComposerActivity extends AppCompatActivity } private void placeTelecomCall() { - TelecomUtil.placeCall( - this, - new CallIntentBuilder(contact.getNumber(), CallInitiationType.Type.CALL_COMPOSER).build()); + PreCall.start( + this, new CallIntentBuilder(contact.getNumber(), CallInitiationType.Type.CALL_COMPOSER)); setResult(RESULT_OK); finish(); } diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java index 6ba31e624..7a117a3f1 100644 --- a/java/com/android/dialer/calldetails/CallDetailsActivity.java +++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java @@ -50,8 +50,8 @@ import com.android.dialer.logging.Logger; import com.android.dialer.logging.UiAction; import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; +import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; -import com.android.dialer.util.DialerUtils; import java.util.Collections; import java.util.List; import java.util.Map; @@ -209,11 +209,10 @@ public class CallDetailsActivity extends AppCompatActivity @Override public void placeImsVideoCall(String phoneNumber) { Logger.get(this).logImpression(DialerImpression.Type.CALL_DETAILS_IMS_VIDEO_CALL_BACK); - DialerUtils.startActivityWithErrorToast( + PreCall.start( this, new CallIntentBuilder(phoneNumber, CallInitiationType.Type.CALL_DETAILS) - .setIsVideoCall(true) - .build()); + .setIsVideoCall(true)); } @Override @@ -244,7 +243,7 @@ public class CallDetailsActivity extends AppCompatActivity callIntentBuilder.setAllowAssistedDial(true); } - DialerUtils.startActivityWithErrorToast(this, callIntentBuilder.build()); + PreCall.start(this, callIntentBuilder); } @NonNull diff --git a/java/com/android/dialer/callintent/CallIntentBuilder.java b/java/com/android/dialer/callintent/CallIntentBuilder.java index aabeabdc8..ff490c296 100644 --- a/java/com/android/dialer/callintent/CallIntentBuilder.java +++ b/java/com/android/dialer/callintent/CallIntentBuilder.java @@ -172,6 +172,11 @@ public class CallIntentBuilder implements Parcelable { return outgoingCallExtras; } + /** + * @deprecated Use {@link com.android.dialer.precall.PreCall#getIntent(android.content.Context, + * CallIntentBuilder)} instead. + */ + @Deprecated public Intent build() { Intent intent = new Intent(Intent.ACTION_CALL, uri); diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java index 9ddb65df4..16147f604 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java @@ -138,7 +138,7 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder { private void setOnClickListenerForRow(CoalescedRow row) { itemView.setOnClickListener( (view) -> { - Intent callbackIntent = CallLogIntents.getCallBackIntent(row); + Intent callbackIntent = CallLogIntents.getCallBackIntent(context, row); if (callbackIntent != null) { context.startActivity(callbackIntent); } diff --git a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java index 7077d0231..404c41787 100644 --- a/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java +++ b/java/com/android/dialer/calllog/ui/menu/PrimaryAction.java @@ -42,7 +42,7 @@ final class PrimaryAction { .build()) .setPrimaryText(CallLogEntryText.buildPrimaryText(context, row)) .setSecondaryText(CallLogEntryText.buildSecondaryTextForBottomSheet(context, row)) - .setIntent(CallLogIntents.getCallBackIntent(row)) + .setIntent(CallLogIntents.getCallBackIntent(context, row)) .build(); } } diff --git a/java/com/android/dialer/calllogutils/CallLogIntents.java b/java/com/android/dialer/calllogutils/CallLogIntents.java index 11308e607..b06fe6e93 100644 --- a/java/com/android/dialer/calllogutils/CallLogIntents.java +++ b/java/com/android/dialer/calllogutils/CallLogIntents.java @@ -15,6 +15,7 @@ */ package com.android.dialer.calllogutils; +import android.content.Context; import android.content.Intent; import android.provider.CallLog.Calls; import android.support.annotation.Nullable; @@ -22,6 +23,7 @@ import android.text.TextUtils; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.calllog.model.CoalescedRow; +import com.android.dialer.precall.PreCall; /** Provides intents related to call log entries. */ public final class CallLogIntents { @@ -35,10 +37,9 @@ public final class CallLogIntents { * @return null if the provided {@code row} doesn't have a number */ @Nullable - public static Intent getCallBackIntent(CoalescedRow row) { + public static Intent getCallBackIntent(Context context, CoalescedRow row) { // TODO(zachh): Do something with parsed values to make more dialable? String originalNumber = row.number().getRawInput().getNumber(); - // TODO(zachh): Make this more sophisticated, e.g. return null for non-dialable numbers? if (TextUtils.isEmpty(originalNumber)) { return null; @@ -46,10 +47,11 @@ public final class CallLogIntents { // TODO(zachh): More granular logging? // TODO(zachh): Support assisted dialing. - return new CallIntentBuilder(originalNumber, CallInitiationType.Type.CALL_LOG) - .setPhoneAccountHandle( - PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId())) - .setIsVideoCall((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO) - .build(); + return PreCall.getIntent( + context, + new CallIntentBuilder(originalNumber, CallInitiationType.Type.CALL_LOG) + .setPhoneAccountHandle( + PhoneAccountUtils.getAccount(row.phoneAccountComponentName(), row.phoneAccountId())) + .setIsVideoCall((row.features() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO)); } } diff --git a/java/com/android/dialer/contactactions/IntentModule.java b/java/com/android/dialer/contactactions/IntentModule.java index 5a4870cbe..57eb50a9b 100644 --- a/java/com/android/dialer/contactactions/IntentModule.java +++ b/java/com/android/dialer/contactactions/IntentModule.java @@ -24,6 +24,7 @@ import android.support.annotation.StringRes; import android.telecom.PhoneAccountHandle; import com.android.dialer.callintent.CallInitiationType.Type; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.precall.PreCall; /** * {@link ContactActionModule} useful for making easy to build modules based on starting an intent. @@ -66,9 +67,10 @@ public class IntentModule implements ContactActionModule { // TODO(zachh): Support post-dial digits; consider using DialerPhoneNumber. return new IntentModule( context, - new CallIntentBuilder(number, initiationType) - .setPhoneAccountHandle(phoneAccountHandle) - .build(), + PreCall.getIntent( + context, + new CallIntentBuilder(number, initiationType) + .setPhoneAccountHandle(phoneAccountHandle)), R.string.call, R.drawable.quantum_ic_call_white_24); } @@ -81,10 +83,11 @@ public class IntentModule implements ContactActionModule { // TODO(zachh): Support post-dial digits; consider using DialerPhoneNumber. return new IntentModule( context, - new CallIntentBuilder(number, initiationType) - .setPhoneAccountHandle(phoneAccountHandle) - .setIsVideoCall(true) - .build(), + PreCall.getIntent( + context, + new CallIntentBuilder(number, initiationType) + .setPhoneAccountHandle(phoneAccountHandle) + .setIsVideoCall(true)), R.string.video_call, R.drawable.quantum_ic_videocam_white_24); } diff --git a/java/com/android/dialer/dialpadview/DialpadFragment.java b/java/com/android/dialer/dialpadview/DialpadFragment.java index 659d120b1..e85b57e33 100644 --- a/java/com/android/dialer/dialpadview/DialpadFragment.java +++ b/java/com/android/dialer/dialpadview/DialpadFragment.java @@ -83,10 +83,10 @@ import com.android.dialer.location.GeoUtil; import com.android.dialer.logging.UiAction; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.performancereport.PerformanceReport; +import com.android.dialer.precall.PreCall; import com.android.dialer.proguard.UsedByReflection; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.CallUtil; -import com.android.dialer.util.DialerUtils; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.widget.FloatingActionButtonController; import java.util.HashSet; @@ -997,9 +997,8 @@ public class DialpadFragment extends Fragment } public void callVoicemail() { - DialerUtils.startActivityWithErrorToast( - getActivity(), - CallIntentBuilder.forVoicemail(null, CallInitiationType.Type.DIALPAD).build()); + PreCall.start( + getContext(), CallIntentBuilder.forVoicemail(null, CallInitiationType.Type.DIALPAD)); hideAndClearDialpad(); } @@ -1049,9 +1048,7 @@ public class DialpadFragment extends Fragment // Clear the digits just in case. clearDialpad(); } else { - final Intent intent = - new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD).build(); - DialerUtils.startActivityWithErrorToast(getActivity(), intent); + PreCall.start(getContext(), new CallIntentBuilder(number, CallInitiationType.Type.DIALPAD)); hideAndClearDialpad(); } } diff --git a/java/com/android/dialer/interactions/PhoneNumberInteraction.java b/java/com/android/dialer/interactions/PhoneNumberInteraction.java index 255f6c380..15c6ce899 100644 --- a/java/com/android/dialer/interactions/PhoneNumberInteraction.java +++ b/java/com/android/dialer/interactions/PhoneNumberInteraction.java @@ -60,6 +60,7 @@ import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.logging.InteractionEvent; import com.android.dialer.logging.Logger; +import com.android.dialer.precall.PreCall; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.PermissionsUtil; import com.android.dialer.util.TransactionSafeActivity; @@ -183,10 +184,11 @@ public class PhoneNumberInteraction implements OnLoadCompleteListener { break; default: intent = - new CallIntentBuilder(phoneNumber, callSpecificAppData) - .setIsVideoCall(isVideoCall) - .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing()) - .build(); + PreCall.getIntent( + context, + new CallIntentBuilder(phoneNumber, callSpecificAppData) + .setIsVideoCall(isVideoCall) + .setAllowAssistedDial(callSpecificAppData.getAllowAssistedDialing())); break; } DialerUtils.startActivityWithErrorToast(context, intent); @@ -224,7 +226,7 @@ public class PhoneNumberInteraction implements OnLoadCompleteListener { // crash when the user tries to use such a shortcut, check for this condition and ask the user // for the permission. if (!PermissionsUtil.hasPhonePermissions(mContext)) { - LogUtil.i("PhoneNumberInteraction.startInteraction", "Need phone permissions: CALL_PHONE"); + LogUtil.i("PhoneNumberInteraction.startInteraction", "Need phone permission: CALL_PHONE"); ActivityCompat.requestPermissions( (Activity) mContext, new String[] {permission.CALL_PHONE}, REQUEST_CALL_PHONE); return; diff --git a/java/com/android/dialer/precall/PreCall.java b/java/com/android/dialer/precall/PreCall.java index 93fd8e9b6..4f021f142 100644 --- a/java/com/android/dialer/precall/PreCall.java +++ b/java/com/android/dialer/precall/PreCall.java @@ -21,6 +21,7 @@ import android.content.Intent; import android.support.annotation.MainThread; import android.support.annotation.NonNull; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.util.DialerUtils; import com.google.common.collect.ImmutableList; /** Interface to prepare a {@link CallIntentBuilder} before placing the call with telecom. */ @@ -41,4 +42,12 @@ public interface PreCall { @NonNull @MainThread Intent buildIntent(Context context, CallIntentBuilder builder); + + static Intent getIntent(Context context, CallIntentBuilder builder) { + return PreCallComponent.get(context).getPreCall().buildIntent(context, builder); + } + + static void start(Context context, CallIntentBuilder builder) { + DialerUtils.startActivityWithErrorToast(context, getIntent(context, builder)); + } } diff --git a/java/com/android/dialer/precall/PreCallCoordinator.java b/java/com/android/dialer/precall/PreCallCoordinator.java index b5e9e8594..40b909a51 100644 --- a/java/com/android/dialer/precall/PreCallCoordinator.java +++ b/java/com/android/dialer/precall/PreCallCoordinator.java @@ -19,6 +19,7 @@ package com.android.dialer.precall; import android.app.Activity; import android.support.annotation.MainThread; import android.support.annotation.NonNull; +import android.support.annotation.VisibleForTesting; import com.android.dialer.callintent.CallIntentBuilder; /** @@ -27,6 +28,8 @@ import com.android.dialer.callintent.CallIntentBuilder; */ public interface PreCallCoordinator { + @VisibleForTesting public String EXTRA_CALL_INTENT_BUILDER = "extra_call_intent_builder"; + @NonNull CallIntentBuilder getBuilder(); diff --git a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java index 25083ef0b..6302a2395 100644 --- a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java +++ b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java @@ -38,8 +38,6 @@ public class PreCallCoordinatorImpl implements PreCallCoordinator { private static final String SAVED_STATE_CURRENT_ACTION = "current_action"; - static final String EXTRA_CALL_INTENT_BUILDER = "extra_call_intent_builder"; - @NonNull private final Activity activity; private CallIntentBuilder builder; diff --git a/java/com/android/dialer/precall/impl/PreCallImpl.java b/java/com/android/dialer/precall/impl/PreCallImpl.java index fc2eff8b1..21c5dc9e2 100644 --- a/java/com/android/dialer/precall/impl/PreCallImpl.java +++ b/java/com/android/dialer/precall/impl/PreCallImpl.java @@ -22,6 +22,7 @@ import android.support.annotation.NonNull; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.precall.PreCall; import com.android.dialer.precall.PreCallAction; +import com.android.dialer.precall.PreCallCoordinator; import com.google.common.collect.ImmutableList; import javax.inject.Inject; @@ -40,7 +41,7 @@ public class PreCallImpl implements PreCall { @Override public Intent buildIntent(Context context, CallIntentBuilder builder) { Intent intent = new Intent(context, PreCallActivity.class); - intent.putExtra(PreCallCoordinatorImpl.EXTRA_CALL_INTENT_BUILDER, builder); + intent.putExtra(PreCallCoordinator.EXTRA_CALL_INTENT_BUILDER, builder); return intent; } } diff --git a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java index c0a6700eb..e797a0390 100644 --- a/java/com/android/dialer/searchfragment/list/NewSearchFragment.java +++ b/java/com/android/dialer/searchfragment/list/NewSearchFragment.java @@ -58,6 +58,7 @@ import com.android.dialer.enrichedcall.EnrichedCallComponent; import com.android.dialer.enrichedcall.EnrichedCallManager.CapabilitiesListener; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.precall.PreCall; import com.android.dialer.searchfragment.common.RowClickListener; import com.android.dialer.searchfragment.common.SearchCursor; import com.android.dialer.searchfragment.cp2.SearchContactsCursorLoader; @@ -483,12 +484,11 @@ public final class NewSearchFragment extends Fragment .setCharactersInSearchString(query == null ? 0 : query.length()) .setAllowAssistedDialing(allowAssistedDial) .build(); - Intent intent = + PreCall.start( + getContext(), new CallIntentBuilder(phoneNumber, callSpecificAppData) .setIsVideoCall(isVideoCall) - .setAllowAssistedDial(allowAssistedDial) - .build(); - DialerUtils.startActivityWithErrorToast(getActivity(), intent); + .setAllowAssistedDial(allowAssistedDial)); FragmentUtils.getParentUnsafe(this, SearchFragmentListener.class).onCallPlaced(); } diff --git a/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java b/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java index 62e5c72b0..b557a8259 100644 --- a/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java +++ b/java/com/android/dialer/searchfragment/list/SearchActionViewHolder.java @@ -31,6 +31,7 @@ import com.android.dialer.callintent.CallSpecificAppData; import com.android.dialer.common.Assert; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; +import com.android.dialer.precall.PreCall; import com.android.dialer.util.DialerUtils; import com.android.dialer.util.IntentUtil; import java.lang.annotation.Retention; @@ -128,8 +129,8 @@ final class SearchActionViewHolder extends RecyclerView.ViewHolder implements On .setPositionOfSelectedSearchResult(position) .setCharactersInSearchString(query.length()) .build(); - intent = new CallIntentBuilder(query, callSpecificAppData).setIsVideoCall(true).build(); - DialerUtils.startActivityWithErrorToast(context, intent); + PreCall.start( + context, new CallIntentBuilder(query, callSpecificAppData).setIsVideoCall(true)); break; case Action.SEND_SMS: diff --git a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java index 2e1fd5e9d..f15b236dd 100644 --- a/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java +++ b/java/com/android/dialer/searchfragment/nearbyplaces/NearbyPlaceViewHolder.java @@ -29,11 +29,11 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.contactphoto.ContactPhotoManager; import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.precall.PreCall; import com.android.dialer.searchfragment.common.Projections; import com.android.dialer.searchfragment.common.QueryBoldingUtil; import com.android.dialer.searchfragment.common.R; import com.android.dialer.searchfragment.common.SearchCursor; -import com.android.dialer.telecom.TelecomUtil; /** ViewHolder for a nearby place row. */ public final class NearbyPlaceViewHolder extends RecyclerView.ViewHolder @@ -93,7 +93,6 @@ public final class NearbyPlaceViewHolder extends RecyclerView.ViewHolder @Override public void onClick(View v) { - TelecomUtil.placeCall( - context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH).build()); + PreCall.start(context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH)); } } diff --git a/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java b/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java index 339855fbb..9d369003d 100644 --- a/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java +++ b/java/com/android/dialer/searchfragment/remote/RemoteContactViewHolder.java @@ -32,11 +32,11 @@ import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.contactphoto.ContactPhotoManager; import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.precall.PreCall; import com.android.dialer.searchfragment.common.Projections; import com.android.dialer.searchfragment.common.QueryBoldingUtil; import com.android.dialer.searchfragment.common.R; import com.android.dialer.searchfragment.common.SearchCursor; -import com.android.dialer.telecom.TelecomUtil; /** ViewHolder for a nearby place row. */ public final class RemoteContactViewHolder extends RecyclerView.ViewHolder @@ -132,7 +132,6 @@ public final class RemoteContactViewHolder extends RecyclerView.ViewHolder @Override public void onClick(View v) { - TelecomUtil.placeCall( - context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH).build()); + PreCall.start(context, new CallIntentBuilder(number, CallInitiationType.Type.REGULAR_SEARCH)); } } diff --git a/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java b/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java index 526d45ed7..099450ae8 100644 --- a/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java +++ b/java/com/android/incallui/disconnectdialog/VideoCallNotAvailablePrompt.java @@ -19,7 +19,6 @@ package com.android.incallui.disconnectdialog; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; -import android.content.Intent; import android.support.annotation.NonNull; import android.telecom.DisconnectCause; import android.telecom.PhoneAccountHandle; @@ -28,7 +27,7 @@ import com.android.contacts.common.compat.telecom.TelecomManagerCompat; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.LogUtil; -import com.android.dialer.util.DialerUtils; +import com.android.dialer.precall.PreCall; import com.android.incallui.call.DialerCall; /** Prompt user to make voice call if video call is not currently available. */ @@ -67,10 +66,9 @@ public class VideoCallNotAvailablePrompt implements DisconnectDialog { private void makeVoiceCall(Context context, String number, PhoneAccountHandle accountHandle) { LogUtil.enterBlock("VideoCallNotAvailablePrompt.makeVoiceCall"); - Intent intent = + PreCall.start( + context, new CallIntentBuilder(number, CallInitiationType.Type.IMS_VIDEO_BLOCKED_FALLBACK_TO_VOICE) - .setPhoneAccountHandle(accountHandle) - .build(); - DialerUtils.startActivityWithErrorToast(context, intent); + .setPhoneAccountHandle(accountHandle)); } } diff --git a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java index 2f8dc7ad8..3608c3602 100644 --- a/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java +++ b/java/com/android/voicemail/impl/sms/LegacyModeSmsHandler.java @@ -28,6 +28,7 @@ import android.telephony.TelephonyManager; import android.telephony.VisualVoicemailSms; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.precall.PreCall; import com.android.voicemail.VoicemailClient; import com.android.voicemail.impl.OmtpConstants; import com.android.voicemail.impl.OmtpVvmCarrierConfigHelper; @@ -94,9 +95,10 @@ public class LegacyModeSmsHandler { PendingIntent.getActivity( context, CALL_VOICEMAIL_REQUEST_CODE, - CallIntentBuilder.forVoicemail( - phoneAccountHandle, CallInitiationType.Type.LEGACY_VOICEMAIL_NOTIFICATION) - .build(), + PreCall.getIntent( + context, + CallIntentBuilder.forVoicemail( + phoneAccountHandle, CallInitiationType.Type.LEGACY_VOICEMAIL_NOTIFICATION)), PendingIntent.FLAG_UPDATE_CURRENT); } else { Intent launchVoicemailSettingsIntent = -- cgit v1.2.3 From 9b3342f3b61d149c16ec2573148def3baaf094a5 Mon Sep 17 00:00:00 2001 From: zachh Date: Tue, 7 Nov 2017 18:12:18 -0800 Subject: Added temporary logging to debug problem with null phone numbers from remote contacts. Bug: 68942044 Test: none PiperOrigin-RevId: 174944384 Change-Id: Ie03ce41e517cfb73081231898a7e9dcc3feee2f2 --- .../dialer/searchfragment/list/SearchAdapter.java | 36 ++++++++++++++++++++++ .../remote/RemoteDirectoriesCursorLoader.java | 17 ++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/java/com/android/dialer/searchfragment/list/SearchAdapter.java b/java/com/android/dialer/searchfragment/list/SearchAdapter.java index dc78953b5..cc090ac47 100644 --- a/java/com/android/dialer/searchfragment/list/SearchAdapter.java +++ b/java/com/android/dialer/searchfragment/list/SearchAdapter.java @@ -17,6 +17,7 @@ package com.android.dialer.searchfragment.list; import android.content.Context; +import android.database.Cursor; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; @@ -26,12 +27,15 @@ import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; +import com.android.dialer.searchfragment.common.Projections; import com.android.dialer.searchfragment.common.RowClickListener; import com.android.dialer.searchfragment.common.SearchCursor; import com.android.dialer.searchfragment.cp2.SearchContactViewHolder; import com.android.dialer.searchfragment.list.SearchCursorManager.RowType; import com.android.dialer.searchfragment.nearbyplaces.NearbyPlaceViewHolder; import com.android.dialer.searchfragment.remote.RemoteContactViewHolder; +import com.android.dialer.searchfragment.remote.RemoteDirectoriesCursorLoader; import java.util.List; /** RecyclerView adapter for {@link NewSearchFragment}. */ @@ -99,6 +103,23 @@ public final class SearchAdapter extends RecyclerView.Adapter { } else if (holder instanceof NearbyPlaceViewHolder) { ((NearbyPlaceViewHolder) holder).bind(searchCursorManager.getCursor(position), query); } else if (holder instanceof RemoteContactViewHolder) { + Cursor cursor = searchCursorManager.getCursor(position); + // Temporary logging to identify cause of a bug: + if (cursor.getString(Projections.PHONE_NUMBER) == null) { + LogUtil.e( + "SearchAdapter.onBindViewHolder", "cursor class: %s", cursor.getClass().getName()); + LogUtil.e("SearchAdapter.onBindViewHolder", "position: %d", position); + LogUtil.e( + "SearchAdapter.onBindViewHolder", + "query length: %s", + query == null ? "null" : query.length()); + logDirectories(); + LogUtil.e( + "SearchAdapter.onBindViewHolder", + "directory id: %d", + ((SearchCursor) cursor).getDirectoryId()); + throw new IllegalStateException("Null phone number reading remote contact"); + } ((RemoteContactViewHolder) holder).bind(searchCursorManager.getCursor(position), query); } else if (holder instanceof HeaderViewHolder) { String header = @@ -114,6 +135,21 @@ public final class SearchAdapter extends RecyclerView.Adapter { } } + private void logDirectories() { + try (Cursor directories = new RemoteDirectoriesCursorLoader(context).loadInBackground()) { + if (directories.moveToFirst()) { + do { + LogUtil.e( + "SearchAdapter.logDirectories", + "directory: %s", + RemoteDirectoriesCursorLoader.readDirectory(directories)); + } while (directories.moveToNext()); + } else { + LogUtil.e("SearchAdapter.logDirectories", "no directories found"); + } + } + } + public void setContactsCursor(SearchCursor cursor) { if (searchCursorManager.setContactsCursor(cursor)) { // Since this is a new contacts cursor, we need to reapply the filter. diff --git a/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java b/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java index de71025cd..3d16c4351 100644 --- a/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java +++ b/java/com/android/dialer/searchfragment/remote/RemoteDirectoriesCursorLoader.java @@ -36,12 +36,14 @@ public final class RemoteDirectoriesCursorLoader extends CursorLoader { private static final int DISPLAY_NAME = 1; private static final int PHOTO_SUPPORT = 2; + private static final int AUTHORITY = 3; @VisibleForTesting static final String[] PROJECTION = { ContactsContract.Directory._ID, ContactsContract.Directory.DISPLAY_NAME, ContactsContract.Directory.PHOTO_SUPPORT, + ContactsContract.Directory.DIRECTORY_AUTHORITY, }; public RemoteDirectoriesCursorLoader(Context context) { @@ -51,7 +53,10 @@ public final class RemoteDirectoriesCursorLoader extends CursorLoader { /** @return current cursor row represented as a {@link Directory}. */ public static Directory readDirectory(Cursor cursor) { return Directory.create( - cursor.getInt(ID), cursor.getString(DISPLAY_NAME), cursor.getInt(PHOTO_SUPPORT) != 0); + cursor.getInt(ID), + cursor.getString(DISPLAY_NAME), + cursor.getInt(PHOTO_SUPPORT) != 0, + cursor.getString(AUTHORITY)); } private static Uri getContentUri() { @@ -63,8 +68,14 @@ public final class RemoteDirectoriesCursorLoader extends CursorLoader { /** POJO representing the results returned from {@link RemoteDirectoriesCursorLoader}. */ @AutoValue public abstract static class Directory { + public static Directory create( + int id, @Nullable String displayName, boolean supportsPhotos, @Nullable String authority) { + return new AutoValue_RemoteDirectoriesCursorLoader_Directory( + id, displayName, supportsPhotos, authority); + } + public static Directory create(int id, @Nullable String displayName, boolean supportsPhotos) { - return new AutoValue_RemoteDirectoriesCursorLoader_Directory(id, displayName, supportsPhotos); + return create(id, displayName, supportsPhotos, null); } public abstract int getId(); @@ -73,5 +84,7 @@ public final class RemoteDirectoriesCursorLoader extends CursorLoader { abstract @Nullable String getDisplayName(); abstract boolean supportsPhotos(); + + abstract @Nullable String authority(); } } -- cgit v1.2.3 From b7dba5aaa8c477d97121fc6e3411332e66cbabe8 Mon Sep 17 00:00:00 2001 From: Android Dialer Date: Tue, 7 Nov 2017 21:22:15 -0800 Subject: Expose tab index to protected Bug: 68840377 Test: manual verify no regression from inconsistently showing promo PiperOrigin-RevId: 174957368 Change-Id: I0ed4fa1b24e693e91705744f60a7a385385cec64 --- java/com/android/dialer/app/DialtactsActivity.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/com/android/dialer/app/DialtactsActivity.java b/java/com/android/dialer/app/DialtactsActivity.java index 3087a1768..4c2634184 100644 --- a/java/com/android/dialer/app/DialtactsActivity.java +++ b/java/com/android/dialer/app/DialtactsActivity.java @@ -1554,6 +1554,7 @@ public class DialtactsActivity extends TransactionSafeActivity if (tabIndex != mPreviouslySelectedTabIndex) { mFloatingActionButtonController.scaleIn(); } + LogUtil.i("DialtactsActivity.onPageSelected", "tabIndex: %d", tabIndex); mPreviouslySelectedTabIndex = tabIndex; timeTabSelected = SystemClock.elapsedRealtime(); } @@ -1675,6 +1676,10 @@ public class DialtactsActivity extends TransactionSafeActivity exitSearchUi(); } + protected int getPreviouslySelectedTabIndex() { + return mPreviouslySelectedTabIndex; + } + /** Popup menu accessible from the search bar */ protected class OptionsPopupMenu extends PopupMenu { -- cgit v1.2.3