diff options
author | Uchenna Okoye <uokoye@google.com> | 2021-09-30 22:34:54 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-09-30 22:34:54 +0000 |
commit | 6d173c6f4b4684e2669e559b0b92862f7ab5dbd2 (patch) | |
tree | 3a4832bc21305375be5d4ff4f1a757c9b13a7594 | |
parent | 33bd9cdf2cf3514da531fb9d7c9258306ac7f016 (diff) | |
parent | e121b23c169fc4911ecd5118b29ea81370f7d85e (diff) | |
download | Messenger-6d173c6f4b4684e2669e559b0b92862f7ab5dbd2.tar.gz |
Fix UI changes am: e121b23c16
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Car/Messenger/+/15952552
Change-Id: Id8bf2cf17cbaa44a8519419f27f9843bf89ad55f
23 files changed, 178 insertions, 100 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8787f44..d48bd17 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -28,9 +28,9 @@ <activity android:name=".core.ui.launcher.MessageLauncherActivity" - android:launchMode="singleTask" android:exported="true" - android:screenOrientation="landscape"> + android:screenOrientation="landscape" + android:launchMode="singleTask"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/res/drawable/ic_reply.xml b/res/drawable/ic_reply.xml new file mode 100644 index 0000000..33dcc9c --- /dev/null +++ b/res/drawable/ic_reply.xml @@ -0,0 +1,27 @@ +<!-- + ~ Copyright (C) 2021 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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="76dp" + android:height="76dp" + android:viewportWidth="76" + android:viewportHeight="76"> + <path + android:pathData="M16,0L60,0A16,16 0,0 1,76 16L76,60A16,16 0,0 1,60 76L16,76A16,16 0,0 1,0 60L0,16A16,16 0,0 1,16 0z" + android:fillColor="#3C4043"/> + <path + android:pathData="M45.3333,34.3333H28.5217L32.5,30.355L35.085,27.77L32.5,25.1667L21.5,36.1667L32.5,47.1667L35.085,44.5817L32.5,41.9783L28.5217,38H45.3333C48.3583,38 50.8333,40.475 50.8333,43.5V50.8333H54.5V43.5C54.5,38.44 50.3933,34.3333 45.3333,34.3333Z" + android:fillColor="#ffffff"/> +</vector> diff --git a/res/drawable/ic_subtitle_play.xml b/res/drawable/ic_subtitle_play.xml new file mode 100644 index 0000000..9eccfaf --- /dev/null +++ b/res/drawable/ic_subtitle_play.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2021 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. + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="11dp" + android:height="14dp" + android:viewportHeight="14" + android:viewportWidth="11"> + <path + android:fillColor="@color/secondary_text_color" + android:pathData="M2,3.64L7.27,7L2,10.36V3.64ZM0,0V14L11,7L0,0Z" /> +</vector> diff --git a/res/layout/conversation_list_item.xml b/res/layout/conversation_list_item.xml index 1240337..3739d9d 100644 --- a/res/layout/conversation_list_item.xml +++ b/res/layout/conversation_list_item.xml @@ -52,16 +52,15 @@ limitations under the License. android:background="?android:attr/selectableItemBackground" android:contentDescription="@string/cd_reply_action_button" android:scaleType="center" - android:src="@drawable/car_ui_icon_reply" + android:src="@drawable/ic_reply" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/mute_action_button" - app:layout_constraintStart_toEndOf="@id/guideline_end" + app:layout_constraintEnd_toEndOf="parent" android:visibility="visible" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/play_action_button" - android:layout_width="0dp" + android:layout_width="100dp" android:layout_height="match_parent" android:background="?android:attr/selectableItemBackground" android:contentDescription="@string/cd_play_action_button" @@ -69,8 +68,7 @@ limitations under the License. android:scaleY=".4" android:src="@drawable/ic_play" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@id/mute_action_button" - app:layout_constraintStart_toEndOf="@id/guideline_end" + app:layout_constraintEnd_toEndOf="parent" tools:visibility="gone" app:layout_constraintTop_toTopOf="parent" /> @@ -78,13 +76,14 @@ limitations under the License. android:id="@+id/mute_action_button" android:layout_width="0dp" android:layout_height="match_parent" + android:visibility="gone" android:background="?android:attr/selectableItemBackground" android:contentDescription="@string/cd_mute_button" android:scaleType="center" android:src="@drawable/car_ui_icon_toggle_mute" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@id/guideline_mid" + app:layout_constraintStart_toEndOf="@id/guideline_end" app:layout_constraintTop_toTopOf="parent" /> <TextView @@ -128,7 +127,7 @@ limitations under the License. app:layout_constraintStart_toEndOf="@id/last_action_icon_view" app:layout_constraintTop_toBottomOf="@id/title" app:layout_constraintEnd_toStartOf="@id/preview_dot" - tools:visibility="gone" + tools:visibility="visible" android:ellipsize="end" android:maxLength="20" tools:text="Let this be the preview. Lots of preview with @@ -181,7 +180,6 @@ limitations under the License. android:id="@+id/date_time_view" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="@dimen/message_history_text_margin_end" android:layout_marginStart="6dp" android:singleLine="true" app:layout_constraintBottom_toBottomOf="@id/text_metadata" @@ -223,12 +221,5 @@ limitations under the License. android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" - app:layout_constraintGuide_end="200dp" /> - - <androidx.constraintlayout.widget.Guideline - android:id="@+id/guideline_mid" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:orientation="vertical" app:layout_constraintGuide_end="100dp" /> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/res/values/config.xml b/res/values/config.xml index 849ef92..c44885f 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -18,7 +18,7 @@ <bool name="group_avatar_fill_background">false</bool> <bool name="direct_send_supported">true</bool> <bool name="direct_reply_supported">true</bool> - <bool name="ttr_conversation_supported">false</bool> + <bool name="ttr_conversation_supported">true</bool> <!-- The maximum number of individual avatars used for group avatar. diff --git a/res/values/strings.xml b/res/values/strings.xml index 0b40bb7..3108071 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -38,19 +38,23 @@ </plurals> <!-- Button text for when disconnected from Bluetooth [CHAR LIMIT=40] --> - <string name="app_name" translatable="false">Car Messenger</string> + <string name="app_name" translatable="false">SMS</string> <!-- Button text for connecting to Bluetooth [CHAR LIMIT=40] --> <string name="bluetooth_disconnected" translatable="false">Bluetooth disconnected</string> <!-- Status when no new messages[CHAR LIMIT=40] --> + <string name="no_messages" translatable="false">No messages</string> + <string name="connect_bluetooth_button_text" translatable="false">Connect to Bluetooth</string> <!-- Status when replied [CHAR LIMIT=40] --> - <string name="no_messages" translatable="false">No messages</string> + <string name="replied" translatable="false">Replied</string> + + <!-- Status - Tap To Read Aloud [CHAR LIMIT=40] --> + <string name="tap_to_read_aloud">Tap to read aloud</string> <!-- Dot separator [CHAR LIMIT=1] --> - <string name="replied" translatable="false">Replied</string> <string name="dot" translatable="false">ยท</string> <string name="action_reply" translatable="false">Reply</string> <string name="action_mute" translatable="false">Mute</string> diff --git a/res/values/styles.xml b/res/values/styles.xml index 0e8c798..8845c0a 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -17,7 +17,11 @@ <!-- Message history --> <style name="TextAppearance.MessageHistoryTitle" parent="TextAppearance.Body1" /> - <style name="TextAppearance.MessageHistoryTextPreview" parent="TextAppearance.Body3"> + <style name="TextAppearance.MessageHistoryTextPreviewUnread" parent="TextAppearance.CarUi.Body1"> + <item name="android:textColor">@color/unread_color</item> + </style> + + <style name="TextAppearance.MessageHistoryTextPreview" parent="TextAppearance.CarUi.Body1"> <item name="android:textColor">@color/secondary_text_color</item> </style> <!-- Customized text color for unread messages can be added here --> @@ -103,4 +107,4 @@ <item name="android:gravity">center</item> <item name="android:paddingHorizontal">@dimen/hero_button_corner_radius</item> </style> -</resources> +</resources>
\ No newline at end of file diff --git a/src/com/android/car/messenger/core/interfaces/DataModel.java b/src/com/android/car/messenger/core/interfaces/DataModel.java index 93a728f..2822ecf 100644 --- a/src/com/android/car/messenger/core/interfaces/DataModel.java +++ b/src/com/android/car/messenger/core/interfaces/DataModel.java @@ -18,8 +18,10 @@ package com.android.car.messenger.core.interfaces; import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; + import com.android.car.messenger.common.Conversation; import com.android.car.messenger.core.models.UserAccount; + import java.util.Collection; /** diff --git a/src/com/android/car/messenger/core/shared/NotificationHandler.java b/src/com/android/car/messenger/core/shared/NotificationHandler.java index f9836ec..ddee570 100644 --- a/src/com/android/car/messenger/core/shared/NotificationHandler.java +++ b/src/com/android/car/messenger/core/shared/NotificationHandler.java @@ -73,21 +73,18 @@ public class NotificationHandler { Notification notification = ConversationPayloadHandler.createNotificationFromConversation( context, channelId, tapToReadConversation, R.drawable.ic_message, null); - notification.contentIntent = createServiceIntent(); - + notification.contentIntent = createContentIntent(); notificationManager.notify(tapToReadConversation.getId().hashCode(), notification); } - private static PendingIntent createServiceIntent() { + private static PendingIntent createContentIntent() { Context context = AppFactory.get().getContext(); - Intent intent = new Intent(context, MessageLauncherActivity.class) .addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP - | Intent.FLAG_ACTIVITY_SINGLE_TOP) - .setClass(context, MessengerService.class); + | Intent.FLAG_ACTIVITY_SINGLE_TOP); return PendingIntent.getActivity( context, diff --git a/src/com/android/car/messenger/core/ui/conversationlist/ConversationItemViewHolder.java b/src/com/android/car/messenger/core/ui/conversationlist/ConversationItemViewHolder.java index cb7f324..4f4de71 100644 --- a/src/com/android/car/messenger/core/ui/conversationlist/ConversationItemViewHolder.java +++ b/src/com/android/car/messenger/core/ui/conversationlist/ConversationItemViewHolder.java @@ -16,12 +16,16 @@ package com.android.car.messenger.core.ui.conversationlist; +import android.content.Context; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.Drawable; import androidx.recyclerview.widget.RecyclerView; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import com.android.car.messenger.R; @@ -106,15 +110,19 @@ public class ConversationItemViewHolder extends RecyclerView.ViewHolder { } private void setUpTextAppearance(@NonNull UIConversationItem uiData) { + Context context = AppFactory.get().getContext(); if (uiData.shouldUseUnreadTheme()) { mTitleView.setTextAppearance(R.style.TextAppearance_MessageHistoryUnreadTitle); - mPreviewTextView.setTextAppearance(R.style.TextAppearance_MessageHistoryTextPreview); + mPreviewTextView.setTextAppearance( + R.style.TextAppearance_MessageHistoryTextPreviewUnread); mTextMetadataView.setTextAppearance( R.style.TextAppearance_MessageHistoryUnreadMetadata); mTextMetadataDotView.setTextAppearance( R.style.TextAppearance_MessageHistoryUnreadMetadata); mDateTimeView.setTextAppearance(R.style.TextAppearance_MessageHistoryUnreadMetadata); - mDotSeparatorView.setTextAppearance(R.style.TextAppearance_MessageHistoryTextPreview); + mDotSeparatorView.setTextAppearance( + R.style.TextAppearance_MessageHistoryTextPreviewUnread); + updateSubtitleIcon(context.getColor(R.color.unread_color)); ViewUtils.setVisible(mUnreadIconIndicator, /* visible= */ true); } else { mTitleView.setTextAppearance(R.style.TextAppearance_MessageHistoryTitle); @@ -124,14 +132,20 @@ public class ConversationItemViewHolder extends RecyclerView.ViewHolder { R.style.TextAppearance_MessageHistoryTextPreview); mDateTimeView.setTextAppearance(R.style.TextAppearance_MessageHistoryTextPreview); mDotSeparatorView.setTextAppearance(R.style.TextAppearance_MessageHistoryTextPreview); + updateSubtitleIcon(context.getColor(R.color.secondary_text_color)); ViewUtils.setVisible(mUnreadIconIndicator, /* visible= */ false); } } + private void updateSubtitleIcon(@ColorInt int color) { + PorterDuffColorFilter porterDuffColorFilter = + new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP); + mSubtitleIconView.getDrawable().setColorFilter(porterDuffColorFilter); + } + private void updateMuteButton(boolean isMuted) { int drawableRes = isMuted ? R.drawable.ic_unmute : R.drawable.ic_mute; Drawable drawable = AppFactory.get().getContext().getDrawable(drawableRes); - mMuteActionButton.setImageDrawable(drawable); } diff --git a/src/com/android/car/messenger/core/ui/conversationlist/ConversationListFragment.java b/src/com/android/car/messenger/core/ui/conversationlist/ConversationListFragment.java index b00fb5f..bc27889 100644 --- a/src/com/android/car/messenger/core/ui/conversationlist/ConversationListFragment.java +++ b/src/com/android/car/messenger/core/ui/conversationlist/ConversationListFragment.java @@ -16,13 +16,13 @@ package com.android.car.messenger.core.ui.conversationlist; import android.app.Activity; -import androidx.lifecycle.ViewModelProvider; import android.content.Intent; import android.os.Bundle; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.ViewModelProvider; import com.android.car.messenger.R; import com.android.car.messenger.common.Conversation; @@ -110,6 +110,15 @@ public class ConversationListFragment extends MessageListBaseFragment R.string.connect_bluetooth_button_text, v -> startActivity(launchIntent), true); + removeMenuItems(); + } + + private void removeMenuItems() { + Activity activity = getActivity(); + if (activity == null || mToolbar == null) { + return; + } + mToolbar.setMenuItems(new ArrayList<>()); } private void setMenuItems() { @@ -117,6 +126,9 @@ public class ConversationListFragment extends MessageListBaseFragment if (activity == null || mUserAccount == null || mToolbar == null) { return; } + if (!mToolbar.getMenuItems().isEmpty()) { + return; + } if (!getResources().getBoolean(R.bool.direct_send_supported)) { return; } diff --git a/src/com/android/car/messenger/core/ui/conversationlist/ConversationListViewModel.java b/src/com/android/car/messenger/core/ui/conversationlist/ConversationListViewModel.java index 6b5d199..e16bff5 100644 --- a/src/com/android/car/messenger/core/ui/conversationlist/ConversationListViewModel.java +++ b/src/com/android/car/messenger/core/ui/conversationlist/ConversationListViewModel.java @@ -18,19 +18,23 @@ package com.android.car.messenger.core.ui.conversationlist; import android.annotation.SuppressLint; import android.app.Application; -import androidx.lifecycle.AndroidViewModel; import android.car.drivingstate.CarUxRestrictions; +import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.Transformations; +import com.android.car.messenger.common.Conversation; import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.interfaces.DataModel; import com.android.car.messenger.core.models.UserAccount; import com.android.car.messenger.core.util.L; +import java.util.Collection; import java.util.List; import java.util.stream.Collectors; @@ -77,20 +81,10 @@ public class ConversationListViewModel extends AndroidViewModel { MediatorLiveData<UIConversationLog> mutableLiveData = new MediatorLiveData<>(); mutableLiveData.postValue(UIConversationLog.getLoadingState()); mutableLiveData.addSource( - AppFactory.get().getCarStateListener().getUxrRestrictions(), - uxrRestrictions -> - subscribeToConversations(userAccount, mutableLiveData, uxrRestrictions)); - return mutableLiveData; - } - - private void subscribeToConversations( - @NonNull UserAccount userAccount, - MediatorLiveData<UIConversationLog> mutableLiveData, - CarUxRestrictions uxRestrictions) { - L.w("Got new ux restrictions: " + uxRestrictions); - mutableLiveData.addSource( - mDataModel.getConversations(userAccount), - list -> { + subscribeToConversations(userAccount), + pair -> { + CarUxRestrictions uxRestrictions = pair.first; + Collection<Conversation> list = pair.second; List<UIConversationItem> data = list.stream() .map( @@ -102,5 +96,19 @@ public class ConversationListViewModel extends AndroidViewModel { UIConversationLog log = UIConversationLog.getLoadedState(data); mutableLiveData.postValue(log); }); + return mutableLiveData; + } + + private LiveData<Pair<CarUxRestrictions, Collection<Conversation>>> subscribeToConversations( + @NonNull UserAccount userAccount) { + final LiveData<Collection<Conversation>> liveData = + mDataModel.getConversations(userAccount); + return Transformations.switchMap( + AppFactory.get().getCarStateListener().getUxrRestrictions(), + uxRestrictions -> { + L.d("Got new ux restrictions: " + uxRestrictions); + return Transformations.map( + liveData, conversations -> new Pair<>(uxRestrictions, conversations)); + }); } } diff --git a/src/com/android/car/messenger/core/ui/conversationlist/UIConversationItemConverter.java b/src/com/android/car/messenger/core/ui/conversationlist/UIConversationItemConverter.java index 00f2a71..baa7056 100644 --- a/src/com/android/car/messenger/core/ui/conversationlist/UIConversationItemConverter.java +++ b/src/com/android/car/messenger/core/ui/conversationlist/UIConversationItemConverter.java @@ -42,12 +42,10 @@ public class UIConversationItemConverter { long timestamp = ConversationUtil.getConversationTimestamp(conversation); boolean isReplied = ConversationUtil.isReplied(conversation); - Drawable subtitleIcon = null; - - // show reply icon to the side when replied - if (isReplied) { - subtitleIcon = context.getDrawable(R.drawable.car_ui_icon_reply); - } + Drawable subtitleIcon = + isReplied + ? context.getDrawable(R.drawable.car_ui_icon_reply) + : context.getDrawable(R.drawable.ic_subtitle_play); boolean showTextPreview = (carUxRestrictions.getActiveRestrictions() @@ -64,6 +62,8 @@ public class UIConversationItemConverter { } } else { if (isUnread) { + // in place of text preview, we show "tap to read aloud" when unread + textPreview = context.getString(R.string.tap_to_read_aloud); textMetadata = getNumberOfUnreadMessages(context, conversation.getUnreadCount()); } else if (isReplied) { textMetadata = context.getString(R.string.replied); @@ -72,10 +72,6 @@ public class UIConversationItemConverter { } } - boolean showPlayIcon = isUnread; - boolean showReplyIcon = - !showPlayIcon && context.getResources().getBoolean(R.bool.direct_reply_supported); - return new UIConversationItem( conversation.getId(), Objects.requireNonNull(conversation.getConversationTitle()), @@ -84,9 +80,9 @@ public class UIConversationItemConverter { textMetadata, timestamp, getConversationAvatar(context, conversation), - /* showMuteIcon= */ true, - /* showReplyIcon= */ showReplyIcon, - /* showPlayIcon= */ showPlayIcon, + /* showMuteIcon= */ false, + /* showReplyIcon= */ true, + /* showPlayIcon= */ false, isUnread, conversation.isMuted(), conversation); diff --git a/src/com/android/car/messenger/core/ui/launcher/MessageLauncherActivity.java b/src/com/android/car/messenger/core/ui/launcher/MessageLauncherActivity.java index 14c1951..0c114cc 100644 --- a/src/com/android/car/messenger/core/ui/launcher/MessageLauncherActivity.java +++ b/src/com/android/car/messenger/core/ui/launcher/MessageLauncherActivity.java @@ -16,12 +16,12 @@ package com.android.car.messenger.core.ui.launcher; -import androidx.lifecycle.ViewModelProvider; import android.os.Bundle; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.annotation.NonNull; +import androidx.lifecycle.ViewModelProvider; import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.models.UserAccount; diff --git a/src/com/android/car/messenger/core/ui/launcher/MessageLauncherViewModel.java b/src/com/android/car/messenger/core/ui/launcher/MessageLauncherViewModel.java index 2df42c1..47503e6 100644 --- a/src/com/android/car/messenger/core/ui/launcher/MessageLauncherViewModel.java +++ b/src/com/android/car/messenger/core/ui/launcher/MessageLauncherViewModel.java @@ -17,14 +17,17 @@ package com.android.car.messenger.core.ui.launcher; import android.app.Application; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.Transformations; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; + import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.interfaces.DataModel; import com.android.car.messenger.core.models.UserAccount; + import java.util.List; import java.util.stream.Collectors; diff --git a/src/com/android/car/messenger/core/util/VoiceUtil.java b/src/com/android/car/messenger/core/util/VoiceUtil.java index bd7997b..7791b1b 100644 --- a/src/com/android/car/messenger/core/util/VoiceUtil.java +++ b/src/com/android/car/messenger/core/util/VoiceUtil.java @@ -29,7 +29,6 @@ import static com.android.car.assist.CarVoiceInteractionSession.VOICE_ACTION_REP import static com.android.car.assist.CarVoiceInteractionSession.VOICE_ACTION_SEND_SMS; import static com.android.car.messenger.core.shared.MessageConstants.ACTION_DIRECT_SEND; import static com.android.car.messenger.core.shared.MessageConstants.ACTION_MARK_AS_READ; -import static com.android.car.messenger.core.shared.MessageConstants.ACTION_MUTE; import static com.android.car.messenger.core.shared.MessageConstants.ACTION_REPLY; import static com.android.car.messenger.core.shared.MessageConstants.EXTRA_ACCOUNT_ID; import static com.android.car.messenger.core.shared.MessageConstants.EXTRA_CONVERSATION_KEY; @@ -189,23 +188,9 @@ public class VoiceUtil { markAsReadIntent), null); - final int muteIcon = R.drawable.car_ui_icon_toggle_mute; - final String muteString = context.getString(R.string.action_mute); - PendingIntent muteIntent = createServiceIntent(ACTION_MUTE, conversationKey, userAccountId); - ConversationAction muteAction = - new ConversationAction( - ActionType.ACTION_TYPE_MUTE, - new RemoteAction( - Icon.createWithResource(context, muteIcon), - muteString, - muteString, - muteIntent), - null); - List<ConversationAction> actions = new ArrayList<>(); actions.add(replyAction); actions.add(markAsReadAction); - actions.add(muteAction); builder.setActions(actions); return builder.build(); } diff --git a/src/com/android/car/messenger/impl/datamodels/ContentProviderLiveData.java b/src/com/android/car/messenger/impl/datamodels/ContentProviderLiveData.java index fbd6d14..bf3ebae 100644 --- a/src/com/android/car/messenger/impl/datamodels/ContentProviderLiveData.java +++ b/src/com/android/car/messenger/impl/datamodels/ContentProviderLiveData.java @@ -19,8 +19,10 @@ package com.android.car.messenger.impl.datamodels; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.lifecycle.MediatorLiveData; + import com.android.car.messenger.core.interfaces.AppFactory; /** diff --git a/src/com/android/car/messenger/impl/datamodels/ConversationsPerDeviceFetchManager.java b/src/com/android/car/messenger/impl/datamodels/ConversationsPerDeviceFetchManager.java index 379e922..19689de 100644 --- a/src/com/android/car/messenger/impl/datamodels/ConversationsPerDeviceFetchManager.java +++ b/src/com/android/car/messenger/impl/datamodels/ConversationsPerDeviceFetchManager.java @@ -25,13 +25,16 @@ import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.telephony.SubscriptionInfo; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import androidx.lifecycle.MediatorLiveData; import androidx.lifecycle.Observer; + import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.models.UserAccount; + import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; diff --git a/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java b/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java index 05e5c57..2195bc5 100644 --- a/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java +++ b/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java @@ -125,6 +125,13 @@ public class NewMessageLiveData extends ContentProviderLiveData<Conversation> { Conversation conversation; try { conversation = fetchConversation(conversationId); + Instant offset = + Objects.requireNonNull( + mOffsetMap.getOrDefault( + userAccount.getId(), userAccount.getConnectionTime())); + conversation + .getMessages() + .removeIf(message -> message.getTimestamp() < offset.toEpochMilli()); conversation.getExtras().putInt(MessageConstants.EXTRA_ACCOUNT_ID, userAccount.getId()); } catch (CursorIndexOutOfBoundsException e) { L.w("Error occurred fetching conversation Id " + conversationId); diff --git a/src/com/android/car/messenger/impl/datamodels/TelephonyDataModel.java b/src/com/android/car/messenger/impl/datamodels/TelephonyDataModel.java index 40568cc..82a3d0a 100644 --- a/src/com/android/car/messenger/impl/datamodels/TelephonyDataModel.java +++ b/src/com/android/car/messenger/impl/datamodels/TelephonyDataModel.java @@ -18,15 +18,17 @@ package com.android.car.messenger.impl.datamodels; import static com.android.car.messenger.core.shared.MessageConstants.KEY_MUTED_CONVERSATIONS; -import androidx.lifecycle.Transformations; import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.net.Uri; import android.provider.Telephony; import android.telephony.SmsManager; + import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; +import androidx.lifecycle.Transformations; + import com.android.car.messenger.common.Conversation; import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.interfaces.DataModel; @@ -34,6 +36,7 @@ import com.android.car.messenger.core.models.UserAccount; import com.android.car.messenger.core.util.L; import com.android.car.messenger.impl.datamodels.UserAccountLiveData.UserAccountChangeList; import com.android.car.messenger.impl.datamodels.util.CursorUtils; + import java.util.Collection; import java.util.HashSet; import java.util.Set; diff --git a/src/com/android/car/messenger/impl/datamodels/UserAccountLiveData.java b/src/com/android/car/messenger/impl/datamodels/UserAccountLiveData.java index feaecea..b5314dd 100644 --- a/src/com/android/car/messenger/impl/datamodels/UserAccountLiveData.java +++ b/src/com/android/car/messenger/impl/datamodels/UserAccountLiveData.java @@ -20,12 +20,15 @@ import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener; import android.telephony.TelephonyManager; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; + import com.android.car.messenger.core.interfaces.AppFactory; import com.android.car.messenger.core.models.UserAccount; import com.android.car.messenger.impl.datamodels.UserAccountLiveData.UserAccountChangeList; + import java.time.Instant; import java.util.ArrayList; import java.util.Collection; diff --git a/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java b/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java index 8da6318..555d91c 100644 --- a/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java +++ b/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java @@ -130,6 +130,16 @@ public final class MessageUtils { L.d("Message was not able to be parsed. Skipping."); continue; } + if (message.getText().trim().isEmpty()) { + // There are occasions where a user may send + // a text message plus an image or audio and + // bluetooth will post two messages to the database (b/182834412), + // one with a text and one blank + // This leads to boomerang notifications, one with text and one that is empty. + // Validating or removing messages when blank is a mitigation on our end. + L.d("Message is blank. Skipped. "); + continue; + } if (message.getMessageType() == MessageType.MESSAGE_TYPE_SENT) { hasBeenRepliedTo = true; } @@ -138,25 +148,6 @@ public final class MessageUtils { } /** - * Parses each message in the cursor and returns the item for further processing - * - * @param messageCursor The message cursor to be parsed for SMS and MMS messages and returns - * true for the method to continue parsing the cursor or false to return. - */ - @Nullable - public static Message parseCurrentMessage(@NonNull Cursor messageCursor) { - Message message = null; - Context context = AppFactory.get().getContext(); - try { - message = parseMessageAtPoint(context, messageCursor, false); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - L.d("Message was not able to be parsed. Skipping."); - } - return message; - } - - /** * Parses message at the point in cursor. * * @throws IllegalArgumentException if desired columns are missing. diff --git a/src/com/android/car/messenger/impl/datamodels/util/MmsUtils.java b/src/com/android/car/messenger/impl/datamodels/util/MmsUtils.java index 808ce86..7f87e69 100644 --- a/src/com/android/car/messenger/impl/datamodels/util/MmsUtils.java +++ b/src/com/android/car/messenger/impl/datamodels/util/MmsUtils.java @@ -82,6 +82,7 @@ class MmsUtils { stringBuilder.append(cursor.getString(cursor.getColumnIndex(Part.TEXT))); stringBuilder.append(" "); } + return stringBuilder.toString().replace(REPLACE_CHARS, ""); } |