diff options
Diffstat (limited to 'java/com/android/incallui')
-rw-r--r-- | java/com/android/incallui/ActiveCallsCallListListener.java | 4 | ||||
-rw-r--r-- | java/com/android/incallui/InCallActivity.java | 84 | ||||
-rw-r--r-- | java/com/android/incallui/InCallPresenter.java | 5 | ||||
-rw-r--r-- | java/com/android/incallui/ReturnToCallController.java | 33 | ||||
-rw-r--r-- | java/com/android/incallui/call/DialerCall.java | 34 | ||||
-rw-r--r-- | java/com/android/incallui/callconfiguration/call_configuration.proto (renamed from java/com/android/incallui/call_configuration.proto) | 0 | ||||
-rw-r--r-- | java/com/android/incallui/rtt/impl/RttChatAdapter.java | 5 | ||||
-rw-r--r-- | java/com/android/incallui/rtt/impl/RttChatMessageViewHolder.java | 1 | ||||
-rw-r--r-- | java/com/android/incallui/rtt/impl/res/values/strings.xml | 4 | ||||
-rw-r--r-- | java/com/android/incallui/rtt/protocol/RttChatMessage.java (renamed from java/com/android/incallui/rtt/impl/RttChatMessage.java) | 39 |
10 files changed, 122 insertions, 87 deletions
diff --git a/java/com/android/incallui/ActiveCallsCallListListener.java b/java/com/android/incallui/ActiveCallsCallListListener.java index 3e4cb9375..d94db8836 100644 --- a/java/com/android/incallui/ActiveCallsCallListListener.java +++ b/java/com/android/incallui/ActiveCallsCallListListener.java @@ -49,10 +49,10 @@ public class ActiveCallsCallListListener implements CallList.Listener { public void onCallListChange(CallList callList) { ImmutableList.Builder<ActiveCallInfo> activeCalls = ImmutableList.builder(); for (DialerCall call : callList.getAllCalls()) { - if (call.getState() != DialerCallState.DISCONNECTED) { + if (call.getState() != DialerCallState.DISCONNECTED && call.getAccountHandle() != null) { activeCalls.add( ActiveCallInfo.builder() - .setPhoneAccountHandle(Optional.fromNullable(call.getAccountHandle())) + .setPhoneAccountHandle(Optional.of(call.getAccountHandle())) .build()); } } diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 0f0e9d9f2..5ac6b5029 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -55,8 +55,6 @@ import android.view.animation.AnimationUtils; import android.widget.CheckBox; import android.widget.Toast; import com.android.contacts.common.widget.SelectPhoneAccountDialogFragment; -import com.android.contacts.common.widget.SelectPhoneAccountDialogOptions; -import com.android.contacts.common.widget.SelectPhoneAccountDialogOptionsUtil; import com.android.dialer.animation.AnimUtils; import com.android.dialer.animation.AnimationListenerAdapter; import com.android.dialer.common.Assert; @@ -65,7 +63,6 @@ import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.common.concurrent.UiListener; import com.android.dialer.configprovider.ConfigProviderBindings; -import com.android.dialer.logging.DialerImpression.Type; import com.android.dialer.logging.Logger; import com.android.dialer.logging.ScreenEvent; import com.android.dialer.metrics.Metrics; @@ -73,7 +70,7 @@ import com.android.dialer.metrics.MetricsComponent; 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.PreferredSimComponent; import com.android.dialer.util.ViewUtil; import com.android.incallui.answer.bindings.AnswerBindings; import com.android.incallui.answer.protocol.AnswerScreen; @@ -365,79 +362,44 @@ public class InCallActivity extends TransactionSafeFragmentActivity return false; } - ListenableFuture<PreferredAccountWorker.Result> preferredAccountFuture = - DialerExecutorComponent.get(this) - .backgroundExecutor() - .submit( - () -> { - try { - return new PreferredAccountWorker(waitingForAccountCall.getNumber()) - .doInBackground(getApplicationContext()); - } catch (Throwable throwable) { - throw new Exception(throwable); - } - }); + PreferredAccountWorker preferredAccountWorker = + PreferredSimComponent.get(this).preferredAccountWorker(); + + Bundle extras = waitingForAccountCall.getIntentExtras(); + List<PhoneAccountHandle> phoneAccountHandles = + extras == null + ? new ArrayList<>() + : extras.getParcelableArrayList(Call.AVAILABLE_PHONE_ACCOUNTS); + ListenableFuture<PreferredAccountWorker.Result> preferredAccountFuture = + preferredAccountWorker.selectAccount( + waitingForAccountCall.getNumber(), phoneAccountHandles); preferredAccountWorkerResultListener.listen( this, preferredAccountFuture, result -> { - if (result.getPhoneAccountHandle().isPresent()) { - Logger.get(this).logImpression(Type.DUAL_SIM_SELECTION_PREFERRED_USED); - selectPhoneAccountListener.onPhoneAccountSelected( - result.getPhoneAccountHandle().get(), false, waitingForAccountCall.getId()); + if (!isVisible()) { + LogUtil.i( + "CallingAccountSelector.showPhoneAccountSelectionDialog", + "activity ended before result returned"); return; } - if (result.getSuggestion().isPresent()) { - LogUtil.i( - "CallingAccountSelector.processPreferredAccount", - "SIM suggested: " + result.getSuggestion().get().reason); - if (result.getSuggestion().get().shouldAutoSelect) { - Logger.get(this).logImpression(Type.DUAL_SIM_SELECTION_SUGGESTION_AUTO_SELECTED); - LogUtil.i( - "CallingAccountSelector.processPreferredAccount", "Auto selected suggestion"); - selectPhoneAccountListener.onPhoneAccountSelected( - result.getSuggestion().get().phoneAccountHandle, - false, - waitingForAccountCall.getId()); - return; - } + String callId = waitingForAccountCall.getId(); + if (result.getSelectedPhoneAccountHandle().isPresent()) { + selectPhoneAccountListener.onPhoneAccountSelected( + result.getSelectedPhoneAccountHandle().get(), false, callId); + return; } - Bundle extras = waitingForAccountCall.getIntentExtras(); - List<PhoneAccountHandle> phoneAccountHandles = - extras == null - ? new ArrayList<>() - : extras.getParcelableArrayList(Call.AVAILABLE_PHONE_ACCOUNTS); waitingForAccountCall.setPreferredAccountRecorder( new PreferredAccountRecorder( waitingForAccountCall.getNumber(), result.getSuggestion().orNull(), result.getDataId().orNull())); - SelectPhoneAccountDialogOptions.Builder optionsBuilder = - SelectPhoneAccountDialogOptions.newBuilder() - .setTitle(R.string.select_phone_account_for_calls) - .setCanSetDefault(result.getDataId().isPresent()) - .setSetDefaultLabel(R.string.select_phone_account_for_calls_remember) - .setCallId(waitingForAccountCall.getId()); - - for (PhoneAccountHandle phoneAccountHandle : phoneAccountHandles) { - SelectPhoneAccountDialogOptions.Entry.Builder entryBuilder = - SelectPhoneAccountDialogOptions.Entry.newBuilder(); - SelectPhoneAccountDialogOptionsUtil.setPhoneAccountHandle( - entryBuilder, phoneAccountHandle); - Optional<String> hint = - SuggestionProvider.getHint( - this, phoneAccountHandle, result.getSuggestion().orNull()); - if (hint.isPresent()) { - entryBuilder.setHint(hint.get()); - } - optionsBuilder.addEntries(entryBuilder); - } - selectPhoneAccountDialogFragment = SelectPhoneAccountDialogFragment.newInstance( - optionsBuilder.build(), selectPhoneAccountListener); + result.getDialogOptionsBuilder().get().setCallId(callId).build(), + selectPhoneAccountListener); selectPhoneAccountDialogFragment.show(getFragmentManager(), Tags.SELECT_ACCOUNT_FRAGMENT); }, throwable -> { diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 8193c6e05..ccc564806 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -414,7 +414,7 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud * Return whether we should start call in bubble mode and not show InCallActivity. The call mode * should be set in CallConfiguration in EXTRA_OUTGOING_CALL_EXTRAS when starting a call intent. */ - private boolean shouldStartInBubbleMode() { + public boolean shouldStartInBubbleMode() { if (!ReturnToCallController.isEnabled(context)) { return false; } @@ -427,6 +427,9 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud if (dialerCall == null) { return false; } + if (dialerCall.isEmergencyCall()) { + return false; + } Bundle extras = dialerCall.getIntentExtras(); boolean result = shouldStartInBubbleModeWithExtras(extras); diff --git a/java/com/android/incallui/ReturnToCallController.java b/java/com/android/incallui/ReturnToCallController.java index 4a7b3fbce..96bdda1ba 100644 --- a/java/com/android/incallui/ReturnToCallController.java +++ b/java/com/android/incallui/ReturnToCallController.java @@ -37,6 +37,7 @@ import com.android.dialer.lettertile.LetterTileDrawable; import com.android.dialer.telecom.TelecomUtil; import com.android.incallui.ContactInfoCache.ContactCacheEntry; import com.android.incallui.ContactInfoCache.ContactInfoCacheCallback; +import com.android.incallui.InCallPresenter.InCallState; import com.android.incallui.InCallPresenter.InCallUiListener; import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.audiomode.AudioModeProvider.AudioModeListener; @@ -77,6 +78,8 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio private final ContactInfoCache contactInfoCache; + private InCallState inCallState; + public static boolean isEnabled(Context context) { return ConfigProviderBindings.get(context).getBoolean("enable_return_to_call_bubble_v2", false); } @@ -186,7 +189,19 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio return; } - if ((bubble == null || !(bubble.isVisible() || bubble.isDismissed())) + boolean shouldStartInBubbleMode = InCallPresenter.getInstance().shouldStartInBubbleMode(); + InCallState newInCallState = + InCallPresenter.getInstance().getPotentialStateFromCallList(callList); + boolean isNewBackgroundCall = + newInCallState != inCallState + && newInCallState == InCallState.OUTGOING + && shouldStartInBubbleMode; + if (bubble != null && isNewBackgroundCall) { + // If new outgoing call is in bubble mode, update bubble info. + // We don't update if new call is not in bubble mode even if the existing call is. + bubble.setBubbleInfo(generateBubbleInfoForBackgroundCalling()); + } + if ((bubble == null || !(bubble.isVisible() || bubble.isDismissed()) || isNewBackgroundCall) && getCall() != null && !InCallPresenter.getInstance().isShowingInCallUi()) { LogUtil.i("ReturnToCallController.onCallListChange", "going to show bubble"); @@ -195,6 +210,7 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio // The call to display might be different for the existing bubble startContactInfoSearch(); } + inCallState = newInCallState; } @Override @@ -274,7 +290,20 @@ public class ReturnToCallController implements InCallUiListener, Listener, Audio .setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null)) .setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call)) .setStartingYPosition( - context.getResources().getDimensionPixelOffset(R.dimen.return_to_call_initial_offset_y)) + InCallPresenter.getInstance().shouldStartInBubbleMode() + ? context.getResources().getDisplayMetrics().heightPixels / 2 + : context + .getResources() + .getDimensionPixelOffset(R.dimen.return_to_call_initial_offset_y)) + .setActions(generateActions()) + .build(); + } + + private BubbleInfo generateBubbleInfoForBackgroundCalling() { + return BubbleInfo.builder() + .setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null)) + .setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call)) + .setStartingYPosition(context.getResources().getDisplayMetrics().heightPixels / 2) .setActions(generateActions()) .build(); } diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index d57de15e5..1c2744644 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -83,6 +83,7 @@ import com.android.dialer.util.PermissionsUtil; import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.call.state.DialerCallState; import com.android.incallui.latencyreport.LatencyReport; +import com.android.incallui.rtt.protocol.RttChatMessage; import com.android.incallui.speakeasy.runtime.Constraints; import com.android.incallui.videotech.VideoTech; import com.android.incallui.videotech.VideoTech.VideoTechListener; @@ -92,6 +93,7 @@ import com.android.incallui.videotech.ims.ImsVideoTech; import com.android.incallui.videotech.utils.VideoUtils; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.MoreExecutors; +import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -1084,6 +1086,32 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa getTelecomCall().respondToRttRequest(rttRequestId, accept); } + @TargetApi(28) + private void saveRttTranscript() { + if (!BuildCompat.isAtLeastP()) { + return; + } + // Save any remaining text in the buffer that's not shown by UI yet. + // This may happen when the call is switched to background before disconnect. + try { + String messageLeft = getRttCall().readImmediately(); + if (!TextUtils.isEmpty(messageLeft)) { + rttTranscript = + RttChatMessage.getRttTranscriptWithNewRemoteMessage(rttTranscript, messageLeft); + } + } catch (IOException e) { + LogUtil.e("DialerCall.saveRttTranscript", "error when reading remaining message", e); + } + // Don't save transcript if it's empty. + if (rttTranscript.getMessagesCount() == 0) { + return; + } + Futures.addCallback( + RttTranscriptUtil.saveRttTranscript(context, rttTranscript), + new DefaultFutureCallback<>(), + MoreExecutors.directExecutor()); + } + public boolean hasReceivedVideoUpgradeRequest() { return VideoUtils.hasReceivedVideoUpgradeRequest(getVideoTech().getSessionModificationState()); } @@ -1615,11 +1643,9 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa videoTechManager.dispatchRemovedFromCallList(); } // TODO(a bug): Add tests for it to make sure no crash on subsequent call to this method. + // TODO(wangqi): Consider moving this to a DialerCallListener. if (rttTranscript != null && !isCallRemoved) { - Futures.addCallback( - RttTranscriptUtil.saveRttTranscript(context, rttTranscript), - new DefaultFutureCallback<>(), - MoreExecutors.directExecutor()); + saveRttTranscript(); } isCallRemoved = true; } diff --git a/java/com/android/incallui/call_configuration.proto b/java/com/android/incallui/callconfiguration/call_configuration.proto index 2cf3c065c..2cf3c065c 100644 --- a/java/com/android/incallui/call_configuration.proto +++ b/java/com/android/incallui/callconfiguration/call_configuration.proto diff --git a/java/com/android/incallui/rtt/impl/RttChatAdapter.java b/java/com/android/incallui/rtt/impl/RttChatAdapter.java index f1cde759c..160377889 100644 --- a/java/com/android/incallui/rtt/impl/RttChatAdapter.java +++ b/java/com/android/incallui/rtt/impl/RttChatAdapter.java @@ -29,6 +29,7 @@ import android.view.ViewGroup; import com.android.dialer.common.LogUtil; import com.android.dialer.rtt.RttTranscript; import com.android.dialer.rtt.RttTranscriptMessage; +import com.android.incallui.rtt.protocol.RttChatMessage; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -133,13 +134,13 @@ public class RttChatAdapter extends RecyclerView.Adapter<ViewHolder> { rttChatMessage.append(newMessage); rttMessages.add(rttChatMessage); lastIndexOfLocalMessage = rttMessages.size() - 1; - notifyItemInserted(lastIndexOfLocalMessage); + notifyItemInserted(toItemPosition(lastIndexOfLocalMessage)); } else { rttChatMessage.append(newMessage); // Clear empty message bubble. if (TextUtils.isEmpty(rttChatMessage.getContent())) { rttMessages.remove(lastIndexOfLocalMessage); - notifyItemRemoved(lastIndexOfLocalMessage); + notifyItemRemoved(toItemPosition(lastIndexOfLocalMessage)); lastIndexOfLocalMessage = -1; } else { notifyItemChanged(toItemPosition(lastIndexOfLocalMessage)); diff --git a/java/com/android/incallui/rtt/impl/RttChatMessageViewHolder.java b/java/com/android/incallui/rtt/impl/RttChatMessageViewHolder.java index 2beea9530..56161eccc 100644 --- a/java/com/android/incallui/rtt/impl/RttChatMessageViewHolder.java +++ b/java/com/android/incallui/rtt/impl/RttChatMessageViewHolder.java @@ -25,6 +25,7 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; +import com.android.incallui.rtt.protocol.RttChatMessage; /** ViewHolder class for RTT chat message bubble. */ public class RttChatMessageViewHolder extends ViewHolder { diff --git a/java/com/android/incallui/rtt/impl/res/values/strings.xml b/java/com/android/incallui/rtt/impl/res/values/strings.xml index 462eea563..fc60eceed 100644 --- a/java/com/android/incallui/rtt/impl/res/values/strings.xml +++ b/java/com/android/incallui/rtt/impl/res/values/strings.xml @@ -31,6 +31,6 @@ <string name="rtt_status_banner_text">Waiting for <xliff:g id="name">%s</xliff:g> to join RTT call…</string> <!-- Text for RTT transcript advisory. [CHAR LIMIT=NONE] --> - <string name="rtt_transcript_advisory">The other party can see you typing. Transcripts stored on your device in the call history.</string> + <string name="rtt_transcript_advisory">The other party can see you typing. Transcripts are stored on your device in the call history.</string> -</resources>
\ No newline at end of file +</resources> diff --git a/java/com/android/incallui/rtt/impl/RttChatMessage.java b/java/com/android/incallui/rtt/protocol/RttChatMessage.java index 2f3933a50..5680529ee 100644 --- a/java/com/android/incallui/rtt/impl/RttChatMessage.java +++ b/java/com/android/incallui/rtt/protocol/RttChatMessage.java @@ -14,25 +14,24 @@ * limitations under the License */ -package com.android.incallui.rtt.impl; +package com.android.incallui.rtt.protocol; import android.support.annotation.NonNull; import com.android.dialer.common.Assert; import com.android.dialer.rtt.RttTranscript; import com.android.dialer.rtt.RttTranscriptMessage; -import com.android.incallui.rtt.protocol.Constants; import com.google.common.base.Splitter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** Message class that holds one RTT chat content. */ -final class RttChatMessage { +public final class RttChatMessage { private static final Splitter SPLITTER = Splitter.on(Constants.BUBBLE_BREAKER); - boolean isRemote; - long timstamp; + public boolean isRemote; + private long timstamp; private final StringBuilder content = new StringBuilder(); private boolean isFinished; @@ -44,7 +43,7 @@ final class RttChatMessage { isFinished = true; } - void unfinish() { + public void unfinish() { isFinished = false; } @@ -74,7 +73,7 @@ final class RttChatMessage { * * <p>"hello world" -> "hello new world" : "\b\b\b\b\bnew world" */ - static String computeChangedString(String oldMessage, String newMesssage) { + public static String computeChangedString(String oldMessage, String newMesssage) { StringBuilder modify = new StringBuilder(); int indexChangeStart = 0; while (indexChangeStart < oldMessage.length() @@ -91,8 +90,21 @@ final class RttChatMessage { return modify.toString(); } + public static RttTranscript getRttTranscriptWithNewRemoteMessage( + RttTranscript rttTranscript, @NonNull String text) { + List<RttChatMessage> messageList = fromTranscript(rttTranscript); + updateRemoteRttChatMessage(messageList, text); + return RttTranscript.newBuilder() + .setId(rttTranscript.getId()) + .setNumber(rttTranscript.getNumber()) + .setTimestamp(rttTranscript.getTimestamp()) + .addAllMessages(toTranscriptMessageList(messageList)) + .build(); + } + /** Update list of {@code RttChatMessage} based on given remote text. */ - static void updateRemoteRttChatMessage(List<RttChatMessage> messageList, @NonNull String text) { + public static void updateRemoteRttChatMessage( + List<RttChatMessage> messageList, @NonNull String text) { Assert.isNotNull(messageList); Iterator<String> splitText = SPLITTER.split(text).iterator(); @@ -163,7 +175,7 @@ final class RttChatMessage { return i; } - static int getLastIndexRemoteMessage(List<RttChatMessage> messageList) { + public static int getLastIndexRemoteMessage(List<RttChatMessage> messageList) { int i = messageList.size() - 1; while (i >= 0 && !messageList.get(i).isRemote) { i--; @@ -171,7 +183,7 @@ final class RttChatMessage { return i; } - static int getLastIndexLocalMessage(List<RttChatMessage> messageList) { + public static int getLastIndexLocalMessage(List<RttChatMessage> messageList) { int i = messageList.size() - 1; while (i >= 0 && messageList.get(i).isRemote) { i--; @@ -179,7 +191,8 @@ final class RttChatMessage { return i; } - static List<RttTranscriptMessage> toTranscriptMessageList(List<RttChatMessage> messageList) { + public static List<RttTranscriptMessage> toTranscriptMessageList( + List<RttChatMessage> messageList) { List<RttTranscriptMessage> transcriptMessageList = new ArrayList<>(); for (RttChatMessage message : messageList) { transcriptMessageList.add( @@ -193,7 +206,7 @@ final class RttChatMessage { return transcriptMessageList; } - static List<RttChatMessage> fromTranscript(RttTranscript rttTranscript) { + public static List<RttChatMessage> fromTranscript(RttTranscript rttTranscript) { List<RttChatMessage> messageList = new ArrayList<>(); if (rttTranscript == null) { return messageList; @@ -211,7 +224,7 @@ final class RttChatMessage { return messageList; } - RttChatMessage() { + public RttChatMessage() { timstamp = System.currentTimeMillis(); } } |