further clean up on session restoration

This commit is contained in:
Ryan ZHAO 2021-02-23 11:56:03 +11:00
parent 690687064f
commit 2f57090cfa
10 changed files with 9 additions and 204 deletions

View File

@ -136,7 +136,6 @@ import org.thoughtcrime.securesms.loki.activities.EditClosedGroupActivity;
import org.thoughtcrime.securesms.loki.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.api.PublicChatInfoUpdateWorker;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabaseDelegate;
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2;
import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt;
@ -144,7 +143,6 @@ import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities;
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities;
import org.thoughtcrime.securesms.loki.views.MentionCandidateSelectionView;
import org.thoughtcrime.securesms.loki.views.ProfilePictureView;
import org.thoughtcrime.securesms.loki.views.SessionRestoreBannerView;
import org.thoughtcrime.securesms.mediasend.Media;
import org.thoughtcrime.securesms.mediasend.MediaSendActivity;
import org.thoughtcrime.securesms.mms.AttachmentManager;
@ -228,8 +226,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
InputPanel.Listener,
InputPanel.MediaListener,
ComposeText.CursorPositionChangedListener,
ConversationSearchBottomBar.EventListener,
LokiThreadDatabaseDelegate
ConversationSearchBottomBar.EventListener
{
private static final String TAG = ConversationActivity.class.getSimpleName();
@ -311,9 +308,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private ArrayList<Mention> mentions = new ArrayList<>();
private String oldText = "";
// Restoration
protected SessionRestoreBannerView sessionRestoreBannerView;
private final PushCharacterCalculator characterCalculator = new PushCharacterCalculator();
@Override
@ -383,17 +377,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
}
});
sessionRestoreBannerView.setOnRestore(() -> {
updateSessionRestoreBanner();
return Unit.INSTANCE;
});
sessionRestoreBannerView.setOnDismiss(() -> {
// TODO: Maybe silence for x minutes?
DatabaseFactory.getLokiThreadDatabase(ConversationActivity.this).removeAllSessionRestoreDevices(threadId);
updateSessionRestoreBanner();
return Unit.INSTANCE;
});
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(threadId, this);
PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId);
@ -483,12 +466,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
ApplicationContext.getInstance(this).messageNotifier.setVisibleThread(threadId);
markThreadAsRead();
DatabaseFactory.getLokiThreadDatabase(this).setDelegate(this);
inputPanel.setHint(getResources().getString(R.string.ConversationActivity_message));
updateSessionRestoreBanner();
Log.i(TAG, "onResume() Finished: " + (System.currentTimeMillis() - getIntent().getLongExtra(TIMING_EXTRA, 0)));
}
@ -553,13 +532,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
case PICK_AUDIO:
setMedia(data.getData(), MediaType.AUDIO);
break;
// case PICK_CONTACT:
// if (isSecureText && !isSmsForced()) {
//// openContactShareEditor(data.getData());
// } else {
// addAttachmentContactInfo(data.getData());
// }
// break;
case TAKE_PHOTO:
if (attachmentManager.getCaptureUri() != null) {
setMedia(attachmentManager.getCaptureUri(), MediaType.IMAGE);
@ -1322,16 +1294,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
return future;
}
private void updateSessionRestoreBanner() {
Set<String> devices = DatabaseFactory.getLokiThreadDatabase(this).getSessionRestoreDevices(threadId);
if (devices.size() > 0) {
sessionRestoreBannerView.update(recipient);
sessionRestoreBannerView.show();
} else {
sessionRestoreBannerView.hide();
}
}
private void initializeViews() {
profilePictureView = findViewById(R.id.profilePictureView);
titleTextView = findViewById(R.id.titleTextView);
@ -1350,7 +1312,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
searchNav = ViewUtil.findById(this, R.id.conversation_search_nav);
mentionCandidateSelectionViewContainer = ViewUtil.findById(this, R.id.mentionCandidateSelectionViewContainer);
mentionCandidateSelectionView = ViewUtil.findById(this, R.id.userSelectionView);
sessionRestoreBannerView = ViewUtil.findById(this, R.id.sessionRestoreBannerView);
messageStatusProgressBar = ViewUtil.findById(this, R.id.messageStatusProgressBar);
muteIndicatorImageView = ViewUtil.findById(this, R.id.muteIndicatorImageView);
subtitleTextView = ViewUtil.findById(this, R.id.subtitleTextView);
@ -1825,13 +1786,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
updateLinkPreviewState();
}
@Override
public void handleSessionRestoreDevicesChanged(long threadID) {
if (threadID == this.threadId) {
runOnUiThread(this::updateSessionRestoreBanner);
}
}
private void sendMessage() {
if (inputPanel.isRecordingInLockedMode()) {
inputPanel.releaseRecordingLock();

View File

@ -251,7 +251,8 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
"SmsSendJob",
"SmsSentJob",
"SmsReceiveJob",
"PushGroupUpdateJob");
"PushGroupUpdateJob",
"ResetThreadSessionJob");
}
db.setTransactionSuccessful();

