diff options
author | erfanian <erfanian@google.com> | 2018-04-04 18:03:17 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2018-04-04 18:03:17 -0700 |
commit | 49c91b2d6c64cd9c30e52cded91fe2122e7cdde8 (patch) | |
tree | 42d357cb4cc1cc7f33bfe803dbdbc5d4129ce819 | |
parent | 29c7c5e1f564e9e9ed55797866d0d5b64499c55c (diff) | |
parent | 241f73a4f72fc3f25f36b033b0c43f1933bad378 (diff) |
Merge changes If1ae5505,I65e9c6ac,I1a72ca86,I417b46ed,I60f97924 am: 9f14cd7ee2
am: 241f73a4f7
Change-Id: I8d357ee51154541497d7dacb143d335473a9fa17
11 files changed, 199 insertions, 72 deletions
diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java index e316f66b5..e0a69ca85 100644 --- a/java/com/android/dialer/calllog/ui/menu/Modules.java +++ b/java/com/android/dialer/calllog/ui/menu/Modules.java @@ -18,6 +18,7 @@ package com.android.dialer.calllog.ui.menu; import android.content.Context; import android.provider.CallLog.Calls; +import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import com.android.dialer.blockreportspam.BlockReportSpamDialogInfo; @@ -123,10 +124,21 @@ final class Modules { return Collections.emptyList(); } - List<HistoryItemActionModule> modules = new ArrayList<>(); + boolean isDuoCall = + DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME + .flattenToString() + .equals(row.getPhoneAccountComponentName()); + + // Obtain a PhoneAccountHandle that will be used to start carrier voice/video calls. + // If the row is for a Duo call, we should use the default phone account as the one included in + // the row is for Duo only. PhoneAccountHandle phoneAccountHandle = - TelecomUtil.composePhoneAccountHandle( - row.getPhoneAccountComponentName(), row.getPhoneAccountId()); + isDuoCall + ? TelecomUtil.getDefaultOutgoingPhoneAccount(context, PhoneAccount.SCHEME_TEL) + : TelecomUtil.composePhoneAccountHandle( + row.getPhoneAccountComponentName(), row.getPhoneAccountId()); + + List<HistoryItemActionModule> modules = new ArrayList<>(); // Add an audio call item modules.add( @@ -136,10 +148,6 @@ final class Modules { // Add a video item if (1) the call log entry is for a video call, and (2) the call is not spam. if ((row.getFeatures() & Calls.FEATURES_VIDEO) == Calls.FEATURES_VIDEO && !row.getNumberAttributes().getIsSpam()) { - boolean isDuoCall = - DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME - .flattenToString() - .equals(row.getPhoneAccountComponentName()); modules.add( isDuoCall ? new DuoCallModule(context, normalizedNumber, CallInitiationType.Type.CALL_LOG) diff --git a/java/com/android/dialer/rtt/rtt_transcript.proto b/java/com/android/dialer/rtt/rtt_transcript.proto new file mode 100644 index 000000000..a580b0d2f --- /dev/null +++ b/java/com/android/dialer/rtt/rtt_transcript.proto @@ -0,0 +1,30 @@ +syntax = "proto2"; + +option java_package = "com.android.dialer.rtt"; +option java_multiple_files = true; +option optimize_for = LITE_RUNTIME; + + +package com.android.dialer.rtt; + +// RTT transcript which contains chat history of a RTT call. +message RttTranscript { + // Unique ID used for database. + optional string id = 1; + // Phone number of RTT call. + optional string number = 2; + // Timestamp when the RTT call is created. + optional int64 timestamp = 3; + // Chat messages. + repeated RttTranscriptMessage messages = 4; +} + +// Single chat message inside a RTT call. +message RttTranscriptMessage { + optional string content = 1; + optional int64 timestamp = 2; + // Whether this message is sent from local device or received from remote + // party. + optional bool is_remote = 3; + optional bool is_finished = 4; +}
\ No newline at end of file diff --git a/java/com/android/dialer/widget/ContactPhotoView.java b/java/com/android/dialer/widget/ContactPhotoView.java index 6fcc89ab0..5020875dc 100644 --- a/java/com/android/dialer/widget/ContactPhotoView.java +++ b/java/com/android/dialer/widget/ContactPhotoView.java @@ -86,12 +86,15 @@ public final class ContactPhotoView extends FrameLayout { private void setBadge(PhotoInfo photoInfo) { // No badge for spam numbers. if (photoInfo.getIsSpam()) { + hideBadge(); return; } if (photoInfo.getIsVideo()) { contactBadgeContainer.setVisibility(View.VISIBLE); videoCallBadge.setVisibility(View.VISIBLE); + } else { + hideBadge(); } } } diff --git a/java/com/android/incallui/CallButtonPresenter.java b/java/com/android/incallui/CallButtonPresenter.java index 833460398..7e05badfe 100644 --- a/java/com/android/incallui/CallButtonPresenter.java +++ b/java/com/android/incallui/CallButtonPresenter.java @@ -42,6 +42,7 @@ import com.android.incallui.audiomode.AudioModeProvider.AudioModeListener; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCall.CameraDirection; +import com.android.incallui.call.DialerCall.State; import com.android.incallui.call.TelecomAdapter; import com.android.incallui.incall.protocol.InCallButtonIds; import com.android.incallui.incall.protocol.InCallButtonUi; @@ -480,6 +481,7 @@ public class CallButtonPresenter && InCallPresenter.getInstance().getCallList().getAllCalls().size() == 1; boolean showUpgradeToRtt = call.canUpgradeToRttCall(); + boolean enableUpgradeToRtt = showUpgradeToRtt && call.getState() == State.ACTIVE; inCallButtonUi.showButton(InCallButtonIds.BUTTON_AUDIO, true); inCallButtonUi.showButton(InCallButtonIds.BUTTON_SWAP, showSwap); @@ -491,6 +493,7 @@ public class CallButtonPresenter inCallButtonUi.enableButton(InCallButtonIds.BUTTON_ADD_CALL, showAddCall); inCallButtonUi.showButton(InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO, showUpgradeToVideo); inCallButtonUi.showButton(InCallButtonIds.BUTTON_UPGRADE_TO_RTT, showUpgradeToRtt); + inCallButtonUi.enableButton(InCallButtonIds.BUTTON_UPGRADE_TO_RTT, enableUpgradeToRtt); inCallButtonUi.showButton(InCallButtonIds.BUTTON_DOWNGRADE_TO_AUDIO, showDowngradeToAudio); inCallButtonUi.showButton( InCallButtonIds.BUTTON_SWITCH_CAMERA, diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 65ef323fe..44d8667ca 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -151,6 +151,7 @@ public class InCallActivity extends TransactionSafeFragmentActivity private boolean didShowVideoCallScreen; private boolean didShowRttCallScreen; private boolean didShowSpeakEasyScreen; + private String lastShownSpeakEasyScreenUniqueCallid = ""; private boolean dismissKeyguard; private boolean isInShowMainInCallFragment; private boolean isRecreating; // whether the activity is going to be recreated @@ -1353,15 +1354,18 @@ public class InCallActivity extends TransactionSafeFragmentActivity private boolean showSpeakEasyFragment(FragmentTransaction transaction, DialerCall call) { - // TODO(erfanian): Support multiple speakeasy screens. if (didShowSpeakEasyScreen) { - return false; + if (lastShownSpeakEasyScreenUniqueCallid.equals(call.getUniqueCallId())) { + return false; + } + hideSpeakEasyFragment(transaction); } Optional<Fragment> speakEasyFragment = speakEasyCallManager.getSpeakEasyFragment(call); if (speakEasyFragment.isPresent()) { transaction.add(R.id.main, speakEasyFragment.get(), Tags.SPEAK_EASY_SCREEN); didShowSpeakEasyScreen = true; + lastShownSpeakEasyScreenUniqueCallid = call.getUniqueCallId(); return true; } return false; diff --git a/java/com/android/incallui/RttCallPresenter.java b/java/com/android/incallui/RttCallPresenter.java index 939c9d00b..5e8390793 100644 --- a/java/com/android/incallui/RttCallPresenter.java +++ b/java/com/android/incallui/RttCallPresenter.java @@ -23,6 +23,7 @@ import android.os.Looper; import android.telecom.Call.RttCall; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.ThreadUtil; +import com.android.dialer.rtt.RttTranscript; import com.android.incallui.InCallPresenter.InCallState; import com.android.incallui.InCallPresenter.InCallStateListener; import com.android.incallui.call.CallList; @@ -62,6 +63,10 @@ public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListe LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiReady"); InCallPresenter.getInstance().addListener(this); startListenOnRemoteMessage(); + DialerCall call = CallList.getInstance().getActiveCall(); + if (call != null) { + rttCallScreen.onRestoreRttChat(call.getRttTranscript()); + } } @Override @@ -69,6 +74,21 @@ public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListe LogUtil.enterBlock("RttCallPresenter.onRttCallScreenUiUnready"); InCallPresenter.getInstance().removeListener(this); stopListenOnRemoteMessage(); + DialerCall call = CallList.getInstance().getActiveCall(); + if (call != null) { + saveTranscript(call); + } + } + + private void saveTranscript(DialerCall dialerCall) { + LogUtil.enterBlock("RttCallPresenter.saveTranscript"); + RttTranscript.Builder builder = RttTranscript.newBuilder(); + builder + .setId(dialerCall.getNumber() + dialerCall.getCreationTimeMillis()) + .setTimestamp(dialerCall.getCreationTimeMillis()) + .setNumber(dialerCall.getNumber()) + .addAllMessages(rttCallScreen.getRttTranscriptMessageList()); + dialerCall.setRttTranscript(builder.build()); } @Override @@ -82,7 +102,7 @@ public class RttCallPresenter implements RttCallScreenDelegate, InCallStateListe private void startListenOnRemoteMessage() { DialerCall call = CallList.getInstance().getActiveCall(); if (call == null) { - LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call is active yet"); + LogUtil.i("RttCallPresenter.startListenOnRemoteMessage", "call is not active yet"); return; } rttCall = call.getRttCall(); diff --git a/java/com/android/incallui/call/DialerCall.java b/java/com/android/incallui/call/DialerCall.java index 35f9481c5..3372c0329 100644 --- a/java/com/android/incallui/call/DialerCall.java +++ b/java/com/android/incallui/call/DialerCall.java @@ -73,6 +73,7 @@ import com.android.dialer.logging.ContactLookupResult.Type; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.preferredsim.PreferredAccountRecorder; +import com.android.dialer.rtt.RttTranscript; import com.android.dialer.telecom.TelecomCallUtil; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.theme.R; @@ -206,6 +207,16 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa */ private boolean isCallSubjectSupported; + public RttTranscript getRttTranscript() { + return rttTranscript; + } + + public void setRttTranscript(RttTranscript rttTranscript) { + this.rttTranscript = rttTranscript; + } + + private RttTranscript rttTranscript; + private final Call.Callback telecomCallCallback = new Call.Callback() { @Override @@ -951,6 +962,16 @@ public class DialerCall implements VideoTechListener, StateChangedListener, Capa return telecomCall.getDetails().getConnectTimeMillis(); } + /** + * Gets the time when the call is created (see {@link Details#getCreationTimeMillis()}). This is + * the same time that is logged as the start time in the Call Log (see {@link + * android.provider.CallLog.Calls#DATE}). + */ + @TargetApi(26) + public long getCreationTimeMillis() { + return telecomCall.getDetails().getCreationTimeMillis(); + } + public boolean isConferenceCall() { return hasProperty(Call.Details.PROPERTY_CONFERENCE); } diff --git a/java/com/android/incallui/rtt/impl/RttChatAdapter.java b/java/com/android/incallui/rtt/impl/RttChatAdapter.java index fb73d19c0..692266335 100644 --- a/java/com/android/incallui/rtt/impl/RttChatAdapter.java +++ b/java/com/android/incallui/rtt/impl/RttChatAdapter.java @@ -18,8 +18,6 @@ package com.android.incallui.rtt.impl; import android.content.Context; import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; @@ -27,6 +25,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.android.dialer.common.LogUtil; +import com.android.dialer.rtt.RttTranscript; +import com.android.dialer.rtt.RttTranscriptMessage; import java.util.ArrayList; import java.util.List; @@ -41,23 +41,14 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde void onUpdateLocalMessage(int position); } - private static final String KEY_MESSAGE_DATA = "key_message_data"; - private static final String KEY_LAST_LOCAL_MESSAGE = "key_last_local_message"; - private final Context context; - private final List<RttChatMessage> rttMessages; + private List<RttChatMessage> rttMessages = new ArrayList<>(); private int lastIndexOfLocalMessage = -1; private final MessageListener messageListener; - RttChatAdapter(Context context, MessageListener listener, @Nullable Bundle savedInstanceState) { + RttChatAdapter(Context context, MessageListener listener) { this.context = context; this.messageListener = listener; - if (savedInstanceState == null) { - rttMessages = new ArrayList<>(); - } else { - rttMessages = savedInstanceState.getParcelableArrayList(KEY_MESSAGE_DATA); - lastIndexOfLocalMessage = savedInstanceState.getInt(KEY_LAST_LOCAL_MESSAGE); - } } @Override @@ -168,12 +159,35 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde } } - void onSaveInstanceState(@NonNull Bundle bundle) { - bundle.putParcelableArrayList(KEY_MESSAGE_DATA, (ArrayList<RttChatMessage>) rttMessages); - bundle.putInt(KEY_LAST_LOCAL_MESSAGE, lastIndexOfLocalMessage); - } - void setAvatarDrawable(Drawable drawable) { avatarDrawable = drawable; } + + /** + * Restores RTT chat history from {@code RttTranscript}. + * + * @param rttTranscript transcript saved previously. + * @return last unfinished local message, return null if there is no current editing local + * message. + */ + @Nullable + String onRestoreRttChat(RttTranscript rttTranscript) { + LogUtil.enterBlock("RttChatAdapater.onRestoreRttChat"); + rttMessages = RttChatMessage.fromTranscript(rttTranscript); + lastIndexOfLocalMessage = RttChatMessage.getLastIndexLocalMessage(rttMessages); + notifyDataSetChanged(); + if (lastIndexOfLocalMessage < 0) { + return null; + } + RttChatMessage message = rttMessages.get(lastIndexOfLocalMessage); + if (!message.isFinished()) { + return message.getContent(); + } else { + return null; + } + } + + List<RttTranscriptMessage> getRttTranscriptMessageList() { + return RttChatMessage.toTranscriptMessageList(rttMessages); + } } diff --git a/java/com/android/incallui/rtt/impl/RttChatFragment.java b/java/com/android/incallui/rtt/impl/RttChatFragment.java index a889408c0..53ad5829e 100644 --- a/java/com/android/incallui/rtt/impl/RttChatFragment.java +++ b/java/com/android/incallui/rtt/impl/RttChatFragment.java @@ -49,6 +49,8 @@ import com.android.dialer.common.FragmentUtils; import com.android.dialer.common.LogUtil; import com.android.dialer.common.UiUtil; import com.android.dialer.lettertile.LetterTileDrawable; +import com.android.dialer.rtt.RttTranscript; +import com.android.dialer.rtt.RttTranscriptMessage; import com.android.dialer.util.DrawableConverter; import com.android.incallui.audioroute.AudioRouteSelectorDialogFragment.AudioRouteSelectorPresenter; import com.android.incallui.call.DialerCall.State; @@ -69,6 +71,7 @@ import com.android.incallui.rtt.protocol.Constants; import com.android.incallui.rtt.protocol.RttCallScreen; import com.android.incallui.rtt.protocol.RttCallScreenDelegate; import com.android.incallui.rtt.protocol.RttCallScreenDelegateFactory; +import java.util.List; /** RTT chat fragment to show chat bubbles. */ public class RttChatFragment extends Fragment @@ -150,6 +153,11 @@ public class RttChatFragment extends Fragment inCallButtonUiDelegate.onInCallButtonUiReady(this); } + @Override + public List<RttTranscriptMessage> getRttTranscriptMessageList() { + return adapter.getRttTranscriptMessageList(); + } + @Nullable @Override public View onCreateView( @@ -172,10 +180,7 @@ public class RttChatFragment extends Fragment if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) { String lastMessage = adapter.retrieveLastLocalMessage(); if (lastMessage != null) { - isClearingInput = true; - editText.setText(lastMessage); - editText.setSelection(lastMessage.length()); - isClearingInput = false; + resumeInput(lastMessage); rttCallScreenDelegate.onLocalMessage("\b"); return true; } @@ -188,7 +193,7 @@ public class RttChatFragment extends Fragment layoutManager.setStackFromEnd(true); recyclerView.setLayoutManager(layoutManager); recyclerView.setHasFixedSize(false); - adapter = new RttChatAdapter(getContext(), this, savedInstanceState); + adapter = new RttChatAdapter(getContext(), this); recyclerView.setAdapter(adapter); recyclerView.addOnScrollListener( new OnScrollListener() { @@ -215,9 +220,7 @@ public class RttChatFragment extends Fragment submitButton.setOnClickListener( v -> { adapter.submitLocalMessage(); - isClearingInput = true; - editText.setText(""); - isClearingInput = false; + resumeInput(""); rttCallScreenDelegate.onLocalMessage(Constants.BUBBLE_BREAKER); // Auto scrolling for new messages should be resumed since user has submit current // message. @@ -314,6 +317,21 @@ public class RttChatFragment extends Fragment } @Override + public void onRestoreRttChat(RttTranscript rttTranscript) { + String unfinishedLocalMessage = adapter.onRestoreRttChat(rttTranscript); + if (unfinishedLocalMessage != null) { + resumeInput(unfinishedLocalMessage); + } + } + + private void resumeInput(String input) { + isClearingInput = true; + editText.setText(input); + editText.setSelection(input.length()); + isClearingInput = false; + } + + @Override public void onStart() { LogUtil.enterBlock("RttChatFragment.onStart"); super.onStart(); @@ -324,7 +342,6 @@ public class RttChatFragment extends Fragment @Override public void onSaveInstanceState(@NonNull Bundle bundle) { super.onSaveInstanceState(bundle); - adapter.onSaveInstanceState(bundle); } @Override diff --git a/java/com/android/incallui/rtt/impl/RttChatMessage.java b/java/com/android/incallui/rtt/impl/RttChatMessage.java index 0060b1bd1..2f3933a50 100644 --- a/java/com/android/incallui/rtt/impl/RttChatMessage.java +++ b/java/com/android/incallui/rtt/impl/RttChatMessage.java @@ -16,22 +16,23 @@ package com.android.incallui.rtt.impl; -import android.os.Parcel; -import android.os.Parcelable; 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 implements Parcelable { +final class RttChatMessage { private static final Splitter SPLITTER = Splitter.on(Constants.BUBBLE_BREAKER); boolean isRemote; - public boolean hasAvatar; + long timstamp; private final StringBuilder content = new StringBuilder(); private boolean isFinished; @@ -178,40 +179,39 @@ final class RttChatMessage implements Parcelable { return i; } - @Override - public int describeContents() { - return 0; + static List<RttTranscriptMessage> toTranscriptMessageList(List<RttChatMessage> messageList) { + List<RttTranscriptMessage> transcriptMessageList = new ArrayList<>(); + for (RttChatMessage message : messageList) { + transcriptMessageList.add( + RttTranscriptMessage.newBuilder() + .setContent(message.getContent()) + .setTimestamp(message.timstamp) + .setIsRemote(message.isRemote) + .setIsFinished(message.isFinished) + .build()); + } + return transcriptMessageList; } - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(getContent()); - boolean[] values = new boolean[2]; - values[0] = isRemote; - values[1] = isFinished; - dest.writeBooleanArray(values); + static List<RttChatMessage> fromTranscript(RttTranscript rttTranscript) { + List<RttChatMessage> messageList = new ArrayList<>(); + if (rttTranscript == null) { + return messageList; + } + for (RttTranscriptMessage message : rttTranscript.getMessagesList()) { + RttChatMessage chatMessage = new RttChatMessage(); + chatMessage.append(message.getContent()); + chatMessage.timstamp = message.getTimestamp(); + chatMessage.isRemote = message.getIsRemote(); + if (message.getIsFinished()) { + chatMessage.finish(); + } + messageList.add(chatMessage); + } + return messageList; } - public static final Parcelable.Creator<RttChatMessage> CREATOR = - new Parcelable.Creator<RttChatMessage>() { - @Override - public RttChatMessage createFromParcel(Parcel in) { - return new RttChatMessage(in); - } - - @Override - public RttChatMessage[] newArray(int size) { - return new RttChatMessage[size]; - } - }; - - private RttChatMessage(Parcel in) { - content.append(in.readString()); - boolean[] values = new boolean[2]; - in.readBooleanArray(values); - isRemote = values[0]; - isFinished = values[1]; + RttChatMessage() { + timstamp = System.currentTimeMillis(); } - - RttChatMessage() {} } diff --git a/java/com/android/incallui/rtt/protocol/RttCallScreen.java b/java/com/android/incallui/rtt/protocol/RttCallScreen.java index 531b18df6..420274c73 100644 --- a/java/com/android/incallui/rtt/protocol/RttCallScreen.java +++ b/java/com/android/incallui/rtt/protocol/RttCallScreen.java @@ -17,7 +17,10 @@ package com.android.incallui.rtt.protocol; import android.support.v4.app.Fragment; +import com.android.dialer.rtt.RttTranscript; +import com.android.dialer.rtt.RttTranscriptMessage; import com.android.incallui.incall.protocol.InCallScreen; +import java.util.List; /** Interface for call RTT call module. */ public interface RttCallScreen extends InCallScreen { @@ -28,6 +31,10 @@ public interface RttCallScreen extends InCallScreen { void onRemoteMessage(String message); + void onRestoreRttChat(RttTranscript rttTranscript); + + List<RttTranscriptMessage> getRttTranscriptMessageList(); + Fragment getRttCallScreenFragment(); String getCallId(); |