From 56f79ba6c6608f7041f5e65866b7164499ca7676 Mon Sep 17 00:00:00 2001 From: twyen Date: Mon, 30 Apr 2018 14:25:46 -0700 Subject: Refactor PreferredAccountWorker to provide the dialog to be shown. When dual SIM selection support is added to In Call UI it was a rush order and codes are duplicated. This CL moves the duplicated logic into PreferredAccountWorker so the same dialog can be shown for both. TEST=manual Bug: 69675796,72618783 Test: manual PiperOrigin-RevId: 194845320 Change-Id: Id283ca7616580b0efd4e8f02e63691c70ee7f93c --- .../android/dialer/precall/PreCallCoordinator.java | 7 + .../precall/impl/CallingAccountSelector.java | 266 ++++----------------- .../precall/impl/PreCallCoordinatorImpl.java | 25 ++ .../android/dialer/precall/impl/PreCallModule.java | 5 +- .../dialer/precall/impl/res/values/strings.xml | 13 - 5 files changed, 88 insertions(+), 228 deletions(-) (limited to 'java/com/android/dialer/precall') diff --git a/java/com/android/dialer/precall/PreCallCoordinator.java b/java/com/android/dialer/precall/PreCallCoordinator.java index cb3221afd..9c24e0d69 100644 --- a/java/com/android/dialer/precall/PreCallCoordinator.java +++ b/java/com/android/dialer/precall/PreCallCoordinator.java @@ -21,6 +21,8 @@ import android.support.annotation.MainThread; import android.support.annotation.NonNull; import android.support.annotation.VisibleForTesting; import com.android.dialer.callintent.CallIntentBuilder; +import com.android.dialer.function.Consumer; +import com.google.common.util.concurrent.ListenableFuture; /** * Runs {@link PreCallAction} one by one to prepare a {@link @@ -65,4 +67,9 @@ public interface PreCallCoordinator { @MainThread @NonNull PendingAction startPendingAction(); + + void listen( + ListenableFuture future, + Consumer successListener, + Consumer failureListener); } diff --git a/java/com/android/dialer/precall/impl/CallingAccountSelector.java b/java/com/android/dialer/precall/impl/CallingAccountSelector.java index 8f63fa0db..b22e4d973 100644 --- a/java/com/android/dialer/precall/impl/CallingAccountSelector.java +++ b/java/com/android/dialer/precall/impl/CallingAccountSelector.java @@ -29,13 +29,9 @@ import android.telephony.PhoneNumberUtils; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment.SelectPhoneAccountListener; import com.android.contacts.common.widget.SelectPhoneAccountDialogOptions; -import com.android.contacts.common.widget.SelectPhoneAccountDialogOptionsUtil; -import com.android.dialer.activecalls.ActiveCallInfo; -import com.android.dialer.activecalls.ActiveCallsComponent; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; -import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.logging.DialerImpression.Type; import com.android.dialer.logging.Logger; @@ -44,13 +40,10 @@ import com.android.dialer.precall.PreCallCoordinator; import com.android.dialer.precall.PreCallCoordinator.PendingAction; import com.android.dialer.preferredsim.PreferredAccountRecorder; import com.android.dialer.preferredsim.PreferredAccountWorker; -import com.android.dialer.preferredsim.PreferredAccountWorker.Result; import com.android.dialer.preferredsim.suggestion.SuggestionProvider; import com.android.dialer.preferredsim.suggestion.SuggestionProvider.Suggestion; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableList; import java.util.List; -import java.util.Objects; +import javax.inject.Inject; /** PreCallAction to select which phone account to call with. Ignored if there's only one account */ @SuppressWarnings("MissingPermission") @@ -62,6 +55,13 @@ public class CallingAccountSelector implements PreCallAction { private boolean isDiscarding; + private final PreferredAccountWorker preferredAccountWorker; + + @Inject + CallingAccountSelector(PreferredAccountWorker preferredAccountWorker) { + this.preferredAccountWorker = preferredAccountWorker; + } + @Override public boolean requiresUi(Context context, CallIntentBuilder builder) { if (!ConfigProviderBindings.get(context) @@ -97,7 +97,13 @@ public class CallingAccountSelector implements PreCallAction { } switch (builder.getUri().getScheme()) { case PhoneAccount.SCHEME_VOICEMAIL: - showDialog(coordinator, coordinator.startPendingAction(), null, null, null); + showDialog( + coordinator, + coordinator.startPendingAction(), + preferredAccountWorker.getVoicemailDialogOptions(), + null, + null, + null); Logger.get(coordinator.getActivity()).logImpression(Type.DUAL_SIM_SELECTION_VOICEMAIL); break; case PhoneAccount.SCHEME_TEL: @@ -120,224 +126,58 @@ public class CallingAccountSelector implements PreCallAction { Activity activity = coordinator.getActivity(); String phoneNumber = builder.getUri().getSchemeSpecificPart(); PendingAction pendingAction = coordinator.startPendingAction(); - DialerExecutorComponent.get(coordinator.getActivity()) - .dialerExecutorFactory() - .createNonUiTaskBuilder(new PreferredAccountWorker(phoneNumber)) - .onSuccess( - (result -> { - if (isDiscarding) { - return; - } - if (result.getPhoneAccountHandle().isPresent()) { - usePreferredAccount(coordinator, pendingAction, result); - return; - } - PhoneAccountHandle defaultPhoneAccount = - activity - .getSystemService(TelecomManager.class) - .getDefaultOutgoingPhoneAccount(builder.getUri().getScheme()); - if (defaultPhoneAccount != null) { - useDefaultAccount(coordinator, pendingAction, result, defaultPhoneAccount); - return; - } - if (result.getSuggestion().isPresent()) { - LogUtil.i( - "CallingAccountSelector.processPreferredAccount", - "SIM suggested: " + result.getSuggestion().get().reason); - if (result.getSuggestion().get().shouldAutoSelect) { - useSuggestedAccount(coordinator, pendingAction, result); - return; - } - } - showDialog( - coordinator, - pendingAction, - result.getDataId().orNull(), - phoneNumber, - result.getSuggestion().orNull()); - })) - .build() - .executeParallel(activity); - } - private void usePreferredAccount( - PreCallCoordinator coordinator, PendingAction pendingAction, Result result) { - String phoneNumber = coordinator.getBuilder().getUri().getSchemeSpecificPart(); - if (isSelectable(coordinator.getActivity(), result.getPhoneAccountHandle().get())) { - Logger.get(coordinator.getActivity()).logImpression(Type.DUAL_SIM_SELECTION_PREFERRED_USED); - coordinator.getBuilder().setPhoneAccountHandle(result.getPhoneAccountHandle().get()); - pendingAction.finish(); - } else { - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_PREFERRED_NOT_SELECTABLE); - LogUtil.i("CallingAccountSelector.usePreferredAccount", "preferred account not selectable"); - showDialog( - coordinator, - pendingAction, - result.getDataId().orNull(), - phoneNumber, - result.getSuggestion().orNull()); - } - } - - private void useDefaultAccount( - PreCallCoordinator coordinator, - PendingAction pendingAction, - Result result, - PhoneAccountHandle defaultPhoneAccount) { - CallIntentBuilder builder = coordinator.getBuilder(); - String phoneNumber = builder.getUri().getSchemeSpecificPart(); - if (isSelectable(coordinator.getActivity(), defaultPhoneAccount)) { - Logger.get(coordinator.getActivity()).logImpression(Type.DUAL_SIM_SELECTION_GLOBAL_USED); - builder.setPhoneAccountHandle(defaultPhoneAccount); - pendingAction.finish(); - } else { - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_GLOBAL_NOT_SELECTABLE); - LogUtil.i("CallingAccountSelector.useDefaultAccount", "default account not selectable"); - showDialog( - coordinator, - pendingAction, - result.getDataId().orNull(), - phoneNumber, - result.getSuggestion().orNull()); - } - } - - private void useSuggestedAccount( - PreCallCoordinator coordinator, PendingAction pendingAction, Result result) { - CallIntentBuilder builder = coordinator.getBuilder(); - String phoneNumber = builder.getUri().getSchemeSpecificPart(); - if (isSelectable(coordinator.getActivity(), result.getSuggestion().get().phoneAccountHandle)) { - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_SUGGESTION_AUTO_SELECTED); - LogUtil.i("CallingAccountSelector.processPreferredAccount", "Auto selected suggestion"); - builder.setPhoneAccountHandle(result.getSuggestion().get().phoneAccountHandle); - builder - .getInCallUiIntentExtras() - .putString( - SuggestionProvider.EXTRA_SIM_SUGGESTION_REASON, - result.getSuggestion().get().reason.name()); - pendingAction.finish(); - } else { - LogUtil.i("CallingAccountSelector.useSuggestedAccount", "suggested account not selectable"); - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_SUGGESTION_AUTO_NOT_SELECTABLE); - showDialog( - coordinator, - pendingAction, - result.getDataId().orNull(), - phoneNumber, - result.getSuggestion().orNull()); - } - } - - /** - * Most devices are DSDS (dual SIM dual standby) which only one SIM can have active calls at a - * time. TODO(twyen): support other dual SIM modes when the API is exposed. - */ - private static boolean isSelectable(Context context, PhoneAccountHandle phoneAccountHandle) { - ImmutableList activeCalls = - ActiveCallsComponent.get(context).activeCalls().getActiveCalls(); - if (activeCalls.isEmpty()) { - return true; - } - for (ActiveCallInfo activeCall : activeCalls) { - if (Objects.equals(phoneAccountHandle, activeCall.phoneAccountHandle().orNull())) { - return true; - } - } - return false; - } - - private static Optional getActiveCallLabel(Context context) { - ImmutableList activeCalls = - ActiveCallsComponent.get(context).activeCalls().getActiveCalls(); - - if (activeCalls.isEmpty()) { - LogUtil.e("CallingAccountSelector.getActiveCallLabel", "active calls no longer exist"); - return Optional.absent(); - } - ActiveCallInfo activeCall = activeCalls.get(0); - if (!activeCall.phoneAccountHandle().isPresent()) { - LogUtil.e("CallingAccountSelector.getActiveCallLabel", "active call has no phone account"); - return Optional.absent(); - } - PhoneAccount phoneAccount = - context - .getSystemService(TelecomManager.class) - .getPhoneAccount(activeCall.phoneAccountHandle().get()); - if (phoneAccount == null) { - LogUtil.e("CallingAccountSelector.getActiveCallLabel", "phone account not found"); - return Optional.absent(); - } - return Optional.of(phoneAccount.getLabel().toString()); + coordinator.listen( + preferredAccountWorker.selectAccount( + phoneNumber, + activity.getSystemService(TelecomManager.class).getCallCapablePhoneAccounts()), + result -> { + if (result.getSelectedPhoneAccountHandle().isPresent()) { + + if (result.getSuggestion().isPresent() + && result + .getSelectedPhoneAccountHandle() + .get() + .equals(result.getSuggestion().get().phoneAccountHandle)) { + builder + .getInCallUiIntentExtras() + .putString( + SuggestionProvider.EXTRA_SIM_SUGGESTION_REASON, + result.getSuggestion().get().reason.name()); + } + + coordinator + .getBuilder() + .setPhoneAccountHandle(result.getSelectedPhoneAccountHandle().get()); + pendingAction.finish(); + return; + } + showDialog( + coordinator, + pendingAction, + result.getDialogOptionsBuilder().get().build(), + result.getDataId().orNull(), + phoneNumber, + result.getSuggestion().orNull()); + }, + (throwable) -> { + throw new RuntimeException(throwable); + }); } @MainThread private void showDialog( PreCallCoordinator coordinator, PendingAction pendingAction, + SelectPhoneAccountDialogOptions dialogOptions, @Nullable String dataId, @Nullable String number, @Nullable Suggestion suggestion) { Assert.isMainThread(); - Logger.get(coordinator.getActivity()).logImpression(Type.DUAL_SIM_SELECTION_SHOWN); - if (dataId != null) { - Logger.get(coordinator.getActivity()).logImpression(Type.DUAL_SIM_SELECTION_IN_CONTACTS); - } - if (suggestion != null) { - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_SUGGESTION_AVAILABLE); - switch (suggestion.reason) { - case INTRA_CARRIER: - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_SUGGESTED_CARRIER); - break; - case FREQUENT: - Logger.get(coordinator.getActivity()) - .logImpression(Type.DUAL_SIM_SELECTION_SUGGESTED_FREQUENCY); - break; - default: - } - } - SelectPhoneAccountDialogOptions.Builder optionsBuilder = - SelectPhoneAccountDialogOptions.newBuilder() - .setTitle(R.string.pre_call_select_phone_account) - .setCanSetDefault(dataId != null) - .setSetDefaultLabel(R.string.pre_call_select_phone_account_remember); - for (PhoneAccountHandle phoneAccountHandle : - coordinator - .getActivity() - .getSystemService(TelecomManager.class) - .getCallCapablePhoneAccounts()) { - SelectPhoneAccountDialogOptions.Entry.Builder entryBuilder = - SelectPhoneAccountDialogOptions.Entry.newBuilder(); - SelectPhoneAccountDialogOptionsUtil.setPhoneAccountHandle(entryBuilder, phoneAccountHandle); - if (isSelectable(coordinator.getActivity(), phoneAccountHandle)) { - Optional hint = - SuggestionProvider.getHint(coordinator.getActivity(), phoneAccountHandle, suggestion); - if (hint.isPresent()) { - entryBuilder.setHint(hint.get()); - } - } else { - entryBuilder.setEnabled(false); - Optional activeCallLabel = getActiveCallLabel(coordinator.getActivity()); - if (activeCallLabel.isPresent()) { - entryBuilder.setHint( - coordinator - .getActivity() - .getString( - R.string.pre_call_select_phone_account_hint_other_sim_in_use, - activeCallLabel.get())); - } - } - optionsBuilder.addEntries(entryBuilder); - } selectPhoneAccountDialogFragment = SelectPhoneAccountDialogFragment.newInstance( - optionsBuilder.build(), + dialogOptions, new SelectedListener( coordinator, pendingAction, diff --git a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java index 36af62245..f2ff0e3e3 100644 --- a/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java +++ b/java/com/android/dialer/precall/impl/PreCallCoordinatorImpl.java @@ -24,6 +24,9 @@ import android.support.annotation.Nullable; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.common.concurrent.UiListener; +import com.android.dialer.function.Consumer; import com.android.dialer.logging.DialerImpression.Type; import com.android.dialer.logging.Logger; import com.android.dialer.precall.PreCallAction; @@ -31,6 +34,9 @@ import com.android.dialer.precall.PreCallComponent; import com.android.dialer.precall.PreCallCoordinator; import com.android.dialer.telecom.TelecomUtil; import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; /** * Implements {@link PreCallCoordinator}. Listens to the life cycle of {@link PreCallActivity} to @@ -49,6 +55,8 @@ public class PreCallCoordinatorImpl implements PreCallCoordinator { private PendingAction pendingAction; private boolean aborted = false; + private UiListener uiListener; + PreCallCoordinatorImpl(@NonNull Activity activity) { this.activity = Assert.isNotNull(activity); } @@ -61,6 +69,9 @@ public class PreCallCoordinatorImpl implements PreCallCoordinator { } else { builder = Assert.isNotNull(intent.getParcelableExtra(EXTRA_CALL_INTENT_BUILDER)); } + uiListener = + DialerExecutorComponent.get(activity) + .createUiListener(activity.getFragmentManager(), "PreCallCoordinatorImpl.uiListener"); } void onRestoreInstanceState(Bundle savedInstanceState) { @@ -152,4 +163,18 @@ public class PreCallCoordinatorImpl implements PreCallCoordinator { onActionFinished(); } } + + @SuppressWarnings("unchecked") + @Override + public void listen( + ListenableFuture future, + Consumer successListener, + Consumer failureListener) { + + uiListener.listen( + activity, + Futures.transform(future, (output) -> (Object) output, MoreExecutors.directExecutor()), + output -> successListener.accept((OutputT) output), + failureListener::accept); + } } diff --git a/java/com/android/dialer/precall/impl/PreCallModule.java b/java/com/android/dialer/precall/impl/PreCallModule.java index 4643b1976..9820e2b66 100644 --- a/java/com/android/dialer/precall/impl/PreCallModule.java +++ b/java/com/android/dialer/precall/impl/PreCallModule.java @@ -36,12 +36,13 @@ public abstract class PreCallModule { @Provides @Singleton - public static ImmutableList provideActions() { + public static ImmutableList provideActions( + CallingAccountSelector callingAccountSelector) { return ImmutableList.of( new PermissionCheckAction(), new MalformedNumberRectifier( ImmutableList.of(new UkRegionPrefixInInternationalFormatHandler())), - new CallingAccountSelector(), + callingAccountSelector, new AssistedDialAction()); } } diff --git a/java/com/android/dialer/precall/impl/res/values/strings.xml b/java/com/android/dialer/precall/impl/res/values/strings.xml index 5e7ddd36c..a920f0720 100644 --- a/java/com/android/dialer/precall/impl/res/values/strings.xml +++ b/java/com/android/dialer/precall/impl/res/values/strings.xml @@ -17,17 +17,4 @@ Cannot make call without phone permission - - - Choose SIM for this call - - - Remember this choice - - - Not available while using %1$s \ No newline at end of file -- cgit v1.2.3