View File

@ -15,13 +15,11 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint;
import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver;
import org.thoughtcrime.securesms.loki.api.PrepareAttachmentAudioExtrasJob;
import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob;
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJobV2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -50,7 +48,6 @@ public final class JobManagerFactories {
put(TypingSendJob.KEY, new TypingSendJob.Factory());
put(UpdateApkJob.KEY, new UpdateApkJob.Factory());
put(PrepareAttachmentAudioExtrasJob.KEY, new PrepareAttachmentAudioExtrasJob.Factory());
put(ResetThreadSessionJob.KEY, new ResetThreadSessionJob.Factory());
}};
factoryKeys.addAll(factoryHashMap.keySet());
return factoryHashMap;

View File

@ -28,11 +28,9 @@ import network.loki.messenger.R
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
import org.thoughtcrime.securesms.conversation.ConversationActivity
import org.session.libsession.messaging.threads.Address
import org.session.libsession.utilities.GroupUtil
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob
import org.thoughtcrime.securesms.loki.utilities.*
import org.thoughtcrime.securesms.loki.views.ConversationView
import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetViewDelegate
@ -40,8 +38,6 @@ import org.thoughtcrime.securesms.loki.views.SeedReminderViewDelegate
import org.thoughtcrime.securesms.mms.GlideApp
import org.thoughtcrime.securesms.mms.GlideRequests
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.TextSecurePreferences.getBooleanPreference
import org.session.libsession.utilities.TextSecurePreferences.setBooleanPreference
import org.session.libsession.utilities.Util
import org.session.libsignal.service.loki.utilities.mentions.MentionsManager
import org.session.libsignal.utilities.ThreadUtils

View File

