aut resend failed message

This commit is contained in:
Arne 2022-07-05 23:21:38 +02:00
parent fedf46a6be
commit e665ca2b0d
8 changed files with 80 additions and 3 deletions

View file

@ -263,6 +263,19 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
onMessageFound.onMessageFound(result);
}
}
public void findResendAbleFailedMessage(OnMessageFound onMessageFound) {
final ArrayList<Message> results = new ArrayList<>();
synchronized (this.messages) {
for (final Message message : this.messages) {
if (message.getStatus() == Message.STATUS_SEND_FAILED && !message.isFileOrImage()) {
results.add(message);
}
}
}
for (final Message result : results) {
onMessageFound.onMessageFound(result);
}
}
public void findUnreadMessagesAndCalls(OnMessageFound onMessageFound) {
final ArrayList<Message> results = new ArrayList<>();

View file

@ -124,6 +124,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
private String errorMessage = null;
private Set<ReadByMarker> readByMarkers = new CopyOnWriteArraySet<>();
private String retractId = null;
protected int resendCount = 0;
private Boolean isGeoUri = null;
private Boolean isXmppUri = null;
@ -1127,4 +1128,11 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
message.setType(isFile ? Message.TYPE_PRIVATE_FILE : Message.TYPE_PRIVATE);
return true;
}
public int getResendCount(){
return resendCount;
}
public int increaseResendCount(){
return ++resendCount;
}
}

View file

