diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-04-04 23:56:31 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-04-04 23:56:31 +0000 |
commit | 9f14cd7ee2e46185f80ce9c364b22687a1d651ff (patch) | |
tree | d2efff2512c24fa05f9fd87c383d4da3f89d4fe9 /java | |
parent | d5408c9423f20bef650ca838ff66bb5ecf60f818 (diff) | |
parent | 612d13a1295afb0f0b9e8217fc0efb211836c949 (diff) |
Merge changes If1ae5505,I65e9c6ac,I1a72ca86,I417b46ed,I60f97924
* changes:
Better support for multi call.
Migrate RTT chat history to use proto buffer.
Disable RTT request button when the call is not active yet.
Use the default phone account for a voice call when the call log item is for Duo.
Explicitly hide the badge in ContactPhotoView when it shouldn't be shown.
Diffstat (limited to 'java')
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(); |