@ -22,7 +22,7 @@ class ClosedGroupPoller private constructor(private val context: Context) {
override fun run() {
poll()
handler.postDelayed(this, ClosedGroupPoller.pollInterval)
handler.postDelayed(this, pollInterval)
}
}
@ -40,24 +40,24 @@ class ClosedGroupPoller private constructor(private val context: Context) {
// endregion
// region Error
public class InsufficientSnodesException() : Exception("No snodes left to poll.")
public class PollingCanceledException() : Exception("Polling canceled.")
class InsufficientSnodesException() : Exception("No snodes left to poll.")
class PollingCanceledException() : Exception("Polling canceled.")
// endregion
// region Public API
public fun startIfNeeded() {
fun startIfNeeded() {
if (isPolling) { return }
isPolling = true
task.run()
}
public fun pollOnce(): List<Promise<Unit, Exception>> {
fun pollOnce(): List<Promise<Unit, Exception>> {
if (isPolling) { return listOf() }
isPolling = true
return poll()
}
public fun stopIfNeeded() {
fun stopIfNeeded() {
isPolling = false
handler.removeCallbacks(task)
}

View File

@ -1,71 +0,0 @@
package org.thoughtcrime.securesms.loki.api
import org.session.libsession.messaging.jobs.Data
import org.session.libsession.messaging.threads.Address
import org.thoughtcrime.securesms.jobmanager.Job
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
import org.thoughtcrime.securesms.jobs.BaseJob
import org.session.libsignal.utilities.logging.Log
import org.session.libsession.messaging.threads.recipients.Recipient
import org.thoughtcrime.securesms.sms.MessageSender
import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage
import org.thoughtcrime.securesms.sms.OutgoingTextMessage
import java.util.concurrent.TimeUnit
class ResetThreadSessionJob private constructor(
parameters: Parameters,
private val address: Address,
private val threadId: Long)
: BaseJob(parameters) {
companion object {
const val KEY = "ResetThreadSessionJob"
const val DATA_KEY_ADDRESS = "address"
const val DATA_KEY_THREAD_ID = "thread_id"
}
constructor(address: Address, threadId: Long) : this(Parameters.Builder()
.addConstraint(NetworkConstraint.KEY)
.setQueue(KEY)
.setLifespan(TimeUnit.DAYS.toMillis(1))
.setMaxAttempts(Parameters.UNLIMITED)
.build(),
address,
threadId)
override fun serialize(): Data {
return Data.Builder()
.putParcelable(DATA_KEY_ADDRESS, address)
.putLong(DATA_KEY_THREAD_ID, threadId)
.build()
}
override fun getFactoryKey(): String { return KEY }
public override fun onRun() {
val recipient = Recipient.from(context, address, false)
// Only reset sessions for private chats.
if (recipient.isGroupRecipient) return
Log.v(KEY, "Resetting session for thread: \"$threadId\", recipient: \"${address.serialize()}\"")
val message = OutgoingEndSessionMessage(OutgoingTextMessage(recipient, "TERMINATE", 0, -1))
MessageSender.send(context, message, threadId, false, null)
}
public override fun onShouldRetry(e: Exception): Boolean {
return false
}
override fun onCanceled() { }
class Factory : Job.Factory<ResetThreadSessionJob> {
override fun create(parameters: Parameters, data: Data): ResetThreadSessionJob {
val address = data.getParcelable(DATA_KEY_ADDRESS, Address.CREATOR)!!
val threadId = data.getLong(DATA_KEY_THREAD_ID)
return ResetThreadSessionJob(parameters, address, threadId)
}
}
}

View File

@ -19,7 +19,6 @@ import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol
import org.session.libsignal.service.loki.utilities.PublicKeyValidation
class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiThreadDatabaseProtocol {
var delegate: LokiThreadDatabaseDelegate? = null
companion object {
private val sessionResetTable = "loki_thread_session_reset_database"
@ -83,24 +82,4 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa
override fun removePublicChat(threadID: Long) {
databaseHelper.writableDatabase.delete(publicChatTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() ))
}
fun addSessionRestoreDevice(threadID: Long, publicKey: String) {
val devices = getSessionRestoreDevices(threadID).toMutableSet()
if (devices.add(publicKey)) {
TextSecurePreferences.setStringPreference(context, "session_restore_devices_$threadID", devices.joinToString(","))
delegate?.handleSessionRestoreDevicesChanged(threadID)
}
}
fun getSessionRestoreDevices(threadID: Long): Set<String> {
return TextSecurePreferences.getStringPreference(context, "session_restore_devices_$threadID", "")!!
.split(",")
.filter { PublicKeyValidation.isValid(it) }
.toSet()
}
fun removeAllSessionRestoreDevices(threadID: Long) {
TextSecurePreferences.setStringPreference(context, "session_restore_devices_$threadID", "")
delegate?.handleSessionRestoreDevicesChanged(threadID)
}
}

View File

@ -1,6 +0,0 @@
package org.thoughtcrime.securesms.loki.database
interface LokiThreadDatabaseDelegate {
fun handleSessionRestoreDevicesChanged(threadID: Long)
}

View File

@ -1,40 +0,0 @@
package org.thoughtcrime.securesms.loki.views
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import kotlinx.android.synthetic.main.session_restore_banner.view.*
import network.loki.messenger.R
import org.session.libsession.messaging.threads.recipients.Recipient
class SessionRestoreBannerView : LinearLayout {
lateinit var recipient: Recipient
var onDismiss: (() -> Unit)? = null
var onRestore: (() -> Unit)? = null
constructor(context: Context) : super(context, null)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init {
LayoutInflater.from(context).inflate(R.layout.session_restore_banner, this, true)
restoreButton.setOnClickListener { onRestore?.invoke() }
dismissButton.setOnClickListener { onDismiss?.invoke() }
}
fun update(recipient: Recipient) {
this.recipient = recipient
messageTextView.text = context.getString(R.string.session_reset_banner_message, recipient.toShortString())
}
fun show() {
sessionRestoreBanner.visibility = View.VISIBLE
}
fun hide() {
sessionRestoreBanner.visibility = View.GONE
}
}

View File

@ -134,11 +134,6 @@
android:background="?android:dividerHorizontal"
android:elevation="1dp" />
<org.thoughtcrime.securesms.loki.views.SessionRestoreBannerView
android:id="@+id/sessionRestoreBannerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ViewStub
android:id="@+id/group_share_profile_view_stub"
android:layout_width="match_parent"