@ -15,6 +15,8 @@ import static eu.siacs.conversations.ui.SettingsActivity.SHOW_OWN_ACCOUNTS;
import static eu.siacs.conversations.ui.SettingsActivity.USE_INNER_STORAGE;
import static eu.siacs.conversations.utils.RichPreview.RICH_LINK_METADATA;
import static eu.siacs.conversations.utils.StorageHelper.getAppMediaDirectory;
import android.content.res.Resources;
import android.os.Handler;
import android.Manifest;
import androidx.annotation.RequiresApi;
@ -231,6 +233,7 @@ public class XmppConnectionService extends Service {
private final SerialSingleThreadExecutor mNotificationExecutor = new SerialSingleThreadExecutor("NotificationExecutor");
public final SerialSingleThreadExecutor mWebPreviewExecutor = new SerialSingleThreadExecutor("WebPreview");
public final SerialSingleThreadExecutor mNotificationChannelExecutor = new SerialSingleThreadExecutor("updateNotificationChannels");
public final SerialSingleThreadExecutor mMessageResendTaskExecuter = new SerialSingleThreadExecutor("MessageResender");
private final ReplacingTaskManager mRosterSyncTaskManager = new ReplacingTaskManager();
private final IBinder mBinder = new XmppConnectionBinder();
private final List<Conversation> conversations = new CopyOnWriteArrayList<>();
@ -881,6 +884,7 @@ public class XmppConnectionService extends Service {
for (Conversation conversation : conversations) {
if (conversation.getAccount() == account && !account.pendingConferenceJoins.contains(conversation)) {
resendFailedFileMessages(conversation);
resendFailedMessages(conversation);
}
}
final boolean lowTimeout = isInLowPingTimeoutMode(account);
@ -911,7 +915,9 @@ public class XmppConnectionService extends Service {
}
}
}
public int maxResendTime(){
return Integer.parseInt(getPreferences().getString(SettingsActivity.MAX_RESEND_TIME, getResources().getString(R.string.max_resend_time)));
}
private void deleteWebpreviewCache() {
new Thread(() -> {
try {
@ -1993,7 +1999,18 @@ public class XmppConnectionService extends Service {
mDatabaseWriterExecutor.execute((runnable));
}
private void resendFailedMessages(final Conversation conversation) {
final Runnable runnable = () -> {
conversation.findResendAbleFailedMessage(message -> {
if (message.increaseResendCount() < maxResendTime()) {
Log.d(Config.LOGTAG, "Resend failed message " + message.getErrorMessage() + " at times " + message.getResendCount() + " bytes for " + conversation.getJid());
// because it'll use a custom delay here, only the last time will delay the message.
resendFailedMessages(message);
}
});
};
mMessageResendTaskExecuter.execute((runnable));
}
private void resendFailedFileMessages(final Conversation conversation) {
final Runnable runnable = () -> {
conversation.findFailedMessagesWithFiles(message -> {
@ -4563,8 +4580,25 @@ public class XmppConnectionService extends Service {
updateConversationUi();
if (oldStatus != status && status == Message.STATUS_SEND_FAILED) {
mNotificationService.pushFailedDelivery(message);
// resend it
mMessageResendTaskExecuter.execute(() -> {
try {
if (message.increaseResendCount() <= maxResendTime() / 2) {
Thread.sleep(resendDelay());
resendFailedMessages(message);
}
}
catch (Exception ignore){
// if system halt, give it up
Log.w(Config.LOGTAG,"System Halt, so the message resend give up");
}
});
}
}
private long resendDelay() {
return Long.parseLong(getPreferences().getString(SettingsActivity.RESEND_DELAY, getResources().getString(R.string.resend_delay)));
}
public SharedPreferences getPreferences() {
return PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

View file

@ -93,6 +93,8 @@ public class SettingsActivity extends XmppActivity implements
public static final String MIN_ANDROID_SDK21_SHOWN = "min_android_sdk21_shown";
public static final String INDIVIDUAL_NOTIFICATION_PREFIX = "individual_notification_set_";
public static final String PAUSE_VOICE = "pause_voice_on_move_from_ear";
public static final String MAX_RESEND_TIME = "max_resend_time";
public static final String RESEND_DELAY = "resend_delay";
public static final int REQUEST_CREATE_BACKUP = 0xbf8701;
public static final int REQUEST_IMPORT_SETTINGS = 0xbf8702;

View file

@ -277,7 +277,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
break;
case Message.STATUS_SEND_FAILED:
DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message);
if (isResendable && file.exists()) {
if (isResendable && file.exists() || message.getResendCount() < activity.xmppConnectionService.maxResendTime()) {
info = getContext().getString(R.string.send_failed_resend);
} else {
final String errorMessage = message.getErrorMessage();

View file

@ -93,6 +93,8 @@
<integer name="low_video_res">360</integer>
<integer name="mid_video_res">720</integer>
<integer name="high_video_res">1080</integer>
<string name="max_resend_time">4</string>
<string name="resend_delay">500</string>
<bool name="easy_downloader">false</bool>
<bool name="hide_memory_warning">false</bool>
<bool name="pause_voice">false</bool>

View file

@ -1204,4 +1204,8 @@
<string name="download_failed_invalid_file">Download failed: Invalid file</string>
<string name="orbot_not_found">Orbot not found</string>
<string name="account_status_temporary_auth_failure">Temporary authentication failure</string>
<string name="pref_max_resend_time_title">Max Time of resend failed Message</string>
<string name="pref_max_resend_time_summary">When plain message send fail, the max time to resend it. when resend count bigger than half max time, message will be delay for traffic reason.</string>
<string name="pref_resend_delay_title">Resend Delay (MillsSecond)</string>
<string name="pref_resend_delay_summary">Resend Delay (MillsSecond), the time for delay resend.</string>
</resources>

View file

@ -474,6 +474,20 @@
android:targetClass="com.huawei.systemmanager.optimize.process.ProtectActivity"
android:targetPackage="com.huawei.systemmanager" />
</PreferenceScreen>
<EditTextPreference
android:defaultValue="@string/max_resend_time"
android:key="max_resend_time"
android:summary="@string/pref_max_resend_time_summary"
android:title="@string/pref_max_resend_time_title"
android:inputType="number"
/>
<EditTextPreference
android:defaultValue="@string/resend_delay"
android:key="resend_delay"
android:summary="@string/pref_resend_delay_summary"
android:title="@string/pref_resend_delay_title"
android:inputType="number"
/>
<CheckBoxPreference
android:defaultValue="@bool/enable_multi_accounts"
android:key="enable_multi_accounts"