Messaging: Let there be lambdas

Change-Id: Iee1fc46c92ea9159abb10d92d34baee937bdee0c
This commit is contained in:
Michael W
2024-12-26 14:55:12 +01:00
parent c1b4aa4dfe
commit d43b6ff1c4
84 changed files with 991 additions and 1697 deletions
@@ -51,7 +51,6 @@ import com.android.messaging.datamodel.data.ConversationData.ConversationDataLis
import com.android.messaging.datamodel.data.ConversationData.SimpleConversationDataListener;
import com.android.messaging.datamodel.data.DraftMessageData;
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftForSendTask;
import com.android.messaging.datamodel.data.DraftMessageData.CheckDraftTaskCallback;
import com.android.messaging.datamodel.data.DraftMessageData.DraftMessageDataListener;
import com.android.messaging.datamodel.data.MessageData;
import com.android.messaging.datamodel.data.MessagePartData;
@@ -197,20 +196,14 @@ public class ComposeMessageView extends LinearLayout
R.id.compose_message_text);
mComposeEditText.setOnEditorActionListener(this);
mComposeEditText.addTextChangedListener(this);
mComposeEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(final View v, final boolean hasFocus) {
if (v == mComposeEditText && hasFocus) {
mHost.onComposeEditTextFocused();
}
mComposeEditText.setOnFocusChangeListener((v, hasFocus) -> {
if (v == mComposeEditText && hasFocus) {
mHost.onComposeEditTextFocused();
}
});
mComposeEditText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (mHost.shouldHideAttachmentsWhenSimSelectorShown()) {
hideSimSelector();
}
mComposeEditText.setOnClickListener(arg0 -> {
if (mHost.shouldHideAttachmentsWhenSimSelectorShown()) {
hideSimSelector();
}
});
@@ -221,26 +214,20 @@ public class ComposeMessageView extends LinearLayout
.getMaxTextLimit()) });
mSelfSendIcon = (SimIconView) findViewById(R.id.self_send_icon);
mSelfSendIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mSelfSendIcon.setOnClickListener(v -> {
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
getSelfSubscriptionListEntry());
hideAttachmentsWhenShowingSims(shown);
});
mSelfSendIcon.setOnLongClickListener(v -> {
if (mHost.shouldShowSubjectEditor()) {
showSubjectEditor();
} else {
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
getSelfSubscriptionListEntry());
hideAttachmentsWhenShowingSims(shown);
}
});
mSelfSendIcon.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(final View v) {
if (mHost.shouldShowSubjectEditor()) {
showSubjectEditor();
} else {
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
getSelfSubscriptionListEntry());
hideAttachmentsWhenShowingSims(shown);
}
return true;
}
return true;
});
mComposeSubjectText = (PlainTextEditText) findViewById(
@@ -255,35 +242,25 @@ public class ComposeMessageView extends LinearLayout
.getMaxSubjectLength())});
mDeleteSubjectButton = (ImageButton) findViewById(R.id.delete_subject_button);
mDeleteSubjectButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View clickView) {
hideSubjectEditor();
mComposeSubjectText.setText(null);
mBinding.getData().setMessageSubject(null);
}
mDeleteSubjectButton.setOnClickListener(clickView -> {
hideSubjectEditor();
mComposeSubjectText.setText(null);
mBinding.getData().setMessageSubject(null);
});
mSubjectView = findViewById(R.id.subject_view);
mSendButton = (ImageButton) findViewById(R.id.send_message_button);
mSendButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View clickView) {
sendMessageInternal(true /* checkMessageSize */);
}
});
mSendButton.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(final View arg0) {
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
getSelfSubscriptionListEntry());
hideAttachmentsWhenShowingSims(shown);
if (mHost.shouldShowSubjectEditor()) {
showSubjectEditor();
}
return true;
mSendButton.setOnClickListener(clickView ->
sendMessageInternal(true /* checkMessageSize */));
mSendButton.setOnLongClickListener(arg0 -> {
boolean shown = mInputManager.toggleSimSelector(true /* animate */,
getSelfSubscriptionListEntry());
hideAttachmentsWhenShowingSims(shown);
if (mHost.shouldShowSubjectEditor()) {
showSubjectEditor();
}
return true;
});
mSendButton.setAccessibilityDelegate(new AccessibilityDelegate() {
@Override
@@ -306,12 +283,9 @@ public class ComposeMessageView extends LinearLayout
mAttachMediaButton =
(ImageButton) findViewById(R.id.attach_media_button);
mAttachMediaButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View clickView) {
// Showing the media picker is treated as starting to compose the message.
mInputManager.showHideMediaPicker(true /* show */, true /* animate */);
}
mAttachMediaButton.setOnClickListener(clickView -> {
// Showing the media picker is treated as starting to compose the message.
mInputManager.showHideMediaPicker(true /* show */, true /* animate */);
});
mAttachmentPreview = (AttachmentPreview) findViewById(R.id.attachment_draft_view);
@@ -394,69 +368,60 @@ public class ComposeMessageView extends LinearLayout
mBinding.getData().setMessageSubject(subject);
// Asynchronously check the draft against various requirements before sending.
mBinding.getData().checkDraftForAction(checkMessageSize,
mHost.getConversationSelfSubId(), new CheckDraftTaskCallback() {
@Override
public void onDraftChecked(DraftMessageData data, int result) {
mBinding.ensureBound(data);
switch (result) {
case CheckDraftForSendTask.RESULT_PASSED:
// Continue sending after check succeeded.
final MessageData message = mBinding.getData()
.prepareMessageForSending(mBinding);
if (message != null && message.hasContent()) {
playSentSound();
mHost.sendMessage(message);
hideSubjectEditor();
if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) {
AccessibilityUtil.announceForAccessibilityCompat(
ComposeMessageView.this, null,
R.string.sending_message);
mHost.getConversationSelfSubId(), (data, result) -> {
mBinding.ensureBound(data);
switch (result) {
case CheckDraftForSendTask.RESULT_PASSED:
// Continue sending after check succeeded.
final MessageData message = mBinding.getData()
.prepareMessageForSending(mBinding);
if (message != null && message.hasContent()) {
playSentSound();
mHost.sendMessage(message);
hideSubjectEditor();
if (AccessibilityUtil.isTouchExplorationEnabled(getContext())) {
AccessibilityUtil.announceForAccessibilityCompat(
ComposeMessageView.this, null,
R.string.sending_message);
}
}
}
break;
break;
case CheckDraftForSendTask.RESULT_HAS_PENDING_ATTACHMENTS:
// Cannot send while there's still attachment(s) being loaded.
UiUtils.showToastAtBottom(
R.string.cant_send_message_while_loading_attachments);
break;
case CheckDraftForSendTask.RESULT_HAS_PENDING_ATTACHMENTS:
// Cannot send while there's still attachment(s) being loaded.
UiUtils.showToastAtBottom(
R.string.cant_send_message_while_loading_attachments);
break;
case CheckDraftForSendTask.RESULT_NO_SELF_PHONE_NUMBER_IN_GROUP_MMS:
mHost.promptForSelfPhoneNumber();
break;
case CheckDraftForSendTask.RESULT_NO_SELF_PHONE_NUMBER_IN_GROUP_MMS:
mHost.promptForSelfPhoneNumber();
break;
case CheckDraftForSendTask.RESULT_MESSAGE_OVER_LIMIT:
Assert.isTrue(checkMessageSize);
mHost.warnOfExceedingMessageLimit(
true /*sending*/, false /* tooManyVideos */);
break;
case CheckDraftForSendTask.RESULT_MESSAGE_OVER_LIMIT:
Assert.isTrue(checkMessageSize);
mHost.warnOfExceedingMessageLimit(
true /*sending*/, false /* tooManyVideos */);
break;
case CheckDraftForSendTask.RESULT_VIDEO_ATTACHMENT_LIMIT_EXCEEDED:
Assert.isTrue(checkMessageSize);
mHost.warnOfExceedingMessageLimit(
true /*sending*/, true /* tooManyVideos */);
break;
case CheckDraftForSendTask.RESULT_VIDEO_ATTACHMENT_LIMIT_EXCEEDED:
Assert.isTrue(checkMessageSize);
mHost.warnOfExceedingMessageLimit(
true /*sending*/, true /* tooManyVideos */);
break;
case CheckDraftForSendTask.RESULT_SIM_NOT_READY:
// Cannot send if there is no active subscription
UiUtils.showToastAtBottom(
R.string.cant_send_message_without_active_subscription);
break;
case CheckDraftForSendTask.RESULT_SIM_NOT_READY:
// Cannot send if there is no active subscription
UiUtils.showToastAtBottom(
R.string.cant_send_message_without_active_subscription);
break;
default:
break;
}
}
}, mBinding);
} else {
mHost.warnOfMissingActionConditions(true /*sending*/,
new Runnable() {
@Override
public void run() {
sendMessageInternal(checkMessageSize);
default:
break;
}
});
}, mBinding);
} else {
mHost.warnOfMissingActionConditions(true /*sending*/, () ->
sendMessageInternal(checkMessageSize));
}
}
@@ -110,12 +110,9 @@ public class ConversationFastScroller extends RecyclerView.OnScrollListener impl
private AnimatorSet mHideAnimation;
private ObjectAnimator mHidePreviewAnimation;
private final Runnable mHideTrackRunnable = new Runnable() {
@Override
public void run() {
hide(true /* animate */);
mPendingHide = false;
}
private final Runnable mHideTrackRunnable = () -> {
hide(true /* animate */);
mPendingHide = false;
};
private ConversationFastScroller(RecyclerView rv, int position) {
@@ -28,10 +28,6 @@ import android.content.BroadcastReceiver;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
@@ -420,19 +416,13 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
mAdapter = new ConversationMessageAdapter(getActivity(), null, this,
null,
// Sets the item click listener on the Recycler item views.
new View.OnClickListener() {
@Override
public void onClick(final View v) {
final ConversationMessageView messageView = (ConversationMessageView) v;
handleMessageClick(messageView);
}
v -> {
final ConversationMessageView messageView = (ConversationMessageView) v;
handleMessageClick(messageView);
},
new View.OnLongClickListener() {
@Override
public boolean onLongClick(final View view) {
selectMessage((ConversationMessageView) view);
return true;
}
view -> {
selectMessage((ConversationMessageView) view);
return true;
}
);
}
@@ -555,23 +545,17 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
view.setAlpha(0);
mPopupTransitionAnimation = new PopupTransitionAnimation(startRect, view);
mPopupTransitionAnimation.setOnStartCallback(new Runnable() {
@Override
public void run() {
final int startWidth = composeBubbleRect.width();
attachmentView.onMessageAnimationStart();
messageBubble.kickOffMorphAnimation(startWidth,
messageBubble.findViewById(R.id.message_text_and_info)
.getMeasuredWidth());
}
});
mPopupTransitionAnimation.setOnStopCallback(new Runnable() {
@Override
public void run() {
view.setAlpha(1);
dispatchAddFinished(holder);
}
});
mPopupTransitionAnimation.setOnStartCallback(() -> {
final int startWidth = composeBubbleRect.width();
attachmentView.onMessageAnimationStart();
messageBubble.kickOffMorphAnimation(startWidth,
messageBubble.findViewById(R.id.message_text_and_info)
.getMeasuredWidth());
});
mPopupTransitionAnimation.setOnStopCallback(() -> {
view.setAlpha(1);
dispatchAddFinished(holder);
});
mPopupTransitionAnimation.startAfterLayoutComplete();
mAddAnimations.add(holder);
return true;
@@ -827,13 +811,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
.setTitle(getResources().getQuantityString(
R.plurals.delete_conversations_confirmation_dialog_title, 1))
.setPositiveButton(R.string.delete_conversation_confirmation_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog,
final int button) {
deleteConversation();
}
})
(dialog, button) -> deleteConversation())
.setNegativeButton(R.string.delete_conversation_decline_button, null)
.show();
} else {
@@ -894,12 +872,9 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
UiUtils.showSnackBarWithCustomAction(getActivity(),
getView().getRootView(),
getString(R.string.in_conversation_notify_new_message_text),
SnackBar.Action.createCustomAction(new Runnable() {
@Override
public void run() {
scrollToBottom(true /* smoothScroll */);
mComposeMessageView.hideAllComposeInputs(false /* animate */);
}
SnackBar.Action.createCustomAction(() -> {
scrollToBottom(true /* smoothScroll */);
mComposeMessageView.hideAllComposeInputs(false /* animate */);
},
getString(R.string.in_conversation_notify_new_message_action)),
null /* interactions */,
@@ -1036,13 +1011,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
LogUtil.w(LogUtil.BUGLE_TAG, "Message can't be sent: conv participants not loaded");
}
} else {
warnOfMissingActionConditions(true /*sending*/,
new Runnable() {
@Override
public void run() {
sendMessage(message);
}
});
warnOfMissingActionConditions(true /*sending*/, () -> sendMessage(message));
}
}
@@ -1137,14 +1106,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
mBinding.getData().resendMessage(mBinding, messageId);
}
} else {
warnOfMissingActionConditions(true /*sending*/,
new Runnable() {
@Override
public void run() {
retrySend(messageId);
}
});
warnOfMissingActionConditions(true /*sending*/, () -> retrySend(messageId));
}
}
@@ -1154,12 +1116,8 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
.setTitle(R.string.delete_message_confirmation_dialog_title)
.setMessage(R.string.delete_message_confirmation_dialog_text)
.setPositiveButton(R.string.delete_message_confirmation_button,
new OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
mBinding.getData().deleteMessage(mBinding, messageId);
}
})
(dialog, which) ->
mBinding.getData().deleteMessage(mBinding, messageId))
.setNegativeButton(android.R.string.cancel, null);
builder.setOnDismissListener(dialog -> mHost.dismissActionMode());
builder.create().show();
@@ -1506,19 +1464,11 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
} else {
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_sending)
.setNegativeButton(R.string.attachment_limit_reached_send_anyway,
new OnClickListener() {
@Override
public void onClick(final DialogInterface dialog,
final int which) {
composeMessageView.sendMessageIgnoreMessageSizeLimit();
}
});
(dialog, which) ->
composeMessageView.sendMessageIgnoreMessageSizeLimit());
}
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
@Override
public void onClick(final DialogInterface dialog, final int which) {
showAttachmentChooser(conversationId, activity);
}});
builder.setPositiveButton(android.R.string.ok, (dialog, which) ->
showAttachmentChooser(conversationId, activity));
} else {
builder.setMessage(R.string.attachment_limit_reached_dialog_message_when_composing)
.setPositiveButton(android.R.string.ok, null);
@@ -1557,12 +1507,7 @@ public class ConversationFragment extends Fragment implements ConversationDataLi
final LayoutInflater inflator = (LayoutInflater)
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
customView = inflator.inflate(R.layout.action_bar_conversation_name, null);
customView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
onBackPressed();
}
});
customView.setOnClickListener(v -> onBackPressed());
actionBar.setCustomView(customView);
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -123,12 +124,9 @@ public class ConversationMessageView extends FrameLayout implements View.OnClick
@Override
protected void onFinishInflate() {
mContactIconView = (ContactIconView) findViewById(R.id.conversation_icon);
mContactIconView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(final View view) {
ConversationMessageView.this.performLongClick();
return true;
}
mContactIconView.setOnLongClickListener(view -> {
ConversationMessageView.this.performLongClick();
return true;
});
mMessageAttachmentsView = (LinearLayout) findViewById(R.id.message_attachments);
@@ -1044,40 +1042,13 @@ public class ConversationMessageView extends FrameLayout implements View.OnClick
}
// Sort photos in MultiAttachLayout in the same order as the ConversationImagePartsView
static final Comparator<MessagePartData> sImageComparator = new Comparator<MessagePartData>(){
@Override
public int compare(final MessagePartData x, final MessagePartData y) {
return x.getPartId().compareTo(y.getPartId());
}
};
static final Comparator<MessagePartData> sImageComparator =
Comparator.comparing(MessagePartData::getPartId);
static final Predicate<MessagePartData> sVideoFilter = new Predicate<MessagePartData>() {
@Override
public boolean apply(final MessagePartData part) {
return part.isVideo();
}
};
static final Predicate<MessagePartData> sAudioFilter = new Predicate<MessagePartData>() {
@Override
public boolean apply(final MessagePartData part) {
return part.isAudio();
}
};
static final Predicate<MessagePartData> sVCardFilter = new Predicate<MessagePartData>() {
@Override
public boolean apply(final MessagePartData part) {
return part.isVCard();
}
};
static final Predicate<MessagePartData> sImageFilter = new Predicate<MessagePartData>() {
@Override
public boolean apply(final MessagePartData part) {
return part.isImage();
}
};
static final Predicate<MessagePartData> sVideoFilter = MessagePartData::isVideo;
static final Predicate<MessagePartData> sAudioFilter = MessagePartData::isAudio;
static final Predicate<MessagePartData> sVCardFilter = MessagePartData::isVCard;
static final Predicate<MessagePartData> sImageFilter = MessagePartData::isImage;
interface AttachmentViewBinder {
void bindView(View view, MessagePartData attachment);
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,13 +49,10 @@ abstract class ConversationSimSelector extends ConversationInput {
if (mPendingShow != null && mDataReady) {
final boolean show = mPendingShow.first;
final boolean animate = mPendingShow.second;
ThreadUtil.getMainThreadHandler().post(new Runnable() {
@Override
public void run() {
// This will No-Op if we are no longer attached to the host.
mConversationInputBase.showHideInternal(ConversationSimSelector.this,
show, animate);
}
ThreadUtil.getMainThreadHandler().post(() -> {
// This will No-Op if we are no longer attached to the host.
mConversationInputBase.showHideInternal(ConversationSimSelector.this,
show, animate);
});
mPendingShow = null;
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +20,6 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -53,30 +53,18 @@ public class EnterSelfPhoneNumberDialog extends DialogFragment {
builder.setTitle(R.string.enter_phone_number_title)
.setMessage(R.string.enter_phone_number_text)
.setView(mEditText)
.setNegativeButton(android.R.string.cancel,
new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog,
final int button) {
dismiss();
}
})
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(final DialogInterface dialog,
final int button) {
final String newNumber = mEditText.getText().toString();
dismiss();
if (!TextUtils.isEmpty(newNumber)) {
savePhoneNumberInPrefs(newNumber);
// TODO: Remove this toast and just auto-send
// the message instead
UiUtils.showToast(
R.string
.toast_after_setting_default_sms_app_for_message_send);
}
}
.setNegativeButton(android.R.string.cancel, (dialog, button) -> dismiss())
.setPositiveButton(android.R.string.ok, (dialog, button) -> {
final String newNumber = mEditText.getText().toString();
dismiss();
if (!TextUtils.isEmpty(newNumber)) {
savePhoneNumberInPrefs(newNumber);
// TODO: Remove this toast and just auto-send
// the message instead
UiUtils.showToast(
R.string
.toast_after_setting_default_sms_app_for_message_send);
}
});
return builder.create();
}
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2024 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +19,6 @@ package com.android.messaging.ui.conversation;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -49,12 +49,7 @@ public class SimSelectorItemView extends LinearLayout {
mNameTextView = (TextView) findViewById(R.id.name);
mDetailsTextView = (TextView) findViewById(R.id.details);
mSimIconView = (SimIconView) findViewById(R.id.sim_icon);
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mHost.onSimItemClicked(mData);
}
});
setOnClickListener(v -> mHost.onSimItemClicked(mData));
}
public void bind(final SubscriptionListEntry simEntry) {
@@ -64,12 +64,7 @@ public class SimSelectorView extends FrameLayout implements SimSelectorItemView.
mSimListView.setAdapter(mAdapter);
// Clicking anywhere outside the switcher list should dismiss.
setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showOrHide(false, true);
}
});
setOnClickListener(v -> showOrHide(false, true));
}
public void bind(final SubscriptionListData data) {
@@ -102,12 +97,9 @@ public class SimSelectorView extends FrameLayout implements SimSelectorItemView.
setAlpha(mShow ? 0.0f : 1.0f);
animate().alpha(mShow ? 1.0f : 0.0f)
.setDuration(UiUtils.REVEAL_ANIMATION_DURATION)
.withEndAction(new Runnable() {
@Override
public void run() {
setAlpha(1.0f);
setVisibility(mShow ? VISIBLE : GONE);
}
.withEndAction(() -> {
setAlpha(1.0f);
setVisibility(mShow ? VISIBLE : GONE);
});
} else {
setVisibility(mShow ? VISIBLE : GONE);