From e00bbaeceb399da24f06c8f1a626cbbf07eab4ad Mon Sep 17 00:00:00 2001 From: wangqi Date: Tue, 17 Apr 2018 14:48:03 -0700 Subject: Add RTT transcript screen. Bug: 67596257 Test: CallDetailsCursorLoaderTest PiperOrigin-RevId: 193259769 Change-Id: I8c6a8eb9a6bf06e9c1c25c45fc035f8db8ae5a65 --- java/com/android/dialer/rtt/AndroidManifest.xml | 21 ++++ .../android/dialer/rtt/RttTranscriptActivity.java | 122 +++++++++++++++++++++ .../android/dialer/rtt/RttTranscriptAdapter.java | 88 +++++++++++++++ .../dialer/rtt/RttTranscriptMessageViewHolder.java | 95 ++++++++++++++++ java/com/android/dialer/rtt/RttTranscriptUtil.java | 8 +- .../dialer/rtt/res/color/bubble_background.xml | 21 ++++ .../dialer/rtt/res/drawable/message_bubble.xml | 21 ++++ .../rtt/res/layout/activity_rtt_transcript.xml | 30 +++++ .../rtt/res/layout/rtt_transcript_list_item.xml | 54 +++++++++ java/com/android/dialer/rtt/res/values/colors.xml | 20 ++++ java/com/android/dialer/rtt/res/values/dimens.xml | 21 ++++ java/com/android/dialer/rtt/res/values/styles.xml | 36 ++++++ 12 files changed, 536 insertions(+), 1 deletion(-) create mode 100644 java/com/android/dialer/rtt/AndroidManifest.xml create mode 100644 java/com/android/dialer/rtt/RttTranscriptActivity.java create mode 100644 java/com/android/dialer/rtt/RttTranscriptAdapter.java create mode 100644 java/com/android/dialer/rtt/RttTranscriptMessageViewHolder.java create mode 100644 java/com/android/dialer/rtt/res/color/bubble_background.xml create mode 100644 java/com/android/dialer/rtt/res/drawable/message_bubble.xml create mode 100644 java/com/android/dialer/rtt/res/layout/activity_rtt_transcript.xml create mode 100644 java/com/android/dialer/rtt/res/layout/rtt_transcript_list_item.xml create mode 100644 java/com/android/dialer/rtt/res/values/colors.xml create mode 100644 java/com/android/dialer/rtt/res/values/dimens.xml create mode 100644 java/com/android/dialer/rtt/res/values/styles.xml (limited to 'java/com/android/dialer/rtt') diff --git a/java/com/android/dialer/rtt/AndroidManifest.xml b/java/com/android/dialer/rtt/AndroidManifest.xml new file mode 100644 index 000000000..c92fb1ceb --- /dev/null +++ b/java/com/android/dialer/rtt/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/rtt/RttTranscriptActivity.java b/java/com/android/dialer/rtt/RttTranscriptActivity.java new file mode 100644 index 000000000..2087250b3 --- /dev/null +++ b/java/com/android/dialer/rtt/RttTranscriptActivity.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2018 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.rtt; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MenuItem; +import com.android.dialer.common.Assert; +import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.common.concurrent.UiListener; +import com.android.dialer.glidephotomanager.PhotoInfo; +import com.android.dialer.protos.ProtoParsers; +import com.google.common.util.concurrent.ListenableFuture; + +/** Activity holds RTT transcript. */ +public class RttTranscriptActivity extends AppCompatActivity { + + public static final String EXTRA_TRANSCRIPT_ID = "extra_transcript_id"; + public static final String EXTRA_PRIMARY_TEXT = "extra_primary_text"; + public static final String EXTRA_PHOTO_INFO = "extra_photo_info"; + + private RttTranscriptAdapter adapter; + private UiListener rttTranscriptUiListener; + + public static Intent getIntent( + Context context, String transcriptId, String primaryText, PhotoInfo photoInfo) { + Intent intent = new Intent(context, RttTranscriptActivity.class); + intent.putExtra(RttTranscriptActivity.EXTRA_TRANSCRIPT_ID, transcriptId); + intent.putExtra(RttTranscriptActivity.EXTRA_PRIMARY_TEXT, primaryText); + ProtoParsers.put(intent, RttTranscriptActivity.EXTRA_PHOTO_INFO, Assert.isNotNull(photoInfo)); + return intent; + } + + @Override + protected void onCreate(@Nullable Bundle bundle) { + super.onCreate(bundle); + setContentView(R.layout.activity_rtt_transcript); + ActionBar actionBar = getSupportActionBar(); + actionBar.setDisplayShowHomeEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); + + RecyclerView recyclerView = findViewById(R.id.rtt_recycler_view); + LinearLayoutManager layoutManager = new LinearLayoutManager(this); + layoutManager.setStackFromEnd(true); + recyclerView.setLayoutManager(layoutManager); + recyclerView.setHasFixedSize(true); + adapter = new RttTranscriptAdapter(this); + recyclerView.setAdapter(adapter); + + rttTranscriptUiListener = + DialerExecutorComponent.get(this) + .createUiListener(getFragmentManager(), "Load RTT transcript"); + handleIntent(getIntent()); + } + + private void handleIntent(Intent intent) { + Assert.checkArgument(intent.hasExtra(EXTRA_TRANSCRIPT_ID)); + Assert.checkArgument(intent.hasExtra(EXTRA_PRIMARY_TEXT)); + Assert.checkArgument(intent.hasExtra(EXTRA_PHOTO_INFO)); + + String id = intent.getStringExtra(EXTRA_TRANSCRIPT_ID); + rttTranscriptUiListener.listen( + this, + getRttTranscript(id), + adapter::setRttTranscript, + throwable -> { + throw new RuntimeException(throwable); + }); + + String primaryText = intent.getStringExtra(EXTRA_PRIMARY_TEXT); + getSupportActionBar().setTitle(primaryText); + + PhotoInfo photoInfo = + ProtoParsers.getTrusted(intent, EXTRA_PHOTO_INFO, PhotoInfo.getDefaultInstance()); + // Photo shown here shouldn't have video or RTT badge. + PhotoInfo sanitizedPhotoInfo = + PhotoInfo.newBuilder().mergeFrom(photoInfo).setIsRtt(false).setIsVideo(false).build(); + adapter.setPhotoInfo(sanitizedPhotoInfo); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleIntent(intent); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + onBackPressed(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private ListenableFuture getRttTranscript(String id) { + return DialerExecutorComponent.get(this) + .backgroundExecutor() + .submit(() -> new RttTranscriptUtil(this).getRttTranscript(id)); + } +} diff --git a/java/com/android/dialer/rtt/RttTranscriptAdapter.java b/java/com/android/dialer/rtt/RttTranscriptAdapter.java new file mode 100644 index 000000000..6e030349d --- /dev/null +++ b/java/com/android/dialer/rtt/RttTranscriptAdapter.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2018 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.rtt; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import com.android.dialer.glidephotomanager.PhotoInfo; + +/** Adapter class for holding RTT chat data. */ +public class RttTranscriptAdapter extends RecyclerView.Adapter { + + private PhotoInfo photoInfo; + + private final Context context; + private RttTranscript rttTranscript; + + RttTranscriptAdapter(Context context) { + this.context = context; + } + + @Override + public RttTranscriptMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + LayoutInflater layoutInflater = LayoutInflater.from(context); + View view = layoutInflater.inflate(R.layout.rtt_transcript_list_item, parent, false); + return new RttTranscriptMessageViewHolder(view); + } + + @Override + public int getItemViewType(int position) { + return super.getItemViewType(position); + } + + @Override + public void onBindViewHolder(RttTranscriptMessageViewHolder rttChatMessageViewHolder, int i) { + boolean isSameGroup = false; + boolean hasMoreInSameGroup = false; + RttTranscriptMessage rttTranscriptMessage = rttTranscript.getMessages(i); + if (i > 0) { + isSameGroup = + rttTranscriptMessage.getIsRemote() == rttTranscript.getMessages(i - 1).getIsRemote(); + } + if (i + 1 < getItemCount()) { + hasMoreInSameGroup = + rttTranscriptMessage.getIsRemote() == rttTranscript.getMessages(i + 1).getIsRemote(); + } + rttChatMessageViewHolder.setMessage(rttTranscriptMessage, isSameGroup, photoInfo); + if (hasMoreInSameGroup) { + rttChatMessageViewHolder.hideTimestamp(); + } else { + rttChatMessageViewHolder.showTimestamp( + rttTranscriptMessage.getTimestamp(), rttTranscriptMessage.getIsRemote(), i == 0); + } + } + + @Override + public int getItemCount() { + if (rttTranscript == null) { + return 0; + } + return rttTranscript.getMessagesCount(); + } + + void setRttTranscript(RttTranscript rttTranscript) { + this.rttTranscript = rttTranscript; + notifyDataSetChanged(); + } + + void setPhotoInfo(PhotoInfo photoInfo) { + this.photoInfo = photoInfo; + } +} diff --git a/java/com/android/dialer/rtt/RttTranscriptMessageViewHolder.java b/java/com/android/dialer/rtt/RttTranscriptMessageViewHolder.java new file mode 100644 index 000000000..daa8136fe --- /dev/null +++ b/java/com/android/dialer/rtt/RttTranscriptMessageViewHolder.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2018 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.rtt; + +import android.content.Context; +import android.content.res.Resources; +import android.support.v7.widget.RecyclerView.ViewHolder; +import android.text.format.DateUtils; +import android.view.Gravity; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; +import android.widget.TextView; +import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent; +import com.android.dialer.glidephotomanager.PhotoInfo; + +/** ViewHolder class for RTT chat message bubble. */ +public class RttTranscriptMessageViewHolder extends ViewHolder { + + private final TextView messageTextView; + private final Resources resources; + private final ImageView avatarImageView; + private final View container; + private final TextView timestampTextView; + + RttTranscriptMessageViewHolder(View view) { + super(view); + container = view.findViewById(R.id.rtt_chat_message_container); + messageTextView = view.findViewById(R.id.rtt_chat_message); + avatarImageView = view.findViewById(R.id.rtt_chat_avatar); + timestampTextView = view.findViewById(R.id.rtt_chat_timestamp); + resources = view.getResources(); + } + + void setMessage(RttTranscriptMessage message, boolean isSameGroup, PhotoInfo photoInfo) { + messageTextView.setText(message.getContent()); + LinearLayout.LayoutParams params = (LayoutParams) container.getLayoutParams(); + params.gravity = message.getIsRemote() ? Gravity.START : Gravity.END; + params.topMargin = + isSameGroup + ? resources.getDimensionPixelSize(R.dimen.rtt_transcript_same_group_message_margin_top) + : resources.getDimensionPixelSize(R.dimen.rtt_transcript_message_margin_top); + container.setLayoutParams(params); + messageTextView.setEnabled(message.getIsRemote()); + if (message.getIsRemote()) { + if (isSameGroup) { + avatarImageView.setVisibility(View.INVISIBLE); + } else { + avatarImageView.setVisibility(View.VISIBLE); + GlidePhotoManagerComponent.get(container.getContext()) + .glidePhotoManager() + .loadContactPhoto(avatarImageView, photoInfo); + } + messageTextView.setTextAppearance(R.style.RttTranscriptBubble_Remote); + } else { + avatarImageView.setVisibility(View.GONE); + messageTextView.setTextAppearance(R.style.RttTranscriptBubble_Local); + } + } + + void showTimestamp(long timestamp, boolean isRemote, boolean showFullDate) { + timestampTextView.setVisibility(View.VISIBLE); + timestampTextView.setText( + getTimestampText(timestampTextView.getContext(), timestamp, showFullDate)); + timestampTextView.setGravity(isRemote ? Gravity.START : Gravity.END); + } + + void hideTimestamp() { + timestampTextView.setVisibility(View.GONE); + } + + private String getTimestampText(Context context, long timestamp, boolean showFullDate) { + return DateUtils.formatDateTime( + context, + timestamp, + showFullDate + ? DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME + : DateUtils.FORMAT_SHOW_TIME); + } +} diff --git a/java/com/android/dialer/rtt/RttTranscriptUtil.java b/java/com/android/dialer/rtt/RttTranscriptUtil.java index e55d2ea55..19b46b01a 100644 --- a/java/com/android/dialer/rtt/RttTranscriptUtil.java +++ b/java/com/android/dialer/rtt/RttTranscriptUtil.java @@ -30,7 +30,13 @@ public final class RttTranscriptUtil { private final RttTranscriptDatabaseHelper databaseHelper; public RttTranscriptUtil(Context context) { - databaseHelper = new RttTranscriptDatabaseHelper(context); + databaseHelper = new RttTranscriptDatabaseHelper(context.getApplicationContext()); + } + + @Override + protected void finalize() throws Throwable { + databaseHelper.close(); + super.finalize(); } /** @return true if there is RTT transcript available. */ diff --git a/java/com/android/dialer/rtt/res/color/bubble_background.xml b/java/com/android/dialer/rtt/res/color/bubble_background.xml new file mode 100644 index 000000000..fb29ab6c5 --- /dev/null +++ b/java/com/android/dialer/rtt/res/color/bubble_background.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/rtt/res/drawable/message_bubble.xml b/java/com/android/dialer/rtt/res/drawable/message_bubble.xml new file mode 100644 index 000000000..2b01f62f9 --- /dev/null +++ b/java/com/android/dialer/rtt/res/drawable/message_bubble.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/rtt/res/layout/activity_rtt_transcript.xml b/java/com/android/dialer/rtt/res/layout/activity_rtt_transcript.xml new file mode 100644 index 000000000..628a7932e --- /dev/null +++ b/java/com/android/dialer/rtt/res/layout/activity_rtt_transcript.xml @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/java/com/android/dialer/rtt/res/layout/rtt_transcript_list_item.xml b/java/com/android/dialer/rtt/res/layout/rtt_transcript_list_item.xml new file mode 100644 index 000000000..d86a6823a --- /dev/null +++ b/java/com/android/dialer/rtt/res/layout/rtt_transcript_list_item.xml @@ -0,0 +1,54 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/com/android/dialer/rtt/res/values/colors.xml b/java/com/android/dialer/rtt/res/values/colors.xml new file mode 100644 index 000000000..5de06f9f2 --- /dev/null +++ b/java/com/android/dialer/rtt/res/values/colors.xml @@ -0,0 +1,20 @@ + + + + #37474F + #ECEFF1 + \ No newline at end of file diff --git a/java/com/android/dialer/rtt/res/values/dimens.xml b/java/com/android/dialer/rtt/res/values/dimens.xml new file mode 100644 index 000000000..a36cdd746 --- /dev/null +++ b/java/com/android/dialer/rtt/res/values/dimens.xml @@ -0,0 +1,21 @@ + + + + 16dp + 2dp + 40dp + diff --git a/java/com/android/dialer/rtt/res/values/styles.xml b/java/com/android/dialer/rtt/res/values/styles.xml new file mode 100644 index 000000000..d8bc245ef --- /dev/null +++ b/java/com/android/dialer/rtt/res/values/styles.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3