From 51856138e3ae23606c7f5ad04756a6db89ee5390 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 24 Apr 2023 15:38:06 +1000 Subject: [PATCH 01/19] refactor on SignalAudioManager --- .../securesms/service/WebRtcCallService.kt | 1 + .../securesms/webrtc/CallManager.kt | 4 + .../webrtc/audio/SignalAudioManager.kt | 99 +++++++++---------- .../libsignal/utilities/ThreadUtils.kt | 9 +- 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt index b5e9b78a74..3ae3d30f01 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt @@ -799,6 +799,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener { wantsToAnswerReceiver?.let { receiver -> LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver) } + callManager.shutDownAudioManager() powerButtonReceiver = null wiredHeadsetStateReceiver = null networkChangedReceiver = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt index 07e73bedd2..d96de5eedb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt @@ -93,6 +93,10 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va peerConnectionObservers.remove(listener) } + fun shutDownAudioManager() { + signalAudioManager.shutdown() + } + private val _audioEvents = MutableStateFlow(AudioEnabled(false)) val audioEvents = _audioEvents.asSharedFlow() private val _videoEvents = MutableStateFlow(VideoEnabled(false)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt index 67514c58be..6eb1304430 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt @@ -9,6 +9,7 @@ import android.media.SoundPool import android.os.HandlerThread import network.loki.messenger.R import org.session.libsignal.utilities.Log +import org.session.libsignal.utilities.ThreadUtils import org.thoughtcrime.securesms.webrtc.AudioManagerCommand import org.thoughtcrime.securesms.webrtc.audio.SignalBluetoothManager.State as BState @@ -32,10 +33,10 @@ class SignalAudioManager(private val context: Context, private val eventListener: EventListener?, private val androidAudioManager: AudioManagerCompat) { - private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio").apply { start() } - private var handler: SignalAudioHandler? = null + private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio", ThreadUtils.PRIORITY_IMPORTANT_BACKGROUND_THREAD).apply { start() } + private var handler: SignalAudioHandler? = SignalAudioHandler(commandAndControlThread!!.looper) - private var signalBluetoothManager: SignalBluetoothManager? = null + private var signalBluetoothManager: SignalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler!!) private var state: State = State.UNINITIALIZED @@ -62,12 +63,9 @@ class SignalAudioManager(private val context: Context, private var wiredHeadsetReceiver: WiredHeadsetReceiver? = null fun handleCommand(command: AudioManagerCommand) { - if (command == AudioManagerCommand.Initialize) { - initialize() - return - } handler?.post { when (command) { + is AudioManagerCommand.Initialize -> initialize() is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState() is AudioManagerCommand.Start -> start() is AudioManagerCommand.Stop -> stop(command.playDisconnect) @@ -84,34 +82,37 @@ class SignalAudioManager(private val context: Context, Log.i(TAG, "Initializing audio manager state: $state") if (state == State.UNINITIALIZED) { - commandAndControlThread = HandlerThread("call-audio").apply { start() } - handler = SignalAudioHandler(commandAndControlThread!!.looper) + savedAudioMode = androidAudioManager.mode + savedIsSpeakerPhoneOn = androidAudioManager.isSpeakerphoneOn + savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute + hasWiredHeadset = androidAudioManager.isWiredHeadsetOn - signalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler!!) + androidAudioManager.requestCallAudioFocus() - handler!!.post { + setMicrophoneMute(false) - savedAudioMode = androidAudioManager.mode - savedIsSpeakerPhoneOn = androidAudioManager.isSpeakerphoneOn - savedIsMicrophoneMute = androidAudioManager.isMicrophoneMute - hasWiredHeadset = androidAudioManager.isWiredHeadsetOn + audioDevices.clear() - androidAudioManager.requestCallAudioFocus() + signalBluetoothManager.start() - setMicrophoneMute(false) + updateAudioDeviceState() - audioDevices.clear() + wiredHeadsetReceiver = WiredHeadsetReceiver() + context.registerReceiver(wiredHeadsetReceiver, IntentFilter(AudioManager.ACTION_HEADSET_PLUG)) - signalBluetoothManager!!.start() + state = State.PREINITIALIZED - updateAudioDeviceState() + Log.d(TAG, "Initialized") + } + } - wiredHeadsetReceiver = WiredHeadsetReceiver() - context.registerReceiver(wiredHeadsetReceiver, IntentFilter(AudioManager.ACTION_HEADSET_PLUG)) - - state = State.PREINITIALIZED - - Log.d(TAG, "Initialized") + fun shutdown() { + handler!!.post { + stop(false) + if (commandAndControlThread != null) { + Log.i(TAG, "Shutting down command and control") + commandAndControlThread?.quitSafely() + commandAndControlThread = null } } } @@ -138,23 +139,11 @@ class SignalAudioManager(private val context: Context, private fun stop(playDisconnect: Boolean) { Log.d(TAG, "Stopping. state: $state") - if (state == State.UNINITIALIZED) { - Log.i(TAG, "Trying to stop AudioManager in incorrect state: $state") - return - } - handler?.post { - incomingRinger.stop() - outgoingRinger.stop() - stop(false) - if (commandAndControlThread != null) { - Log.i(TAG, "Shutting down command and control") - commandAndControlThread?.quitSafely() - commandAndControlThread = null - } - } + incomingRinger.stop() + outgoingRinger.stop() - if (playDisconnect) { + if (playDisconnect && state != State.UNINITIALIZED) { val volume: Float = androidAudioManager.ringVolumeWithMinimum() soundPool.play(disconnectedSoundId, volume, volume, 0, 0, 1.0f) } @@ -170,7 +159,7 @@ class SignalAudioManager(private val context: Context, } wiredHeadsetReceiver = null - signalBluetoothManager?.stop() + signalBluetoothManager.stop() setSpeakerphoneOn(savedIsSpeakerPhoneOn) setMicrophoneMute(savedIsMicrophoneMute) @@ -189,19 +178,19 @@ class SignalAudioManager(private val context: Context, TAG, "updateAudioDeviceState(): " + "wired: $hasWiredHeadset " + - "bt: ${signalBluetoothManager!!.state} " + + "bt: ${signalBluetoothManager.state} " + "available: $audioDevices " + "selected: $selectedAudioDevice " + "userSelected: $userSelectedAudioDevice" ) - if (signalBluetoothManager!!.state.shouldUpdate()) { - signalBluetoothManager!!.updateDevice() + if (signalBluetoothManager.state.shouldUpdate()) { + signalBluetoothManager.updateDevice() } val newAudioDevices = mutableSetOf(AudioDevice.SPEAKER_PHONE) - if (signalBluetoothManager!!.state.hasDevice()) { + if (signalBluetoothManager.state.hasDevice()) { newAudioDevices += AudioDevice.BLUETOOTH } @@ -217,7 +206,7 @@ class SignalAudioManager(private val context: Context, var audioDeviceSetUpdated = audioDevices != newAudioDevices audioDevices = newAudioDevices - if (signalBluetoothManager!!.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) { + if (signalBluetoothManager.state == BState.UNAVAILABLE && userSelectedAudioDevice == AudioDevice.BLUETOOTH) { userSelectedAudioDevice = AudioDevice.NONE } @@ -230,7 +219,7 @@ class SignalAudioManager(private val context: Context, userSelectedAudioDevice = AudioDevice.NONE } - val btState = signalBluetoothManager!!.state + val btState = signalBluetoothManager.state val needBluetoothAudioStart = btState == BState.AVAILABLE && (userSelectedAudioDevice == AudioDevice.NONE || userSelectedAudioDevice == AudioDevice.BLUETOOTH || autoSwitchToBluetooth) @@ -238,27 +227,27 @@ class SignalAudioManager(private val context: Context, (userSelectedAudioDevice != AudioDevice.NONE && userSelectedAudioDevice != AudioDevice.BLUETOOTH) if (btState.hasDevice()) { - Log.i(TAG, "Need bluetooth audio: state: ${signalBluetoothManager!!.state} start: $needBluetoothAudioStart stop: $needBluetoothAudioStop") + Log.i(TAG, "Need bluetooth audio: state: ${signalBluetoothManager.state} start: $needBluetoothAudioStart stop: $needBluetoothAudioStop") } if (needBluetoothAudioStop) { - signalBluetoothManager!!.stopScoAudio() - signalBluetoothManager!!.updateDevice() + signalBluetoothManager.stopScoAudio() + signalBluetoothManager.updateDevice() } - if (!autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.UNAVAILABLE) { + if (!autoSwitchToBluetooth && signalBluetoothManager.state == BState.UNAVAILABLE) { autoSwitchToBluetooth = true } - if (needBluetoothAudioStart && !needBluetoothAudioStop) { - if (!signalBluetoothManager!!.startScoAudio()) { + if (!needBluetoothAudioStop && needBluetoothAudioStart) { + if (!signalBluetoothManager.startScoAudio()) { Log.e(TAG,"Failed to start sco audio") audioDevices.remove(AudioDevice.BLUETOOTH) audioDeviceSetUpdated = true } } - if (autoSwitchToBluetooth && signalBluetoothManager!!.state == BState.CONNECTED) { + if (autoSwitchToBluetooth && signalBluetoothManager.state == BState.CONNECTED) { userSelectedAudioDevice = AudioDevice.BLUETOOTH autoSwitchToBluetooth = false } diff --git a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt index 0700d01f66..ac81564bd1 100644 --- a/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt +++ b/libsignal/src/main/java/org/session/libsignal/utilities/ThreadUtils.kt @@ -1,13 +1,12 @@ package org.session.libsignal.utilities -import java.util.concurrent.ExecutorService -import java.util.concurrent.Executors -import java.util.concurrent.LinkedBlockingQueue -import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.TimeUnit +import android.os.Process +import java.util.concurrent.* object ThreadUtils { + const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE + val executorPool: ExecutorService = Executors.newCachedThreadPool() @JvmStatic From c7bbdb778b93fb97bad93dad020240055c6507c8 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 24 Apr 2023 15:50:53 +1000 Subject: [PATCH 02/19] minor refactor --- .../securesms/webrtc/audio/SignalAudioHandler.kt | 2 +- .../securesms/webrtc/audio/SignalAudioManager.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioHandler.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioHandler.kt index 89eba2a3aa..7ca44f46dc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioHandler.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioHandler.kt @@ -15,7 +15,7 @@ class SignalAudioHandler(looper: Looper) : Handler(looper) { } } - fun isOnHandler(): Boolean { + private fun isOnHandler(): Boolean { return Looper.myLooper() == looper } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt index 6eb1304430..229cbd13dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/audio/SignalAudioManager.kt @@ -34,9 +34,9 @@ class SignalAudioManager(private val context: Context, private val androidAudioManager: AudioManagerCompat) { private var commandAndControlThread: HandlerThread? = HandlerThread("call-audio", ThreadUtils.PRIORITY_IMPORTANT_BACKGROUND_THREAD).apply { start() } - private var handler: SignalAudioHandler? = SignalAudioHandler(commandAndControlThread!!.looper) + private var handler: SignalAudioHandler = SignalAudioHandler(commandAndControlThread!!.looper) - private var signalBluetoothManager: SignalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler!!) + private var signalBluetoothManager: SignalBluetoothManager = SignalBluetoothManager(context, this, androidAudioManager, handler) private var state: State = State.UNINITIALIZED @@ -63,7 +63,7 @@ class SignalAudioManager(private val context: Context, private var wiredHeadsetReceiver: WiredHeadsetReceiver? = null fun handleCommand(command: AudioManagerCommand) { - handler?.post { + handler.post { when (command) { is AudioManagerCommand.Initialize -> initialize() is AudioManagerCommand.UpdateAudioDeviceState -> updateAudioDeviceState() @@ -107,7 +107,7 @@ class SignalAudioManager(private val context: Context, } fun shutdown() { - handler!!.post { + handler.post { stop(false) if (commandAndControlThread != null) { Log.i(TAG, "Shutting down command and control") @@ -172,7 +172,7 @@ class SignalAudioManager(private val context: Context, } private fun updateAudioDeviceState() { - handler!!.assertHandlerThread() + handler.assertHandlerThread() Log.i( TAG, @@ -362,7 +362,7 @@ class SignalAudioManager(private val context: Context, val pluggedIn = intent.getIntExtra("state", 0) == 1 val hasMic = intent.getIntExtra("microphone", 0) == 1 - handler?.post { onWiredHeadsetChange(pluggedIn, hasMic) } + handler.post { onWiredHeadsetChange(pluggedIn, hasMic) } } } From 2630c97a4efe34ffad3d43b5bd72a39ee2357bc9 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 1 May 2023 17:01:57 +1000 Subject: [PATCH 03/19] add where clause for marking all jobs pending to reduce the time for writing to db --- .../org/thoughtcrime/securesms/database/JobDatabase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java index ef4746923b..21719df20b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java @@ -138,7 +138,10 @@ public class JobDatabase extends Database { ContentValues contentValues = new ContentValues(); contentValues.put(Jobs.IS_RUNNING, 0); - databaseHelper.getWritableDatabase().update(Jobs.TABLE_NAME, contentValues, null, null); + String query = Jobs.IS_RUNNING + " = ?"; + String[] args = new String[] { "1" }; + + databaseHelper.getWritableDatabase().update(Jobs.TABLE_NAME, contentValues, query, args); } public synchronized void deleteJobs(@NonNull List jobIds) { From d868021f0ac5f3f1770b6c0aad2f841f7df9eb3b Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 4 May 2023 15:30:09 +1000 Subject: [PATCH 04/19] move job running status from database to memory --- .../securesms/database/JobDatabase.java | 33 +++++++++---------- .../securesms/database/SessionJobDatabase.kt | 2 +- .../securesms/database/Storage.kt | 2 +- .../securesms/jobs/FastJobStorageTest.java | 10 ------ 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java index 21719df20b..5e84d5e23a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -22,6 +23,8 @@ public class JobDatabase extends Database { Constraints.CREATE_TABLE, Dependencies.CREATE_TABLE }; + private static final ArrayList runningJobs = new ArrayList<>(); + public static final class Jobs { public static final String TABLE_NAME = "job_spec"; private static final String ID = "_id"; @@ -113,18 +116,17 @@ public class JobDatabase extends Database { } public synchronized void updateJobRunningState(@NonNull String id, boolean isRunning) { - ContentValues contentValues = new ContentValues(); - contentValues.put(Jobs.IS_RUNNING, isRunning ? 1 : 0); - - String query = Jobs.JOB_SPEC_ID + " = ?"; - String[] args = new String[]{ id }; - - databaseHelper.getWritableDatabase().update(Jobs.TABLE_NAME, contentValues, query, args); + if (!isRunning) { + JobDatabase.runningJobs.remove(id); + } else if (!JobDatabase.runningJobs.contains(id)) { + JobDatabase.runningJobs.add(id); + } } public synchronized void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime) { + updateJobRunningState(id, isRunning); + ContentValues contentValues = new ContentValues(); - contentValues.put(Jobs.IS_RUNNING, isRunning ? 1 : 0); contentValues.put(Jobs.RUN_ATTEMPT, runAttempt); contentValues.put(Jobs.NEXT_RUN_ATTEMPT_TIME, nextRunAttemptTime); @@ -135,13 +137,7 @@ public class JobDatabase extends Database { } public synchronized void updateAllJobsToBePending() { - ContentValues contentValues = new ContentValues(); - contentValues.put(Jobs.IS_RUNNING, 0); - - String query = Jobs.IS_RUNNING + " = ?"; - String[] args = new String[] { "1" }; - - databaseHelper.getWritableDatabase().update(Jobs.TABLE_NAME, contentValues, query, args); + JobDatabase.runningJobs.clear(); } public synchronized void deleteJobs(@NonNull List jobIds) { @@ -202,7 +198,7 @@ public class JobDatabase extends Database { contentValues.put(Jobs.MAX_INSTANCES, job.getMaxInstances()); contentValues.put(Jobs.LIFESPAN, job.getLifespan()); contentValues.put(Jobs.SERIALIZED_DATA, job.getSerializedData()); - contentValues.put(Jobs.IS_RUNNING, job.isRunning() ? 1 : 0); + updateJobRunningState(job.getId(), job.isRunning()); db.insertWithOnConflict(Jobs.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE); } @@ -226,7 +222,8 @@ public class JobDatabase extends Database { } private @NonNull JobSpec jobSpecFromCursor(@NonNull Cursor cursor) { - return new JobSpec(cursor.getString(cursor.getColumnIndexOrThrow(Jobs.JOB_SPEC_ID)), + String jobId = cursor.getString(cursor.getColumnIndexOrThrow(Jobs.JOB_SPEC_ID)); + return new JobSpec(jobId, cursor.getString(cursor.getColumnIndexOrThrow(Jobs.FACTORY_KEY)), cursor.getString(cursor.getColumnIndexOrThrow(Jobs.QUEUE_KEY)), cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.CREATE_TIME)), @@ -237,7 +234,7 @@ public class JobDatabase extends Database { cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.LIFESPAN)), cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.MAX_INSTANCES)), cursor.getString(cursor.getColumnIndexOrThrow(Jobs.SERIALIZED_DATA)), - cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.IS_RUNNING)) == 1); + JobDatabase.runningJobs.contains(jobId)); } private @NonNull ConstraintSpec constraintSpecFromCursor(@NonNull Cursor cursor) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SessionJobDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/SessionJobDatabase.kt index 66497d9da8..b081fb007e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SessionJobDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SessionJobDatabase.kt @@ -46,7 +46,7 @@ class SessionJobDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa databaseHelper.writableDatabase.delete(sessionJobTable, "${Companion.jobID} = ?", arrayOf( jobID )) } - fun getAllPendingJobs(type: String): Map { + fun getAllJobs(type: String): Map { val database = databaseHelper.readableDatabase return database.getAll(sessionJobTable, "$jobType = ?", arrayOf( type )) { cursor -> val jobID = cursor.getString(jobID) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 076fa57afc..0d7ea3352f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -211,7 +211,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, } override fun getAllPendingJobs(type: String): Map { - return DatabaseComponent.get(context).sessionJobDatabase().getAllPendingJobs(type) + return DatabaseComponent.get(context).sessionJobDatabase().getAllJobs(type) } override fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob? { diff --git a/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java b/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java index ee1f232b54..a6624189d1 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java +++ b/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java @@ -74,16 +74,6 @@ public class FastJobStorageTest { assertEquals(DataSet1.JOB_2, subject.getJobSpec(DataSet1.JOB_2.getId())); } - @Test - public void updateAllJobsToBePending_writesToDatabase() { - JobDatabase database = noopDatabase(); - FastJobStorage subject = new FastJobStorage(database); - - subject.updateAllJobsToBePending(); - - verify(database).updateAllJobsToBePending(); - } - @Test public void updateAllJobsToBePending_allArePending() { FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, true), From 375815c7190444f0a4d49b304095551866ce0cd5 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Fri, 5 May 2023 16:51:44 +1000 Subject: [PATCH 05/19] WIP: refactor on jobs using old job table --- .../securesms/jobmanager/JobManager.java | 39 --- .../securesms/jobs/JobManagerFactories.java | 4 +- .../securesms/jobs/LocalBackupJob.java | 83 ------ .../securesms/jobs/LocalBackupJob.kt | 61 ++++ .../securesms/jobs/UpdateApkJob.java | 271 ------------------ .../securesms/jobs/UpdateApkJob.kt | 200 +++++++++++++ .../service/UpdateApkRefreshListener.java | 2 + .../sskenvironment/ProfileManager.kt | 1 + 8 files changed, 266 insertions(+), 395 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java index 5906afd292..abb15d9f75 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java @@ -78,35 +78,6 @@ public class JobManager implements ConstraintObserver.Notifier { new Chain(this, Collections.singletonList(job)).enqueue(); } - /** - * Begins the creation of a job chain with a single job. - * @see Chain - */ - public Chain startChain(@NonNull Job job) { - return new Chain(this, Collections.singletonList(job)); - } - - /** - * Begins the creation of a job chain with a set of jobs that can be run in parallel. - * @see Chain - */ - public Chain startChain(@NonNull List jobs) { - return new Chain(this, jobs); - } - - /** - * Retrieves a string representing the state of the job queue. Intended for debugging. - */ - public @NonNull String getDebugInfo() { - Future result = executor.submit(jobController::getDebugInfo); - try { - return result.get(); - } catch (ExecutionException | InterruptedException e) { - Log.w(TAG, "Failed to retrieve Job info.", e); - return "Failed to retrieve Job info."; - } - } - /** * Adds a listener to that will be notified when the job queue has been drained. */ @@ -261,16 +232,6 @@ public class JobManager implements ConstraintObserver.Notifier { private Data.Serializer dataSerializer = new JsonDataSerializer(); private JobStorage jobStorage = null; - public @NonNull Builder setJobThreadCount(int jobThreadCount) { - this.jobThreadCount = jobThreadCount; - return this; - } - - public @NonNull Builder setExecutorFactory(@NonNull ExecutorFactory executorFactory) { - this.executorFactory = executorFactory; - return this; - } - public @NonNull Builder setJobFactories(@NonNull Map jobFactories) { this.jobFactories = jobFactories; return this; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index ef73325f37..468bf58369 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -29,9 +29,9 @@ public final class JobManagerFactories { public static Map getJobFactories(@NonNull Application application) { HashMap factoryHashMap = new HashMap() {{ put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory()); - put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); + put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory()); put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application)); - put(UpdateApkJob.KEY, new UpdateApkJob.Factory()); + put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory()); put(PrepareAttachmentAudioExtrasJob.KEY, new PrepareAttachmentAudioExtrasJob.Factory()); }}; factoryKeys.addAll(factoryHashMap.keySet()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java deleted file mode 100644 index e5715db263..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.session.libsession.messaging.utilities.Data; -import org.session.libsignal.utilities.NoExternalStorageException; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.database.BackupFileRecord; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.service.GenericForegroundService; -import org.thoughtcrime.securesms.util.BackupUtil; - -import java.io.IOException; -import java.util.Collections; - -import network.loki.messenger.R; - -public class LocalBackupJob extends BaseJob { - - public static final String KEY = "LocalBackupJob"; - - private static final String TAG = LocalBackupJob.class.getSimpleName(); - - public LocalBackupJob() { - this(new Job.Parameters.Builder() - .setQueue("__LOCAL_BACKUP__") - .setMaxInstances(1) - .setMaxAttempts(3) - .build()); - } - - private LocalBackupJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull - Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws NoExternalStorageException, IOException { - Log.i(TAG, "Executing backup job..."); - - GenericForegroundService.startForegroundTask(context, - context.getString(R.string.LocalBackupJob_creating_backup), - NotificationChannels.BACKUPS, - R.drawable.ic_launcher_foreground); - - // TODO: Maybe create a new backup icon like ic_signal_backup? - - try { - BackupFileRecord record = BackupUtil.createBackupFile(context); - BackupUtil.deleteAllBackupFiles(context, Collections.singletonList(record)); - - } finally { - GenericForegroundService.stopForegroundTask(context); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception e) { - return false; - } - - @Override - public void onCanceled() { - } - - public static class Factory implements Job.Factory { - @Override - public @NonNull LocalBackupJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new LocalBackupJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt new file mode 100644 index 0000000000..8a71760df3 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt @@ -0,0 +1,61 @@ +package org.thoughtcrime.securesms.jobs + +import android.content.Context +import org.session.libsession.messaging.jobs.Job +import org.session.libsession.messaging.jobs.JobDelegate +import org.session.libsession.messaging.utilities.Data +import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.notifications.NotificationChannels +import org.thoughtcrime.securesms.service.GenericForegroundService +import org.thoughtcrime.securesms.util.BackupUtil.createBackupFile +import org.thoughtcrime.securesms.util.BackupUtil.deleteAllBackupFiles + +import network.loki.messenger.R + + +class LocalBackupJob:Job { + override var delegate: JobDelegate? = null + override var id: String? = null + override var failureCount: Int = 0 + override val maxFailureCount: Int = 0 + + lateinit var context: Context + + companion object { + val TAG = LocalBackupJob::class.simpleName + val KEY: String = "LocalBackupJob" + } + + override fun execute(dispatcherName: String) { + Log.i(TAG, "Executing backup job...") + + GenericForegroundService.startForegroundTask( + context, + context.getString(R.string.LocalBackupJob_creating_backup), + NotificationChannels.BACKUPS, + R.drawable.ic_launcher_foreground + ) + + // TODO: Maybe create a new backup icon like ic_signal_backup? + try { + val record = createBackupFile(context) + deleteAllBackupFiles(context, listOf(record)) + } finally { + GenericForegroundService.stopForegroundTask(context) + } + } + + override fun serialize(): Data { + return Data.EMPTY + } + + override fun getFactoryKey(): String { + return KEY + } + + class Factory: Job.Factory { + override fun create(data: Data): LocalBackupJob { + return LocalBackupJob() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.java deleted file mode 100644 index 5b4ce8d13c..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.java +++ /dev/null @@ -1,271 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - - -import android.app.DownloadManager; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.session.libsession.messaging.utilities.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.service.UpdateApkReadyListener; -import org.session.libsession.utilities.FileUtils; -import org.session.libsignal.utilities.Hex; -import org.session.libsignal.utilities.JsonUtil; -import org.session.libsession.utilities.TextSecurePreferences; - -import java.io.FileInputStream; -import java.io.IOException; -import java.security.MessageDigest; - -import network.loki.messenger.BuildConfig; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; - -public class UpdateApkJob extends BaseJob { - - public static final String KEY = "UpdateApkJob"; - - private static final String TAG = UpdateApkJob.class.getSimpleName(); - - public UpdateApkJob() { - this(new Job.Parameters.Builder() - .setQueue("UpdateApkJob") - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(3) - .build()); - } - - private UpdateApkJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull - Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException, PackageManager.NameNotFoundException { - if (!BuildConfig.PLAY_STORE_DISABLED) return; - - Log.i(TAG, "Checking for APK update..."); - - OkHttpClient client = new OkHttpClient(); - Request request = new Request.Builder().url(String.format("%s/latest.json", BuildConfig.NOPLAY_UPDATE_URL)).build(); - - Response response = client.newCall(request).execute(); - - if (!response.isSuccessful()) { - throw new IOException("Bad response: " + response.message()); - } - - UpdateDescriptor updateDescriptor = JsonUtil.fromJson(response.body().string(), UpdateDescriptor.class); - byte[] digest = Hex.fromStringCondensed(updateDescriptor.getDigest()); - - Log.i(TAG, "Got descriptor: " + updateDescriptor); - - if (updateDescriptor.getVersionCode() > getVersionCode()) { - DownloadStatus downloadStatus = getDownloadStatus(updateDescriptor.getUrl(), digest); - - Log.i(TAG, "Download status: " + downloadStatus.getStatus()); - - if (downloadStatus.getStatus() == DownloadStatus.Status.COMPLETE) { - Log.i(TAG, "Download status complete, notifying..."); - handleDownloadNotify(downloadStatus.getDownloadId()); - } else if (downloadStatus.getStatus() == DownloadStatus.Status.MISSING) { - Log.i(TAG, "Download status missing, starting download..."); - handleDownloadStart(updateDescriptor.getUrl(), updateDescriptor.getVersionName(), digest); - } - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception e) { - return e instanceof IOException; - } - - @Override - public void onCanceled() { - Log.w(TAG, "Update check failed"); - } - - private int getVersionCode() throws PackageManager.NameNotFoundException { - PackageManager packageManager = context.getPackageManager(); - PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0); - - return packageInfo.versionCode; - } - - private DownloadStatus getDownloadStatus(String uri, byte[] theirDigest) { - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Query query = new DownloadManager.Query(); - - query.setFilterByStatus(DownloadManager.STATUS_PAUSED | DownloadManager.STATUS_PENDING | DownloadManager.STATUS_RUNNING | DownloadManager.STATUS_SUCCESSFUL); - - long pendingDownloadId = TextSecurePreferences.getUpdateApkDownloadId(context); - byte[] pendingDigest = getPendingDigest(context); - Cursor cursor = downloadManager.query(query); - - try { - DownloadStatus status = new DownloadStatus(DownloadStatus.Status.MISSING, -1); - - while (cursor != null && cursor.moveToNext()) { - int jobStatus = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)); - String jobRemoteUri = cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_URI)); - long downloadId = cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID)); - byte[] digest = getDigestForDownloadId(downloadId); - - if (jobRemoteUri != null && jobRemoteUri.equals(uri) && downloadId == pendingDownloadId) { - - if (jobStatus == DownloadManager.STATUS_SUCCESSFUL && - digest != null && pendingDigest != null && - MessageDigest.isEqual(pendingDigest, theirDigest) && - MessageDigest.isEqual(digest, theirDigest)) - { - return new DownloadStatus(DownloadStatus.Status.COMPLETE, downloadId); - } else if (jobStatus != DownloadManager.STATUS_SUCCESSFUL) { - status = new DownloadStatus(DownloadStatus.Status.PENDING, downloadId); - } - } - } - - return status; - } finally { - if (cursor != null) cursor.close(); - } - } - - private void handleDownloadStart(String uri, String versionName, byte[] digest) { - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(uri)); - - downloadRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI); - downloadRequest.setTitle("Downloading Signal update"); - downloadRequest.setDescription("Downloading Signal " + versionName); - downloadRequest.setVisibleInDownloadsUi(false); - downloadRequest.setDestinationInExternalFilesDir(context, null, "signal-update.apk"); - downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN); - - long downloadId = downloadManager.enqueue(downloadRequest); - TextSecurePreferences.setUpdateApkDownloadId(context, downloadId); - TextSecurePreferences.setUpdateApkDigest(context, Hex.toStringCondensed(digest)); - } - - private void handleDownloadNotify(long downloadId) { - Intent intent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE); - intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId); - - new UpdateApkReadyListener().onReceive(context, intent); - } - - private @Nullable byte[] getDigestForDownloadId(long downloadId) { - try { - DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); - FileInputStream fin = new FileInputStream(downloadManager.openDownloadedFile(downloadId).getFileDescriptor()); - byte[] digest = FileUtils.getFileDigest(fin); - - fin.close(); - - return digest; - } catch (IOException e) { - Log.w(TAG, e); - return null; - } - } - - private @Nullable byte[] getPendingDigest(Context context) { - try { - String encodedDigest = TextSecurePreferences.getUpdateApkDigest(context); - - if (encodedDigest == null) return null; - - return Hex.fromStringCondensed(encodedDigest); - } catch (IOException e) { - Log.w(TAG, e); - return null; - } - } - - private static class UpdateDescriptor { - @JsonProperty - private int versionCode; - - @JsonProperty - private String versionName; - - @JsonProperty - private String url; - - @JsonProperty - private String sha256sum; - - - public int getVersionCode() { - return versionCode; - } - - public String getVersionName() { - return versionName; - } - - public String getUrl() { - return url; - } - - public @NonNull String toString() { - return "[" + versionCode + ", " + versionName + ", " + url + "]"; - } - - public String getDigest() { - return sha256sum; - } - } - - private static class DownloadStatus { - enum Status { - PENDING, - COMPLETE, - MISSING - } - - private final Status status; - private final long downloadId; - - DownloadStatus(Status status, long downloadId) { - this.status = status; - this.downloadId = downloadId; - } - - public Status getStatus() { - return status; - } - - public long getDownloadId() { - return downloadId; - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull UpdateApkJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new UpdateApkJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt new file mode 100644 index 0000000000..411f01fcde --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt @@ -0,0 +1,200 @@ +package org.thoughtcrime.securesms.jobs + +import androidx.annotation.Nullable + +import android.app.DownloadManager +import android.content.Context +import android.content.Intent +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.net.Uri +import com.fasterxml.jackson.annotation.JsonProperty +import network.loki.messenger.BuildConfig +import okhttp3.OkHttpClient +import okhttp3.Request +import org.session.libsession.messaging.jobs.Job +import org.session.libsession.messaging.jobs.JobDelegate +import org.session.libsession.messaging.utilities.Data +import org.session.libsession.utilities.FileUtils +import org.session.libsession.utilities.TextSecurePreferences.Companion.getUpdateApkDigest +import org.session.libsession.utilities.TextSecurePreferences.Companion.getUpdateApkDownloadId +import org.session.libsession.utilities.TextSecurePreferences.Companion.setUpdateApkDigest +import org.session.libsession.utilities.TextSecurePreferences.Companion.setUpdateApkDownloadId +import org.session.libsignal.utilities.Hex +import org.session.libsignal.utilities.JsonUtil +import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.service.UpdateApkReadyListener +import java.io.FileInputStream +import java.io.IOException +import java.security.MessageDigest + +class UpdateApkJob: Job { + override var delegate: JobDelegate? = null + override var id: String? = null + override var failureCount: Int = 0 + override val maxFailureCount: Int = 0 + + lateinit var context: Context + + companion object { + val TAG = UpdateApkJob::class.simpleName + val KEY: String = "UpdateApkJob" + } + + override fun execute(dispatcherName: String) { + if (!BuildConfig.PLAY_STORE_DISABLED) return + + Log.i(TAG, "Checking for APK update...") + + val client = OkHttpClient() + val request = Request.Builder().url(String.format("%s/latest.json", BuildConfig.NOPLAY_UPDATE_URL)).build() + val response = client.newCall(request).execute() + + if (!response.isSuccessful) { + throw IOException("Bad response: " + response.message()) + } + + val updateDescriptor: UpdateDescriptor = JsonUtil.fromJson( + response.body()!!.string(), + UpdateDescriptor::class.java + ) + val digest = Hex.fromStringCondensed(updateDescriptor.digest) + + Log.i( + TAG, + "Got descriptor: $updateDescriptor" + ) + + if (updateDescriptor.versionCode > getVersionCode()) { + val downloadStatus: DownloadStatus = getDownloadStatus(updateDescriptor.url, digest) + Log.i(TAG, "Download status: " + downloadStatus.status) + if (downloadStatus.status == DownloadStatus.Status.COMPLETE) { + Log.i(TAG, "Download status complete, notifying...") + handleDownloadNotify(downloadStatus.downloadId) + } else if (downloadStatus.status == DownloadStatus.Status.MISSING) { + Log.i(TAG, "Download status missing, starting download...") + handleDownloadStart( + updateDescriptor.url, + updateDescriptor.versionName, + digest + ) + } + } + } + + @Throws(PackageManager.NameNotFoundException::class) + private fun getVersionCode(): Int { + val packageManager: PackageManager = context.getPackageManager() + val packageInfo: PackageInfo = packageManager.getPackageInfo(context.getPackageName(), 0) + return packageInfo.versionCode + } + + private fun getDownloadStatus(uri: String, theirDigest: ByteArray): DownloadStatus { + val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + val query = DownloadManager.Query() + query.setFilterByStatus(DownloadManager.STATUS_PAUSED or DownloadManager.STATUS_PENDING or DownloadManager.STATUS_RUNNING or DownloadManager.STATUS_SUCCESSFUL) + val pendingDownloadId = getUpdateApkDownloadId(context) + val pendingDigest = getPendingDigest(context) + val cursor = downloadManager.query(query) + return try { + var status = DownloadStatus(DownloadStatus.Status.MISSING, -1) + while (cursor != null && cursor.moveToNext()) { + val jobStatus = + cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) + val jobRemoteUri = + cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_URI)) + val downloadId = + cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID)) + val digest = getDigestForDownloadId(downloadId) + if (jobRemoteUri != null && jobRemoteUri == uri && downloadId == pendingDownloadId) { + if (jobStatus == DownloadManager.STATUS_SUCCESSFUL && digest != null && pendingDigest != null && + MessageDigest.isEqual(pendingDigest, theirDigest) && + MessageDigest.isEqual(digest, theirDigest) + ) { + return DownloadStatus(DownloadStatus.Status.COMPLETE, downloadId) + } else if (jobStatus != DownloadManager.STATUS_SUCCESSFUL) { + status = DownloadStatus(DownloadStatus.Status.PENDING, downloadId) + } + } + } + status + } finally { + cursor?.close() + } + } + + private fun handleDownloadStart(uri: String, versionName: String, digest: ByteArray) { + val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + val downloadRequest = DownloadManager.Request(Uri.parse(uri)) + downloadRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) + downloadRequest.setTitle("Downloading Signal update") + downloadRequest.setDescription("Downloading Signal $versionName") + downloadRequest.setVisibleInDownloadsUi(false) + downloadRequest.setDestinationInExternalFilesDir(context, null, "signal-update.apk") + downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN) + val downloadId = downloadManager.enqueue(downloadRequest) + setUpdateApkDownloadId(context, downloadId) + setUpdateApkDigest(context, Hex.toStringCondensed(digest)) + } + + private fun handleDownloadNotify(downloadId: Long) { + val intent = Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE) + intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId) + UpdateApkReadyListener().onReceive(context, intent) + } + + private fun getDigestForDownloadId(downloadId: Long): ByteArray? { + return try { + val downloadManager = + context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager + val fin = FileInputStream(downloadManager.openDownloadedFile(downloadId).fileDescriptor) + val digest = FileUtils.getFileDigest(fin) + fin.close() + digest + } catch (e: IOException) { + Log.w(TAG, e) + null + } + } + + private fun getPendingDigest(context: Context): ByteArray? { + return try { + val encodedDigest = getUpdateApkDigest(context) ?: return null + Hex.fromStringCondensed(encodedDigest) + } catch (e: IOException) { + Log.w(TAG, e) + null + } + } + + override fun serialize(): Data { + return Data.EMPTY + } + + override fun getFactoryKey(): String { + return KEY + } + + private class UpdateDescriptor( + @JsonProperty("versionCode") @Nullable val versionCode: Int, + @JsonProperty("versionName") @Nullable val versionName: String, + @JsonProperty("url") @Nullable val url: String, + @JsonProperty("sha256sum") @Nullable val digest: String) + { + override fun toString(): String { + return "[$versionCode, $versionName, $url]" + } + } + + private class DownloadStatus(val status: Status, val downloadId: Long) { + enum class Status { + PENDING, COMPLETE, MISSING + } + } + + class Factory: Job.Factory { + override fun create(data: Data): UpdateApkJob { + return UpdateApkJob() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java index 187713df95..ef27916ac9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java @@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.service; import android.content.Context; import android.content.Intent; + +import org.session.libsession.messaging.jobs.JobQueue; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.ApplicationContext; diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index c46f75bff8..2615eff588 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.sskenvironment import android.content.Context import org.session.libsession.messaging.contacts.Contact +import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.ApplicationContext From 2b48b52df0b819f39558d792fc05aee3261f4f2a Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 8 May 2023 11:18:33 +1000 Subject: [PATCH 06/19] remove unused jobs and wrap up old job refactoring --- .../securesms/ApplicationContext.java | 2 +- .../securesms/jobs/AvatarDownloadJob.java | 133 ---------------- .../securesms/jobs/JobManagerFactories.java | 10 +- .../jobs/PrepareAttachmentAudioExtrasJob.kt | 133 ---------------- .../jobs/RetrieveProfileAvatarJob.java | 144 ------------------ .../jobs/RetrieveProfileAvatarJob.kt | 99 ++++++++++++ 6 files changed, 104 insertions(+), 417 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index a605a84922..b398d021c5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -355,7 +355,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private void initializeJobManager() { this.jobManager = new JobManager(this, new JobManager.Configuration.Builder() .setDataSerializer(new JsonDataSerializer()) - .setJobFactories(JobManagerFactories.getJobFactories(this)) + .setJobFactories(JobManagerFactories.getJobFactories()) .setConstraintFactories(JobManagerFactories.getConstraintFactories(this)) .setConstraintObservers(JobManagerFactories.getConstraintObservers(this)) .setJobStorage(new FastJobStorage(jobDatabase)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java deleted file mode 100644 index 0bf7ea24e4..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java +++ /dev/null @@ -1,133 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.graphics.Bitmap; - -import androidx.annotation.NonNull; - -import org.session.libsession.messaging.utilities.Data; -import org.session.libsession.utilities.DownloadUtilities; -import org.session.libsession.utilities.GroupRecord; -import org.session.libsignal.exceptions.InvalidMessageException; -import org.session.libsignal.exceptions.NonSuccessfulResponseCodeException; -import org.session.libsignal.messages.SignalServiceAttachmentPointer; -import org.session.libsignal.streams.AttachmentCipherInputStream; -import org.session.libsignal.utilities.Hex; -import org.session.libsignal.utilities.Log; -import org.session.libsignal.utilities.guava.Optional; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.dependencies.DatabaseComponent; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel; -import org.thoughtcrime.securesms.util.BitmapDecodingException; -import org.thoughtcrime.securesms.util.BitmapUtil; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -public class AvatarDownloadJob extends BaseJob { - - public static final String KEY = "AvatarDownloadJob"; - - private static final String TAG = AvatarDownloadJob.class.getSimpleName(); - - private static final int MAX_AVATAR_SIZE = 20 * 1024 * 1024; - - private static final String KEY_GROUP_ID = "group_id"; - - private String groupId; - - public AvatarDownloadJob(@NonNull String groupId) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(10) - .build(), - groupId); - } - - private AvatarDownloadJob(@NonNull Job.Parameters parameters, @NonNull String groupId) { - super(parameters); - this.groupId = groupId; - } - - @Override - public @NonNull Data serialize() { - return new Data.Builder().putString(KEY_GROUP_ID, groupId).build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException { - GroupDatabase database = DatabaseComponent.get(context).groupDatabase(); - Optional record = database.getGroup(groupId); - File attachment = null; - - try { - if (record.isPresent()) { - long avatarId = record.get().getAvatarId(); - String contentType = record.get().getAvatarContentType(); - byte[] key = record.get().getAvatarKey(); - String relay = record.get().getRelay(); - Optional digest = Optional.fromNullable(record.get().getAvatarDigest()); - Optional fileName = Optional.absent(); - String url = record.get().getUrl(); - - if (avatarId == -1 || key == null || url.isEmpty()) { - return; - } - - if (digest.isPresent()) { - Log.i(TAG, "Downloading group avatar with digest: " + Hex.toString(digest.get())); - } - - attachment = File.createTempFile("avatar", "tmp", context.getCacheDir()); - attachment.deleteOnExit(); - - SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), url); - - if (pointer.getUrl().isEmpty()) throw new InvalidMessageException("Missing attachment URL."); - DownloadUtilities.downloadFile(attachment, pointer.getUrl()); - - // Assume we're retrieving an attachment for an open group server if the digest is not set - InputStream inputStream; - if (!pointer.getDigest().isPresent()) { - inputStream = new FileInputStream(attachment); - } else { - inputStream = AttachmentCipherInputStream.createForAttachment(attachment, pointer.getSize().or(0), pointer.getKey(), pointer.getDigest().get()); - } - - Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500); - - database.updateProfilePicture(groupId, avatar); - inputStream.close(); - } - } catch (BitmapDecodingException | NonSuccessfulResponseCodeException | InvalidMessageException e) { - Log.w(TAG, e); - } finally { - if (attachment != null) - attachment.delete(); - } - } - - @Override - public void onCanceled() {} - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof IOException) return true; - return false; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull AvatarDownloadJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new AvatarDownloadJob(parameters, data.getString(KEY_GROUP_ID)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 468bf58369..910a9c09be 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -4,9 +4,9 @@ import android.app.Application; import androidx.annotation.NonNull; +import org.session.libsession.messaging.jobs.Job; import org.thoughtcrime.securesms.jobmanager.Constraint; import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; -import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint; import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; @@ -28,11 +28,9 @@ public final class JobManagerFactories { public static Map getJobFactories(@NonNull Application application) { HashMap factoryHashMap = new HashMap() {{ - put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory()); - put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory()); - put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application)); - put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory()); - put(PrepareAttachmentAudioExtrasJob.KEY, new PrepareAttachmentAudioExtrasJob.Factory()); + put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory()); + put(RetrieveProfileAvatarJob.Companion.getKEY(), new RetrieveProfileAvatarJob.Factory()); + put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory()); }}; factoryKeys.addAll(factoryHashMap.keySet()); return factoryHashMap; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt deleted file mode 100644 index 69794d41bd..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PrepareAttachmentAudioExtrasJob.kt +++ /dev/null @@ -1,133 +0,0 @@ -package org.thoughtcrime.securesms.jobs - -import android.os.Build -import org.greenrobot.eventbus.EventBus -import org.session.libsession.messaging.sending_receiving.attachments.Attachment -import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId -import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachmentAudioExtras -import org.session.libsession.messaging.utilities.Data -import org.session.libsession.utilities.DecodedAudio -import org.session.libsession.utilities.InputStreamMediaDataSource -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.dependencies.DatabaseComponent -import org.thoughtcrime.securesms.jobmanager.Job -import org.thoughtcrime.securesms.jobs.PrepareAttachmentAudioExtrasJob.AudioExtrasUpdatedEvent -import org.thoughtcrime.securesms.mms.PartAuthority -import java.util.* -import java.util.concurrent.TimeUnit - -/** - * Decodes the audio content of the related attachment entry - * and caches the result with [DatabaseAttachmentAudioExtras] data. - * - * It only process attachments with "audio" mime types. - * - * Due to [DecodedAudio] implementation limitations, it only works for API 23+. - * For any lower targets fake data will be generated. - * - * You can subscribe to [AudioExtrasUpdatedEvent] to be notified about the successful result. - */ -//TODO AC: Rewrite to WorkManager API when -// https://github.com/loki-project/session-android/pull/354 is merged. -class PrepareAttachmentAudioExtrasJob : BaseJob { - - companion object { - private const val TAG = "AttachAudioExtrasJob" - - const val KEY = "PrepareAttachmentAudioExtrasJob" - const val DATA_ATTACH_ID = "attachment_id" - - const val VISUAL_RMS_FRAMES = 32 // The amount of values to be computed for the visualization. - } - - private val attachmentId: AttachmentId - - constructor(attachmentId: AttachmentId) : this(Parameters.Builder() - .setQueue(KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .build(), - attachmentId) - - private constructor(parameters: Parameters, attachmentId: AttachmentId) : super(parameters) { - this.attachmentId = attachmentId - } - - override fun serialize(): Data { - return Data.Builder().putParcelable(DATA_ATTACH_ID, attachmentId).build(); - } - - override fun getFactoryKey(): String { return KEY - } - - override fun onShouldRetry(e: Exception): Boolean { - return false - } - - override fun onCanceled() { } - - override fun onRun() { - Log.v(TAG, "Processing attachment: $attachmentId") - - val attachDb = DatabaseComponent.get(context).attachmentDatabase() - val attachment = attachDb.getAttachment(attachmentId) - - if (attachment == null) { - throw IllegalStateException("Cannot find attachment with the ID $attachmentId") - } - if (!attachment.contentType.startsWith("audio/")) { - throw IllegalStateException("Attachment $attachmentId is not of audio type.") - } - - // Check if the audio extras already exist. - if (attachDb.getAttachmentAudioExtras(attachmentId) != null) return - - fun extractAttachmentRandomSeed(attachment: Attachment): Int { - return when { - attachment.digest != null -> attachment.digest!!.sum() - attachment.fileName != null -> attachment.fileName.hashCode() - else -> attachment.hashCode() - } - } - - fun generateFakeRms(seed: Int, frames: Int = VISUAL_RMS_FRAMES): ByteArray { - return ByteArray(frames).apply { Random(seed.toLong()).nextBytes(this) } - } - - var rmsValues: ByteArray - var totalDurationMs: Long = DatabaseAttachmentAudioExtras.DURATION_UNDEFINED - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { - // Due to API version incompatibility, we just display some random waveform for older API. - rmsValues = generateFakeRms(extractAttachmentRandomSeed(attachment)) - } else { - try { - @Suppress("BlockingMethodInNonBlockingContext") - val decodedAudio = PartAuthority.getAttachmentStream(context, attachment.dataUri!!).use { - DecodedAudio.create(InputStreamMediaDataSource(it)) - } - rmsValues = decodedAudio.calculateRms(VISUAL_RMS_FRAMES) - totalDurationMs = (decodedAudio.totalDuration / 1000.0).toLong() - } catch (e: Exception) { - Log.w(TAG, "Failed to decode sample values for the audio attachment \"${attachment.fileName}\".", e) - rmsValues = generateFakeRms(extractAttachmentRandomSeed(attachment)) - } - } - - attachDb.setAttachmentAudioExtras(DatabaseAttachmentAudioExtras( - attachmentId, - rmsValues, - totalDurationMs - )) - - EventBus.getDefault().post(AudioExtrasUpdatedEvent(attachmentId)) - } - - class Factory : Job.Factory { - override fun create(parameters: Parameters, data: Data): PrepareAttachmentAudioExtrasJob { - return PrepareAttachmentAudioExtrasJob(parameters, data.getParcelable(DATA_ATTACH_ID, AttachmentId.CREATOR)) - } - } - - /** Gets dispatched once the audio extras have been updated. */ - data class AudioExtrasUpdatedEvent(val attachmentId: AttachmentId) -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java deleted file mode 100644 index 39b7753035..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.Application; -import android.text.TextUtils; - -import androidx.annotation.NonNull; - -import org.session.libsession.avatars.AvatarHelper; -import org.session.libsession.messaging.utilities.Data; -import org.session.libsession.utilities.Address; -import org.session.libsession.utilities.DownloadUtilities; -import org.session.libsession.utilities.TextSecurePreferences; -import org.session.libsession.utilities.Util; -import org.session.libsession.utilities.recipients.Recipient; -import org.session.libsignal.exceptions.PushNetworkException; -import org.session.libsignal.streams.ProfileCipherInputStream; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.dependencies.DatabaseComponent; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.SecureRandom; -import java.util.concurrent.TimeUnit; - -public class RetrieveProfileAvatarJob extends BaseJob { - - public static final String KEY = "RetrieveProfileAvatarJob"; - - private static final String TAG = RetrieveProfileAvatarJob.class.getSimpleName(); - - private static final int MAX_PROFILE_SIZE_BYTES = 10 * 1024 * 1024; - - private static final String KEY_PROFILE_AVATAR = "profile_avatar"; - private static final String KEY_ADDRESS = "address"; - - - private String profileAvatar; - private Recipient recipient; - - public RetrieveProfileAvatarJob(Recipient recipient, String profileAvatar) { - this(new Job.Parameters.Builder() - .setQueue("RetrieveProfileAvatarJob" + recipient.getAddress().serialize()) - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.HOURS.toMillis(1)) - .setMaxAttempts(2) - .setMaxInstances(1) - .build(), - recipient, - profileAvatar); - } - - private RetrieveProfileAvatarJob(@NonNull Job.Parameters parameters, @NonNull Recipient recipient, String profileAvatar) { - super(parameters); - this.recipient = recipient; - this.profileAvatar = profileAvatar; - } - - @Override - public @NonNull - Data serialize() { - return new Data.Builder() - .putString(KEY_PROFILE_AVATAR, profileAvatar) - .putString(KEY_ADDRESS, recipient.getAddress().serialize()) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException { - RecipientDatabase database = DatabaseComponent.get(context).recipientDatabase(); - byte[] profileKey = recipient.resolve().getProfileKey(); - - if (profileKey == null || (profileKey.length != 32 && profileKey.length != 16)) { - Log.w(TAG, "Recipient profile key is gone!"); - return; - } - - if (AvatarHelper.avatarFileExists(context, recipient.resolve().getAddress()) && Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) { - Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar); - return; - } - - if (TextUtils.isEmpty(profileAvatar)) { - Log.w(TAG, "Removing profile avatar for: " + recipient.getAddress().serialize()); - AvatarHelper.delete(context, recipient.getAddress()); - database.setProfileAvatar(recipient, profileAvatar); - return; - } - - File downloadDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir()); - - try { - DownloadUtilities.downloadFile(downloadDestination, profileAvatar); - InputStream avatarStream = new ProfileCipherInputStream(new FileInputStream(downloadDestination), profileKey); - File decryptDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir()); - - Util.copy(avatarStream, new FileOutputStream(decryptDestination)); - decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.getAddress())); - } finally { - if (downloadDestination != null) downloadDestination.delete(); - } - - if (recipient.isLocalNumber()) { - TextSecurePreferences.setProfileAvatarId(context, new SecureRandom().nextInt()); - } - database.setProfileAvatar(recipient, profileAvatar); - } - - @Override - public boolean onShouldRetry(@NonNull Exception e) { - if (e instanceof PushNetworkException) return true; - return false; - } - - @Override - public void onCanceled() { - } - - public static final class Factory implements Job.Factory { - - private final Application application; - - public Factory(Application application) { - this.application = application; - } - - @Override - public @NonNull RetrieveProfileAvatarJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new RetrieveProfileAvatarJob(parameters, - Recipient.from(application, Address.fromSerialized(data.getString(KEY_ADDRESS)), true), - data.getString(KEY_PROFILE_AVATAR)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt new file mode 100644 index 0000000000..a5b0fce2df --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt @@ -0,0 +1,99 @@ +package org.thoughtcrime.securesms.jobs + +import android.content.Context +import android.text.TextUtils +import org.session.libsession.avatars.AvatarHelper +import org.session.libsession.messaging.jobs.Job +import org.session.libsession.messaging.jobs.JobDelegate +import org.session.libsession.messaging.utilities.Data +import org.session.libsession.utilities.DownloadUtilities.downloadFile +import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfileAvatarId +import org.session.libsession.utilities.Util.copy +import org.session.libsession.utilities.Util.equals +import org.session.libsession.utilities.Address +import org.session.libsession.utilities.recipients.Recipient +import org.session.libsignal.streams.ProfileCipherInputStream +import org.session.libsignal.utilities.Log +import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.InputStream +import java.security.SecureRandom + +class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: Address): Job { + override var delegate: JobDelegate? = null + override var id: String? = null + override var failureCount: Int = 0 + override val maxFailureCount: Int = 0 + + lateinit var context: Context + + companion object { + val TAG = RetrieveProfileAvatarJob::class.simpleName + val KEY: String = "RetrieveProfileAvatarJob" + + // Keys used for database storage + private val PROFILE_AVATAR_KEY = "profileAvatar" + private val RECEIPIENT_ADDRESS_KEY = "recipient" + } + + override fun execute(dispatcherName: String) { + val recipient = Recipient.from(context, recipientAddress, true) + val database = get(context).recipientDatabase() + val profileKey = recipient.resolve().profileKey + + if (profileKey == null || (profileKey.size != 32 && profileKey.size != 16)) { + Log.w(TAG, "Recipient profile key is gone!") + return + } + + if (AvatarHelper.avatarFileExists(context, recipient.resolve().address) && equals(profileAvatar, recipient.resolve().profileAvatar)) { + Log.w(TAG, "Already retrieved profile avatar: $profileAvatar") + return + } + + if (TextUtils.isEmpty(profileAvatar)) { + Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize()) + AvatarHelper.delete(context, recipient.address) + database.setProfileAvatar(recipient, profileAvatar) + return + } + + val downloadDestination = File.createTempFile("avatar", ".jpg", context.cacheDir) + + try { + downloadFile(downloadDestination, profileAvatar) + val avatarStream: InputStream = ProfileCipherInputStream(FileInputStream(downloadDestination), profileKey) + val decryptDestination = File.createTempFile("avatar", ".jpg", context.cacheDir) + copy(avatarStream, FileOutputStream(decryptDestination)) + decryptDestination.renameTo(AvatarHelper.getAvatarFile(context, recipient.address)) + } finally { + downloadDestination.delete() + } + + if (recipient.isLocalNumber) { + setProfileAvatarId(context, SecureRandom().nextInt()) + } + database.setProfileAvatar(recipient, profileAvatar) + } + + override fun serialize(): Data { + return Data.Builder() + .putString(PROFILE_AVATAR_KEY, profileAvatar) + .putString(RECEIPIENT_ADDRESS_KEY, recipientAddress.serialize()) + .build() + } + + override fun getFactoryKey(): String { + return KEY + } + + class Factory: Job.Factory { + override fun create(data: Data): RetrieveProfileAvatarJob { + val profileAvatar = data.getString(PROFILE_AVATAR_KEY) + val recipientAddress = Address.fromSerialized(data.getString(RECEIPIENT_ADDRESS_KEY)) + return RetrieveProfileAvatarJob(profileAvatar, recipientAddress) + } + } +} \ No newline at end of file From 2ceb9e2bf448bf37e7f855de43be87637b4d6607 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 8 May 2023 12:29:21 +1000 Subject: [PATCH 07/19] clean up old job manager --- app/src/main/AndroidManifest.xml | 8 - .../securesms/ApplicationContext.java | 6 - .../securesms/database/Storage.kt | 3 +- .../jobmanager/AlarmManagerScheduler.java | 69 ---- .../jobmanager/CompositeScheduler.java | 22 -- .../jobmanager/ConstraintInstantiator.java | 23 -- .../jobmanager/DependencyInjector.java | 24 -- .../securesms/jobmanager/InAppScheduler.java | 49 --- .../securesms/jobmanager/Job.java | 286 -------------- .../securesms/jobmanager/JobController.java | 354 ------------------ .../securesms/jobmanager/JobInstantiator.java | 5 +- .../securesms/jobmanager/JobLogger.java | 24 -- .../securesms/jobmanager/JobManager.java | 167 +-------- .../securesms/jobmanager/JobRunner.java | 110 ------ .../jobmanager/JobSchedulerScheduler.java | 90 ----- .../securesms/jobmanager/Scheduler.java | 9 - .../thoughtcrime/securesms/jobs/BaseJob.java | 41 -- .../securesms/jobs/FastJobStorage.java | 261 ------------- .../securesms/jobs/JobManagerFactories.java | 2 +- .../service/LocalBackupListener.java | 5 +- .../service/UpdateApkRefreshListener.java | 6 +- .../sskenvironment/ProfileManager.kt | 6 +- .../securesms/jobs/FastJobStorageTest.java | 350 ----------------- 23 files changed, 20 insertions(+), 1900 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/AlarmManagerScheduler.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/CompositeScheduler.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintInstantiator.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/DependencyInjector.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/InAppScheduler.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/Job.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobLogger.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobRunner.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobSchedulerScheduler.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/Scheduler.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/BaseJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java delete mode 100644 app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6755addc03..da3be785c3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -446,17 +446,9 @@ - - diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index b398d021c5..0d5e57352e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -66,9 +66,7 @@ import org.thoughtcrime.securesms.emoji.EmojiSource; import org.thoughtcrime.securesms.groups.OpenGroupManager; import org.thoughtcrime.securesms.home.HomeActivity; import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.jobs.FastJobStorage; import org.thoughtcrime.securesms.jobs.JobManagerFactories; import org.thoughtcrime.securesms.logging.AndroidLogger; import org.thoughtcrime.securesms.logging.PersistentLogger; @@ -354,11 +352,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private void initializeJobManager() { this.jobManager = new JobManager(this, new JobManager.Configuration.Builder() - .setDataSerializer(new JsonDataSerializer()) - .setJobFactories(JobManagerFactories.getJobFactories()) - .setConstraintFactories(JobManagerFactories.getConstraintFactories(this)) .setConstraintObservers(JobManagerFactories.getConstraintObservers(this)) - .setJobStorage(new FastJobStorage(jobDatabase)) .build()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 0d7ea3352f..891df6be87 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -75,8 +75,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, Recipient.from(context, it, false) } TextSecurePreferences.setProfilePictureURL(context, newValue) - RetrieveProfileAvatarJob(ourRecipient, newValue) - ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(ourRecipient, newValue)) + JobQueue.shared.add(RetrieveProfileAvatarJob(newValue, ourRecipient.address)) } override fun getOrGenerateRegistrationID(): Int { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/AlarmManagerScheduler.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/AlarmManagerScheduler.java deleted file mode 100644 index dc1d2afcf1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/AlarmManagerScheduler.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.AlarmManager; -import android.app.Application; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; - -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.ApplicationContext; - -import java.util.List; -import java.util.UUID; - -import network.loki.messenger.BuildConfig; - -/** - * Schedules tasks using the {@link AlarmManager}. - * - * Given that this scheduler is only used when {@link KeepAliveService} is also used (which keeps - * all of the {@link ConstraintObserver}s running), this only needs to schedule future runs in - * situations where all constraints are already met. Otherwise, the {@link ConstraintObserver}s will - * trigger future runs when the constraints are met. - * - * For the same reason, this class also doesn't have to schedule jobs that don't have delays. - * - * Important: Only use on API < 26. - */ -public class AlarmManagerScheduler implements Scheduler { - - private static final String TAG = AlarmManagerScheduler.class.getSimpleName(); - - private final Application application; - - AlarmManagerScheduler(@NonNull Application application) { - this.application = application; - } - - @Override - public void schedule(long delay, @NonNull List constraints) { - if (delay > 0 && Stream.of(constraints).allMatch(Constraint::isMet)) { - setUniqueAlarm(application, System.currentTimeMillis() + delay); - } - } - - private void setUniqueAlarm(@NonNull Context context, long time) { - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - Intent intent = new Intent(context, RetryReceiver.class); - - intent.setAction(BuildConfig.APPLICATION_ID + UUID.randomUUID().toString()); - alarmManager.set(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)); - - Log.i(TAG, "Set an alarm to retry a job in " + (time - System.currentTimeMillis()) + " ms."); - } - - public static class RetryReceiver extends BroadcastReceiver { - - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "Received an alarm to retry a job."); - ApplicationContext.getInstance(context).getJobManager().wakeUp(); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/CompositeScheduler.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/CompositeScheduler.java deleted file mode 100644 index 322366f4f4..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/CompositeScheduler.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -import java.util.Arrays; -import java.util.List; - -class CompositeScheduler implements Scheduler { - - private final List schedulers; - - CompositeScheduler(@NonNull Scheduler... schedulers) { - this.schedulers = Arrays.asList(schedulers); - } - - @Override - public void schedule(long delay, @NonNull List constraints) { - for (Scheduler scheduler : schedulers) { - scheduler.schedule(delay, constraints); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintInstantiator.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintInstantiator.java deleted file mode 100644 index b0a67e3d19..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintInstantiator.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -public class ConstraintInstantiator { - - private final Map constraintFactories; - - ConstraintInstantiator(@NonNull Map constraintFactories) { - this.constraintFactories = new HashMap<>(constraintFactories); - } - - public @NonNull Constraint instantiate(@NonNull String constraintFactoryKey) { - if (constraintFactories.containsKey(constraintFactoryKey)) { - return constraintFactories.get(constraintFactoryKey).create(); - } else { - throw new IllegalStateException("Tried to instantiate a constraint with key '" + constraintFactoryKey + "', but no matching factory was found."); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/DependencyInjector.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/DependencyInjector.java deleted file mode 100644 index c8a266bd87..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/DependencyInjector.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright (C) 2014 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.thoughtcrime.securesms.jobmanager; - -/** - * Interface responsible for injecting dependencies into Jobs. - */ -public interface DependencyInjector { - void injectDependencies(Object object); -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/InAppScheduler.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/InAppScheduler.java deleted file mode 100644 index b0f314eaa6..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/InAppScheduler.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.os.Handler; -import android.os.HandlerThread; -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; - -import org.session.libsignal.utilities.Log; - -import java.util.List; - -/** - * Schedules future runs on an in-app handler. Intended to be used in combination with a persistent - * {@link Scheduler} to improve responsiveness when the app is open. - * - * This should only schedule runs when all constraints are met. Because this only works when the - * app is foregrounded, jobs that don't have their constraints met will be run when the relevant - * {@link ConstraintObserver} is triggered. - * - * Similarly, this does not need to schedule retries with no delay, as this doesn't provide any - * persistence, and other mechanisms will take care of that. - */ -class InAppScheduler implements Scheduler { - - private static final String TAG = InAppScheduler.class.getSimpleName(); - - private final JobManager jobManager; - private final Handler handler; - - InAppScheduler(@NonNull JobManager jobManager) { - HandlerThread handlerThread = new HandlerThread("InAppScheduler"); - handlerThread.start(); - - this.jobManager = jobManager; - this.handler = new Handler(handlerThread.getLooper()); - } - - @Override - public void schedule(long delay, @NonNull List constraints) { - if (delay > 0 && Stream.of(constraints).allMatch(Constraint::isMet)) { - Log.i(TAG, "Scheduling a retry in " + delay + " ms."); - handler.postDelayed(() -> { - Log.i(TAG, "Triggering a job retry."); - jobManager.wakeUp(); - }, delay); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Job.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Job.java deleted file mode 100644 index 990207779d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Job.java +++ /dev/null @@ -1,286 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.WorkerThread; - -import org.session.libsession.messaging.utilities.Data; -import org.session.libsignal.utilities.Log; - -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -/** - * A durable unit of work. - * - * Jobs have {@link Parameters} that describe the conditions upon when you'd like them to run, how - * often they should be retried, and how long they should be retried for. - * - * Never rely on a specific instance of this class being run. It can be created and destroyed as the - * job is retried. State that you want to save is persisted to a {@link Data} object in - * {@link #serialize()}. Your job is then recreated using a {@link Factory} that you register in - * {@link JobManager.Configuration.Builder#setJobFactories(Map)}, which is given the saved - * {@link Data} bundle. - * - * @deprecated - * use WorkManager - * API instead. - */ -public abstract class Job { - - private static final String TAG = Log.tag(Job.class); - - private final Parameters parameters; - - private String id; - private int runAttempt; - private long nextRunAttemptTime; - - protected Context context; - - public Job(@NonNull Parameters parameters) { - this.parameters = parameters; - } - - public final String getId() { - return id; - } - - public final @NonNull Parameters getParameters() { - return parameters; - } - - public final int getRunAttempt() { - return runAttempt; - } - - public final long getNextRunAttemptTime() { - return nextRunAttemptTime; - } - - /** - * This is already called by {@link JobController} during job submission, but if you ever run a - * job without submitting it to the {@link JobManager}, then you'll need to invoke this yourself. - */ - public final void setContext(@NonNull Context context) { - this.context = context; - } - - /** Should only be invoked by {@link JobController} */ - final void setId(@NonNull String id) { - this.id = id; - } - - /** Should only be invoked by {@link JobController} */ - final void setRunAttempt(int runAttempt) { - this.runAttempt = runAttempt; - } - - /** Should only be invoked by {@link JobController} */ - final void setNextRunAttemptTime(long nextRunAttemptTime) { - this.nextRunAttemptTime = nextRunAttemptTime; - } - - @WorkerThread - final void onSubmit() { - Log.i(TAG, JobLogger.format(this, "onSubmit()")); - onAdded(); - } - - /** - * Called when the job is first submitted to the {@link JobManager}. - */ - @WorkerThread - public void onAdded() { - } - - /** - * Called after a job has run and its determined that a retry is required. - */ - @WorkerThread - public void onRetry() { - } - - /** - * Serialize your job state so that it can be recreated in the future. - */ - public abstract @NonNull Data serialize(); - - /** - * Returns the key that can be used to find the relevant factory needed to create your job. - */ - public abstract @NonNull String getFactoryKey(); - - /** - * Called to do your actual work. - */ - @WorkerThread - public abstract @NonNull Result run(); - - /** - * Called when your job has completely failed. - */ - @WorkerThread - public abstract void onCanceled(); - - public interface Factory { - @NonNull T create(@NonNull Parameters parameters, @NonNull Data data); - } - - public enum Result { - SUCCESS, FAILURE, RETRY - } - - public static final class Parameters { - - public static final int IMMORTAL = -1; - public static final int UNLIMITED = -1; - - private final long createTime; - private final long lifespan; - private final int maxAttempts; - private final long maxBackoff; - private final int maxInstances; - private final String queue; - private final List constraintKeys; - - private Parameters(long createTime, - long lifespan, - int maxAttempts, - long maxBackoff, - int maxInstances, - @Nullable String queue, - @NonNull List constraintKeys) - { - this.createTime = createTime; - this.lifespan = lifespan; - this.maxAttempts = maxAttempts; - this.maxBackoff = maxBackoff; - this.maxInstances = maxInstances; - this.queue = queue; - this.constraintKeys = constraintKeys; - } - - public long getCreateTime() { - return createTime; - } - - public long getLifespan() { - return lifespan; - } - - public int getMaxAttempts() { - return maxAttempts; - } - - public long getMaxBackoff() { - return maxBackoff; - } - - public int getMaxInstances() { - return maxInstances; - } - - public @Nullable String getQueue() { - return queue; - } - - public List getConstraintKeys() { - return constraintKeys; - } - - - public static final class Builder { - - private long createTime = System.currentTimeMillis(); - private long maxBackoff = TimeUnit.SECONDS.toMillis(30); - private long lifespan = IMMORTAL; - private int maxAttempts = 1; - private int maxInstances = UNLIMITED; - private String queue = null; - private List constraintKeys = new LinkedList<>(); - - /** Should only be invoked by {@link JobController} */ - Builder setCreateTime(long createTime) { - this.createTime = createTime; - return this; - } - - /** - * Specify the amount of time this job is allowed to be retried. Defaults to {@link #IMMORTAL}. - */ - public @NonNull Builder setLifespan(long lifespan) { - this.lifespan = lifespan; - return this; - } - - /** - * Specify the maximum number of times you want to attempt this job. Defaults to 1. - */ - public @NonNull Builder setMaxAttempts(int maxAttempts) { - this.maxAttempts = maxAttempts; - return this; - } - - /** - * Specify the longest amount of time to wait between retries. No guarantees that this will - * be respected on API >= 26. - */ - public @NonNull Builder setMaxBackoff(long maxBackoff) { - this.maxBackoff = maxBackoff; - return this; - } - - /** - * Specify the maximum number of instances you'd want of this job at any given time. If - * enqueueing this job would put it over that limit, it will be ignored. - * - * Duplicates are determined by two jobs having the same {@link Job#getFactoryKey()}. - * - * This property is ignored if the job is submitted as part of a {@link JobManager.Chain}. - * - * Defaults to {@link #UNLIMITED}. - */ - public @NonNull Builder setMaxInstances(int maxInstances) { - this.maxInstances = maxInstances; - return this; - } - - /** - * Specify a string representing a queue. All jobs within the same queue are run in a - * serialized fashion -- one after the other, in order of insertion. Failure of a job earlier - * in the queue has no impact on the execution of jobs later in the queue. - */ - public @NonNull Builder setQueue(@Nullable String queue) { - this.queue = queue; - return this; - } - - /** - * Add a constraint via the key that was used to register its factory in - * {@link JobManager.Configuration)}; - */ - public @NonNull Builder addConstraint(@NonNull String constraintKey) { - constraintKeys.add(constraintKey); - return this; - } - - /** - * Set constraints via the key that was used to register its factory in - * {@link JobManager.Configuration)}; - */ - public @NonNull Builder setConstraints(@NonNull List constraintKeys) { - this.constraintKeys.clear(); - this.constraintKeys.addAll(constraintKeys); - return this; - } - - public @NonNull Parameters build() { - return new Parameters(createTime, lifespan, maxAttempts, maxBackoff, maxInstances, queue, constraintKeys); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java deleted file mode 100644 index 33345a03e1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobController.java +++ /dev/null @@ -1,354 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.WorkerThread; - -import com.annimon.stream.Stream; - -import org.session.libsession.messaging.utilities.Data; -import org.session.libsession.utilities.Debouncer; -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; -import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.UUID; - -/** - * Manages the queue of jobs. This is the only class that should write to {@link JobStorage} to - * ensure consistency. - */ -class JobController { - - private static final String TAG = JobController.class.getSimpleName(); - - private final Application application; - private final JobStorage jobStorage; - private final JobInstantiator jobInstantiator; - private final ConstraintInstantiator constraintInstantiator; - private final Data.Serializer dataSerializer; - private final Scheduler scheduler; - private final Debouncer debouncer; - private final Callback callback; - private final Set runningJobs; - - JobController(@NonNull Application application, - @NonNull JobStorage jobStorage, - @NonNull JobInstantiator jobInstantiator, - @NonNull ConstraintInstantiator constraintInstantiator, - @NonNull Data.Serializer dataSerializer, - @NonNull Scheduler scheduler, - @NonNull Debouncer debouncer, - @NonNull Callback callback) - { - this.application = application; - this.jobStorage = jobStorage; - this.jobInstantiator = jobInstantiator; - this.constraintInstantiator = constraintInstantiator; - this.dataSerializer = dataSerializer; - this.scheduler = scheduler; - this.debouncer = debouncer; - this.callback = callback; - this.runningJobs = new HashSet<>(); - } - - @WorkerThread - synchronized void init() { - jobStorage.init(); - jobStorage.updateAllJobsToBePending(); - notifyAll(); - } - - synchronized void wakeUp() { - notifyAll(); - } - - @WorkerThread - synchronized void submitNewJobChain(@NonNull List> chain) { - chain = Stream.of(chain).filterNot(List::isEmpty).toList(); - - if (chain.isEmpty()) { - Log.w(TAG, "Tried to submit an empty job chain. Skipping."); - return; - } - - if (chainExceedsMaximumInstances(chain)) { - Job solo = chain.get(0).get(0); - Log.w(TAG, JobLogger.format(solo, "Already at the max instance count of " + solo.getParameters().getMaxInstances() + ". Skipping.")); - return; - } - - insertJobChain(chain); - scheduleJobs(chain.get(0)); - triggerOnSubmit(chain); - notifyAll(); - } - - @WorkerThread - synchronized void onRetry(@NonNull Job job) { - int nextRunAttempt = job.getRunAttempt() + 1; - long nextRunAttemptTime = calculateNextRunAttemptTime(System.currentTimeMillis(), nextRunAttempt, job.getParameters().getMaxBackoff()); - - jobStorage.updateJobAfterRetry(job.getId(), false, nextRunAttempt, nextRunAttemptTime); - - List constraints = Stream.of(jobStorage.getConstraintSpecs(job.getId())) - .map(ConstraintSpec::getFactoryKey) - .map(constraintInstantiator::instantiate) - .toList(); - - - long delay = Math.max(0, nextRunAttemptTime - System.currentTimeMillis()); - - Log.i(TAG, JobLogger.format(job, "Scheduling a retry in " + delay + " ms.")); - scheduler.schedule(delay, constraints); - - notifyAll(); - } - - synchronized void onJobFinished(@NonNull Job job) { - runningJobs.remove(job.getId()); - } - - @WorkerThread - synchronized void onSuccess(@NonNull Job job) { - jobStorage.deleteJob(job.getId()); - notifyAll(); - } - - /** - * @return The list of all dependent jobs that should also be failed. - */ - @WorkerThread - synchronized @NonNull List onFailure(@NonNull Job job) { - List dependents = Stream.of(jobStorage.getDependencySpecsThatDependOnJob(job.getId())) - .map(DependencySpec::getJobId) - .map(jobStorage::getJobSpec) - .withoutNulls() - .map(jobSpec -> { - List constraintSpecs = jobStorage.getConstraintSpecs(jobSpec.getId()); - return createJob(jobSpec, constraintSpecs); - }) - .toList(); - - List all = new ArrayList<>(dependents.size() + 1); - all.add(job); - all.addAll(dependents); - - jobStorage.deleteJobs(Stream.of(all).map(Job::getId).toList()); - - return dependents; - } - - /** - * Retrieves the next job that is eligible for execution. To be 'eligible' means that the job: - * - Has no dependencies - * - Has no unmet constraints - * - * This method will block until a job is available. - * When the job returned from this method has been run, you must call {@link #onJobFinished(Job)}. - */ - @WorkerThread - synchronized @NonNull Job pullNextEligibleJobForExecution() { - try { - Job job; - - while ((job = getNextEligibleJobForExecution()) == null) { - if (runningJobs.isEmpty()) { - debouncer.publish(callback::onEmpty); - } - - wait(); - } - - jobStorage.updateJobRunningState(job.getId(), true); - runningJobs.add(job.getId()); - - return job; - } catch (InterruptedException e) { - Log.e(TAG, "Interrupted."); - throw new AssertionError(e); - } - } - - /** - * Retrieves a string representing the state of the job queue. Intended for debugging. - */ - @WorkerThread - synchronized @NonNull String getDebugInfo() { - List jobs = jobStorage.getAllJobSpecs(); - List constraints = jobStorage.getAllConstraintSpecs(); - List dependencies = jobStorage.getAllDependencySpecs(); - - StringBuilder info = new StringBuilder(); - - info.append("-- Jobs\n"); - if (!jobs.isEmpty()) { - Stream.of(jobs).forEach(j -> info.append(j.toString()).append('\n')); - } else { - info.append("None\n"); - } - - info.append("\n-- Constraints\n"); - if (!constraints.isEmpty()) { - Stream.of(constraints).forEach(c -> info.append(c.toString()).append('\n')); - } else { - info.append("None\n"); - } - - info.append("\n-- Dependencies\n"); - if (!dependencies.isEmpty()) { - Stream.of(dependencies).forEach(d -> info.append(d.toString()).append('\n')); - } else { - info.append("None\n"); - } - - return info.toString(); - } - - @WorkerThread - private boolean chainExceedsMaximumInstances(@NonNull List> chain) { - if (chain.size() == 1 && chain.get(0).size() == 1) { - Job solo = chain.get(0).get(0); - - if (solo.getParameters().getMaxInstances() != Job.Parameters.UNLIMITED && - jobStorage.getJobInstanceCount(solo.getFactoryKey()) >= solo.getParameters().getMaxInstances()) - { - return true; - } - } - return false; - } - - @WorkerThread - private void triggerOnSubmit(@NonNull List> chain) { - Stream.of(chain) - .forEach(list -> Stream.of(list).forEach(job -> { - job.setContext(application); - job.onSubmit(); - })); - } - - @WorkerThread - private void insertJobChain(@NonNull List> chain) { - List fullSpecs = new LinkedList<>(); - List dependsOn = Collections.emptyList(); - - for (List jobList : chain) { - for (Job job : jobList) { - fullSpecs.add(buildFullSpec(job, dependsOn)); - } - dependsOn = jobList; - } - - jobStorage.insertJobs(fullSpecs); - } - - @WorkerThread - private @NonNull FullSpec buildFullSpec(@NonNull Job job, @NonNull List dependsOn) { - String id = UUID.randomUUID().toString(); - - job.setId(id); - job.setRunAttempt(0); - - JobSpec jobSpec = new JobSpec(job.getId(), - job.getFactoryKey(), - job.getParameters().getQueue(), - job.getParameters().getCreateTime(), - job.getNextRunAttemptTime(), - job.getRunAttempt(), - job.getParameters().getMaxAttempts(), - job.getParameters().getMaxBackoff(), - job.getParameters().getLifespan(), - job.getParameters().getMaxInstances(), - dataSerializer.serialize(job.serialize()), - false); - - List constraintSpecs = Stream.of(job.getParameters().getConstraintKeys()) - .map(key -> new ConstraintSpec(jobSpec.getId(), key)) - .toList(); - - List dependencySpecs = Stream.of(dependsOn) - .map(depends -> new DependencySpec(job.getId(), depends.getId())) - .toList(); - - return new FullSpec(jobSpec, constraintSpecs, dependencySpecs); - } - - @WorkerThread - private void scheduleJobs(@NonNull List jobs) { - for (Job job : jobs) { - List constraints = Stream.of(job.getParameters().getConstraintKeys()) - .map(key -> new ConstraintSpec(job.getId(), key)) - .map(ConstraintSpec::getFactoryKey) - .map(constraintInstantiator::instantiate) - .toList(); - - scheduler.schedule(0, constraints); - } - } - - @WorkerThread - private @Nullable Job getNextEligibleJobForExecution() { - List jobSpecs = jobStorage.getPendingJobsWithNoDependenciesInCreatedOrder(System.currentTimeMillis()); - - for (JobSpec jobSpec : jobSpecs) { - List constraintSpecs = jobStorage.getConstraintSpecs(jobSpec.getId()); - List constraints = Stream.of(constraintSpecs) - .map(ConstraintSpec::getFactoryKey) - .map(constraintInstantiator::instantiate) - .toList(); - - if (Stream.of(constraints).allMatch(Constraint::isMet)) { - return createJob(jobSpec, constraintSpecs); - } - } - - return null; - } - - private @NonNull Job createJob(@NonNull JobSpec jobSpec, @NonNull List constraintSpecs) { - Job.Parameters parameters = buildJobParameters(jobSpec, constraintSpecs); - Data data = dataSerializer.deserialize(jobSpec.getSerializedData()); - Job job = jobInstantiator.instantiate(jobSpec.getFactoryKey(), parameters, data); - - job.setId(jobSpec.getId()); - job.setRunAttempt(jobSpec.getRunAttempt()); - job.setNextRunAttemptTime(jobSpec.getNextRunAttemptTime()); - job.setContext(application); - - return job; - } - - private @NonNull Job.Parameters buildJobParameters(@NonNull JobSpec jobSpec, @NonNull List constraintSpecs) { - return new Job.Parameters.Builder() - .setCreateTime(jobSpec.getCreateTime()) - .setLifespan(jobSpec.getLifespan()) - .setMaxAttempts(jobSpec.getMaxAttempts()) - .setQueue(jobSpec.getQueueKey()) - .setConstraints(Stream.of(constraintSpecs).map(ConstraintSpec::getFactoryKey).toList()) - .build(); - } - - private long calculateNextRunAttemptTime(long currentTime, int nextAttempt, long maxBackoff) { - int boundedAttempt = Math.min(nextAttempt, 30); - long exponentialBackoff = (long) Math.pow(2, boundedAttempt) * 1000; - long actualBackoff = Math.min(exponentialBackoff, maxBackoff); - - return currentTime + actualBackoff; - } - - interface Callback { - void onEmpty(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java index 6d1527d131..81e378288d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.jobmanager; import androidx.annotation.NonNull; +import org.session.libsession.messaging.jobs.Job; import org.session.libsession.messaging.utilities.Data; import java.util.HashMap; @@ -15,9 +16,9 @@ class JobInstantiator { this.jobFactories = new HashMap<>(jobFactories); } - public @NonNull Job instantiate(@NonNull String jobFactoryKey, @NonNull Job.Parameters parameters, @NonNull Data data) { + public @NonNull Job instantiate(@NonNull String jobFactoryKey, @NonNull Data data) { if (jobFactories.containsKey(jobFactoryKey)) { - return jobFactories.get(jobFactoryKey).create(parameters, data); + return jobFactories.get(jobFactoryKey).create(data); } else { throw new IllegalStateException("Tried to instantiate a job with key '" + jobFactoryKey + "', but no matching factory was found."); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobLogger.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobLogger.java deleted file mode 100644 index c35f6dc1ac..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobLogger.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; -import android.text.TextUtils; - -public class JobLogger { - - public static String format(@NonNull Job job, @NonNull String event) { - return format(job, "", event); - } - - public static String format(@NonNull Job job, @NonNull String extraTag, @NonNull String event) { - String id = job.getId(); - String tag = TextUtils.isEmpty(extraTag) ? "" : "[" + extraTag + "]"; - long timeSinceSubmission = System.currentTimeMillis() - job.getParameters().getCreateTime(); - int runAttempt = job.getRunAttempt() + 1; - String maxAttempts = job.getParameters().getMaxAttempts() == Job.Parameters.UNLIMITED ? "Unlimited" - : String.valueOf(job.getParameters().getMaxAttempts()); - String lifespan = job.getParameters().getLifespan() == Job.Parameters.IMMORTAL ? "Immortal" - : String.valueOf(job.getParameters().getLifespan()) + " ms"; - return String.format("[%s][%s]%s %s (Time Since Submission: %d ms, Lifespan: %s, Run Attempt: %d/%s)", - id, job.getClass().getSimpleName(), tag, event, timeSinceSubmission, lifespan, runAttempt, maxAttempts); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java index abb15d9f75..7bbd7679f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java @@ -6,24 +6,14 @@ import android.os.Build; import androidx.annotation.NonNull; -import org.session.libsession.messaging.utilities.Data; -import org.session.libsession.utilities.Debouncer; import org.session.libsignal.utilities.Log; import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory; -import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; -import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; /** * Allows the scheduling of durable jobs that will be run as early as possible. @@ -33,32 +23,13 @@ public class JobManager implements ConstraintObserver.Notifier { private static final String TAG = JobManager.class.getSimpleName(); private final ExecutorService executor; - private final JobController jobController; - private final JobRunner[] jobRunners; private final Set emptyQueueListeners = new CopyOnWriteArraySet<>(); public JobManager(@NonNull Application application, @NonNull Configuration configuration) { this.executor = configuration.getExecutorFactory().newSingleThreadExecutor("JobManager"); - this.jobRunners = new JobRunner[configuration.getJobThreadCount()]; - this.jobController = new JobController(application, - configuration.getJobStorage(), - configuration.getJobInstantiator(), - configuration.getConstraintFactories(), - configuration.getDataSerializer(), - Build.VERSION.SDK_INT < 26 ? new AlarmManagerScheduler(application) - : new CompositeScheduler(new InAppScheduler(this), new JobSchedulerScheduler(application)), - new Debouncer(500), - this::onEmptyQueue); executor.execute(() -> { - jobController.init(); - - for (int i = 0; i < jobRunners.length; i++) { - jobRunners[i] = new JobRunner(application, i + 1, jobController); - jobRunners[i].start(); - } - for (ConstraintObserver constraintObserver : configuration.getConstraintObservers()) { constraintObserver.register(this); } @@ -71,13 +42,6 @@ public class JobManager implements ConstraintObserver.Notifier { }); } - /** - * Enqueues a single job to be run. - */ - public void add(@NonNull Job job) { - new Chain(this, Collections.singletonList(job)).enqueue(); - } - /** * Adds a listener to that will be notified when the job queue has been drained. */ @@ -105,166 +69,45 @@ public class JobManager implements ConstraintObserver.Notifier { /** * Pokes the system to take another pass at the job queue. */ - void wakeUp() { - executor.execute(jobController::wakeUp); - } - - private void enqueueChain(@NonNull Chain chain) { - executor.execute(() -> { - jobController.submitNewJobChain(chain.getJobListChain()); - wakeUp(); - }); - } - - private void onEmptyQueue() { - executor.execute(() -> { - for (EmptyQueueListener listener : emptyQueueListeners) { - listener.onQueueEmpty(); - } - }); - } + void wakeUp() {} public interface EmptyQueueListener { void onQueueEmpty(); } - /** - * Allows enqueuing work that depends on each other. Jobs that appear later in the chain will - * only run after all jobs earlier in the chain have been completed. If a job fails, all jobs - * that occur later in the chain will also be failed. - */ - public static class Chain { - - private final JobManager jobManager; - private final List> jobs; - - private Chain(@NonNull JobManager jobManager, @NonNull List jobs) { - this.jobManager = jobManager; - this.jobs = new LinkedList<>(); - - this.jobs.add(new ArrayList<>(jobs)); - } - - public Chain then(@NonNull Job job) { - return then(Collections.singletonList(job)); - } - - public Chain then(@NonNull List jobs) { - if (!jobs.isEmpty()) { - this.jobs.add(new ArrayList<>(jobs)); - } - return this; - } - - public void enqueue() { - jobManager.enqueueChain(this); - } - - private List> getJobListChain() { - return jobs; - } - } - public static class Configuration { private final ExecutorFactory executorFactory; - private final int jobThreadCount; - private final JobInstantiator jobInstantiator; - private final ConstraintInstantiator constraintInstantiator; private final List constraintObservers; - private final Data.Serializer dataSerializer; - private final JobStorage jobStorage; - private Configuration(int jobThreadCount, - @NonNull ExecutorFactory executorFactory, - @NonNull JobInstantiator jobInstantiator, - @NonNull ConstraintInstantiator constraintInstantiator, - @NonNull List constraintObservers, - @NonNull Data.Serializer dataSerializer, - @NonNull JobStorage jobStorage) + private Configuration(@NonNull ExecutorFactory executorFactory, + @NonNull List constraintObservers) { this.executorFactory = executorFactory; - this.jobThreadCount = jobThreadCount; - this.jobInstantiator = jobInstantiator; - this.constraintInstantiator = constraintInstantiator; this.constraintObservers = constraintObservers; - this.dataSerializer = dataSerializer; - this.jobStorage = jobStorage; - } - - int getJobThreadCount() { - return jobThreadCount; } @NonNull ExecutorFactory getExecutorFactory() { return executorFactory; } - @NonNull JobInstantiator getJobInstantiator() { - return jobInstantiator; - } - - @NonNull - ConstraintInstantiator getConstraintFactories() { - return constraintInstantiator; - } - @NonNull List getConstraintObservers() { return constraintObservers; } - @NonNull Data.Serializer getDataSerializer() { - return dataSerializer; - } - - @NonNull JobStorage getJobStorage() { - return jobStorage; - } - - public static class Builder { private ExecutorFactory executorFactory = new DefaultExecutorFactory(); - private int jobThreadCount = 1; - private Map jobFactories = new HashMap<>(); - private Map constraintFactories = new HashMap<>(); private List constraintObservers = new ArrayList<>(); - private Data.Serializer dataSerializer = new JsonDataSerializer(); - private JobStorage jobStorage = null; - - public @NonNull Builder setJobFactories(@NonNull Map jobFactories) { - this.jobFactories = jobFactories; - return this; - } - - public @NonNull Builder setConstraintFactories(@NonNull Map constraintFactories) { - this.constraintFactories = constraintFactories; - return this; - } public @NonNull Builder setConstraintObservers(@NonNull List constraintObservers) { this.constraintObservers = constraintObservers; return this; } - public @NonNull Builder setDataSerializer(@NonNull Data.Serializer dataSerializer) { - this.dataSerializer = dataSerializer; - return this; - } - - public @NonNull Builder setJobStorage(@NonNull JobStorage jobStorage) { - this.jobStorage = jobStorage; - return this; - } - public @NonNull Configuration build() { - return new Configuration(jobThreadCount, - executorFactory, - new JobInstantiator(jobFactories), - new ConstraintInstantiator(constraintFactories), - new ArrayList<>(constraintObservers), - dataSerializer, - jobStorage); + return new Configuration(executorFactory, + new ArrayList<>(constraintObservers)); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobRunner.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobRunner.java deleted file mode 100644 index 6eadf0fd5d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobRunner.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.Application; -import android.os.PowerManager; -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; - -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.util.WakeLockUtil; - -import java.util.List; -import java.util.concurrent.TimeUnit; - -class JobRunner extends Thread { - - private static final String TAG = JobRunner.class.getSimpleName(); - - private static long WAKE_LOCK_TIMEOUT = TimeUnit.MINUTES.toMillis(10); - - private final Application application; - private final int id; - private final JobController jobController; - - JobRunner(@NonNull Application application, int id, @NonNull JobController jobController) { - super("JobRunner-" + id); - - this.application = application; - this.id = id; - this.jobController = jobController; - } - - @Override - public synchronized void run() { - while (true) { - Job job = jobController.pullNextEligibleJobForExecution(); - Job.Result result = run(job); - - jobController.onJobFinished(job); - - switch (result) { - case SUCCESS: - jobController.onSuccess(job); - break; - case RETRY: - jobController.onRetry(job); - job.onRetry(); - break; - case FAILURE: - List dependents = jobController.onFailure(job); - job.onCanceled(); - Stream.of(dependents).forEach(Job::onCanceled); - break; - } - } - } - - private Job.Result run(@NonNull Job job) { - Log.i(TAG, JobLogger.format(job, String.valueOf(id), "Running job.")); - - if (isJobExpired(job)) { - Log.w(TAG, JobLogger.format(job, String.valueOf(id), "Failing after surpassing its lifespan.")); - return Job.Result.FAILURE; - } - - Job.Result result = null; - PowerManager.WakeLock wakeLock = null; - - try { - wakeLock = WakeLockUtil.acquire(application, PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TIMEOUT, job.getId()); - result = job.run(); - } catch (Exception e) { - Log.w(TAG, JobLogger.format(job, String.valueOf(id), "Failing due to an unexpected exception."), e); - return Job.Result.FAILURE; - } finally { - if (wakeLock != null) { - WakeLockUtil.release(wakeLock, job.getId()); - } - } - - printResult(job, result); - - if (result == Job.Result.RETRY && job.getRunAttempt() + 1 >= job.getParameters().getMaxAttempts() && - job.getParameters().getMaxAttempts() != Job.Parameters.UNLIMITED) - { - Log.w(TAG, JobLogger.format(job, String.valueOf(id), "Failing after surpassing its max number of attempts.")); - return Job.Result.FAILURE; - } - - return result; - } - - private boolean isJobExpired(@NonNull Job job) { - long expirationTime = job.getParameters().getCreateTime() + job.getParameters().getLifespan(); - - if (expirationTime < 0) { - expirationTime = Long.MAX_VALUE; - } - - return job.getParameters().getLifespan() != Job.Parameters.IMMORTAL && expirationTime <= System.currentTimeMillis(); - } - - private void printResult(@NonNull Job job, @NonNull Job.Result result) { - if (result == Job.Result.FAILURE) { - Log.w(TAG, JobLogger.format(job, String.valueOf(id), "Job failed.")); - } else { - Log.i(TAG, JobLogger.format(job, String.valueOf(id), "Job finished with result: " + result)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobSchedulerScheduler.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobSchedulerScheduler.java deleted file mode 100644 index 40acbf520b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobSchedulerScheduler.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.Application; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.app.job.JobService; -import android.content.ComponentName; -import android.content.Context; -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import androidx.annotation.RequiresApi; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.session.libsignal.utilities.Log; - -import java.util.List; - -@RequiresApi(26) -public class JobSchedulerScheduler implements Scheduler { - - private static final String TAG = JobSchedulerScheduler.class.getSimpleName(); - - private static final String PREF_NAME = "JobSchedulerScheduler_prefs"; - private static final String PREF_NEXT_ID = "pref_next_id"; - - private static final int MAX_ID = 75; - - private final Application application; - - JobSchedulerScheduler(@NonNull Application application) { - this.application = application; - } - - @RequiresApi(26) - @Override - public void schedule(long delay, @NonNull List constraints) { - JobInfo.Builder jobInfoBuilder = new JobInfo.Builder(getNextId(), new ComponentName(application, SystemService.class)) - .setMinimumLatency(delay) - .setPersisted(true); - - for (Constraint constraint : constraints) { - constraint.applyToJobInfo(jobInfoBuilder); - } - - Log.i(TAG, "Scheduling a run in " + delay + " ms."); - JobScheduler jobScheduler = application.getSystemService(JobScheduler.class); - jobScheduler.schedule(jobInfoBuilder.build()); - } - - private int getNextId() { - SharedPreferences prefs = application.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); - int returnedId = prefs.getInt(PREF_NEXT_ID, 0); - int nextId = returnedId + 1 > MAX_ID ? 0 : returnedId + 1; - - prefs.edit().putInt(PREF_NEXT_ID, nextId).apply(); - - return returnedId; - } - - @RequiresApi(api = 26) - public static class SystemService extends JobService { - - @Override - public boolean onStartJob(JobParameters params) { - Log.d(TAG, "onStartJob()"); - - JobManager jobManager = ApplicationContext.getInstance(getApplicationContext()).getJobManager(); - - jobManager.addOnEmptyQueueListener(new JobManager.EmptyQueueListener() { - @Override - public void onQueueEmpty() { - jobManager.removeOnEmptyQueueListener(this); - jobFinished(params, false); - Log.d(TAG, "jobFinished()"); - } - }); - - jobManager.wakeUp(); - - return true; - } - - @Override - public boolean onStopJob(JobParameters params) { - Log.d(TAG, "onStopJob()"); - return false; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Scheduler.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Scheduler.java deleted file mode 100644 index 194acd39b2..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/Scheduler.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -import java.util.List; - -public interface Scheduler { - void schedule(long delay, @NonNull List constraints); -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/BaseJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/BaseJob.java deleted file mode 100644 index 0c11cc552b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/BaseJob.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.JobLogger; -import org.session.libsignal.utilities.Log; - -/** - * @deprecated - * use WorkManager - * API instead. - */ -public abstract class BaseJob extends Job { - - private static final String TAG = BaseJob.class.getSimpleName(); - - public BaseJob(@NonNull Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Result run() { - try { - onRun(); - return Result.SUCCESS; - } catch (Exception e) { - if (onShouldRetry(e)) { - Log.i(TAG, JobLogger.format(this, "Encountered a retryable exception."), e); - return Result.RETRY; - } else { - Log.w(TAG, JobLogger.format(this, "Encountered a failing exception."), e); - return Result.FAILURE; - } - } - } - - protected abstract void onRun() throws Exception; - - protected abstract boolean onShouldRetry(@NonNull Exception e); -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java deleted file mode 100644 index 3b50dc2733..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/FastJobStorage.java +++ /dev/null @@ -1,261 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.annimon.stream.Stream; - -import org.thoughtcrime.securesms.database.JobDatabase; -import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; -import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobStorage; - -import org.session.libsession.utilities.Util; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; - -public class FastJobStorage implements JobStorage { - - private final JobDatabase jobDatabase; - - private final List jobs; - private final Map> constraintsByJobId; - private final Map> dependenciesByJobId; - - public FastJobStorage(@NonNull JobDatabase jobDatabase) { - this.jobDatabase = jobDatabase; - this.jobs = new ArrayList<>(); - this.constraintsByJobId = new HashMap<>(); - this.dependenciesByJobId = new HashMap<>(); - } - - @Override - public synchronized void init() { - List jobSpecs = jobDatabase.getAllJobSpecs(); - List constraintSpecs = jobDatabase.getAllConstraintSpecs(); - List dependencySpecs = jobDatabase.getAllDependencySpecs(); - - jobs.addAll(jobSpecs); - - for (ConstraintSpec constraintSpec: constraintSpecs) { - List jobConstraints = Util.getOrDefault(constraintsByJobId, constraintSpec.getJobSpecId(), new LinkedList<>()); - jobConstraints.add(constraintSpec); - constraintsByJobId.put(constraintSpec.getJobSpecId(), jobConstraints); - } - - for (DependencySpec dependencySpec : dependencySpecs) { - List jobDependencies = Util.getOrDefault(dependenciesByJobId, dependencySpec.getJobId(), new LinkedList<>()); - jobDependencies.add(dependencySpec); - dependenciesByJobId.put(dependencySpec.getJobId(), jobDependencies); - } - } - - @Override - public synchronized void insertJobs(@NonNull List fullSpecs) { - jobDatabase.insertJobs(fullSpecs); - - for (FullSpec fullSpec : fullSpecs) { - jobs.add(fullSpec.getJobSpec()); - constraintsByJobId.put(fullSpec.getJobSpec().getId(), fullSpec.getConstraintSpecs()); - dependenciesByJobId.put(fullSpec.getJobSpec().getId(), fullSpec.getDependencySpecs()); - } - } - - @Override - public synchronized @Nullable JobSpec getJobSpec(@NonNull String id) { - for (JobSpec jobSpec : jobs) { - if (jobSpec.getId().equals(id)) { - return jobSpec; - } - } - return null; - } - - @Override - public synchronized @NonNull List getAllJobSpecs() { - return new ArrayList<>(jobs); - } - - @Override - public synchronized @NonNull List getPendingJobsWithNoDependenciesInCreatedOrder(long currentTime) { - return Stream.of(jobs) - .filter(j -> JobManagerFactories.hasFactoryForKey(j.getFactoryKey())) - .filterNot(JobSpec::isRunning) - .filter(this::firstInQueue) - .filter(j -> !dependenciesByJobId.containsKey(j.getId()) || dependenciesByJobId.get(j.getId()).isEmpty()) - .filter(j -> j.getNextRunAttemptTime() <= currentTime) - .sorted((j1, j2) -> Long.compare(j1.getCreateTime(), j2.getCreateTime())) - .toList(); - } - - private boolean firstInQueue(@NonNull JobSpec job) { - if (job.getQueueKey() == null) { - return true; - } - - return Stream.of(jobs) - .filter(j -> Util.equals(j.getQueueKey(), job.getQueueKey())) - .sorted((j1, j2) -> Long.compare(j1.getCreateTime(), j2.getCreateTime())) - .toList() - .get(0) - .equals(job); - } - - @Override - public synchronized int getJobInstanceCount(@NonNull String factoryKey) { - return (int) Stream.of(jobs) - .filter(j -> j.getFactoryKey().equals(factoryKey)) - .count(); - } - - @Override - public synchronized void updateJobRunningState(@NonNull String id, boolean isRunning) { - jobDatabase.updateJobRunningState(id, isRunning); - - ListIterator iter = jobs.listIterator(); - - while (iter.hasNext()) { - JobSpec existing = iter.next(); - if (existing.getId().equals(id)) { - JobSpec updated = new JobSpec(existing.getId(), - existing.getFactoryKey(), - existing.getQueueKey(), - existing.getCreateTime(), - existing.getNextRunAttemptTime(), - existing.getRunAttempt(), - existing.getMaxAttempts(), - existing.getMaxBackoff(), - existing.getLifespan(), - existing.getMaxInstances(), - existing.getSerializedData(), - isRunning); - iter.set(updated); - } - } - } - - @Override - public synchronized void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime) { - jobDatabase.updateJobAfterRetry(id, isRunning, runAttempt, nextRunAttemptTime); - - ListIterator iter = jobs.listIterator(); - - while (iter.hasNext()) { - JobSpec existing = iter.next(); - if (existing.getId().equals(id)) { - JobSpec updated = new JobSpec(existing.getId(), - existing.getFactoryKey(), - existing.getQueueKey(), - existing.getCreateTime(), - nextRunAttemptTime, - runAttempt, - existing.getMaxAttempts(), - existing.getMaxBackoff(), - existing.getLifespan(), - existing.getMaxInstances(), - existing.getSerializedData(), - isRunning); - iter.set(updated); - } - } - } - - @Override - public synchronized void updateAllJobsToBePending() { - jobDatabase.updateAllJobsToBePending(); - - ListIterator iter = jobs.listIterator(); - - while (iter.hasNext()) { - JobSpec existing = iter.next(); - JobSpec updated = new JobSpec(existing.getId(), - existing.getFactoryKey(), - existing.getQueueKey(), - existing.getCreateTime(), - existing.getNextRunAttemptTime(), - existing.getRunAttempt(), - existing.getMaxAttempts(), - existing.getMaxBackoff(), - existing.getLifespan(), - existing.getMaxInstances(), - existing.getSerializedData(), - false); - iter.set(updated); - } - } - - @Override - public synchronized void deleteJob(@NonNull String jobId) { - deleteJobs(Collections.singletonList(jobId)); - } - - @Override - public synchronized void deleteJobs(@NonNull List jobIds) { - jobDatabase.deleteJobs(jobIds); - - Set deleteIds = new HashSet<>(jobIds); - - Iterator jobIter = jobs.iterator(); - while (jobIter.hasNext()) { - if (deleteIds.contains(jobIter.next().getId())) { - jobIter.remove(); - } - } - - for (String jobId : jobIds) { - constraintsByJobId.remove(jobId); - dependenciesByJobId.remove(jobId); - - for (Map.Entry> entry : dependenciesByJobId.entrySet()) { - Iterator depedencyIter = entry.getValue().iterator(); - - while (depedencyIter.hasNext()) { - if (depedencyIter.next().getDependsOnJobId().equals(jobId)) { - depedencyIter.remove(); - } - } - } - } - } - - @Override - public synchronized @NonNull List getConstraintSpecs(@NonNull String jobId) { - return Util.getOrDefault(constraintsByJobId, jobId, new LinkedList<>()); - } - - @Override - public synchronized @NonNull List getAllConstraintSpecs() { - return Stream.of(constraintsByJobId) - .map(Map.Entry::getValue) - .flatMap(Stream::of) - .toList(); - } - - @Override - public synchronized @NonNull List getDependencySpecsThatDependOnJob(@NonNull String jobSpecId) { - return Stream.of(dependenciesByJobId.entrySet()) - .map(Map.Entry::getValue) - .flatMap(Stream::of) - .filter(j -> j.getDependsOnJobId().equals(jobSpecId)) - .toList(); - } - - @Override - public @NonNull List getAllDependencySpecs() { - return Stream.of(dependenciesByJobId) - .map(Map.Entry::getValue) - .flatMap(Stream::of) - .toList(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 910a9c09be..d892c0f439 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -26,7 +26,7 @@ public final class JobManagerFactories { private static Collection factoryKeys = new ArrayList<>(); - public static Map getJobFactories(@NonNull Application application) { + public static Map getJobFactories() { HashMap factoryHashMap = new HashMap() {{ put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory()); put(RetrieveProfileAvatarJob.Companion.getKEY(), new RetrieveProfileAvatarJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java index 0b1b3f8423..9cf88f4094 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.service; import android.content.Context; import android.content.Intent; +import org.session.libsession.messaging.jobs.JobQueue; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.jobs.LocalBackupJob; import org.session.libsession.utilities.TextSecurePreferences; @@ -21,7 +22,9 @@ public class LocalBackupListener extends PersistentAlarmManagerListener { @Override protected long onAlarm(Context context, long scheduledTime) { if (TextSecurePreferences.isBackupEnabled(context)) { - ApplicationContext.getInstance(context).getJobManager().add(new LocalBackupJob()); + LocalBackupJob job = new LocalBackupJob(); + job.context = context; + JobQueue.getShared().add(job); } long nextTime = System.currentTimeMillis() + INTERVAL; diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java index ef27916ac9..01ade94214 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java @@ -31,9 +31,9 @@ public class UpdateApkRefreshListener extends PersistentAlarmManagerListener { if (scheduledTime != 0 && BuildConfig.PLAY_STORE_DISABLED) { Log.i(TAG, "Queueing APK update job..."); - ApplicationContext.getInstance(context) - .getJobManager() - .add(new UpdateApkJob()); + UpdateApkJob job = new UpdateApkJob(); + job.context = context; + JobQueue.getShared().add(job); } long newTime = System.currentTimeMillis() + INTERVAL; diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index 2615eff588..3b6db9a76f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -41,9 +41,9 @@ class ProfileManager : SSKEnvironment.ProfileManagerProtocol { } override fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String) { - val job = RetrieveProfileAvatarJob(recipient, profilePictureURL) - val jobManager = ApplicationContext.getInstance(context).jobManager - jobManager.add(job) + val job = RetrieveProfileAvatarJob(profilePictureURL, recipient.address) + job.context = context + JobQueue.shared.add(job) val sessionID = recipient.address.serialize() val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() var contact = contactDatabase.getContactWithSessionID(sessionID) diff --git a/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java b/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java deleted file mode 100644 index a6624189d1..0000000000 --- a/app/src/test/java/org/thoughtcrime/securesms/jobs/FastJobStorageTest.java +++ /dev/null @@ -1,350 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Application; - -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; - -import org.junit.Test; -import org.session.libsession.messaging.utilities.Data; -import org.thoughtcrime.securesms.database.JobDatabase; -import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; -import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; -import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class FastJobStorageTest { - - private static final JsonDataSerializer serializer = new JsonDataSerializer(); - private static final String EMPTY_DATA = serializer.serialize(Data.EMPTY); - - @Test - public void init_allStoredDataAvailable() { - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS)); - - subject.init(); - - DataSet1.assertJobsMatch(subject.getAllJobSpecs()); - DataSet1.assertConstraintsMatch(subject.getAllConstraintSpecs()); - DataSet1.assertDependenciesMatch(subject.getAllDependencySpecs()); - } - - @Test - public void insertJobs_writesToDatabase() { - JobDatabase database = noopDatabase(); - FastJobStorage subject = new FastJobStorage(database); - - subject.insertJobs(DataSet1.FULL_SPECS); - - verify(database).insertJobs(DataSet1.FULL_SPECS); - } - - @Test - public void insertJobs_dataCanBeFound() { - FastJobStorage subject = new FastJobStorage(noopDatabase()); - - subject.insertJobs(DataSet1.FULL_SPECS); - - DataSet1.assertJobsMatch(subject.getAllJobSpecs()); - DataSet1.assertConstraintsMatch(subject.getAllConstraintSpecs()); - DataSet1.assertDependenciesMatch(subject.getAllDependencySpecs()); - } - - @Test - public void insertJobs_individualJobCanBeFound() { - FastJobStorage subject = new FastJobStorage(noopDatabase()); - - subject.insertJobs(DataSet1.FULL_SPECS); - - assertEquals(DataSet1.JOB_1, subject.getJobSpec(DataSet1.JOB_1.getId())); - assertEquals(DataSet1.JOB_2, subject.getJobSpec(DataSet1.JOB_2.getId())); - } - - @Test - public void updateAllJobsToBePending_allArePending() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", AvatarDownloadJob.KEY, null, 1, 1, 1, 1, 1, 1, 1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - - subject.init(); - subject.updateAllJobsToBePending(); - - assertFalse(subject.getJobSpec("1").isRunning()); - assertFalse(subject.getJobSpec("2").isRunning()); - } - - @Test - public void updateJobRunningState_writesToDatabase() { - JobDatabase database = noopDatabase(); - FastJobStorage subject = new FastJobStorage(database); - - subject.updateJobRunningState("1", true); - - verify(database).updateJobRunningState("1", true); - } - - @Test - public void updateJobRunningState_stateUpdated() { - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS)); - subject.init(); - - subject.updateJobRunningState(DataSet1.JOB_1.getId(), true); - assertTrue(subject.getJobSpec(DataSet1.JOB_1.getId()).isRunning()); - - subject.updateJobRunningState(DataSet1.JOB_1.getId(), false); - assertFalse(subject.getJobSpec(DataSet1.JOB_1.getId()).isRunning()); - } - - @Test - public void updateJobAfterRetry_writesToDatabase() { - JobDatabase database = noopDatabase(); - FastJobStorage subject = new FastJobStorage(database); - - subject.updateJobAfterRetry("1", true, 1, 10); - - verify(database).updateJobAfterRetry("1", true, 1, 10); - } - - @Test - public void updateJobAfterRetry_stateUpdated() { - FullSpec fullSpec = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 0, 0, 0, 3, 30000, -1, -1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Collections.singletonList(fullSpec))); - - subject.init(); - subject.updateJobAfterRetry("1", false, 1, 10); - - JobSpec job = subject.getJobSpec("1"); - - assertNotNull(job); - assertFalse(job.isRunning()); - assertEquals(1, job.getRunAttempt()); - assertEquals(10, job.getNextRunAttemptTime()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenEarlierItemInQueueInRunning() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", AvatarDownloadJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - subject.init(); - - assertEquals(0, subject.getPendingJobsWithNoDependenciesInCreatedOrder(1).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenAllJobsAreRunning() { - FullSpec fullSpec = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Collections.singletonList(fullSpec))); - subject.init(); - - assertEquals(0, subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenNextRunTimeIsAfterCurrentTime() { - FullSpec fullSpec = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, "q", 0, 10, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Collections.singletonList(fullSpec))); - subject.init(); - - assertEquals(0, subject.getPendingJobsWithNoDependenciesInCreatedOrder(0).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_noneWhenDependentOnAnotherJob() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.singletonList(new DependencySpec("2", "1"))); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - subject.init(); - - assertEquals(0, subject.getPendingJobsWithNoDependenciesInCreatedOrder(0).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_singleEligibleJob() { - FullSpec fullSpec = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Collections.singletonList(fullSpec))); - subject.init(); - - assertEquals(1, subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_multipleEligibleJobs() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - subject.init(); - - assertEquals(2, subject.getPendingJobsWithNoDependenciesInCreatedOrder(10).size()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_singleEligibleJobInMixedList() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, true), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", AvatarDownloadJob.KEY, null, 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - subject.init(); - - List jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10); - - assertEquals(1, jobs.size()); - assertEquals("2", jobs.get(0).getId()); - } - - @Test - public void getPendingJobsWithNoDependenciesInCreatedOrder_firstItemInQueue() { - FullSpec fullSpec1 = new FullSpec(new JobSpec("1", RetrieveProfileAvatarJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - FullSpec fullSpec2 = new FullSpec(new JobSpec("2", RetrieveProfileAvatarJob.KEY, "q", 0, 0, 0, 0, 0, -1, -1, EMPTY_DATA, false), - Collections.emptyList(), - Collections.emptyList()); - - JobManagerFactories.getJobFactories(mock(Application.class)); - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(Arrays.asList(fullSpec1, fullSpec2))); - subject.init(); - - List jobs = subject.getPendingJobsWithNoDependenciesInCreatedOrder(10); - - assertEquals(1, jobs.size()); - assertEquals("1", jobs.get(0).getId()); - } - - @Test - public void deleteJobs_writesToDatabase() { - JobDatabase database = noopDatabase(); - FastJobStorage subject = new FastJobStorage(database); - List ids = Arrays.asList("1", "2"); - - subject.deleteJobs(ids); - - verify(database).deleteJobs(ids); - } - - @Test - public void deleteJobs_deletesAllRelevantPieces() { - FastJobStorage subject = new FastJobStorage(fixedDataDatabase(DataSet1.FULL_SPECS)); - - subject.init(); - subject.deleteJobs(Collections.singletonList("id1")); - - List jobs = subject.getAllJobSpecs(); - List constraints = subject.getAllConstraintSpecs(); - List dependencies = subject.getAllDependencySpecs(); - - assertEquals(1, jobs.size()); - assertEquals(DataSet1.JOB_2, jobs.get(0)); - assertEquals(1, constraints.size()); - assertEquals(DataSet1.CONSTRAINT_2, constraints.get(0)); - assertEquals(0, dependencies.size()); - } - - - private JobDatabase noopDatabase() { - JobDatabase database = mock(JobDatabase.class); - - when(database.getAllJobSpecs()).thenReturn(Collections.emptyList()); - when(database.getAllConstraintSpecs()).thenReturn(Collections.emptyList()); - when(database.getAllDependencySpecs()).thenReturn(Collections.emptyList()); - - return database; - } - - private JobDatabase fixedDataDatabase(List fullSpecs) { - JobDatabase database = mock(JobDatabase.class); - - when(database.getAllJobSpecs()).thenReturn(Stream.of(fullSpecs).map(FullSpec::getJobSpec).toList()); - when(database.getAllConstraintSpecs()).thenReturn(Stream.of(fullSpecs).map(FullSpec::getConstraintSpecs).flatMap(Stream::of).toList()); - when(database.getAllDependencySpecs()).thenReturn(Stream.of(fullSpecs).map(FullSpec::getDependencySpecs).flatMap(Stream::of).toList()); - - return database; - } - - private static final class DataSet1 { - static final JobSpec JOB_1 = new JobSpec("id1", "f1", "q1", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, false); - static final JobSpec JOB_2 = new JobSpec("id2", "f2", "q2", 1, 2, 3, 4, 5, 6, 7, EMPTY_DATA, false); - static final ConstraintSpec CONSTRAINT_1 = new ConstraintSpec("id1", "f1"); - static final ConstraintSpec CONSTRAINT_2 = new ConstraintSpec("id2", "f2"); - static final DependencySpec DEPENDENCY_2 = new DependencySpec("id2", "id1"); - static final FullSpec FULL_SPEC_1 = new FullSpec(JOB_1, Collections.singletonList(CONSTRAINT_1), Collections.emptyList()); - static final FullSpec FULL_SPEC_2 = new FullSpec(JOB_2, Collections.singletonList(CONSTRAINT_2), Collections.singletonList(DEPENDENCY_2)); - static final List FULL_SPECS = Arrays.asList(FULL_SPEC_1, FULL_SPEC_2); - - static void assertJobsMatch(@NonNull List jobs) { - assertEquals(jobs.size(), 2); - assertTrue(jobs.contains(DataSet1.JOB_1)); - assertTrue(jobs.contains(DataSet1.JOB_1)); - } - - static void assertConstraintsMatch(@NonNull List constraints) { - assertEquals(constraints.size(), 2); - assertTrue(constraints.contains(DataSet1.CONSTRAINT_1)); - assertTrue(constraints.contains(DataSet1.CONSTRAINT_2)); - } - - static void assertDependenciesMatch(@NonNull List dependencies) { - assertEquals(dependencies.size(), 1); - assertTrue(dependencies.contains(DataSet1.DEPENDENCY_2)); - } - } -} From b494088c3db0e09a3dc3b8df35e8d969f2b31f83 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 8 May 2023 17:12:20 +1000 Subject: [PATCH 08/19] WIP: further refactor on old jobs --- .../securesms/ApplicationContext.java | 14 --- .../securesms/database/Storage.kt | 3 +- .../jobmanager/ConstraintObserver.java | 12 -- .../securesms/jobmanager/JobInstantiator.java | 26 ---- .../securesms/jobmanager/JobManager.java | 114 ------------------ .../impl/CellServiceConstraint.java | 48 -------- .../impl/CellServiceConstraintObserver.java | 38 ------ .../impl/NetworkConstraintObserver.java | 36 ------ .../impl/NetworkOrCellServiceConstraint.java | 48 -------- .../impl/SqlCipherMigrationConstraint.java | 48 -------- .../SqlCipherMigrationConstraintObserver.java | 32 ----- .../securesms/jobs/JobManagerFactories.java | 57 --------- .../sskenvironment/ProfileManager.kt | 3 +- .../libsession/database/StorageProtocol.kt | 1 + .../jobs/RetrieveProfileAvatarJob.kt | 14 +-- 15 files changed, 9 insertions(+), 485 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintObserver.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraint.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraintObserver.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraintObserver.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkOrCellServiceConstraint.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraint.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraintObserver.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java rename {app/src/main/java/org/thoughtcrime/securesms => libsession/src/main/java/org/session/libsession/messaging}/jobs/RetrieveProfileAvatarJob.kt (90%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 0d5e57352e..df1bed7b3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -65,9 +65,7 @@ import org.thoughtcrime.securesms.dependencies.DatabaseModule; import org.thoughtcrime.securesms.emoji.EmojiSource; import org.thoughtcrime.securesms.groups.OpenGroupManager; import org.thoughtcrime.securesms.home.HomeActivity; -import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.jobs.JobManagerFactories; import org.thoughtcrime.securesms.logging.AndroidLogger; import org.thoughtcrime.securesms.logging.PersistentLogger; import org.thoughtcrime.securesms.logging.UncaughtExceptionLogger; @@ -130,7 +128,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private ExpiringMessageManager expiringMessageManager; private TypingStatusRepository typingStatusRepository; private TypingStatusSender typingStatusSender; - private JobManager jobManager; private ReadReceiptManager readReceiptManager; private ProfileManager profileManager; public MessageNotifier messageNotifier = null; @@ -227,7 +224,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO initializeProfileManager(); initializePeriodicTasks(); SSKEnvironment.Companion.configure(getTypingStatusRepository(), getReadReceiptManager(), getProfileManager(), messageNotifier, getExpiringMessageManager()); - initializeJobManager(); initializeWebRtc(); initializeBlobProvider(); resubmitProfilePictureIfNeeded(); @@ -284,10 +280,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO LocaleParser.Companion.configure(new LocaleParseHelper()); } - public JobManager getJobManager() { - return jobManager; - } - public ExpiringMessageManager getExpiringMessageManager() { return expiringMessageManager; } @@ -350,12 +342,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionLogger(originalHandler)); } - private void initializeJobManager() { - this.jobManager = new JobManager(this, new JobManager.Configuration.Builder() - .setConstraintObservers(JobManagerFactories.getConstraintObservers(this)) - .build()); - } - private void initializeExpiringMessageManager() { this.expiringMessageManager = new ExpiringMessageManager(this); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 891df6be87..3e21f63c09 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -42,13 +42,12 @@ import org.session.libsignal.messages.SignalServiceGroup import org.session.libsignal.utilities.IdPrefix import org.session.libsignal.utilities.KeyHelper import org.session.libsignal.utilities.guava.Optional -import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.MessageId import org.thoughtcrime.securesms.database.model.ReactionRecord import org.thoughtcrime.securesms.dependencies.DatabaseComponent import org.thoughtcrime.securesms.groups.OpenGroupManager -import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob +import org.session.libsession.messaging.jobs.RetrieveProfileAvatarJob import org.thoughtcrime.securesms.mms.PartAuthority import org.thoughtcrime.securesms.util.SessionMetaProtocol import java.security.MessageDigest diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintObserver.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintObserver.java deleted file mode 100644 index fd7f4fd43c..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ConstraintObserver.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -public interface ConstraintObserver { - - void register(@NonNull Notifier notifier); - - interface Notifier { - void onConstraintMet(@NonNull String reason); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java deleted file mode 100644 index 81e378288d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobInstantiator.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -import org.session.libsession.messaging.jobs.Job; -import org.session.libsession.messaging.utilities.Data; - -import java.util.HashMap; -import java.util.Map; - -class JobInstantiator { - - private final Map jobFactories; - - JobInstantiator(@NonNull Map jobFactories) { - this.jobFactories = new HashMap<>(jobFactories); - } - - public @NonNull Job instantiate(@NonNull String jobFactoryKey, @NonNull Data data) { - if (jobFactories.containsKey(jobFactoryKey)) { - return jobFactories.get(jobFactoryKey).create(data); - } else { - throw new IllegalStateException("Tried to instantiate a job with key '" + jobFactoryKey + "', but no matching factory was found."); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java deleted file mode 100644 index 7bbd7679f7..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/JobManager.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import android.app.Application; -import android.content.Intent; -import android.os.Build; - -import androidx.annotation.NonNull; - -import org.session.libsignal.utilities.Log; -import org.thoughtcrime.securesms.jobmanager.impl.DefaultExecutorFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutorService; - -/** - * Allows the scheduling of durable jobs that will be run as early as possible. - */ -public class JobManager implements ConstraintObserver.Notifier { - - private static final String TAG = JobManager.class.getSimpleName(); - - private final ExecutorService executor; - - private final Set emptyQueueListeners = new CopyOnWriteArraySet<>(); - - public JobManager(@NonNull Application application, @NonNull Configuration configuration) { - this.executor = configuration.getExecutorFactory().newSingleThreadExecutor("JobManager"); - - executor.execute(() -> { - for (ConstraintObserver constraintObserver : configuration.getConstraintObservers()) { - constraintObserver.register(this); - } - - if (Build.VERSION.SDK_INT < 26) { - application.startService(new Intent(application, KeepAliveService.class)); - } - - wakeUp(); - }); - } - - /** - * Adds a listener to that will be notified when the job queue has been drained. - */ - void addOnEmptyQueueListener(@NonNull EmptyQueueListener listener) { - executor.execute(() -> { - emptyQueueListeners.add(listener); - }); - } - - /** - * Removes a listener that was added via {@link #addOnEmptyQueueListener(EmptyQueueListener)}. - */ - void removeOnEmptyQueueListener(@NonNull EmptyQueueListener listener) { - executor.execute(() -> { - emptyQueueListeners.remove(listener); - }); - } - - @Override - public void onConstraintMet(@NonNull String reason) { - Log.i(TAG, "onConstraintMet(" + reason + ")"); - wakeUp(); - } - - /** - * Pokes the system to take another pass at the job queue. - */ - void wakeUp() {} - - public interface EmptyQueueListener { - void onQueueEmpty(); - } - - public static class Configuration { - - private final ExecutorFactory executorFactory; - private final List constraintObservers; - - private Configuration(@NonNull ExecutorFactory executorFactory, - @NonNull List constraintObservers) - { - this.executorFactory = executorFactory; - this.constraintObservers = constraintObservers; - } - - @NonNull ExecutorFactory getExecutorFactory() { - return executorFactory; - } - - @NonNull List getConstraintObservers() { - return constraintObservers; - } - - public static class Builder { - - private ExecutorFactory executorFactory = new DefaultExecutorFactory(); - private List constraintObservers = new ArrayList<>(); - - public @NonNull Builder setConstraintObservers(@NonNull List constraintObservers) { - this.constraintObservers = constraintObservers; - return this; - } - - public @NonNull Configuration build() { - return new Configuration(executorFactory, - new ArrayList<>(constraintObservers)); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraint.java deleted file mode 100644 index 6d6fc0499f..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraint.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.app.job.JobInfo; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Constraint; -import org.thoughtcrime.securesms.sms.TelephonyServiceState; - -public class CellServiceConstraint implements Constraint { - - public static final String KEY = "CellServiceConstraint"; - - private final Application application; - - public CellServiceConstraint(@NonNull Application application) { - this.application = application; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public boolean isMet() { - TelephonyServiceState telephonyServiceState = new TelephonyServiceState(); - return telephonyServiceState.isConnected(application); - } - - @Override - public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) { - } - - public static final class Factory implements Constraint.Factory { - - private final Application application; - - public Factory(@NonNull Application application) { - this.application = application; - } - - @Override - public CellServiceConstraint create() { - return new CellServiceConstraint(application); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraintObserver.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraintObserver.java deleted file mode 100644 index fd0971dc57..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/CellServiceConstraintObserver.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.content.Context; -import androidx.annotation.NonNull; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; - -import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; - -public class CellServiceConstraintObserver implements ConstraintObserver { - - private static final String REASON = CellServiceConstraintObserver.class.getSimpleName(); - - private Notifier notifier; - - public CellServiceConstraintObserver(@NonNull Application application) { - TelephonyManager telephonyManager = (TelephonyManager) application.getSystemService(Context.TELEPHONY_SERVICE); - ServiceStateListener serviceStateListener = new ServiceStateListener(); - - telephonyManager.listen(serviceStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); - } - - @Override - public void register(@NonNull Notifier notifier) { - this.notifier = notifier; - } - - private class ServiceStateListener extends PhoneStateListener { - @Override - public void onServiceStateChanged(ServiceState serviceState) { - if (serviceState.getState() == ServiceState.STATE_IN_SERVICE && notifier != null) { - notifier.onConstraintMet(REASON); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraintObserver.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraintObserver.java deleted file mode 100644 index ef4a61c7c5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkConstraintObserver.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; - -public class NetworkConstraintObserver implements ConstraintObserver { - - private static final String REASON = NetworkConstraintObserver.class.getSimpleName(); - - private final Application application; - - public NetworkConstraintObserver(Application application) { - this.application = application; - } - - @Override - public void register(@NonNull Notifier notifier) { - application.registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - NetworkConstraint constraint = new NetworkConstraint.Factory(application).create(); - - if (constraint.isMet()) { - notifier.onConstraintMet(REASON); - } - } - }, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkOrCellServiceConstraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkOrCellServiceConstraint.java deleted file mode 100644 index c17931f977..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/NetworkOrCellServiceConstraint.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.app.job.JobInfo; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Constraint; - -public class NetworkOrCellServiceConstraint implements Constraint { - - public static final String KEY = "NetworkOrCellServiceConstraint"; - - private final NetworkConstraint networkConstraint; - private final CellServiceConstraint serviceConstraint; - - public NetworkOrCellServiceConstraint(@NonNull Application application) { - networkConstraint = new NetworkConstraint.Factory(application).create(); - serviceConstraint = new CellServiceConstraint.Factory(application).create(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public boolean isMet() { - return networkConstraint.isMet() || serviceConstraint.isMet(); - } - - @Override - public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) { - } - - public static class Factory implements Constraint.Factory { - - private final Application application; - - public Factory(@NonNull Application application) { - this.application = application; - } - - @Override - public NetworkOrCellServiceConstraint create() { - return new NetworkOrCellServiceConstraint(application); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraint.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraint.java deleted file mode 100644 index 32fa84b6f5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraint.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import android.app.Application; -import android.app.job.JobInfo; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Constraint; -import org.session.libsession.utilities.TextSecurePreferences; - -public class SqlCipherMigrationConstraint implements Constraint { - - public static final String KEY = "SqlCipherMigrationConstraint"; - - private final Application application; - - private SqlCipherMigrationConstraint(@NonNull Application application) { - this.application = application; - } - - @Override - public boolean isMet() { - return !TextSecurePreferences.getNeedsSqlCipherMigration(application); - } - - @NonNull - @Override - public String getFactoryKey() { - return KEY; - } - - @Override - public void applyToJobInfo(@NonNull JobInfo.Builder jobInfoBuilder) { - } - - public static final class Factory implements Constraint.Factory { - - private final Application application; - - public Factory(@NonNull Application application) { - this.application = application; - } - - @Override - public SqlCipherMigrationConstraint create() { - return new SqlCipherMigrationConstraint(application); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraintObserver.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraintObserver.java deleted file mode 100644 index 0c9225434d..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/SqlCipherMigrationConstraintObserver.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import androidx.annotation.NonNull; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; -import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; - -public class SqlCipherMigrationConstraintObserver implements ConstraintObserver { - - private static final String REASON = SqlCipherMigrationConstraintObserver.class.getSimpleName(); - - private Notifier notifier; - - public SqlCipherMigrationConstraintObserver() { - EventBus.getDefault().register(this); - } - - @Override - public void register(@NonNull Notifier notifier) { - this.notifier = notifier; - } - - @Subscribe(threadMode = ThreadMode.MAIN) - public void onEvent(SqlCipherNeedsMigrationEvent event) { - if (notifier != null) notifier.onConstraintMet(REASON); - } - - public static class SqlCipherNeedsMigrationEvent { - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java deleted file mode 100644 index d892c0f439..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.app.Application; - -import androidx.annotation.NonNull; - -import org.session.libsession.messaging.jobs.Job; -import org.thoughtcrime.securesms.jobmanager.Constraint; -import org.thoughtcrime.securesms.jobmanager.ConstraintObserver; -import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraint; -import org.thoughtcrime.securesms.jobmanager.impl.CellServiceConstraintObserver; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint; -import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint; -import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public final class JobManagerFactories { - - private static Collection factoryKeys = new ArrayList<>(); - - public static Map getJobFactories() { - HashMap factoryHashMap = new HashMap() {{ - put(LocalBackupJob.Companion.getKEY(), new LocalBackupJob.Factory()); - put(RetrieveProfileAvatarJob.Companion.getKEY(), new RetrieveProfileAvatarJob.Factory()); - put(UpdateApkJob.Companion.getKEY(), new UpdateApkJob.Factory()); - }}; - factoryKeys.addAll(factoryHashMap.keySet()); - return factoryHashMap; - } - - public static Map getConstraintFactories(@NonNull Application application) { - return new HashMap() {{ - put(CellServiceConstraint.KEY, new CellServiceConstraint.Factory(application)); - put(NetworkConstraint.KEY, new NetworkConstraint.Factory(application)); - put(NetworkOrCellServiceConstraint.KEY, new NetworkOrCellServiceConstraint.Factory(application)); - put(SqlCipherMigrationConstraint.KEY, new SqlCipherMigrationConstraint.Factory(application)); - }}; - } - - public static List getConstraintObservers(@NonNull Application application) { - return Arrays.asList(new CellServiceConstraintObserver(application), - new NetworkConstraintObserver(application), - new SqlCipherMigrationConstraintObserver()); - } - - public static boolean hasFactoryForKey(String factoryKey) { - return factoryKeys.contains(factoryKey); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index 3b6db9a76f..08ca6090bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -5,9 +5,8 @@ import org.session.libsession.messaging.contacts.Contact import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.utilities.SSKEnvironment import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.dependencies.DatabaseComponent -import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob +import org.session.libsession.messaging.jobs.RetrieveProfileAvatarJob class ProfileManager : SSKEnvironment.ProfileManagerProtocol { diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index d75e209d11..8ae9442748 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -38,6 +38,7 @@ interface StorageProtocol { fun getUserX25519KeyPair(): ECKeyPair fun getUserProfile(): Profile fun setUserProfilePictureURL(newProfilePicture: String) + fun // Signal fun getOrGenerateRegistrationID(): Int diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt similarity index 90% rename from app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt rename to libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index a5b0fce2df..f00ba49a5f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -1,10 +1,9 @@ -package org.thoughtcrime.securesms.jobs +package org.session.libsession.messaging.jobs import android.content.Context import android.text.TextUtils import org.session.libsession.avatars.AvatarHelper -import org.session.libsession.messaging.jobs.Job -import org.session.libsession.messaging.jobs.JobDelegate +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.utilities.Data import org.session.libsession.utilities.DownloadUtilities.downloadFile import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfileAvatarId @@ -27,8 +26,6 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: override var failureCount: Int = 0 override val maxFailureCount: Int = 0 - lateinit var context: Context - companion object { val TAG = RetrieveProfileAvatarJob::class.simpleName val KEY: String = "RetrieveProfileAvatarJob" @@ -39,8 +36,9 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: } override fun execute(dispatcherName: String) { + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val recipient = Recipient.from(context, recipientAddress, true) - val database = get(context).recipientDatabase() val profileKey = recipient.resolve().profileKey if (profileKey == null || (profileKey.size != 32 && profileKey.size != 16)) { @@ -56,7 +54,7 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: if (TextUtils.isEmpty(profileAvatar)) { Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize()) AvatarHelper.delete(context, recipient.address) - database.setProfileAvatar(recipient, profileAvatar) + storage.setProfileAvatar(recipient, profileAvatar) return } @@ -75,7 +73,7 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: if (recipient.isLocalNumber) { setProfileAvatarId(context, SecureRandom().nextInt()) } - database.setProfileAvatar(recipient, profileAvatar) + storage.setProfileAvatar(recipient, profileAvatar) } override fun serialize(): Data { From fa71ea1850e0d3444eac4176df2ac82002b53f96 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Tue, 9 May 2023 14:14:49 +1000 Subject: [PATCH 09/19] make RetrieveProfileAvatarJob work --- .../main/java/org/thoughtcrime/securesms/database/Storage.kt | 5 +++++ .../thoughtcrime/securesms/sskenvironment/ProfileManager.kt | 1 - .../java/org/session/libsession/database/StorageProtocol.kt | 2 +- .../java/org/session/libsession/messaging/jobs/JobQueue.kt | 2 ++ .../libsession/messaging/jobs/RetrieveProfileAvatarJob.kt | 2 -- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 3e21f63c09..54d36af896 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -77,6 +77,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, JobQueue.shared.add(RetrieveProfileAvatarJob(newValue, ourRecipient.address)) } + override fun setProfileAvatar(recipient: Recipient, profileAvatar: String) { + val database = DatabaseComponent.get(context).recipientDatabase() + database.setProfileAvatar(recipient, profileAvatar) + } + override fun getOrGenerateRegistrationID(): Int { var registrationID = TextSecurePreferences.getLocalRegistrationId(context) if (registrationID == 0) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt index 08ca6090bf..f9f5524efa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/sskenvironment/ProfileManager.kt @@ -41,7 +41,6 @@ class ProfileManager : SSKEnvironment.ProfileManagerProtocol { override fun setProfilePictureURL(context: Context, recipient: Recipient, profilePictureURL: String) { val job = RetrieveProfileAvatarJob(profilePictureURL, recipient.address) - job.context = context JobQueue.shared.add(job) val sessionID = recipient.address.serialize() val contactDatabase = DatabaseComponent.get(context).sessionContactDatabase() diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index 8ae9442748..0727d1ab56 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -38,7 +38,7 @@ interface StorageProtocol { fun getUserX25519KeyPair(): ECKeyPair fun getUserProfile(): Profile fun setUserProfilePictureURL(newProfilePicture: String) - fun + fun setProfileAvatar(recipient: Recipient, profileAvatar: String) // Signal fun getOrGenerateRegistrationID(): Int diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt index b78590c729..03b9546c4c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt @@ -125,6 +125,7 @@ class JobQueue : JobDelegate { is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> { txQueue.send(job) } + is RetrieveProfileAvatarJob, is AttachmentDownloadJob -> { mediaQueue.send(job) } @@ -224,6 +225,7 @@ class JobQueue : JobDelegate { GroupAvatarDownloadJob.KEY, BackgroundGroupAddJob.KEY, OpenGroupDeleteJob.KEY, + RetrieveProfileAvatarJob.KEY, ) allJobTypes.forEach { type -> resumePendingJobs(type) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index f00ba49a5f..8ce397a3a9 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -1,6 +1,5 @@ package org.session.libsession.messaging.jobs -import android.content.Context import android.text.TextUtils import org.session.libsession.avatars.AvatarHelper import org.session.libsession.messaging.MessagingModuleConfiguration @@ -13,7 +12,6 @@ import org.session.libsession.utilities.Address import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.streams.ProfileCipherInputStream import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get import java.io.File import java.io.FileInputStream import java.io.FileOutputStream From 89545f0406176069402f5014e33a4a87de0b76a0 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 10 May 2023 15:36:10 +1000 Subject: [PATCH 10/19] further clean up --- app/src/main/AndroidManifest.xml | 6 - .../securesms/ApplicationContext.java | 7 - .../securesms/backup/BackupEvent.kt | 14 - .../securesms/backup/BackupPassphrase.java | 47 - .../securesms/backup/BackupPreferences.kt | 101 - .../securesms/backup/BackupProtos.java | 6778 ----------------- .../securesms/backup/FullBackupExporter.kt | 447 -- .../securesms/backup/FullBackupImporter.kt | 352 - .../securesms/database/JobDatabase.java | 178 - .../dependencies/DatabaseComponent.kt | 1 - .../securesms/dependencies/DatabaseModule.kt | 4 - .../securesms/jobmanager/ExecutorFactory.java | 9 - .../impl/DefaultExecutorFactory.java | 15 - .../persistence/ConstraintSpec.java | 43 - .../persistence/DependencySpec.java | 43 - .../jobmanager/persistence/FullSpec.java | 50 - .../jobmanager/persistence/JobSpec.java | 129 - .../jobmanager/persistence/JobStorage.java | 55 - .../securesms/jobs/LocalBackupJob.kt | 61 - .../securesms/jobs/UpdateApkJob.kt | 200 - .../service/LocalBackupListener.java | 41 - .../service/UpdateApkRefreshListener.java | 49 - .../thoughtcrime/securesms/util/BackupUtil.kt | 313 - 23 files changed, 8943 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/BackupEvent.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/BackupPreferences.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/BackupProtos.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/ExecutorFactory.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/DefaultExecutorFactory.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/ConstraintSpec.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/DependencySpec.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/FullSpec.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobSpec.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobStorage.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index da3be785c3..2d2b2123dd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -407,12 +407,6 @@ - - - - - diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index df1bed7b3b..5a9999a7bc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -55,7 +55,6 @@ import org.signal.aesgcmprovider.AesGcmProvider; import org.thoughtcrime.securesms.components.TypingStatusSender; import org.thoughtcrime.securesms.crypto.KeyPairUtilities; import org.thoughtcrime.securesms.database.EmojiSearchDatabase; -import org.thoughtcrime.securesms.database.JobDatabase; import org.thoughtcrime.securesms.database.LokiAPIDatabase; import org.thoughtcrime.securesms.database.Storage; import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; @@ -78,7 +77,6 @@ import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.service.KeyCachingService; -import org.thoughtcrime.securesms.service.UpdateApkRefreshListener; import org.thoughtcrime.securesms.sskenvironment.ProfileManager; import org.thoughtcrime.securesms.sskenvironment.ReadReceiptManager; import org.thoughtcrime.securesms.sskenvironment.TypingStatusRepository; @@ -142,7 +140,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO @Inject LokiAPIDatabase lokiAPIDatabase; @Inject Storage storage; @Inject MessageDataProvider messageDataProvider; - @Inject JobDatabase jobDatabase; @Inject TextSecurePreferences textSecurePreferences; CallMessageProcessor callMessageProcessor; MessagingModuleConfiguration messagingModuleConfiguration; @@ -364,10 +361,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO private void initializePeriodicTasks() { BackgroundPollWorker.schedulePeriodic(this); - - if (BuildConfig.PLAY_STORE_DISABLED) { - UpdateApkRefreshListener.schedule(this); - } } private void initializeWebRtc() { diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupEvent.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupEvent.kt deleted file mode 100644 index 614dc30bba..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupEvent.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.thoughtcrime.securesms.backup - -data class BackupEvent constructor(val type: Type, val count: Int, val exception: Exception?) { - - enum class Type { - PROGRESS, FINISHED - } - - companion object { - @JvmStatic fun createProgress(count: Int) = BackupEvent(Type.PROGRESS, count, null) - @JvmStatic fun createFinished() = BackupEvent(Type.FINISHED, 0, null) - @JvmStatic fun createFinished(e: Exception?) = BackupEvent(Type.FINISHED, 0, e) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java deleted file mode 100644 index eec2a2e588..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPassphrase.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.thoughtcrime.securesms.backup; - -import android.content.Context; -import android.os.Build; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.thoughtcrime.securesms.crypto.KeyStoreHelper; -import org.session.libsignal.utilities.Log; -import org.session.libsession.utilities.TextSecurePreferences; - -/** - * Allows the getting and setting of the backup passphrase, which is stored encrypted on API >= 23. - */ -public class BackupPassphrase { - - private static final String TAG = BackupPassphrase.class.getSimpleName(); - - public static @Nullable String get(@NonNull Context context) { - String passphrase = TextSecurePreferences.getBackupPassphrase(context); - String encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context); - - if (Build.VERSION.SDK_INT < 23 || (passphrase == null && encryptedPassphrase == null)) { - return passphrase; - } - - if (encryptedPassphrase == null) { - Log.i(TAG, "Migrating to encrypted passphrase."); - set(context, passphrase); - encryptedPassphrase = TextSecurePreferences.getEncryptedBackupPassphrase(context); - } - - KeyStoreHelper.SealedData data = KeyStoreHelper.SealedData.fromString(encryptedPassphrase); - return new String(KeyStoreHelper.unseal(data)); - } - - public static void set(@NonNull Context context, @Nullable String passphrase) { - if (passphrase == null || Build.VERSION.SDK_INT < 23) { - TextSecurePreferences.setBackupPassphrase(context, passphrase); - TextSecurePreferences.setEncryptedBackupPassphrase(context, null); - } else { - KeyStoreHelper.SealedData encryptedPassphrase = KeyStoreHelper.seal(passphrase.getBytes()); - TextSecurePreferences.setEncryptedBackupPassphrase(context, encryptedPassphrase.serialize()); - TextSecurePreferences.setBackupPassphrase(context, null); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPreferences.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPreferences.kt deleted file mode 100644 index 8ddfc23a8b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupPreferences.kt +++ /dev/null @@ -1,101 +0,0 @@ -package org.thoughtcrime.securesms.backup - -import android.content.Context -import android.content.SharedPreferences -import android.os.Build -import android.preference.PreferenceManager -import android.preference.PreferenceManager.getDefaultSharedPreferencesName -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.backup.FullBackupImporter.PREF_PREFIX_TYPE_BOOLEAN -import org.thoughtcrime.securesms.backup.FullBackupImporter.PREF_PREFIX_TYPE_INT -import java.util.* - -object BackupPreferences { - // region Backup related - fun getBackupRecords(context: Context): List { - val preferences = PreferenceManager.getDefaultSharedPreferences(context) - val prefsFileName: String - prefsFileName = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - getDefaultSharedPreferencesName(context) - } else { - context.packageName + "_preferences" - } - val prefList: LinkedList = LinkedList() - addBackupEntryInt(prefList, preferences, prefsFileName, TextSecurePreferences.LOCAL_REGISTRATION_ID_PREF) - addBackupEntryString(prefList, preferences, prefsFileName, TextSecurePreferences.LOCAL_NUMBER_PREF) - addBackupEntryString(prefList, preferences, prefsFileName, TextSecurePreferences.PROFILE_NAME_PREF) - addBackupEntryString(prefList, preferences, prefsFileName, TextSecurePreferences.PROFILE_AVATAR_URL_PREF) - addBackupEntryInt(prefList, preferences, prefsFileName, TextSecurePreferences.PROFILE_AVATAR_ID_PREF) - addBackupEntryString(prefList, preferences, prefsFileName, TextSecurePreferences.PROFILE_KEY_PREF) - addBackupEntryBoolean(prefList, preferences, prefsFileName, TextSecurePreferences.IS_USING_FCM) - return prefList - } - - private fun addBackupEntryString( - outPrefList: MutableList, - prefs: SharedPreferences, - prefFileName: String, - prefKey: String, - ) { - val value = prefs.getString(prefKey, null) - if (value == null) { - logBackupEntry(prefKey, false) - return - } - outPrefList.add(BackupProtos.SharedPreference.newBuilder() - .setFile(prefFileName) - .setKey(prefKey) - .setValue(value) - .build()) - logBackupEntry(prefKey, true) - } - - private fun addBackupEntryInt( - outPrefList: MutableList, - prefs: SharedPreferences, - prefFileName: String, - prefKey: String, - ) { - val value = prefs.getInt(prefKey, -1) - if (value == -1) { - logBackupEntry(prefKey, false) - return - } - outPrefList.add(BackupProtos.SharedPreference.newBuilder() - .setFile(prefFileName) - .setKey(PREF_PREFIX_TYPE_INT + prefKey) // The prefix denotes the type of the preference. - .setValue(value.toString()) - .build()) - logBackupEntry(prefKey, true) - } - - private fun addBackupEntryBoolean( - outPrefList: MutableList, - prefs: SharedPreferences, - prefFileName: String, - prefKey: String, - ) { - if (!prefs.contains(prefKey)) { - logBackupEntry(prefKey, false) - return - } - outPrefList.add(BackupProtos.SharedPreference.newBuilder() - .setFile(prefFileName) - .setKey(PREF_PREFIX_TYPE_BOOLEAN + prefKey) // The prefix denotes the type of the preference. - .setValue(prefs.getBoolean(prefKey, false).toString()) - .build()) - logBackupEntry(prefKey, true) - } - - private fun logBackupEntry(prefName: String, wasIncluded: Boolean) { - val sb = StringBuilder() - sb.append("Backup preference ") - sb.append(if (wasIncluded) "+ " else "- ") - sb.append('\"').append(prefName).append("\" ") - if (!wasIncluded) { - sb.append("(is empty and not included)") - } - Log.d("Loki", sb.toString()) - } // endregion -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupProtos.java b/app/src/main/java/org/thoughtcrime/securesms/backup/BackupProtos.java deleted file mode 100644 index f3b78606f4..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/BackupProtos.java +++ /dev/null @@ -1,6778 +0,0 @@ -// Generated by the protocol buffer compiler. DO NOT EDIT! -// source: Backups.proto - -package org.thoughtcrime.securesms.backup; - -public final class BackupProtos { - private BackupProtos() {} - public static void registerAllExtensions( - com.google.protobuf.ExtensionRegistry registry) { - } - public interface SqlStatementOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string statement = 1; - /** - * optional string statement = 1; - */ - boolean hasStatement(); - /** - * optional string statement = 1; - */ - java.lang.String getStatement(); - /** - * optional string statement = 1; - */ - com.google.protobuf.ByteString - getStatementBytes(); - - // repeated .signal.SqlStatement.SqlParameter parameters = 2; - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - java.util.List - getParametersList(); - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter getParameters(int index); - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - int getParametersCount(); - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - java.util.List - getParametersOrBuilderList(); - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder getParametersOrBuilder( - int index); - } - /** - * Protobuf type {@code signal.SqlStatement} - */ - public static final class SqlStatement extends - com.google.protobuf.GeneratedMessage - implements SqlStatementOrBuilder { - // Use SqlStatement.newBuilder() to construct. - private SqlStatement(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private SqlStatement(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final SqlStatement defaultInstance; - public static SqlStatement getDefaultInstance() { - return defaultInstance; - } - - public SqlStatement getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private SqlStatement( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - statement_ = input.readBytes(); - break; - } - case 18: { - if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { - parameters_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000002; - } - parameters_.add(input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.PARSER, extensionRegistry)); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { - parameters_ = java.util.Collections.unmodifiableList(parameters_); - } - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.class, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public SqlStatement parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new SqlStatement(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public interface SqlParameterOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string stringParamter = 1; - /** - * optional string stringParamter = 1; - */ - boolean hasStringParamter(); - /** - * optional string stringParamter = 1; - */ - java.lang.String getStringParamter(); - /** - * optional string stringParamter = 1; - */ - com.google.protobuf.ByteString - getStringParamterBytes(); - - // optional uint64 integerParameter = 2; - /** - * optional uint64 integerParameter = 2; - */ - boolean hasIntegerParameter(); - /** - * optional uint64 integerParameter = 2; - */ - long getIntegerParameter(); - - // optional double doubleParameter = 3; - /** - * optional double doubleParameter = 3; - */ - boolean hasDoubleParameter(); - /** - * optional double doubleParameter = 3; - */ - double getDoubleParameter(); - - // optional bytes blobParameter = 4; - /** - * optional bytes blobParameter = 4; - */ - boolean hasBlobParameter(); - /** - * optional bytes blobParameter = 4; - */ - com.google.protobuf.ByteString getBlobParameter(); - - // optional bool nullparameter = 5; - /** - * optional bool nullparameter = 5; - */ - boolean hasNullparameter(); - /** - * optional bool nullparameter = 5; - */ - boolean getNullparameter(); - } - /** - * Protobuf type {@code signal.SqlStatement.SqlParameter} - */ - public static final class SqlParameter extends - com.google.protobuf.GeneratedMessage - implements SqlParameterOrBuilder { - // Use SqlParameter.newBuilder() to construct. - private SqlParameter(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private SqlParameter(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final SqlParameter defaultInstance; - public static SqlParameter getDefaultInstance() { - return defaultInstance; - } - - public SqlParameter getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private SqlParameter( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - stringParamter_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - integerParameter_ = input.readUInt64(); - break; - } - case 25: { - bitField0_ |= 0x00000004; - doubleParameter_ = input.readDouble(); - break; - } - case 34: { - bitField0_ |= 0x00000008; - blobParameter_ = input.readBytes(); - break; - } - case 40: { - bitField0_ |= 0x00000010; - nullparameter_ = input.readBool(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_SqlParameter_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_SqlParameter_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.class, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public SqlParameter parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new SqlParameter(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional string stringParamter = 1; - public static final int STRINGPARAMTER_FIELD_NUMBER = 1; - private java.lang.Object stringParamter_; - /** - * optional string stringParamter = 1; - */ - public boolean hasStringParamter() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string stringParamter = 1; - */ - public java.lang.String getStringParamter() { - java.lang.Object ref = stringParamter_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - stringParamter_ = s; - } - return s; - } - } - /** - * optional string stringParamter = 1; - */ - public com.google.protobuf.ByteString - getStringParamterBytes() { - java.lang.Object ref = stringParamter_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - stringParamter_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional uint64 integerParameter = 2; - public static final int INTEGERPARAMETER_FIELD_NUMBER = 2; - private long integerParameter_; - /** - * optional uint64 integerParameter = 2; - */ - public boolean hasIntegerParameter() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint64 integerParameter = 2; - */ - public long getIntegerParameter() { - return integerParameter_; - } - - // optional double doubleParameter = 3; - public static final int DOUBLEPARAMETER_FIELD_NUMBER = 3; - private double doubleParameter_; - /** - * optional double doubleParameter = 3; - */ - public boolean hasDoubleParameter() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional double doubleParameter = 3; - */ - public double getDoubleParameter() { - return doubleParameter_; - } - - // optional bytes blobParameter = 4; - public static final int BLOBPARAMETER_FIELD_NUMBER = 4; - private com.google.protobuf.ByteString blobParameter_; - /** - * optional bytes blobParameter = 4; - */ - public boolean hasBlobParameter() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional bytes blobParameter = 4; - */ - public com.google.protobuf.ByteString getBlobParameter() { - return blobParameter_; - } - - // optional bool nullparameter = 5; - public static final int NULLPARAMETER_FIELD_NUMBER = 5; - private boolean nullparameter_; - /** - * optional bool nullparameter = 5; - */ - public boolean hasNullparameter() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional bool nullparameter = 5; - */ - public boolean getNullparameter() { - return nullparameter_; - } - - private void initFields() { - stringParamter_ = ""; - integerParameter_ = 0L; - doubleParameter_ = 0D; - blobParameter_ = com.google.protobuf.ByteString.EMPTY; - nullparameter_ = false; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getStringParamterBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt64(2, integerParameter_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeDouble(3, doubleParameter_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - output.writeBytes(4, blobParameter_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - output.writeBool(5, nullparameter_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getStringParamterBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(2, integerParameter_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeDoubleSize(3, doubleParameter_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(4, blobParameter_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(5, nullparameter_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.SqlStatement.SqlParameter} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_SqlParameter_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_SqlParameter_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.class, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - stringParamter_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - integerParameter_ = 0L; - bitField0_ = (bitField0_ & ~0x00000002); - doubleParameter_ = 0D; - bitField0_ = (bitField0_ & ~0x00000004); - blobParameter_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000008); - nullparameter_ = false; - bitField0_ = (bitField0_ & ~0x00000010); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_SqlParameter_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter build() { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter result = new org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.stringParamter_ = stringParamter_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.integerParameter_ = integerParameter_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - result.doubleParameter_ = doubleParameter_; - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { - to_bitField0_ |= 0x00000008; - } - result.blobParameter_ = blobParameter_; - if (((from_bitField0_ & 0x00000010) == 0x00000010)) { - to_bitField0_ |= 0x00000010; - } - result.nullparameter_ = nullparameter_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.getDefaultInstance()) return this; - if (other.hasStringParamter()) { - bitField0_ |= 0x00000001; - stringParamter_ = other.stringParamter_; - onChanged(); - } - if (other.hasIntegerParameter()) { - setIntegerParameter(other.getIntegerParameter()); - } - if (other.hasDoubleParameter()) { - setDoubleParameter(other.getDoubleParameter()); - } - if (other.hasBlobParameter()) { - setBlobParameter(other.getBlobParameter()); - } - if (other.hasNullparameter()) { - setNullparameter(other.getNullparameter()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string stringParamter = 1; - private java.lang.Object stringParamter_ = ""; - /** - * optional string stringParamter = 1; - */ - public boolean hasStringParamter() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string stringParamter = 1; - */ - public java.lang.String getStringParamter() { - java.lang.Object ref = stringParamter_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - stringParamter_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string stringParamter = 1; - */ - public com.google.protobuf.ByteString - getStringParamterBytes() { - java.lang.Object ref = stringParamter_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - stringParamter_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string stringParamter = 1; - */ - public Builder setStringParamter( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - stringParamter_ = value; - onChanged(); - return this; - } - /** - * optional string stringParamter = 1; - */ - public Builder clearStringParamter() { - bitField0_ = (bitField0_ & ~0x00000001); - stringParamter_ = getDefaultInstance().getStringParamter(); - onChanged(); - return this; - } - /** - * optional string stringParamter = 1; - */ - public Builder setStringParamterBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - stringParamter_ = value; - onChanged(); - return this; - } - - // optional uint64 integerParameter = 2; - private long integerParameter_ ; - /** - * optional uint64 integerParameter = 2; - */ - public boolean hasIntegerParameter() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint64 integerParameter = 2; - */ - public long getIntegerParameter() { - return integerParameter_; - } - /** - * optional uint64 integerParameter = 2; - */ - public Builder setIntegerParameter(long value) { - bitField0_ |= 0x00000002; - integerParameter_ = value; - onChanged(); - return this; - } - /** - * optional uint64 integerParameter = 2; - */ - public Builder clearIntegerParameter() { - bitField0_ = (bitField0_ & ~0x00000002); - integerParameter_ = 0L; - onChanged(); - return this; - } - - // optional double doubleParameter = 3; - private double doubleParameter_ ; - /** - * optional double doubleParameter = 3; - */ - public boolean hasDoubleParameter() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional double doubleParameter = 3; - */ - public double getDoubleParameter() { - return doubleParameter_; - } - /** - * optional double doubleParameter = 3; - */ - public Builder setDoubleParameter(double value) { - bitField0_ |= 0x00000004; - doubleParameter_ = value; - onChanged(); - return this; - } - /** - * optional double doubleParameter = 3; - */ - public Builder clearDoubleParameter() { - bitField0_ = (bitField0_ & ~0x00000004); - doubleParameter_ = 0D; - onChanged(); - return this; - } - - // optional bytes blobParameter = 4; - private com.google.protobuf.ByteString blobParameter_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes blobParameter = 4; - */ - public boolean hasBlobParameter() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional bytes blobParameter = 4; - */ - public com.google.protobuf.ByteString getBlobParameter() { - return blobParameter_; - } - /** - * optional bytes blobParameter = 4; - */ - public Builder setBlobParameter(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000008; - blobParameter_ = value; - onChanged(); - return this; - } - /** - * optional bytes blobParameter = 4; - */ - public Builder clearBlobParameter() { - bitField0_ = (bitField0_ & ~0x00000008); - blobParameter_ = getDefaultInstance().getBlobParameter(); - onChanged(); - return this; - } - - // optional bool nullparameter = 5; - private boolean nullparameter_ ; - /** - * optional bool nullparameter = 5; - */ - public boolean hasNullparameter() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional bool nullparameter = 5; - */ - public boolean getNullparameter() { - return nullparameter_; - } - /** - * optional bool nullparameter = 5; - */ - public Builder setNullparameter(boolean value) { - bitField0_ |= 0x00000010; - nullparameter_ = value; - onChanged(); - return this; - } - /** - * optional bool nullparameter = 5; - */ - public Builder clearNullparameter() { - bitField0_ = (bitField0_ & ~0x00000010); - nullparameter_ = false; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.SqlStatement.SqlParameter) - } - - static { - defaultInstance = new SqlParameter(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.SqlStatement.SqlParameter) - } - - private int bitField0_; - // optional string statement = 1; - public static final int STATEMENT_FIELD_NUMBER = 1; - private java.lang.Object statement_; - /** - * optional string statement = 1; - */ - public boolean hasStatement() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string statement = 1; - */ - public java.lang.String getStatement() { - java.lang.Object ref = statement_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - statement_ = s; - } - return s; - } - } - /** - * optional string statement = 1; - */ - public com.google.protobuf.ByteString - getStatementBytes() { - java.lang.Object ref = statement_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - statement_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // repeated .signal.SqlStatement.SqlParameter parameters = 2; - public static final int PARAMETERS_FIELD_NUMBER = 2; - private java.util.List parameters_; - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public java.util.List getParametersList() { - return parameters_; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public java.util.List - getParametersOrBuilderList() { - return parameters_; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public int getParametersCount() { - return parameters_.size(); - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter getParameters(int index) { - return parameters_.get(index); - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder getParametersOrBuilder( - int index) { - return parameters_.get(index); - } - - private void initFields() { - statement_ = ""; - parameters_ = java.util.Collections.emptyList(); - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getStatementBytes()); - } - for (int i = 0; i < parameters_.size(); i++) { - output.writeMessage(2, parameters_.get(i)); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getStatementBytes()); - } - for (int i = 0; i < parameters_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, parameters_.get(i)); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.SqlStatement} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.class, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - getParametersFieldBuilder(); - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - statement_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - if (parametersBuilder_ == null) { - parameters_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - } else { - parametersBuilder_.clear(); - } - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SqlStatement_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement build() { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement result = new org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.statement_ = statement_; - if (parametersBuilder_ == null) { - if (((bitField0_ & 0x00000002) == 0x00000002)) { - parameters_ = java.util.Collections.unmodifiableList(parameters_); - bitField0_ = (bitField0_ & ~0x00000002); - } - result.parameters_ = parameters_; - } else { - result.parameters_ = parametersBuilder_.build(); - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance()) return this; - if (other.hasStatement()) { - bitField0_ |= 0x00000001; - statement_ = other.statement_; - onChanged(); - } - if (parametersBuilder_ == null) { - if (!other.parameters_.isEmpty()) { - if (parameters_.isEmpty()) { - parameters_ = other.parameters_; - bitField0_ = (bitField0_ & ~0x00000002); - } else { - ensureParametersIsMutable(); - parameters_.addAll(other.parameters_); - } - onChanged(); - } - } else { - if (!other.parameters_.isEmpty()) { - if (parametersBuilder_.isEmpty()) { - parametersBuilder_.dispose(); - parametersBuilder_ = null; - parameters_ = other.parameters_; - bitField0_ = (bitField0_ & ~0x00000002); - parametersBuilder_ = - com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? - getParametersFieldBuilder() : null; - } else { - parametersBuilder_.addAllMessages(other.parameters_); - } - } - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string statement = 1; - private java.lang.Object statement_ = ""; - /** - * optional string statement = 1; - */ - public boolean hasStatement() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string statement = 1; - */ - public java.lang.String getStatement() { - java.lang.Object ref = statement_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - statement_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string statement = 1; - */ - public com.google.protobuf.ByteString - getStatementBytes() { - java.lang.Object ref = statement_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - statement_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string statement = 1; - */ - public Builder setStatement( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - statement_ = value; - onChanged(); - return this; - } - /** - * optional string statement = 1; - */ - public Builder clearStatement() { - bitField0_ = (bitField0_ & ~0x00000001); - statement_ = getDefaultInstance().getStatement(); - onChanged(); - return this; - } - /** - * optional string statement = 1; - */ - public Builder setStatementBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - statement_ = value; - onChanged(); - return this; - } - - // repeated .signal.SqlStatement.SqlParameter parameters = 2; - private java.util.List parameters_ = - java.util.Collections.emptyList(); - private void ensureParametersIsMutable() { - if (!((bitField0_ & 0x00000002) == 0x00000002)) { - parameters_ = new java.util.ArrayList(parameters_); - bitField0_ |= 0x00000002; - } - } - - private com.google.protobuf.RepeatedFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder> parametersBuilder_; - - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public java.util.List getParametersList() { - if (parametersBuilder_ == null) { - return java.util.Collections.unmodifiableList(parameters_); - } else { - return parametersBuilder_.getMessageList(); - } - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public int getParametersCount() { - if (parametersBuilder_ == null) { - return parameters_.size(); - } else { - return parametersBuilder_.getCount(); - } - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter getParameters(int index) { - if (parametersBuilder_ == null) { - return parameters_.get(index); - } else { - return parametersBuilder_.getMessage(index); - } - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder setParameters( - int index, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter value) { - if (parametersBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureParametersIsMutable(); - parameters_.set(index, value); - onChanged(); - } else { - parametersBuilder_.setMessage(index, value); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder setParameters( - int index, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder builderForValue) { - if (parametersBuilder_ == null) { - ensureParametersIsMutable(); - parameters_.set(index, builderForValue.build()); - onChanged(); - } else { - parametersBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder addParameters(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter value) { - if (parametersBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureParametersIsMutable(); - parameters_.add(value); - onChanged(); - } else { - parametersBuilder_.addMessage(value); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder addParameters( - int index, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter value) { - if (parametersBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureParametersIsMutable(); - parameters_.add(index, value); - onChanged(); - } else { - parametersBuilder_.addMessage(index, value); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder addParameters( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder builderForValue) { - if (parametersBuilder_ == null) { - ensureParametersIsMutable(); - parameters_.add(builderForValue.build()); - onChanged(); - } else { - parametersBuilder_.addMessage(builderForValue.build()); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder addParameters( - int index, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder builderForValue) { - if (parametersBuilder_ == null) { - ensureParametersIsMutable(); - parameters_.add(index, builderForValue.build()); - onChanged(); - } else { - parametersBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder addAllParameters( - java.lang.Iterable values) { - if (parametersBuilder_ == null) { - ensureParametersIsMutable(); - super.addAll(values, parameters_); - onChanged(); - } else { - parametersBuilder_.addAllMessages(values); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder clearParameters() { - if (parametersBuilder_ == null) { - parameters_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000002); - onChanged(); - } else { - parametersBuilder_.clear(); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public Builder removeParameters(int index) { - if (parametersBuilder_ == null) { - ensureParametersIsMutable(); - parameters_.remove(index); - onChanged(); - } else { - parametersBuilder_.remove(index); - } - return this; - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder getParametersBuilder( - int index) { - return getParametersFieldBuilder().getBuilder(index); - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder getParametersOrBuilder( - int index) { - if (parametersBuilder_ == null) { - return parameters_.get(index); } else { - return parametersBuilder_.getMessageOrBuilder(index); - } - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public java.util.List - getParametersOrBuilderList() { - if (parametersBuilder_ != null) { - return parametersBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(parameters_); - } - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder addParametersBuilder() { - return getParametersFieldBuilder().addBuilder( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.getDefaultInstance()); - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder addParametersBuilder( - int index) { - return getParametersFieldBuilder().addBuilder( - index, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.getDefaultInstance()); - } - /** - * repeated .signal.SqlStatement.SqlParameter parameters = 2; - */ - public java.util.List - getParametersBuilderList() { - return getParametersFieldBuilder().getBuilderList(); - } - private com.google.protobuf.RepeatedFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder> - getParametersFieldBuilder() { - if (parametersBuilder_ == null) { - parametersBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameter.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.SqlParameterOrBuilder>( - parameters_, - ((bitField0_ & 0x00000002) == 0x00000002), - getParentForChildren(), - isClean()); - parameters_ = null; - } - return parametersBuilder_; - } - - // @@protoc_insertion_point(builder_scope:signal.SqlStatement) - } - - static { - defaultInstance = new SqlStatement(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.SqlStatement) - } - - public interface SharedPreferenceOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string file = 1; - /** - * optional string file = 1; - */ - boolean hasFile(); - /** - * optional string file = 1; - */ - java.lang.String getFile(); - /** - * optional string file = 1; - */ - com.google.protobuf.ByteString - getFileBytes(); - - // optional string key = 2; - /** - * optional string key = 2; - */ - boolean hasKey(); - /** - * optional string key = 2; - */ - java.lang.String getKey(); - /** - * optional string key = 2; - */ - com.google.protobuf.ByteString - getKeyBytes(); - - // optional string value = 3; - /** - * optional string value = 3; - */ - boolean hasValue(); - /** - * optional string value = 3; - */ - java.lang.String getValue(); - /** - * optional string value = 3; - */ - com.google.protobuf.ByteString - getValueBytes(); - } - /** - * Protobuf type {@code signal.SharedPreference} - */ - public static final class SharedPreference extends - com.google.protobuf.GeneratedMessage - implements SharedPreferenceOrBuilder { - // Use SharedPreference.newBuilder() to construct. - private SharedPreference(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private SharedPreference(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final SharedPreference defaultInstance; - public static SharedPreference getDefaultInstance() { - return defaultInstance; - } - - public SharedPreference getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private SharedPreference( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - file_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - key_ = input.readBytes(); - break; - } - case 26: { - bitField0_ |= 0x00000004; - value_ = input.readBytes(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SharedPreference_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SharedPreference_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.class, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public SharedPreference parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new SharedPreference(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional string file = 1; - public static final int FILE_FIELD_NUMBER = 1; - private java.lang.Object file_; - /** - * optional string file = 1; - */ - public boolean hasFile() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string file = 1; - */ - public java.lang.String getFile() { - java.lang.Object ref = file_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - file_ = s; - } - return s; - } - } - /** - * optional string file = 1; - */ - public com.google.protobuf.ByteString - getFileBytes() { - java.lang.Object ref = file_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - file_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional string key = 2; - public static final int KEY_FIELD_NUMBER = 2; - private java.lang.Object key_; - /** - * optional string key = 2; - */ - public boolean hasKey() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string key = 2; - */ - public java.lang.String getKey() { - java.lang.Object ref = key_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - key_ = s; - } - return s; - } - } - /** - * optional string key = 2; - */ - public com.google.protobuf.ByteString - getKeyBytes() { - java.lang.Object ref = key_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - key_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional string value = 3; - public static final int VALUE_FIELD_NUMBER = 3; - private java.lang.Object value_; - /** - * optional string value = 3; - */ - public boolean hasValue() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional string value = 3; - */ - public java.lang.String getValue() { - java.lang.Object ref = value_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - value_ = s; - } - return s; - } - } - /** - * optional string value = 3; - */ - public com.google.protobuf.ByteString - getValueBytes() { - java.lang.Object ref = value_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - value_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private void initFields() { - file_ = ""; - key_ = ""; - value_ = ""; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getFileBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeBytes(2, getKeyBytes()); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeBytes(3, getValueBytes()); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getFileBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, getKeyBytes()); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(3, getValueBytes()); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.SharedPreference} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SharedPreference_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SharedPreference_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.class, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - file_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - key_ = ""; - bitField0_ = (bitField0_ & ~0x00000002); - value_ = ""; - bitField0_ = (bitField0_ & ~0x00000004); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_SharedPreference_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference build() { - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference result = new org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.file_ = file_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.key_ = key_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - result.value_ = value_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance()) return this; - if (other.hasFile()) { - bitField0_ |= 0x00000001; - file_ = other.file_; - onChanged(); - } - if (other.hasKey()) { - bitField0_ |= 0x00000002; - key_ = other.key_; - onChanged(); - } - if (other.hasValue()) { - bitField0_ |= 0x00000004; - value_ = other.value_; - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string file = 1; - private java.lang.Object file_ = ""; - /** - * optional string file = 1; - */ - public boolean hasFile() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string file = 1; - */ - public java.lang.String getFile() { - java.lang.Object ref = file_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - file_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string file = 1; - */ - public com.google.protobuf.ByteString - getFileBytes() { - java.lang.Object ref = file_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - file_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string file = 1; - */ - public Builder setFile( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - file_ = value; - onChanged(); - return this; - } - /** - * optional string file = 1; - */ - public Builder clearFile() { - bitField0_ = (bitField0_ & ~0x00000001); - file_ = getDefaultInstance().getFile(); - onChanged(); - return this; - } - /** - * optional string file = 1; - */ - public Builder setFileBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - file_ = value; - onChanged(); - return this; - } - - // optional string key = 2; - private java.lang.Object key_ = ""; - /** - * optional string key = 2; - */ - public boolean hasKey() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string key = 2; - */ - public java.lang.String getKey() { - java.lang.Object ref = key_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - key_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string key = 2; - */ - public com.google.protobuf.ByteString - getKeyBytes() { - java.lang.Object ref = key_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - key_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string key = 2; - */ - public Builder setKey( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - key_ = value; - onChanged(); - return this; - } - /** - * optional string key = 2; - */ - public Builder clearKey() { - bitField0_ = (bitField0_ & ~0x00000002); - key_ = getDefaultInstance().getKey(); - onChanged(); - return this; - } - /** - * optional string key = 2; - */ - public Builder setKeyBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - key_ = value; - onChanged(); - return this; - } - - // optional string value = 3; - private java.lang.Object value_ = ""; - /** - * optional string value = 3; - */ - public boolean hasValue() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional string value = 3; - */ - public java.lang.String getValue() { - java.lang.Object ref = value_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - value_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string value = 3; - */ - public com.google.protobuf.ByteString - getValueBytes() { - java.lang.Object ref = value_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - value_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string value = 3; - */ - public Builder setValue( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000004; - value_ = value; - onChanged(); - return this; - } - /** - * optional string value = 3; - */ - public Builder clearValue() { - bitField0_ = (bitField0_ & ~0x00000004); - value_ = getDefaultInstance().getValue(); - onChanged(); - return this; - } - /** - * optional string value = 3; - */ - public Builder setValueBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000004; - value_ = value; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.SharedPreference) - } - - static { - defaultInstance = new SharedPreference(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.SharedPreference) - } - - public interface AttachmentOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional uint64 rowId = 1; - /** - * optional uint64 rowId = 1; - */ - boolean hasRowId(); - /** - * optional uint64 rowId = 1; - */ - long getRowId(); - - // optional uint64 attachmentId = 2; - /** - * optional uint64 attachmentId = 2; - */ - boolean hasAttachmentId(); - /** - * optional uint64 attachmentId = 2; - */ - long getAttachmentId(); - - // optional uint32 length = 3; - /** - * optional uint32 length = 3; - */ - boolean hasLength(); - /** - * optional uint32 length = 3; - */ - int getLength(); - } - /** - * Protobuf type {@code signal.Attachment} - */ - public static final class Attachment extends - com.google.protobuf.GeneratedMessage - implements AttachmentOrBuilder { - // Use Attachment.newBuilder() to construct. - private Attachment(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Attachment(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Attachment defaultInstance; - public static Attachment getDefaultInstance() { - return defaultInstance; - } - - public Attachment getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Attachment( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 8: { - bitField0_ |= 0x00000001; - rowId_ = input.readUInt64(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - attachmentId_ = input.readUInt64(); - break; - } - case 24: { - bitField0_ |= 0x00000004; - length_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Attachment_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Attachment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Attachment.class, org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public Attachment parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Attachment(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional uint64 rowId = 1; - public static final int ROWID_FIELD_NUMBER = 1; - private long rowId_; - /** - * optional uint64 rowId = 1; - */ - public boolean hasRowId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 rowId = 1; - */ - public long getRowId() { - return rowId_; - } - - // optional uint64 attachmentId = 2; - public static final int ATTACHMENTID_FIELD_NUMBER = 2; - private long attachmentId_; - /** - * optional uint64 attachmentId = 2; - */ - public boolean hasAttachmentId() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint64 attachmentId = 2; - */ - public long getAttachmentId() { - return attachmentId_; - } - - // optional uint32 length = 3; - public static final int LENGTH_FIELD_NUMBER = 3; - private int length_; - /** - * optional uint32 length = 3; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional uint32 length = 3; - */ - public int getLength() { - return length_; - } - - private void initFields() { - rowId_ = 0L; - attachmentId_ = 0L; - length_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeUInt64(1, rowId_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt64(2, attachmentId_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeUInt32(3, length_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(1, rowId_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(2, attachmentId_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(3, length_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Attachment parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.Attachment prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.Attachment} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Attachment_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Attachment_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Attachment.class, org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.Attachment.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - rowId_ = 0L; - bitField0_ = (bitField0_ & ~0x00000001); - attachmentId_ = 0L; - bitField0_ = (bitField0_ & ~0x00000002); - length_ = 0; - bitField0_ = (bitField0_ & ~0x00000004); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Attachment_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment build() { - org.thoughtcrime.securesms.backup.BackupProtos.Attachment result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.Attachment result = new org.thoughtcrime.securesms.backup.BackupProtos.Attachment(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.rowId_ = rowId_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.attachmentId_ = attachmentId_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - result.length_ = length_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.Attachment) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.Attachment)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.Attachment other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance()) return this; - if (other.hasRowId()) { - setRowId(other.getRowId()); - } - if (other.hasAttachmentId()) { - setAttachmentId(other.getAttachmentId()); - } - if (other.hasLength()) { - setLength(other.getLength()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.Attachment parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.Attachment) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional uint64 rowId = 1; - private long rowId_ ; - /** - * optional uint64 rowId = 1; - */ - public boolean hasRowId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 rowId = 1; - */ - public long getRowId() { - return rowId_; - } - /** - * optional uint64 rowId = 1; - */ - public Builder setRowId(long value) { - bitField0_ |= 0x00000001; - rowId_ = value; - onChanged(); - return this; - } - /** - * optional uint64 rowId = 1; - */ - public Builder clearRowId() { - bitField0_ = (bitField0_ & ~0x00000001); - rowId_ = 0L; - onChanged(); - return this; - } - - // optional uint64 attachmentId = 2; - private long attachmentId_ ; - /** - * optional uint64 attachmentId = 2; - */ - public boolean hasAttachmentId() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint64 attachmentId = 2; - */ - public long getAttachmentId() { - return attachmentId_; - } - /** - * optional uint64 attachmentId = 2; - */ - public Builder setAttachmentId(long value) { - bitField0_ |= 0x00000002; - attachmentId_ = value; - onChanged(); - return this; - } - /** - * optional uint64 attachmentId = 2; - */ - public Builder clearAttachmentId() { - bitField0_ = (bitField0_ & ~0x00000002); - attachmentId_ = 0L; - onChanged(); - return this; - } - - // optional uint32 length = 3; - private int length_ ; - /** - * optional uint32 length = 3; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional uint32 length = 3; - */ - public int getLength() { - return length_; - } - /** - * optional uint32 length = 3; - */ - public Builder setLength(int value) { - bitField0_ |= 0x00000004; - length_ = value; - onChanged(); - return this; - } - /** - * optional uint32 length = 3; - */ - public Builder clearLength() { - bitField0_ = (bitField0_ & ~0x00000004); - length_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.Attachment) - } - - static { - defaultInstance = new Attachment(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.Attachment) - } - - public interface StickerOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional uint64 rowId = 1; - /** - * optional uint64 rowId = 1; - */ - boolean hasRowId(); - /** - * optional uint64 rowId = 1; - */ - long getRowId(); - - // optional uint32 length = 2; - /** - * optional uint32 length = 2; - */ - boolean hasLength(); - /** - * optional uint32 length = 2; - */ - int getLength(); - } - /** - * Protobuf type {@code signal.Sticker} - */ - public static final class Sticker extends - com.google.protobuf.GeneratedMessage - implements StickerOrBuilder { - // Use Sticker.newBuilder() to construct. - private Sticker(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Sticker(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Sticker defaultInstance; - public static Sticker getDefaultInstance() { - return defaultInstance; - } - - public Sticker getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Sticker( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 8: { - bitField0_ |= 0x00000001; - rowId_ = input.readUInt64(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - length_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Sticker_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Sticker_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Sticker.class, org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public Sticker parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Sticker(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional uint64 rowId = 1; - public static final int ROWID_FIELD_NUMBER = 1; - private long rowId_; - /** - * optional uint64 rowId = 1; - */ - public boolean hasRowId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 rowId = 1; - */ - public long getRowId() { - return rowId_; - } - - // optional uint32 length = 2; - public static final int LENGTH_FIELD_NUMBER = 2; - private int length_; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - - private void initFields() { - rowId_ = 0L; - length_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeUInt64(1, rowId_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt32(2, length_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(1, rowId_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(2, length_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Sticker parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.Sticker prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.Sticker} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Sticker_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Sticker_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Sticker.class, org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.Sticker.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - rowId_ = 0L; - bitField0_ = (bitField0_ & ~0x00000001); - length_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Sticker_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker build() { - org.thoughtcrime.securesms.backup.BackupProtos.Sticker result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.Sticker result = new org.thoughtcrime.securesms.backup.BackupProtos.Sticker(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.rowId_ = rowId_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.length_ = length_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.Sticker) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.Sticker)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.Sticker other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance()) return this; - if (other.hasRowId()) { - setRowId(other.getRowId()); - } - if (other.hasLength()) { - setLength(other.getLength()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.Sticker parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.Sticker) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional uint64 rowId = 1; - private long rowId_ ; - /** - * optional uint64 rowId = 1; - */ - public boolean hasRowId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 rowId = 1; - */ - public long getRowId() { - return rowId_; - } - /** - * optional uint64 rowId = 1; - */ - public Builder setRowId(long value) { - bitField0_ |= 0x00000001; - rowId_ = value; - onChanged(); - return this; - } - /** - * optional uint64 rowId = 1; - */ - public Builder clearRowId() { - bitField0_ = (bitField0_ & ~0x00000001); - rowId_ = 0L; - onChanged(); - return this; - } - - // optional uint32 length = 2; - private int length_ ; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - /** - * optional uint32 length = 2; - */ - public Builder setLength(int value) { - bitField0_ |= 0x00000002; - length_ = value; - onChanged(); - return this; - } - /** - * optional uint32 length = 2; - */ - public Builder clearLength() { - bitField0_ = (bitField0_ & ~0x00000002); - length_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.Sticker) - } - - static { - defaultInstance = new Sticker(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.Sticker) - } - - public interface AvatarOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string name = 1; - /** - * optional string name = 1; - */ - boolean hasName(); - /** - * optional string name = 1; - */ - java.lang.String getName(); - /** - * optional string name = 1; - */ - com.google.protobuf.ByteString - getNameBytes(); - - // optional uint32 length = 2; - /** - * optional uint32 length = 2; - */ - boolean hasLength(); - /** - * optional uint32 length = 2; - */ - int getLength(); - } - /** - * Protobuf type {@code signal.Avatar} - */ - public static final class Avatar extends - com.google.protobuf.GeneratedMessage - implements AvatarOrBuilder { - // Use Avatar.newBuilder() to construct. - private Avatar(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Avatar(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Avatar defaultInstance; - public static Avatar getDefaultInstance() { - return defaultInstance; - } - - public Avatar getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Avatar( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - name_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - length_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Avatar.class, org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public Avatar parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Avatar(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional string name = 1; - public static final int NAME_FIELD_NUMBER = 1; - private java.lang.Object name_; - /** - * optional string name = 1; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional uint32 length = 2; - public static final int LENGTH_FIELD_NUMBER = 2; - private int length_; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - - private void initFields() { - name_ = ""; - length_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getNameBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt32(2, length_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getNameBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(2, length_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Avatar parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.Avatar prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.Avatar} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Avatar.class, org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.Avatar.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - name_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - length_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Avatar_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar build() { - org.thoughtcrime.securesms.backup.BackupProtos.Avatar result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.Avatar result = new org.thoughtcrime.securesms.backup.BackupProtos.Avatar(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.name_ = name_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.length_ = length_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.Avatar) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.Avatar)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.Avatar other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance()) return this; - if (other.hasName()) { - bitField0_ |= 0x00000001; - name_ = other.name_; - onChanged(); - } - if (other.hasLength()) { - setLength(other.getLength()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.Avatar parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.Avatar) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string name = 1; - private java.lang.Object name_ = ""; - /** - * optional string name = 1; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string name = 1; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - name_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string name = 1; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string name = 1; - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - name_ = value; - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder clearName() { - bitField0_ = (bitField0_ & ~0x00000001); - name_ = getDefaultInstance().getName(); - onChanged(); - return this; - } - /** - * optional string name = 1; - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - name_ = value; - onChanged(); - return this; - } - - // optional uint32 length = 2; - private int length_ ; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - /** - * optional uint32 length = 2; - */ - public Builder setLength(int value) { - bitField0_ |= 0x00000002; - length_ = value; - onChanged(); - return this; - } - /** - * optional uint32 length = 2; - */ - public Builder clearLength() { - bitField0_ = (bitField0_ & ~0x00000002); - length_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.Avatar) - } - - static { - defaultInstance = new Avatar(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.Avatar) - } - - public interface DatabaseVersionOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional uint32 version = 1; - /** - * optional uint32 version = 1; - */ - boolean hasVersion(); - /** - * optional uint32 version = 1; - */ - int getVersion(); - } - /** - * Protobuf type {@code signal.DatabaseVersion} - */ - public static final class DatabaseVersion extends - com.google.protobuf.GeneratedMessage - implements DatabaseVersionOrBuilder { - // Use DatabaseVersion.newBuilder() to construct. - private DatabaseVersion(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private DatabaseVersion(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final DatabaseVersion defaultInstance; - public static DatabaseVersion getDefaultInstance() { - return defaultInstance; - } - - public DatabaseVersion getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private DatabaseVersion( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 8: { - bitField0_ |= 0x00000001; - version_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_DatabaseVersion_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_DatabaseVersion_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.class, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public DatabaseVersion parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new DatabaseVersion(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional uint32 version = 1; - public static final int VERSION_FIELD_NUMBER = 1; - private int version_; - /** - * optional uint32 version = 1; - */ - public boolean hasVersion() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint32 version = 1; - */ - public int getVersion() { - return version_; - } - - private void initFields() { - version_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeUInt32(1, version_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(1, version_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.DatabaseVersion} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_DatabaseVersion_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_DatabaseVersion_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.class, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - version_ = 0; - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_DatabaseVersion_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion build() { - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion result = new org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.version_ = version_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance()) return this; - if (other.hasVersion()) { - setVersion(other.getVersion()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional uint32 version = 1; - private int version_ ; - /** - * optional uint32 version = 1; - */ - public boolean hasVersion() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint32 version = 1; - */ - public int getVersion() { - return version_; - } - /** - * optional uint32 version = 1; - */ - public Builder setVersion(int value) { - bitField0_ |= 0x00000001; - version_ = value; - onChanged(); - return this; - } - /** - * optional uint32 version = 1; - */ - public Builder clearVersion() { - bitField0_ = (bitField0_ & ~0x00000001); - version_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.DatabaseVersion) - } - - static { - defaultInstance = new DatabaseVersion(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.DatabaseVersion) - } - - public interface HeaderOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional bytes iv = 1; - /** - * optional bytes iv = 1; - */ - boolean hasIv(); - /** - * optional bytes iv = 1; - */ - com.google.protobuf.ByteString getIv(); - - // optional bytes salt = 2; - /** - * optional bytes salt = 2; - */ - boolean hasSalt(); - /** - * optional bytes salt = 2; - */ - com.google.protobuf.ByteString getSalt(); - } - /** - * Protobuf type {@code signal.Header} - */ - public static final class Header extends - com.google.protobuf.GeneratedMessage - implements HeaderOrBuilder { - // Use Header.newBuilder() to construct. - private Header(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Header(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Header defaultInstance; - public static Header getDefaultInstance() { - return defaultInstance; - } - - public Header getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Header( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - iv_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - salt_ = input.readBytes(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Header_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Header_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Header.class, org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder.class); - } - - public static com.google.protobuf.Parser
PARSER = - new com.google.protobuf.AbstractParser
() { - public Header parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Header(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser
getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional bytes iv = 1; - public static final int IV_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString iv_; - /** - * optional bytes iv = 1; - */ - public boolean hasIv() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes iv = 1; - */ - public com.google.protobuf.ByteString getIv() { - return iv_; - } - - // optional bytes salt = 2; - public static final int SALT_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString salt_; - /** - * optional bytes salt = 2; - */ - public boolean hasSalt() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional bytes salt = 2; - */ - public com.google.protobuf.ByteString getSalt() { - return salt_; - } - - private void initFields() { - iv_ = com.google.protobuf.ByteString.EMPTY; - salt_ = com.google.protobuf.ByteString.EMPTY; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, iv_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeBytes(2, salt_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, iv_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, salt_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.Header parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.Header prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.Header} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Header_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Header_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.Header.class, org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.Header.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - iv_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - salt_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_Header_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Header getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Header build() { - org.thoughtcrime.securesms.backup.BackupProtos.Header result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.Header buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.Header result = new org.thoughtcrime.securesms.backup.BackupProtos.Header(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.iv_ = iv_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.salt_ = salt_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.Header) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.Header)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.Header other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance()) return this; - if (other.hasIv()) { - setIv(other.getIv()); - } - if (other.hasSalt()) { - setSalt(other.getSalt()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.Header parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.Header) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional bytes iv = 1; - private com.google.protobuf.ByteString iv_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes iv = 1; - */ - public boolean hasIv() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes iv = 1; - */ - public com.google.protobuf.ByteString getIv() { - return iv_; - } - /** - * optional bytes iv = 1; - */ - public Builder setIv(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - iv_ = value; - onChanged(); - return this; - } - /** - * optional bytes iv = 1; - */ - public Builder clearIv() { - bitField0_ = (bitField0_ & ~0x00000001); - iv_ = getDefaultInstance().getIv(); - onChanged(); - return this; - } - - // optional bytes salt = 2; - private com.google.protobuf.ByteString salt_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes salt = 2; - */ - public boolean hasSalt() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional bytes salt = 2; - */ - public com.google.protobuf.ByteString getSalt() { - return salt_; - } - /** - * optional bytes salt = 2; - */ - public Builder setSalt(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - salt_ = value; - onChanged(); - return this; - } - /** - * optional bytes salt = 2; - */ - public Builder clearSalt() { - bitField0_ = (bitField0_ & ~0x00000002); - salt_ = getDefaultInstance().getSalt(); - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signal.Header) - } - - static { - defaultInstance = new Header(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.Header) - } - - public interface BackupFrameOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional .signal.Header header = 1; - /** - * optional .signal.Header header = 1; - */ - boolean hasHeader(); - /** - * optional .signal.Header header = 1; - */ - org.thoughtcrime.securesms.backup.BackupProtos.Header getHeader(); - /** - * optional .signal.Header header = 1; - */ - org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder getHeaderOrBuilder(); - - // optional .signal.SqlStatement statement = 2; - /** - * optional .signal.SqlStatement statement = 2; - */ - boolean hasStatement(); - /** - * optional .signal.SqlStatement statement = 2; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement getStatement(); - /** - * optional .signal.SqlStatement statement = 2; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder getStatementOrBuilder(); - - // optional .signal.SharedPreference preference = 3; - /** - * optional .signal.SharedPreference preference = 3; - */ - boolean hasPreference(); - /** - * optional .signal.SharedPreference preference = 3; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference getPreference(); - /** - * optional .signal.SharedPreference preference = 3; - */ - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder getPreferenceOrBuilder(); - - // optional .signal.Attachment attachment = 4; - /** - * optional .signal.Attachment attachment = 4; - */ - boolean hasAttachment(); - /** - * optional .signal.Attachment attachment = 4; - */ - org.thoughtcrime.securesms.backup.BackupProtos.Attachment getAttachment(); - /** - * optional .signal.Attachment attachment = 4; - */ - org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder getAttachmentOrBuilder(); - - // optional .signal.DatabaseVersion version = 5; - /** - * optional .signal.DatabaseVersion version = 5; - */ - boolean hasVersion(); - /** - * optional .signal.DatabaseVersion version = 5; - */ - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion getVersion(); - /** - * optional .signal.DatabaseVersion version = 5; - */ - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder getVersionOrBuilder(); - - // optional bool end = 6; - /** - * optional bool end = 6; - */ - boolean hasEnd(); - /** - * optional bool end = 6; - */ - boolean getEnd(); - - // optional .signal.Avatar avatar = 7; - /** - * optional .signal.Avatar avatar = 7; - */ - boolean hasAvatar(); - /** - * optional .signal.Avatar avatar = 7; - */ - org.thoughtcrime.securesms.backup.BackupProtos.Avatar getAvatar(); - /** - * optional .signal.Avatar avatar = 7; - */ - org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder getAvatarOrBuilder(); - - // optional .signal.Sticker sticker = 8; - /** - * optional .signal.Sticker sticker = 8; - */ - boolean hasSticker(); - /** - * optional .signal.Sticker sticker = 8; - */ - org.thoughtcrime.securesms.backup.BackupProtos.Sticker getSticker(); - /** - * optional .signal.Sticker sticker = 8; - */ - org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder getStickerOrBuilder(); - } - /** - * Protobuf type {@code signal.BackupFrame} - */ - public static final class BackupFrame extends - com.google.protobuf.GeneratedMessage - implements BackupFrameOrBuilder { - // Use BackupFrame.newBuilder() to construct. - private BackupFrame(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private BackupFrame(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final BackupFrame defaultInstance; - public static BackupFrame getDefaultInstance() { - return defaultInstance; - } - - public BackupFrame getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private BackupFrame( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder subBuilder = null; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - subBuilder = header_.toBuilder(); - } - header_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.Header.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(header_); - header_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000001; - break; - } - case 18: { - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder subBuilder = null; - if (((bitField0_ & 0x00000002) == 0x00000002)) { - subBuilder = statement_.toBuilder(); - } - statement_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(statement_); - statement_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000002; - break; - } - case 26: { - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder subBuilder = null; - if (((bitField0_ & 0x00000004) == 0x00000004)) { - subBuilder = preference_.toBuilder(); - } - preference_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(preference_); - preference_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000004; - break; - } - case 34: { - org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder subBuilder = null; - if (((bitField0_ & 0x00000008) == 0x00000008)) { - subBuilder = attachment_.toBuilder(); - } - attachment_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.Attachment.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(attachment_); - attachment_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000008; - break; - } - case 42: { - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder subBuilder = null; - if (((bitField0_ & 0x00000010) == 0x00000010)) { - subBuilder = version_.toBuilder(); - } - version_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(version_); - version_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000010; - break; - } - case 48: { - bitField0_ |= 0x00000020; - end_ = input.readBool(); - break; - } - case 58: { - org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder subBuilder = null; - if (((bitField0_ & 0x00000040) == 0x00000040)) { - subBuilder = avatar_.toBuilder(); - } - avatar_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.Avatar.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(avatar_); - avatar_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000040; - break; - } - case 66: { - org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder subBuilder = null; - if (((bitField0_ & 0x00000080) == 0x00000080)) { - subBuilder = sticker_.toBuilder(); - } - sticker_ = input.readMessage(org.thoughtcrime.securesms.backup.BackupProtos.Sticker.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(sticker_); - sticker_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000080; - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_BackupFrame_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_BackupFrame_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.class, org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public BackupFrame parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new BackupFrame(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional .signal.Header header = 1; - public static final int HEADER_FIELD_NUMBER = 1; - private org.thoughtcrime.securesms.backup.BackupProtos.Header header_; - /** - * optional .signal.Header header = 1; - */ - public boolean hasHeader() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional .signal.Header header = 1; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Header getHeader() { - return header_; - } - /** - * optional .signal.Header header = 1; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder getHeaderOrBuilder() { - return header_; - } - - // optional .signal.SqlStatement statement = 2; - public static final int STATEMENT_FIELD_NUMBER = 2; - private org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement statement_; - /** - * optional .signal.SqlStatement statement = 2; - */ - public boolean hasStatement() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement getStatement() { - return statement_; - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder getStatementOrBuilder() { - return statement_; - } - - // optional .signal.SharedPreference preference = 3; - public static final int PREFERENCE_FIELD_NUMBER = 3; - private org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference preference_; - /** - * optional .signal.SharedPreference preference = 3; - */ - public boolean hasPreference() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference getPreference() { - return preference_; - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder getPreferenceOrBuilder() { - return preference_; - } - - // optional .signal.Attachment attachment = 4; - public static final int ATTACHMENT_FIELD_NUMBER = 4; - private org.thoughtcrime.securesms.backup.BackupProtos.Attachment attachment_; - /** - * optional .signal.Attachment attachment = 4; - */ - public boolean hasAttachment() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional .signal.Attachment attachment = 4; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment getAttachment() { - return attachment_; - } - /** - * optional .signal.Attachment attachment = 4; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder getAttachmentOrBuilder() { - return attachment_; - } - - // optional .signal.DatabaseVersion version = 5; - public static final int VERSION_FIELD_NUMBER = 5; - private org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion version_; - /** - * optional .signal.DatabaseVersion version = 5; - */ - public boolean hasVersion() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion getVersion() { - return version_; - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder getVersionOrBuilder() { - return version_; - } - - // optional bool end = 6; - public static final int END_FIELD_NUMBER = 6; - private boolean end_; - /** - * optional bool end = 6; - */ - public boolean hasEnd() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bool end = 6; - */ - public boolean getEnd() { - return end_; - } - - // optional .signal.Avatar avatar = 7; - public static final int AVATAR_FIELD_NUMBER = 7; - private org.thoughtcrime.securesms.backup.BackupProtos.Avatar avatar_; - /** - * optional .signal.Avatar avatar = 7; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional .signal.Avatar avatar = 7; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar getAvatar() { - return avatar_; - } - /** - * optional .signal.Avatar avatar = 7; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder getAvatarOrBuilder() { - return avatar_; - } - - // optional .signal.Sticker sticker = 8; - public static final int STICKER_FIELD_NUMBER = 8; - private org.thoughtcrime.securesms.backup.BackupProtos.Sticker sticker_; - /** - * optional .signal.Sticker sticker = 8; - */ - public boolean hasSticker() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - /** - * optional .signal.Sticker sticker = 8; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker getSticker() { - return sticker_; - } - /** - * optional .signal.Sticker sticker = 8; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder getStickerOrBuilder() { - return sticker_; - } - - private void initFields() { - header_ = org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance(); - statement_ = org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance(); - preference_ = org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance(); - attachment_ = org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance(); - version_ = org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance(); - end_ = false; - avatar_ = org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance(); - sticker_ = org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance(); - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeMessage(1, header_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeMessage(2, statement_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeMessage(3, preference_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - output.writeMessage(4, attachment_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - output.writeMessage(5, version_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - output.writeBool(6, end_); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - output.writeMessage(7, avatar_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - output.writeMessage(8, sticker_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(1, header_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(2, statement_); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(3, preference_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(4, attachment_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(5, version_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(6, end_); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(7, avatar_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(8, sticker_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signal.BackupFrame} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.thoughtcrime.securesms.backup.BackupProtos.BackupFrameOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_BackupFrame_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_BackupFrame_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.class, org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.Builder.class); - } - - // Construct using org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - getHeaderFieldBuilder(); - getStatementFieldBuilder(); - getPreferenceFieldBuilder(); - getAttachmentFieldBuilder(); - getVersionFieldBuilder(); - getAvatarFieldBuilder(); - getStickerFieldBuilder(); - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - if (headerBuilder_ == null) { - header_ = org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance(); - } else { - headerBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - if (statementBuilder_ == null) { - statement_ = org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance(); - } else { - statementBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - if (preferenceBuilder_ == null) { - preference_ = org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance(); - } else { - preferenceBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); - if (attachmentBuilder_ == null) { - attachment_ = org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance(); - } else { - attachmentBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000008); - if (versionBuilder_ == null) { - version_ = org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance(); - } else { - versionBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000010); - end_ = false; - bitField0_ = (bitField0_ & ~0x00000020); - if (avatarBuilder_ == null) { - avatar_ = org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000040); - if (stickerBuilder_ == null) { - sticker_ = org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance(); - } else { - stickerBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000080); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.internal_static_signal_BackupFrame_descriptor; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame getDefaultInstanceForType() { - return org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.getDefaultInstance(); - } - - public org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame build() { - org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame buildPartial() { - org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame result = new org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - if (headerBuilder_ == null) { - result.header_ = header_; - } else { - result.header_ = headerBuilder_.build(); - } - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - if (statementBuilder_ == null) { - result.statement_ = statement_; - } else { - result.statement_ = statementBuilder_.build(); - } - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - if (preferenceBuilder_ == null) { - result.preference_ = preference_; - } else { - result.preference_ = preferenceBuilder_.build(); - } - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { - to_bitField0_ |= 0x00000008; - } - if (attachmentBuilder_ == null) { - result.attachment_ = attachment_; - } else { - result.attachment_ = attachmentBuilder_.build(); - } - if (((from_bitField0_ & 0x00000010) == 0x00000010)) { - to_bitField0_ |= 0x00000010; - } - if (versionBuilder_ == null) { - result.version_ = version_; - } else { - result.version_ = versionBuilder_.build(); - } - if (((from_bitField0_ & 0x00000020) == 0x00000020)) { - to_bitField0_ |= 0x00000020; - } - result.end_ = end_; - if (((from_bitField0_ & 0x00000040) == 0x00000040)) { - to_bitField0_ |= 0x00000040; - } - if (avatarBuilder_ == null) { - result.avatar_ = avatar_; - } else { - result.avatar_ = avatarBuilder_.build(); - } - if (((from_bitField0_ & 0x00000080) == 0x00000080)) { - to_bitField0_ |= 0x00000080; - } - if (stickerBuilder_ == null) { - result.sticker_ = sticker_; - } else { - result.sticker_ = stickerBuilder_.build(); - } - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame) { - return mergeFrom((org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame other) { - if (other == org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame.getDefaultInstance()) return this; - if (other.hasHeader()) { - mergeHeader(other.getHeader()); - } - if (other.hasStatement()) { - mergeStatement(other.getStatement()); - } - if (other.hasPreference()) { - mergePreference(other.getPreference()); - } - if (other.hasAttachment()) { - mergeAttachment(other.getAttachment()); - } - if (other.hasVersion()) { - mergeVersion(other.getVersion()); - } - if (other.hasEnd()) { - setEnd(other.getEnd()); - } - if (other.hasAvatar()) { - mergeAvatar(other.getAvatar()); - } - if (other.hasSticker()) { - mergeSticker(other.getSticker()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional .signal.Header header = 1; - private org.thoughtcrime.securesms.backup.BackupProtos.Header header_ = org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Header, org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder, org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder> headerBuilder_; - /** - * optional .signal.Header header = 1; - */ - public boolean hasHeader() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional .signal.Header header = 1; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Header getHeader() { - if (headerBuilder_ == null) { - return header_; - } else { - return headerBuilder_.getMessage(); - } - } - /** - * optional .signal.Header header = 1; - */ - public Builder setHeader(org.thoughtcrime.securesms.backup.BackupProtos.Header value) { - if (headerBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - header_ = value; - onChanged(); - } else { - headerBuilder_.setMessage(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .signal.Header header = 1; - */ - public Builder setHeader( - org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder builderForValue) { - if (headerBuilder_ == null) { - header_ = builderForValue.build(); - onChanged(); - } else { - headerBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .signal.Header header = 1; - */ - public Builder mergeHeader(org.thoughtcrime.securesms.backup.BackupProtos.Header value) { - if (headerBuilder_ == null) { - if (((bitField0_ & 0x00000001) == 0x00000001) && - header_ != org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance()) { - header_ = - org.thoughtcrime.securesms.backup.BackupProtos.Header.newBuilder(header_).mergeFrom(value).buildPartial(); - } else { - header_ = value; - } - onChanged(); - } else { - headerBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000001; - return this; - } - /** - * optional .signal.Header header = 1; - */ - public Builder clearHeader() { - if (headerBuilder_ == null) { - header_ = org.thoughtcrime.securesms.backup.BackupProtos.Header.getDefaultInstance(); - onChanged(); - } else { - headerBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - /** - * optional .signal.Header header = 1; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder getHeaderBuilder() { - bitField0_ |= 0x00000001; - onChanged(); - return getHeaderFieldBuilder().getBuilder(); - } - /** - * optional .signal.Header header = 1; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder getHeaderOrBuilder() { - if (headerBuilder_ != null) { - return headerBuilder_.getMessageOrBuilder(); - } else { - return header_; - } - } - /** - * optional .signal.Header header = 1; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Header, org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder, org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder> - getHeaderFieldBuilder() { - if (headerBuilder_ == null) { - headerBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Header, org.thoughtcrime.securesms.backup.BackupProtos.Header.Builder, org.thoughtcrime.securesms.backup.BackupProtos.HeaderOrBuilder>( - header_, - getParentForChildren(), - isClean()); - header_ = null; - } - return headerBuilder_; - } - - // optional .signal.SqlStatement statement = 2; - private org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement statement_ = org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder> statementBuilder_; - /** - * optional .signal.SqlStatement statement = 2; - */ - public boolean hasStatement() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement getStatement() { - if (statementBuilder_ == null) { - return statement_; - } else { - return statementBuilder_.getMessage(); - } - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public Builder setStatement(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement value) { - if (statementBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - statement_ = value; - onChanged(); - } else { - statementBuilder_.setMessage(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public Builder setStatement( - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder builderForValue) { - if (statementBuilder_ == null) { - statement_ = builderForValue.build(); - onChanged(); - } else { - statementBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public Builder mergeStatement(org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement value) { - if (statementBuilder_ == null) { - if (((bitField0_ & 0x00000002) == 0x00000002) && - statement_ != org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance()) { - statement_ = - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.newBuilder(statement_).mergeFrom(value).buildPartial(); - } else { - statement_ = value; - } - onChanged(); - } else { - statementBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000002; - return this; - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public Builder clearStatement() { - if (statementBuilder_ == null) { - statement_ = org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.getDefaultInstance(); - onChanged(); - } else { - statementBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder getStatementBuilder() { - bitField0_ |= 0x00000002; - onChanged(); - return getStatementFieldBuilder().getBuilder(); - } - /** - * optional .signal.SqlStatement statement = 2; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder getStatementOrBuilder() { - if (statementBuilder_ != null) { - return statementBuilder_.getMessageOrBuilder(); - } else { - return statement_; - } - } - /** - * optional .signal.SqlStatement statement = 2; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder> - getStatementFieldBuilder() { - if (statementBuilder_ == null) { - statementBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SqlStatementOrBuilder>( - statement_, - getParentForChildren(), - isClean()); - statement_ = null; - } - return statementBuilder_; - } - - // optional .signal.SharedPreference preference = 3; - private org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference preference_ = org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder> preferenceBuilder_; - /** - * optional .signal.SharedPreference preference = 3; - */ - public boolean hasPreference() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference getPreference() { - if (preferenceBuilder_ == null) { - return preference_; - } else { - return preferenceBuilder_.getMessage(); - } - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public Builder setPreference(org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference value) { - if (preferenceBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - preference_ = value; - onChanged(); - } else { - preferenceBuilder_.setMessage(value); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public Builder setPreference( - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder builderForValue) { - if (preferenceBuilder_ == null) { - preference_ = builderForValue.build(); - onChanged(); - } else { - preferenceBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public Builder mergePreference(org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference value) { - if (preferenceBuilder_ == null) { - if (((bitField0_ & 0x00000004) == 0x00000004) && - preference_ != org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance()) { - preference_ = - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.newBuilder(preference_).mergeFrom(value).buildPartial(); - } else { - preference_ = value; - } - onChanged(); - } else { - preferenceBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public Builder clearPreference() { - if (preferenceBuilder_ == null) { - preference_ = org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.getDefaultInstance(); - onChanged(); - } else { - preferenceBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); - return this; - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder getPreferenceBuilder() { - bitField0_ |= 0x00000004; - onChanged(); - return getPreferenceFieldBuilder().getBuilder(); - } - /** - * optional .signal.SharedPreference preference = 3; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder getPreferenceOrBuilder() { - if (preferenceBuilder_ != null) { - return preferenceBuilder_.getMessageOrBuilder(); - } else { - return preference_; - } - } - /** - * optional .signal.SharedPreference preference = 3; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder> - getPreferenceFieldBuilder() { - if (preferenceBuilder_ == null) { - preferenceBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference.Builder, org.thoughtcrime.securesms.backup.BackupProtos.SharedPreferenceOrBuilder>( - preference_, - getParentForChildren(), - isClean()); - preference_ = null; - } - return preferenceBuilder_; - } - - // optional .signal.Attachment attachment = 4; - private org.thoughtcrime.securesms.backup.BackupProtos.Attachment attachment_ = org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Attachment, org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder> attachmentBuilder_; - /** - * optional .signal.Attachment attachment = 4; - */ - public boolean hasAttachment() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional .signal.Attachment attachment = 4; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment getAttachment() { - if (attachmentBuilder_ == null) { - return attachment_; - } else { - return attachmentBuilder_.getMessage(); - } - } - /** - * optional .signal.Attachment attachment = 4; - */ - public Builder setAttachment(org.thoughtcrime.securesms.backup.BackupProtos.Attachment value) { - if (attachmentBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - attachment_ = value; - onChanged(); - } else { - attachmentBuilder_.setMessage(value); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signal.Attachment attachment = 4; - */ - public Builder setAttachment( - org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder builderForValue) { - if (attachmentBuilder_ == null) { - attachment_ = builderForValue.build(); - onChanged(); - } else { - attachmentBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signal.Attachment attachment = 4; - */ - public Builder mergeAttachment(org.thoughtcrime.securesms.backup.BackupProtos.Attachment value) { - if (attachmentBuilder_ == null) { - if (((bitField0_ & 0x00000008) == 0x00000008) && - attachment_ != org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance()) { - attachment_ = - org.thoughtcrime.securesms.backup.BackupProtos.Attachment.newBuilder(attachment_).mergeFrom(value).buildPartial(); - } else { - attachment_ = value; - } - onChanged(); - } else { - attachmentBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signal.Attachment attachment = 4; - */ - public Builder clearAttachment() { - if (attachmentBuilder_ == null) { - attachment_ = org.thoughtcrime.securesms.backup.BackupProtos.Attachment.getDefaultInstance(); - onChanged(); - } else { - attachmentBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000008); - return this; - } - /** - * optional .signal.Attachment attachment = 4; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder getAttachmentBuilder() { - bitField0_ |= 0x00000008; - onChanged(); - return getAttachmentFieldBuilder().getBuilder(); - } - /** - * optional .signal.Attachment attachment = 4; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder getAttachmentOrBuilder() { - if (attachmentBuilder_ != null) { - return attachmentBuilder_.getMessageOrBuilder(); - } else { - return attachment_; - } - } - /** - * optional .signal.Attachment attachment = 4; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Attachment, org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder> - getAttachmentFieldBuilder() { - if (attachmentBuilder_ == null) { - attachmentBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Attachment, org.thoughtcrime.securesms.backup.BackupProtos.Attachment.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AttachmentOrBuilder>( - attachment_, - getParentForChildren(), - isClean()); - attachment_ = null; - } - return attachmentBuilder_; - } - - // optional .signal.DatabaseVersion version = 5; - private org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion version_ = org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder> versionBuilder_; - /** - * optional .signal.DatabaseVersion version = 5; - */ - public boolean hasVersion() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion getVersion() { - if (versionBuilder_ == null) { - return version_; - } else { - return versionBuilder_.getMessage(); - } - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public Builder setVersion(org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion value) { - if (versionBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - version_ = value; - onChanged(); - } else { - versionBuilder_.setMessage(value); - } - bitField0_ |= 0x00000010; - return this; - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public Builder setVersion( - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder builderForValue) { - if (versionBuilder_ == null) { - version_ = builderForValue.build(); - onChanged(); - } else { - versionBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000010; - return this; - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public Builder mergeVersion(org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion value) { - if (versionBuilder_ == null) { - if (((bitField0_ & 0x00000010) == 0x00000010) && - version_ != org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance()) { - version_ = - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.newBuilder(version_).mergeFrom(value).buildPartial(); - } else { - version_ = value; - } - onChanged(); - } else { - versionBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000010; - return this; - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public Builder clearVersion() { - if (versionBuilder_ == null) { - version_ = org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.getDefaultInstance(); - onChanged(); - } else { - versionBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000010); - return this; - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder getVersionBuilder() { - bitField0_ |= 0x00000010; - onChanged(); - return getVersionFieldBuilder().getBuilder(); - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder getVersionOrBuilder() { - if (versionBuilder_ != null) { - return versionBuilder_.getMessageOrBuilder(); - } else { - return version_; - } - } - /** - * optional .signal.DatabaseVersion version = 5; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder> - getVersionFieldBuilder() { - if (versionBuilder_ == null) { - versionBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion.Builder, org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersionOrBuilder>( - version_, - getParentForChildren(), - isClean()); - version_ = null; - } - return versionBuilder_; - } - - // optional bool end = 6; - private boolean end_ ; - /** - * optional bool end = 6; - */ - public boolean hasEnd() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bool end = 6; - */ - public boolean getEnd() { - return end_; - } - /** - * optional bool end = 6; - */ - public Builder setEnd(boolean value) { - bitField0_ |= 0x00000020; - end_ = value; - onChanged(); - return this; - } - /** - * optional bool end = 6; - */ - public Builder clearEnd() { - bitField0_ = (bitField0_ & ~0x00000020); - end_ = false; - onChanged(); - return this; - } - - // optional .signal.Avatar avatar = 7; - private org.thoughtcrime.securesms.backup.BackupProtos.Avatar avatar_ = org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Avatar, org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder> avatarBuilder_; - /** - * optional .signal.Avatar avatar = 7; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional .signal.Avatar avatar = 7; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar getAvatar() { - if (avatarBuilder_ == null) { - return avatar_; - } else { - return avatarBuilder_.getMessage(); - } - } - /** - * optional .signal.Avatar avatar = 7; - */ - public Builder setAvatar(org.thoughtcrime.securesms.backup.BackupProtos.Avatar value) { - if (avatarBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - avatar_ = value; - onChanged(); - } else { - avatarBuilder_.setMessage(value); - } - bitField0_ |= 0x00000040; - return this; - } - /** - * optional .signal.Avatar avatar = 7; - */ - public Builder setAvatar( - org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder builderForValue) { - if (avatarBuilder_ == null) { - avatar_ = builderForValue.build(); - onChanged(); - } else { - avatarBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000040; - return this; - } - /** - * optional .signal.Avatar avatar = 7; - */ - public Builder mergeAvatar(org.thoughtcrime.securesms.backup.BackupProtos.Avatar value) { - if (avatarBuilder_ == null) { - if (((bitField0_ & 0x00000040) == 0x00000040) && - avatar_ != org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance()) { - avatar_ = - org.thoughtcrime.securesms.backup.BackupProtos.Avatar.newBuilder(avatar_).mergeFrom(value).buildPartial(); - } else { - avatar_ = value; - } - onChanged(); - } else { - avatarBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000040; - return this; - } - /** - * optional .signal.Avatar avatar = 7; - */ - public Builder clearAvatar() { - if (avatarBuilder_ == null) { - avatar_ = org.thoughtcrime.securesms.backup.BackupProtos.Avatar.getDefaultInstance(); - onChanged(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000040); - return this; - } - /** - * optional .signal.Avatar avatar = 7; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder getAvatarBuilder() { - bitField0_ |= 0x00000040; - onChanged(); - return getAvatarFieldBuilder().getBuilder(); - } - /** - * optional .signal.Avatar avatar = 7; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder getAvatarOrBuilder() { - if (avatarBuilder_ != null) { - return avatarBuilder_.getMessageOrBuilder(); - } else { - return avatar_; - } - } - /** - * optional .signal.Avatar avatar = 7; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Avatar, org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder> - getAvatarFieldBuilder() { - if (avatarBuilder_ == null) { - avatarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Avatar, org.thoughtcrime.securesms.backup.BackupProtos.Avatar.Builder, org.thoughtcrime.securesms.backup.BackupProtos.AvatarOrBuilder>( - avatar_, - getParentForChildren(), - isClean()); - avatar_ = null; - } - return avatarBuilder_; - } - - // optional .signal.Sticker sticker = 8; - private org.thoughtcrime.securesms.backup.BackupProtos.Sticker sticker_ = org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Sticker, org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder, org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder> stickerBuilder_; - /** - * optional .signal.Sticker sticker = 8; - */ - public boolean hasSticker() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - /** - * optional .signal.Sticker sticker = 8; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker getSticker() { - if (stickerBuilder_ == null) { - return sticker_; - } else { - return stickerBuilder_.getMessage(); - } - } - /** - * optional .signal.Sticker sticker = 8; - */ - public Builder setSticker(org.thoughtcrime.securesms.backup.BackupProtos.Sticker value) { - if (stickerBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - sticker_ = value; - onChanged(); - } else { - stickerBuilder_.setMessage(value); - } - bitField0_ |= 0x00000080; - return this; - } - /** - * optional .signal.Sticker sticker = 8; - */ - public Builder setSticker( - org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder builderForValue) { - if (stickerBuilder_ == null) { - sticker_ = builderForValue.build(); - onChanged(); - } else { - stickerBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000080; - return this; - } - /** - * optional .signal.Sticker sticker = 8; - */ - public Builder mergeSticker(org.thoughtcrime.securesms.backup.BackupProtos.Sticker value) { - if (stickerBuilder_ == null) { - if (((bitField0_ & 0x00000080) == 0x00000080) && - sticker_ != org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance()) { - sticker_ = - org.thoughtcrime.securesms.backup.BackupProtos.Sticker.newBuilder(sticker_).mergeFrom(value).buildPartial(); - } else { - sticker_ = value; - } - onChanged(); - } else { - stickerBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000080; - return this; - } - /** - * optional .signal.Sticker sticker = 8; - */ - public Builder clearSticker() { - if (stickerBuilder_ == null) { - sticker_ = org.thoughtcrime.securesms.backup.BackupProtos.Sticker.getDefaultInstance(); - onChanged(); - } else { - stickerBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000080); - return this; - } - /** - * optional .signal.Sticker sticker = 8; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder getStickerBuilder() { - bitField0_ |= 0x00000080; - onChanged(); - return getStickerFieldBuilder().getBuilder(); - } - /** - * optional .signal.Sticker sticker = 8; - */ - public org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder getStickerOrBuilder() { - if (stickerBuilder_ != null) { - return stickerBuilder_.getMessageOrBuilder(); - } else { - return sticker_; - } - } - /** - * optional .signal.Sticker sticker = 8; - */ - private com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Sticker, org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder, org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder> - getStickerFieldBuilder() { - if (stickerBuilder_ == null) { - stickerBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.thoughtcrime.securesms.backup.BackupProtos.Sticker, org.thoughtcrime.securesms.backup.BackupProtos.Sticker.Builder, org.thoughtcrime.securesms.backup.BackupProtos.StickerOrBuilder>( - sticker_, - getParentForChildren(), - isClean()); - sticker_ = null; - } - return stickerBuilder_; - } - - // @@protoc_insertion_point(builder_scope:signal.BackupFrame) - } - - static { - defaultInstance = new BackupFrame(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signal.BackupFrame) - } - - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_SqlStatement_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_SqlStatement_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_SqlStatement_SqlParameter_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_SqlStatement_SqlParameter_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_SharedPreference_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_SharedPreference_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_Attachment_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_Attachment_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_Sticker_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_Sticker_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_Avatar_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_Avatar_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_DatabaseVersion_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_DatabaseVersion_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_Header_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_Header_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signal_BackupFrame_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signal_BackupFrame_fieldAccessorTable; - - public static com.google.protobuf.Descriptors.FileDescriptor - getDescriptor() { - return descriptor; - } - private static com.google.protobuf.Descriptors.FileDescriptor - descriptor; - static { - java.lang.String[] descriptorData = { - "\n\rBackups.proto\022\006signal\"\342\001\n\014SqlStatement" + - "\022\021\n\tstatement\030\001 \001(\t\0225\n\nparameters\030\002 \003(\0132" + - "!.signal.SqlStatement.SqlParameter\032\207\001\n\014S" + - "qlParameter\022\026\n\016stringParamter\030\001 \001(\t\022\030\n\020i" + - "ntegerParameter\030\002 \001(\004\022\027\n\017doubleParameter" + - "\030\003 \001(\001\022\025\n\rblobParameter\030\004 \001(\014\022\025\n\rnullpar" + - "ameter\030\005 \001(\010\"<\n\020SharedPreference\022\014\n\004file" + - "\030\001 \001(\t\022\013\n\003key\030\002 \001(\t\022\r\n\005value\030\003 \001(\t\"A\n\nAt" + - "tachment\022\r\n\005rowId\030\001 \001(\004\022\024\n\014attachmentId\030" + - "\002 \001(\004\022\016\n\006length\030\003 \001(\r\"(\n\007Sticker\022\r\n\005rowI", - "d\030\001 \001(\004\022\016\n\006length\030\002 \001(\r\"&\n\006Avatar\022\014\n\004nam" + - "e\030\001 \001(\t\022\016\n\006length\030\002 \001(\r\"\"\n\017DatabaseVersi" + - "on\022\017\n\007version\030\001 \001(\r\"\"\n\006Header\022\n\n\002iv\030\001 \001(" + - "\014\022\014\n\004salt\030\002 \001(\014\"\245\002\n\013BackupFrame\022\036\n\006heade" + - "r\030\001 \001(\0132\016.signal.Header\022\'\n\tstatement\030\002 \001" + - "(\0132\024.signal.SqlStatement\022,\n\npreference\030\003" + - " \001(\0132\030.signal.SharedPreference\022&\n\nattach" + - "ment\030\004 \001(\0132\022.signal.Attachment\022(\n\007versio" + - "n\030\005 \001(\0132\027.signal.DatabaseVersion\022\013\n\003end\030" + - "\006 \001(\010\022\036\n\006avatar\030\007 \001(\0132\016.signal.Avatar\022 \n", - "\007sticker\030\010 \001(\0132\017.signal.StickerB1\n!org.t" + - "houghtcrime.securesms.backupB\014BackupProt" + - "os" - }; - com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = - new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { - public com.google.protobuf.ExtensionRegistry assignDescriptors( - com.google.protobuf.Descriptors.FileDescriptor root) { - descriptor = root; - internal_static_signal_SqlStatement_descriptor = - getDescriptor().getMessageTypes().get(0); - internal_static_signal_SqlStatement_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_SqlStatement_descriptor, - new java.lang.String[] { "Statement", "Parameters", }); - internal_static_signal_SqlStatement_SqlParameter_descriptor = - internal_static_signal_SqlStatement_descriptor.getNestedTypes().get(0); - internal_static_signal_SqlStatement_SqlParameter_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_SqlStatement_SqlParameter_descriptor, - new java.lang.String[] { "StringParamter", "IntegerParameter", "DoubleParameter", "BlobParameter", "Nullparameter", }); - internal_static_signal_SharedPreference_descriptor = - getDescriptor().getMessageTypes().get(1); - internal_static_signal_SharedPreference_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_SharedPreference_descriptor, - new java.lang.String[] { "File", "Key", "Value", }); - internal_static_signal_Attachment_descriptor = - getDescriptor().getMessageTypes().get(2); - internal_static_signal_Attachment_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_Attachment_descriptor, - new java.lang.String[] { "RowId", "AttachmentId", "Length", }); - internal_static_signal_Sticker_descriptor = - getDescriptor().getMessageTypes().get(3); - internal_static_signal_Sticker_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_Sticker_descriptor, - new java.lang.String[] { "RowId", "Length", }); - internal_static_signal_Avatar_descriptor = - getDescriptor().getMessageTypes().get(4); - internal_static_signal_Avatar_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_Avatar_descriptor, - new java.lang.String[] { "Name", "Length", }); - internal_static_signal_DatabaseVersion_descriptor = - getDescriptor().getMessageTypes().get(5); - internal_static_signal_DatabaseVersion_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_DatabaseVersion_descriptor, - new java.lang.String[] { "Version", }); - internal_static_signal_Header_descriptor = - getDescriptor().getMessageTypes().get(6); - internal_static_signal_Header_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_Header_descriptor, - new java.lang.String[] { "Iv", "Salt", }); - internal_static_signal_BackupFrame_descriptor = - getDescriptor().getMessageTypes().get(7); - internal_static_signal_BackupFrame_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signal_BackupFrame_descriptor, - new java.lang.String[] { "Header", "Statement", "Preference", "Attachment", "Version", "End", "Avatar", "Sticker", }); - return null; - } - }; - com.google.protobuf.Descriptors.FileDescriptor - .internalBuildGeneratedFileFrom(descriptorData, - new com.google.protobuf.Descriptors.FileDescriptor[] { - }, assigner); - } - - // @@protoc_insertion_point(outer_class_scope) -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.kt deleted file mode 100644 index 6b5d47a2e6..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupExporter.kt +++ /dev/null @@ -1,447 +0,0 @@ -package org.thoughtcrime.securesms.backup - -import android.content.Context -import android.database.Cursor -import android.net.Uri -import android.text.TextUtils -import androidx.annotation.WorkerThread -import com.annimon.stream.function.Consumer -import com.annimon.stream.function.Predicate -import com.google.protobuf.ByteString -import net.zetetic.database.sqlcipher.SQLiteDatabase -import org.greenrobot.eventbus.EventBus -import org.session.libsession.avatars.AvatarHelper -import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId -import org.session.libsession.utilities.Conversions -import org.session.libsession.utilities.Util -import org.session.libsignal.crypto.kdf.HKDFv3 -import org.session.libsignal.utilities.ByteUtil -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.backup.BackupProtos.Attachment -import org.thoughtcrime.securesms.backup.BackupProtos.Avatar -import org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame -import org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion -import org.thoughtcrime.securesms.backup.BackupProtos.Header -import org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference -import org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement -import org.thoughtcrime.securesms.backup.BackupProtos.Sticker -import org.thoughtcrime.securesms.crypto.AttachmentSecret -import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream -import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream -import org.thoughtcrime.securesms.database.AttachmentDatabase -import org.thoughtcrime.securesms.database.GroupReceiptDatabase -import org.thoughtcrime.securesms.database.JobDatabase -import org.thoughtcrime.securesms.database.LokiAPIDatabase -import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase -import org.thoughtcrime.securesms.database.MmsDatabase -import org.thoughtcrime.securesms.database.MmsSmsColumns -import org.thoughtcrime.securesms.database.PushDatabase -import org.thoughtcrime.securesms.database.SearchDatabase -import org.thoughtcrime.securesms.database.SmsDatabase -import org.thoughtcrime.securesms.util.BackupUtil -import java.io.Closeable -import java.io.File -import java.io.FileInputStream -import java.io.Flushable -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.security.InvalidAlgorithmParameterException -import java.security.InvalidKeyException -import java.security.NoSuchAlgorithmException -import java.util.LinkedList -import javax.crypto.BadPaddingException -import javax.crypto.Cipher -import javax.crypto.IllegalBlockSizeException -import javax.crypto.Mac -import javax.crypto.NoSuchPaddingException -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec - -object FullBackupExporter { - private val TAG = FullBackupExporter::class.java.simpleName - - @JvmStatic - @WorkerThread - @Throws(IOException::class) - fun export(context: Context, - attachmentSecret: AttachmentSecret, - input: SQLiteDatabase, - fileUri: Uri, - passphrase: String) { - - val baseOutputStream = context.contentResolver.openOutputStream(fileUri) - ?: throw IOException("Cannot open an output stream for the file URI: $fileUri") - - var count = 0 - try { - BackupFrameOutputStream(baseOutputStream, passphrase).use { outputStream -> - outputStream.writeDatabaseVersion(input.version) - val tables = exportSchema(input, outputStream) - for (table in tables) if (shouldExportTable(table)) { - count = when (table) { - SmsDatabase.TABLE_NAME, MmsDatabase.TABLE_NAME -> { - exportTable(table, input, outputStream, - { cursor: Cursor -> - cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.EXPIRES_IN)) <= 0 - }, - null, - count) - } - GroupReceiptDatabase.TABLE_NAME -> { - exportTable(table, input, outputStream, - { cursor: Cursor -> - isForNonExpiringMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(GroupReceiptDatabase.MMS_ID))) - }, - null, - count) - } - AttachmentDatabase.TABLE_NAME -> { - exportTable(table, input, outputStream, - { cursor: Cursor -> - isForNonExpiringMessage(input, cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.MMS_ID))) - }, - { cursor: Cursor -> - exportAttachment(attachmentSecret, cursor, outputStream) - }, - count) - } - else -> { - exportTable(table, input, outputStream, null, null, count) - } - } - } - for (preference in BackupUtil.getBackupRecords(context)) { - EventBus.getDefault().post(BackupEvent.createProgress(++count)) - outputStream.writePreferenceEntry(preference) - } - for (preference in BackupPreferences.getBackupRecords(context)) { - EventBus.getDefault().post(BackupEvent.createProgress(++count)) - outputStream.writePreferenceEntry(preference) - } - for (avatar in AvatarHelper.getAvatarFiles(context)) { - EventBus.getDefault().post(BackupEvent.createProgress(++count)) - outputStream.writeAvatar(avatar.name, FileInputStream(avatar), avatar.length()) - } - outputStream.writeEnd() - } - EventBus.getDefault().post(BackupEvent.createFinished()) - } catch (e: Exception) { - Log.e(TAG, "Failed to make full backup.", e) - EventBus.getDefault().post(BackupEvent.createFinished(e)) - throw e - } - } - - private inline fun shouldExportTable(table: String): Boolean { - return table != PushDatabase.TABLE_NAME && - - table != LokiBackupFilesDatabase.TABLE_NAME && - table != LokiAPIDatabase.openGroupProfilePictureTable && - - table != JobDatabase.Jobs.TABLE_NAME && - table != JobDatabase.Constraints.TABLE_NAME && - table != JobDatabase.Dependencies.TABLE_NAME && - - !table.startsWith(SearchDatabase.SMS_FTS_TABLE_NAME) && - !table.startsWith(SearchDatabase.MMS_FTS_TABLE_NAME) && - !table.startsWith("sqlite_") - } - - @Throws(IOException::class) - private fun exportSchema(input: SQLiteDatabase, outputStream: BackupFrameOutputStream): List { - val tables: MutableList = LinkedList() - input.rawQuery("SELECT sql, name, type FROM sqlite_master", null).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - val sql = cursor.getString(0) - val name = cursor.getString(1) - val type = cursor.getString(2) - if (sql != null) { - val isSmsFtsSecretTable = name != null && name != SearchDatabase.SMS_FTS_TABLE_NAME && name.startsWith(SearchDatabase.SMS_FTS_TABLE_NAME) - val isMmsFtsSecretTable = name != null && name != SearchDatabase.MMS_FTS_TABLE_NAME && name.startsWith(SearchDatabase.MMS_FTS_TABLE_NAME) - if (!isSmsFtsSecretTable && !isMmsFtsSecretTable) { - if ("table" == type) { - tables.add(name) - } - outputStream.writeSql(SqlStatement.newBuilder().setStatement(cursor.getString(0)).build()) - } - } - } - } - return tables - } - - @Throws(IOException::class) - private fun exportTable(table: String, - input: SQLiteDatabase, - outputStream: BackupFrameOutputStream, - predicate: Predicate?, - postProcess: Consumer?, - count: Int): Int { - var count = count - val template = "INSERT INTO $table VALUES " - input.rawQuery("SELECT * FROM $table", null).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - EventBus.getDefault().post(BackupEvent.createProgress(++count)) - if (predicate != null && !predicate.test(cursor)) continue - - val statement = StringBuilder(template) - val statementBuilder = SqlStatement.newBuilder() - statement.append('(') - for (i in 0 until cursor.columnCount) { - statement.append('?') - when (cursor.getType(i)) { - Cursor.FIELD_TYPE_STRING -> { - statementBuilder.addParameters(SqlStatement.SqlParameter.newBuilder() - .setStringParamter(cursor.getString(i))) - } - Cursor.FIELD_TYPE_FLOAT -> { - statementBuilder.addParameters(SqlStatement.SqlParameter.newBuilder() - .setDoubleParameter(cursor.getDouble(i))) - } - Cursor.FIELD_TYPE_INTEGER -> { - statementBuilder.addParameters(SqlStatement.SqlParameter.newBuilder() - .setIntegerParameter(cursor.getLong(i))) - } - Cursor.FIELD_TYPE_BLOB -> { - statementBuilder.addParameters(SqlStatement.SqlParameter.newBuilder() - .setBlobParameter(ByteString.copyFrom(cursor.getBlob(i)))) - } - Cursor.FIELD_TYPE_NULL -> { - statementBuilder.addParameters(SqlStatement.SqlParameter.newBuilder() - .setNullparameter(true)) - } - else -> { - throw AssertionError("unknown type?" + cursor.getType(i)) - } - } - if (i < cursor.columnCount - 1) { - statement.append(',') - } - } - statement.append(')') - outputStream.writeSql(statementBuilder.setStatement(statement.toString()).build()) - postProcess?.accept(cursor) - } - } - return count - } - - private fun exportAttachment(attachmentSecret: AttachmentSecret, cursor: Cursor, outputStream: BackupFrameOutputStream) { - try { - val rowId = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ROW_ID)) - val uniqueId = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID)) - var size = cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.SIZE)) - val data = cursor.getString(cursor.getColumnIndexOrThrow(AttachmentDatabase.DATA)) - val random = cursor.getBlob(cursor.getColumnIndexOrThrow(AttachmentDatabase.DATA_RANDOM)) - if (!TextUtils.isEmpty(data) && size <= 0) { - size = calculateVeryOldStreamLength(attachmentSecret, random, data) - } - if (!TextUtils.isEmpty(data) && size > 0) { - val inputStream: InputStream = if (random != null && random.size == 32) { - ModernDecryptingPartInputStream.createFor(attachmentSecret, random, File(data), 0) - } else { - ClassicDecryptingPartInputStream.createFor(attachmentSecret, File(data)) - } - outputStream.writeAttachment(AttachmentId(rowId, uniqueId), inputStream, size) - } - } catch (e: IOException) { - Log.w(TAG, e) - } - } - - @Throws(IOException::class) - private fun calculateVeryOldStreamLength(attachmentSecret: AttachmentSecret, random: ByteArray?, data: String): Long { - var result: Long = 0 - val inputStream: InputStream = if (random != null && random.size == 32) { - ModernDecryptingPartInputStream.createFor(attachmentSecret, random, File(data), 0) - } else { - ClassicDecryptingPartInputStream.createFor(attachmentSecret, File(data)) - } - var read: Int - val buffer = ByteArray(8192) - while (inputStream.read(buffer, 0, buffer.size).also { read = it } != -1) { - result += read.toLong() - } - return result - } - - private fun isForNonExpiringMessage(db: SQLiteDatabase, mmsId: Long): Boolean { - val columns = arrayOf(MmsSmsColumns.EXPIRES_IN) - val where = MmsSmsColumns.ID + " = ?" - val args = arrayOf(mmsId.toString()) - db.query(MmsDatabase.TABLE_NAME, columns, where, args, null, null, null).use { mmsCursor -> - if (mmsCursor != null && mmsCursor.moveToFirst()) { - return mmsCursor.getLong(0) == 0L - } - } - return false - } - - private class BackupFrameOutputStream : Closeable, Flushable { - - private val outputStream: OutputStream - private var cipher: Cipher - private var mac: Mac - private val cipherKey: ByteArray - private val macKey: ByteArray - private val iv: ByteArray - - private var counter: Int = 0 - - constructor(outputStream: OutputStream, passphrase: String) : super() { - try { - val salt = Util.getSecretBytes(32) - val key = BackupUtil.computeBackupKey(passphrase, salt) - val derived = HKDFv3().deriveSecrets(key, "Backup Export".toByteArray(), 64) - val split = ByteUtil.split(derived, 32, 32) - cipherKey = split[0] - macKey = split[1] - cipher = Cipher.getInstance("AES/CTR/NoPadding") - mac = Mac.getInstance("HmacSHA256") - this.outputStream = outputStream - iv = Util.getSecretBytes(16) - counter = Conversions.byteArrayToInt(iv) - mac.init(SecretKeySpec(macKey, "HmacSHA256")) - val header = BackupFrame.newBuilder().setHeader(Header.newBuilder() - .setIv(ByteString.copyFrom(iv)) - .setSalt(ByteString.copyFrom(salt))) - .build().toByteArray() - outputStream.write(Conversions.intToByteArray(header.size)) - outputStream.write(header) - } catch (e: Exception) { - when (e) { - is NoSuchAlgorithmException, - is NoSuchPaddingException, - is InvalidKeyException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - fun writeSql(statement: SqlStatement) { - write(outputStream, BackupFrame.newBuilder().setStatement(statement).build()) - } - - @Throws(IOException::class) - fun writePreferenceEntry(preference: SharedPreference?) { - write(outputStream, BackupFrame.newBuilder().setPreference(preference).build()) - } - - @Throws(IOException::class) - fun writeAvatar(avatarName: String, inputStream: InputStream, size: Long) { - write(outputStream, BackupFrame.newBuilder() - .setAvatar(Avatar.newBuilder() - .setName(avatarName) - .setLength(Util.toIntExact(size)) - .build()) - .build()) - writeStream(inputStream) - } - - @Throws(IOException::class) - fun writeAttachment(attachmentId: AttachmentId, inputStream: InputStream, size: Long) { - write(outputStream, BackupFrame.newBuilder() - .setAttachment(Attachment.newBuilder() - .setRowId(attachmentId.rowId) - .setAttachmentId(attachmentId.uniqueId) - .setLength(Util.toIntExact(size)) - .build()) - .build()) - writeStream(inputStream) - } - - @Throws(IOException::class) - fun writeSticker(rowId: Long, inputStream: InputStream, size: Long) { - write(outputStream, BackupFrame.newBuilder() - .setSticker(Sticker.newBuilder() - .setRowId(rowId) - .setLength(Util.toIntExact(size)) - .build()) - .build()) - writeStream(inputStream) - } - - @Throws(IOException::class) - fun writeDatabaseVersion(version: Int) { - write(outputStream, BackupFrame.newBuilder() - .setVersion(DatabaseVersion.newBuilder().setVersion(version)) - .build()) - } - - @Throws(IOException::class) - fun writeEnd() { - write(outputStream, BackupFrame.newBuilder().setEnd(true).build()) - } - - @Throws(IOException::class) - private fun writeStream(inputStream: InputStream) { - try { - Conversions.intToByteArray(iv, 0, counter++) - cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(cipherKey, "AES"), IvParameterSpec(iv)) - mac.update(iv) - val buffer = ByteArray(8192) - var read: Int - while (inputStream.read(buffer).also { read = it } != -1) { - val ciphertext = cipher.update(buffer, 0, read) - if (ciphertext != null) { - outputStream.write(ciphertext) - mac.update(ciphertext) - } - } - val remainder = cipher.doFinal() - outputStream.write(remainder) - mac.update(remainder) - val attachmentDigest = mac.doFinal() - outputStream.write(attachmentDigest, 0, 10) - } catch (e: Exception) { - when (e) { - is InvalidKeyException, - is InvalidAlgorithmParameterException, - is IllegalBlockSizeException, - is BadPaddingException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - private fun write(out: OutputStream, frame: BackupFrame) { - try { - Conversions.intToByteArray(iv, 0, counter++) - cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(cipherKey, "AES"), IvParameterSpec(iv)) - val frameCiphertext = cipher.doFinal(frame.toByteArray()) - val frameMac = mac.doFinal(frameCiphertext) - val length = Conversions.intToByteArray(frameCiphertext.size + 10) - out.write(length) - out.write(frameCiphertext) - out.write(frameMac, 0, 10) - } catch (e: Exception) { - when (e) { - is InvalidKeyException, - is InvalidAlgorithmParameterException, - is IllegalBlockSizeException, - is BadPaddingException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - override fun flush() { - outputStream.flush() - } - - @Throws(IOException::class) - override fun close() { - outputStream.close() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt deleted file mode 100644 index b40c049bc2..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.kt +++ /dev/null @@ -1,352 +0,0 @@ -package org.thoughtcrime.securesms.backup - -import android.annotation.SuppressLint -import android.content.ContentValues -import android.content.Context -import android.net.Uri -import androidx.annotation.WorkerThread -import net.zetetic.database.sqlcipher.SQLiteDatabase -import org.greenrobot.eventbus.EventBus -import org.session.libsession.avatars.AvatarHelper -import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId -import org.session.libsession.utilities.Address -import org.session.libsession.utilities.Conversions -import org.session.libsession.utilities.Util -import org.session.libsignal.crypto.kdf.HKDFv3 -import org.session.libsignal.utilities.ByteUtil -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.backup.BackupProtos.Attachment -import org.thoughtcrime.securesms.backup.BackupProtos.Avatar -import org.thoughtcrime.securesms.backup.BackupProtos.BackupFrame -import org.thoughtcrime.securesms.backup.BackupProtos.DatabaseVersion -import org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference -import org.thoughtcrime.securesms.backup.BackupProtos.SqlStatement -import org.thoughtcrime.securesms.crypto.AttachmentSecret -import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream -import org.thoughtcrime.securesms.database.AttachmentDatabase -import org.thoughtcrime.securesms.database.GroupReceiptDatabase -import org.thoughtcrime.securesms.database.MmsDatabase -import org.thoughtcrime.securesms.database.MmsSmsColumns -import org.thoughtcrime.securesms.database.SearchDatabase -import org.thoughtcrime.securesms.database.ThreadDatabase -import org.thoughtcrime.securesms.dependencies.DatabaseComponent -import org.thoughtcrime.securesms.util.BackupUtil -import java.io.Closeable -import java.io.File -import java.io.FileOutputStream -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.security.InvalidAlgorithmParameterException -import java.security.InvalidKeyException -import java.security.MessageDigest -import java.security.NoSuchAlgorithmException -import java.util.LinkedList -import java.util.Locale -import javax.crypto.BadPaddingException -import javax.crypto.Cipher -import javax.crypto.IllegalBlockSizeException -import javax.crypto.Mac -import javax.crypto.NoSuchPaddingException -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec - -object FullBackupImporter { - /** - * Because BackupProtos.SharedPreference was made only to serialize string values, - * we use these 3-char prefixes to explicitly cast the values before inserting to a preference file. - */ - const val PREF_PREFIX_TYPE_INT = "i__" - const val PREF_PREFIX_TYPE_BOOLEAN = "b__" - - private val TAG = FullBackupImporter::class.java.simpleName - - @JvmStatic - @WorkerThread - @Throws(IOException::class) - fun importFromUri(context: Context, - attachmentSecret: AttachmentSecret, - db: SQLiteDatabase, - fileUri: Uri, - passphrase: String) { - - val baseInputStream = context.contentResolver.openInputStream(fileUri) - ?: throw IOException("Cannot open an input stream for the file URI: $fileUri") - - var count = 0 - try { - BackupRecordInputStream(baseInputStream, passphrase).use { inputStream -> - db.beginTransaction() - dropAllTables(db) - var frame: BackupFrame - while (!inputStream.readFrame().also { frame = it }.end) { - if (count++ % 100 == 0) EventBus.getDefault().post(BackupEvent.createProgress(count)) - when { - frame.hasVersion() -> processVersion(db, frame.version) - frame.hasStatement() -> processStatement(db, frame.statement) - frame.hasPreference() -> processPreference(context, frame.preference) - frame.hasAttachment() -> processAttachment(context, attachmentSecret, db, frame.attachment, inputStream) - frame.hasAvatar() -> processAvatar(context, frame.avatar, inputStream) - } - } - trimEntriesForExpiredMessages(context, db) - db.setTransactionSuccessful() - } - } finally { - if (db.inTransaction()) { - db.endTransaction() - } - } - EventBus.getDefault().post(BackupEvent.createFinished()) - } - - @Throws(IOException::class) - private fun processVersion(db: SQLiteDatabase, version: DatabaseVersion) { - if (version.version > db.version) { - throw DatabaseDowngradeException(db.version, version.version) - } - db.version = version.version - } - - private fun processStatement(db: SQLiteDatabase, statement: SqlStatement) { - val isForSmsFtsSecretTable = statement.statement.contains(SearchDatabase.SMS_FTS_TABLE_NAME + "_") - val isForMmsFtsSecretTable = statement.statement.contains(SearchDatabase.MMS_FTS_TABLE_NAME + "_") - val isForSqliteSecretTable = statement.statement.toLowerCase(Locale.ENGLISH).startsWith("create table sqlite_") - if (isForSmsFtsSecretTable || isForMmsFtsSecretTable || isForSqliteSecretTable) { - Log.i(TAG, "Ignoring import for statement: " + statement.statement) - return - } - val parameters: MutableList = LinkedList() - for (parameter in statement.parametersList) { - when { - parameter.hasStringParamter() -> parameters.add(parameter.stringParamter) - parameter.hasDoubleParameter() -> parameters.add(parameter.doubleParameter) - parameter.hasIntegerParameter() -> parameters.add(parameter.integerParameter) - parameter.hasBlobParameter() -> parameters.add(parameter.blobParameter.toByteArray()) - parameter.hasNullparameter() -> parameters.add(null) - } - } - if (parameters.size > 0) { - db.execSQL(statement.statement, parameters.toTypedArray()) - } else { - db.execSQL(statement.statement) - } - } - - @Throws(IOException::class) - private fun processAttachment(context: Context, attachmentSecret: AttachmentSecret, - db: SQLiteDatabase, attachment: Attachment, - inputStream: BackupRecordInputStream) { - val partsDirectory = context.getDir(AttachmentDatabase.DIRECTORY, Context.MODE_PRIVATE) - val dataFile = File.createTempFile("part", ".mms", partsDirectory) - val output = ModernEncryptingPartOutputStream.createFor(attachmentSecret, dataFile, false) - inputStream.readAttachmentTo(output.second, attachment.length) - val contentValues = ContentValues() - contentValues.put(AttachmentDatabase.DATA, dataFile.absolutePath) - contentValues.put(AttachmentDatabase.THUMBNAIL, null as String?) - contentValues.put(AttachmentDatabase.DATA_RANDOM, output.first) - db.update(AttachmentDatabase.TABLE_NAME, contentValues, - "${AttachmentDatabase.ROW_ID} = ? AND ${AttachmentDatabase.UNIQUE_ID} = ?", - arrayOf(attachment.rowId.toString(), attachment.attachmentId.toString())) - } - - @Throws(IOException::class) - private fun processAvatar(context: Context, avatar: Avatar, inputStream: BackupRecordInputStream) { - inputStream.readAttachmentTo(FileOutputStream( - AvatarHelper.getAvatarFile(context, Address.fromExternal(context, avatar.name))), avatar.length) - } - - @SuppressLint("ApplySharedPref") - private fun processPreference(context: Context, preference: SharedPreference) { - val preferences = context.getSharedPreferences(preference.file, 0) - val key = preference.key - val value = preference.value - - // See the comment next to PREF_PREFIX_TYPE_* constants. - when { - key.startsWith(PREF_PREFIX_TYPE_INT) -> - preferences.edit().putInt( - key.substring(PREF_PREFIX_TYPE_INT.length), - value.toInt() - ).commit() - key.startsWith(PREF_PREFIX_TYPE_BOOLEAN) -> - preferences.edit().putBoolean( - key.substring(PREF_PREFIX_TYPE_BOOLEAN.length), - value.toBoolean() - ).commit() - else -> - preferences.edit().putString(key, value).commit() - } - } - - private fun dropAllTables(db: SQLiteDatabase) { - db.rawQuery("SELECT name, type FROM sqlite_master", null).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - val name = cursor.getString(0) - val type = cursor.getString(1) - if ("table" == type && !name.startsWith("sqlite_")) { - db.execSQL("DROP TABLE IF EXISTS $name") - } - } - } - } - - private fun trimEntriesForExpiredMessages(context: Context, db: SQLiteDatabase) { - val trimmedCondition = " NOT IN (SELECT ${MmsSmsColumns.ID} FROM ${MmsDatabase.TABLE_NAME})" - db.delete(GroupReceiptDatabase.TABLE_NAME, GroupReceiptDatabase.MMS_ID + trimmedCondition, null) - val columns = arrayOf(AttachmentDatabase.ROW_ID, AttachmentDatabase.UNIQUE_ID) - val where = AttachmentDatabase.MMS_ID + trimmedCondition - db.query(AttachmentDatabase.TABLE_NAME, columns, where, null, null, null, null).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - DatabaseComponent.get(context).attachmentDatabase() - .deleteAttachment(AttachmentId(cursor.getLong(0), cursor.getLong(1))) - } - } - db.query(ThreadDatabase.TABLE_NAME, arrayOf(ThreadDatabase.ID), - ThreadDatabase.EXPIRES_IN + " > 0", null, null, null, null).use { cursor -> - while (cursor != null && cursor.moveToNext()) { - DatabaseComponent.get(context).threadDatabase().update(cursor.getLong(0), false) - } - } - } - - private class BackupRecordInputStream : Closeable { - private val inputStream: InputStream - private val cipher: Cipher - private val mac: Mac - private val cipherKey: ByteArray - private val macKey: ByteArray - private val iv: ByteArray - - private var counter = 0 - - @Throws(IOException::class) - constructor(inputStream: InputStream, passphrase: String) : super() { - try { - this.inputStream = inputStream - val headerLengthBytes = ByteArray(4) - Util.readFully(this.inputStream, headerLengthBytes) - val headerLength = Conversions.byteArrayToInt(headerLengthBytes) - val headerFrame = ByteArray(headerLength) - Util.readFully(this.inputStream, headerFrame) - val frame = BackupFrame.parseFrom(headerFrame) - if (!frame.hasHeader()) { - throw IOException("Backup stream does not start with header!") - } - val header = frame.header - iv = header.iv.toByteArray() - if (iv.size != 16) { - throw IOException("Invalid IV length!") - } - val key = BackupUtil.computeBackupKey(passphrase, if (header.hasSalt()) header.salt.toByteArray() else null) - val derived = HKDFv3().deriveSecrets(key, "Backup Export".toByteArray(), 64) - val split = ByteUtil.split(derived, 32, 32) - cipherKey = split[0] - macKey = split[1] - cipher = Cipher.getInstance("AES/CTR/NoPadding") - mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec(macKey, "HmacSHA256")) - counter = Conversions.byteArrayToInt(iv) - } catch (e: Exception) { - when (e) { - is NoSuchAlgorithmException, - is NoSuchPaddingException, - is InvalidKeyException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - fun readFrame(): BackupFrame { - return readFrame(inputStream) - } - - @Throws(IOException::class) - fun readAttachmentTo(out: OutputStream, length: Int) { - var length = length - try { - Conversions.intToByteArray(iv, 0, counter++) - cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(cipherKey, "AES"), IvParameterSpec(iv)) - mac.update(iv) - val buffer = ByteArray(8192) - while (length > 0) { - val read = inputStream.read(buffer, 0, Math.min(buffer.size, length)) - if (read == -1) throw IOException("File ended early!") - mac.update(buffer, 0, read) - val plaintext = cipher.update(buffer, 0, read) - if (plaintext != null) { - out.write(plaintext, 0, plaintext.size) - } - length -= read - } - val plaintext = cipher.doFinal() - if (plaintext != null) { - out.write(plaintext, 0, plaintext.size) - } - out.close() - val ourMac = ByteUtil.trim(mac.doFinal(), 10) - val theirMac = ByteArray(10) - try { - Util.readFully(inputStream, theirMac) - } catch (e: IOException) { - throw IOException(e) - } - if (!MessageDigest.isEqual(ourMac, theirMac)) { - throw IOException("Bad MAC") - } - } catch (e: Exception) { - when (e) { - is InvalidKeyException, - is InvalidAlgorithmParameterException, - is IllegalBlockSizeException, - is BadPaddingException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - private fun readFrame(`in`: InputStream?): BackupFrame { - return try { - val length = ByteArray(4) - Util.readFully(`in`, length) - val frame = ByteArray(Conversions.byteArrayToInt(length)) - Util.readFully(`in`, frame) - val theirMac = ByteArray(10) - System.arraycopy(frame, frame.size - 10, theirMac, 0, theirMac.size) - mac.update(frame, 0, frame.size - 10) - val ourMac = ByteUtil.trim(mac.doFinal(), 10) - if (!MessageDigest.isEqual(ourMac, theirMac)) { - throw IOException("Bad MAC") - } - Conversions.intToByteArray(iv, 0, counter++) - cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(cipherKey, "AES"), IvParameterSpec(iv)) - val plaintext = cipher.doFinal(frame, 0, frame.size - 10) - BackupFrame.parseFrom(plaintext) - } catch (e: Exception) { - when (e) { - is InvalidKeyException, - is InvalidAlgorithmParameterException, - is IllegalBlockSizeException, - is BadPaddingException -> { - throw AssertionError(e) - } - else -> throw e - } - } - } - - @Throws(IOException::class) - override fun close() { - inputStream.close() - } - } - - class DatabaseDowngradeException internal constructor(currentVersion: Int, backupVersion: Int) : - IOException("Tried to import a backup with version $backupVersion into a database with version $currentVersion") -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java index 5e84d5e23a..ddef0200e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java @@ -1,21 +1,7 @@ package org.thoughtcrime.securesms.database; -import android.content.ContentValues; import android.content.Context; -import android.database.Cursor; -import androidx.annotation.NonNull; - -import net.zetetic.database.sqlcipher.SQLiteDatabase; - import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; -import org.thoughtcrime.securesms.jobmanager.persistence.ConstraintSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.DependencySpec; -import org.thoughtcrime.securesms.jobmanager.persistence.FullSpec; -import org.thoughtcrime.securesms.jobmanager.persistence.JobSpec; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; public class JobDatabase extends Database { @@ -23,8 +9,6 @@ public class JobDatabase extends Database { Constraints.CREATE_TABLE, Dependencies.CREATE_TABLE }; - private static final ArrayList runningJobs = new ArrayList<>(); - public static final class Jobs { public static final String TABLE_NAME = "job_spec"; private static final String ID = "_id"; @@ -84,166 +68,4 @@ public class JobDatabase extends Database { public JobDatabase(Context context, SQLCipherOpenHelper databaseHelper) { super(context, databaseHelper); } - - public synchronized void insertJobs(@NonNull List fullSpecs) { - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - - db.beginTransaction(); - - try { - for (FullSpec fullSpec : fullSpecs) { - insertJobSpec(db, fullSpec.getJobSpec()); - insertConstraintSpecs(db, fullSpec.getConstraintSpecs()); - insertDependencySpecs(db, fullSpec.getDependencySpecs()); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - } - - public synchronized @NonNull List getAllJobSpecs() { - List jobs = new LinkedList<>(); - - try (Cursor cursor = databaseHelper.getReadableDatabase().query(Jobs.TABLE_NAME, null, null, null, null, null, Jobs.CREATE_TIME + ", " + Jobs.ID + " ASC")) { - while (cursor != null && cursor.moveToNext()) { - jobs.add(jobSpecFromCursor(cursor)); - } - } - - return jobs; - } - - public synchronized void updateJobRunningState(@NonNull String id, boolean isRunning) { - if (!isRunning) { - JobDatabase.runningJobs.remove(id); - } else if (!JobDatabase.runningJobs.contains(id)) { - JobDatabase.runningJobs.add(id); - } - } - - public synchronized void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime) { - updateJobRunningState(id, isRunning); - - ContentValues contentValues = new ContentValues(); - contentValues.put(Jobs.RUN_ATTEMPT, runAttempt); - contentValues.put(Jobs.NEXT_RUN_ATTEMPT_TIME, nextRunAttemptTime); - - String query = Jobs.JOB_SPEC_ID + " = ?"; - String[] args = new String[]{ id }; - - databaseHelper.getWritableDatabase().update(Jobs.TABLE_NAME, contentValues, query, args); - } - - public synchronized void updateAllJobsToBePending() { - JobDatabase.runningJobs.clear(); - } - - public synchronized void deleteJobs(@NonNull List jobIds) { - SQLiteDatabase db = databaseHelper.getWritableDatabase(); - - db.beginTransaction(); - - try { - for (String jobId : jobIds) { - String[] arg = new String[]{jobId}; - - db.delete(Jobs.TABLE_NAME, Jobs.JOB_SPEC_ID + " = ?", arg); - db.delete(Constraints.TABLE_NAME, Constraints.JOB_SPEC_ID + " = ?", arg); - db.delete(Dependencies.TABLE_NAME, Dependencies.JOB_SPEC_ID + " = ?", arg); - db.delete(Dependencies.TABLE_NAME, Dependencies.DEPENDS_ON_JOB_SPEC_ID + " = ?", arg); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - } - - public synchronized @NonNull List getAllConstraintSpecs() { - List constraints = new LinkedList<>(); - - try (Cursor cursor = databaseHelper.getReadableDatabase().query(Constraints.TABLE_NAME, null, null, null, null, null, null)) { - while (cursor != null && cursor.moveToNext()) { - constraints.add(constraintSpecFromCursor(cursor)); - } - } - - return constraints; - } - - public synchronized @NonNull List getAllDependencySpecs() { - List dependencies = new LinkedList<>(); - - try (Cursor cursor = databaseHelper.getReadableDatabase().query(Dependencies.TABLE_NAME, null, null, null, null, null, null)) { - while (cursor != null && cursor.moveToNext()) { - dependencies.add(dependencySpecFromCursor(cursor)); - } - } - - return dependencies; - } - - private void insertJobSpec(@NonNull SQLiteDatabase db, @NonNull JobSpec job) { - ContentValues contentValues = new ContentValues(); - contentValues.put(Jobs.JOB_SPEC_ID, job.getId()); - contentValues.put(Jobs.FACTORY_KEY, job.getFactoryKey()); - contentValues.put(Jobs.QUEUE_KEY, job.getQueueKey()); - contentValues.put(Jobs.CREATE_TIME, job.getCreateTime()); - contentValues.put(Jobs.NEXT_RUN_ATTEMPT_TIME, job.getNextRunAttemptTime()); - contentValues.put(Jobs.RUN_ATTEMPT, job.getRunAttempt()); - contentValues.put(Jobs.MAX_ATTEMPTS, job.getMaxAttempts()); - contentValues.put(Jobs.MAX_BACKOFF, job.getMaxBackoff()); - contentValues.put(Jobs.MAX_INSTANCES, job.getMaxInstances()); - contentValues.put(Jobs.LIFESPAN, job.getLifespan()); - contentValues.put(Jobs.SERIALIZED_DATA, job.getSerializedData()); - updateJobRunningState(job.getId(), job.isRunning()); - - db.insertWithOnConflict(Jobs.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE); - } - - private void insertConstraintSpecs(@NonNull SQLiteDatabase db, @NonNull List constraints) { - for (ConstraintSpec constraintSpec : constraints) { - ContentValues contentValues = new ContentValues(); - contentValues.put(Constraints.JOB_SPEC_ID, constraintSpec.getJobSpecId()); - contentValues.put(Constraints.FACTORY_KEY, constraintSpec.getFactoryKey()); - db.insertWithOnConflict(Constraints.TABLE_NAME, null ,contentValues, SQLiteDatabase.CONFLICT_IGNORE); - } - } - - private void insertDependencySpecs(@NonNull SQLiteDatabase db, @NonNull List dependencies) { - for (DependencySpec dependencySpec : dependencies) { - ContentValues contentValues = new ContentValues(); - contentValues.put(Dependencies.JOB_SPEC_ID, dependencySpec.getJobId()); - contentValues.put(Dependencies.DEPENDS_ON_JOB_SPEC_ID, dependencySpec.getDependsOnJobId()); - db.insertWithOnConflict(Dependencies.TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_IGNORE); - } - } - - private @NonNull JobSpec jobSpecFromCursor(@NonNull Cursor cursor) { - String jobId = cursor.getString(cursor.getColumnIndexOrThrow(Jobs.JOB_SPEC_ID)); - return new JobSpec(jobId, - cursor.getString(cursor.getColumnIndexOrThrow(Jobs.FACTORY_KEY)), - cursor.getString(cursor.getColumnIndexOrThrow(Jobs.QUEUE_KEY)), - cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.CREATE_TIME)), - cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.NEXT_RUN_ATTEMPT_TIME)), - cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.RUN_ATTEMPT)), - cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.MAX_ATTEMPTS)), - cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.MAX_BACKOFF)), - cursor.getLong(cursor.getColumnIndexOrThrow(Jobs.LIFESPAN)), - cursor.getInt(cursor.getColumnIndexOrThrow(Jobs.MAX_INSTANCES)), - cursor.getString(cursor.getColumnIndexOrThrow(Jobs.SERIALIZED_DATA)), - JobDatabase.runningJobs.contains(jobId)); - } - - private @NonNull ConstraintSpec constraintSpecFromCursor(@NonNull Cursor cursor) { - return new ConstraintSpec(cursor.getString(cursor.getColumnIndexOrThrow(Constraints.JOB_SPEC_ID)), - cursor.getString(cursor.getColumnIndexOrThrow(Constraints.FACTORY_KEY))); - } - - private @NonNull DependencySpec dependencySpecFromCursor(@NonNull Cursor cursor) { - return new DependencySpec(cursor.getString(cursor.getColumnIndexOrThrow(Dependencies.JOB_SPEC_ID)), - cursor.getString(cursor.getColumnIndexOrThrow(Dependencies.DEPENDS_ON_JOB_SPEC_ID))); - } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt index 648b9c43ec..60d31a19d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseComponent.kt @@ -32,7 +32,6 @@ interface DatabaseComponent { fun recipientDatabase(): RecipientDatabase fun groupReceiptDatabase(): GroupReceiptDatabase fun searchDatabase(): SearchDatabase - fun jobDatabase(): JobDatabase fun lokiAPIDatabase(): LokiAPIDatabase fun lokiMessageDatabase(): LokiMessageDatabase fun lokiThreadDatabase(): LokiThreadDatabase diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt index fba7a7e503..3372e10330 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/DatabaseModule.kt @@ -86,10 +86,6 @@ object DatabaseModule { @Singleton fun searchDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = SearchDatabase(context,openHelper) - @Provides - @Singleton - fun provideJobDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = JobDatabase(context, openHelper) - @Provides @Singleton fun provideLokiApiDatabase(@ApplicationContext context: Context, openHelper: SQLCipherOpenHelper) = LokiAPIDatabase(context,openHelper) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ExecutorFactory.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ExecutorFactory.java deleted file mode 100644 index b0c2b974de..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/ExecutorFactory.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager; - -import androidx.annotation.NonNull; - -import java.util.concurrent.ExecutorService; - -public interface ExecutorFactory { - @NonNull ExecutorService newSingleThreadExecutor(@NonNull String name); -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/DefaultExecutorFactory.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/DefaultExecutorFactory.java deleted file mode 100644 index a9d4591009..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/impl/DefaultExecutorFactory.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.impl; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.ExecutorFactory; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class DefaultExecutorFactory implements ExecutorFactory { - @Override - public @NonNull ExecutorService newSingleThreadExecutor(@NonNull String name) { - return Executors.newSingleThreadExecutor(r -> new Thread(r, name)); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/ConstraintSpec.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/ConstraintSpec.java deleted file mode 100644 index 1dab10ae56..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/ConstraintSpec.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.persistence; - -import androidx.annotation.NonNull; - -import java.util.Objects; - -public final class ConstraintSpec { - - private final String jobSpecId; - private final String factoryKey; - - public ConstraintSpec(@NonNull String jobSpecId, @NonNull String factoryKey) { - this.jobSpecId = jobSpecId; - this.factoryKey = factoryKey; - } - - public String getJobSpecId() { - return jobSpecId; - } - - public String getFactoryKey() { - return factoryKey; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ConstraintSpec that = (ConstraintSpec) o; - return Objects.equals(jobSpecId, that.jobSpecId) && - Objects.equals(factoryKey, that.factoryKey); - } - - @Override - public int hashCode() { - return Objects.hash(jobSpecId, factoryKey); - } - - @Override - public @NonNull String toString() { - return String.format("jobSpecId: %s | factoryKey: %s", jobSpecId, factoryKey); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/DependencySpec.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/DependencySpec.java deleted file mode 100644 index 2faea0485b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/DependencySpec.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.persistence; - -import androidx.annotation.NonNull; - -import java.util.Objects; - -public final class DependencySpec { - - private final String jobId; - private final String dependsOnJobId; - - public DependencySpec(@NonNull String jobId, @NonNull String dependsOnJobId) { - this.jobId = jobId; - this.dependsOnJobId = dependsOnJobId; - } - - public @NonNull String getJobId() { - return jobId; - } - - public @NonNull String getDependsOnJobId() { - return dependsOnJobId; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - DependencySpec that = (DependencySpec) o; - return Objects.equals(jobId, that.jobId) && - Objects.equals(dependsOnJobId, that.dependsOnJobId); - } - - @Override - public int hashCode() { - return Objects.hash(jobId, dependsOnJobId); - } - - @Override - public @NonNull String toString() { - return String.format("jobSpecId: %s | dependsOnJobSpecId: %s", jobId, dependsOnJobId); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/FullSpec.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/FullSpec.java deleted file mode 100644 index f93c0e64bd..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/FullSpec.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.persistence; - -import androidx.annotation.NonNull; - -import java.util.List; -import java.util.Objects; - -public final class FullSpec { - - private final JobSpec jobSpec; - private final List constraintSpecs; - private final List dependencySpecs; - - public FullSpec(@NonNull JobSpec jobSpec, - @NonNull List constraintSpecs, - @NonNull List dependencySpecs) - { - this.jobSpec = jobSpec; - this.constraintSpecs = constraintSpecs; - this.dependencySpecs = dependencySpecs; - } - - public @NonNull JobSpec getJobSpec() { - return jobSpec; - } - - public @NonNull List getConstraintSpecs() { - return constraintSpecs; - } - - public @NonNull List getDependencySpecs() { - return dependencySpecs; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - FullSpec fullSpec = (FullSpec) o; - return Objects.equals(jobSpec, fullSpec.jobSpec) && - Objects.equals(constraintSpecs, fullSpec.constraintSpecs) && - Objects.equals(dependencySpecs, fullSpec.dependencySpecs); - } - - @Override - public int hashCode() { - return Objects.hash(jobSpec, constraintSpecs, dependencySpecs); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobSpec.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobSpec.java deleted file mode 100644 index d5f5cd5b3e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobSpec.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.persistence; - -import android.annotation.SuppressLint; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.Objects; - -public final class JobSpec { - - private final String id; - private final String factoryKey; - private final String queueKey; - private final long createTime; - private final long nextRunAttemptTime; - private final int runAttempt; - private final int maxAttempts; - private final long maxBackoff; - private final long lifespan; - private final int maxInstances; - private final String serializedData; - private final boolean isRunning; - - public JobSpec(@NonNull String id, - @NonNull String factoryKey, - @Nullable String queueKey, - long createTime, - long nextRunAttemptTime, - int runAttempt, - int maxAttempts, - long maxBackoff, - long lifespan, - int maxInstances, - @NonNull String serializedData, - boolean isRunning) - { - this.id = id; - this.factoryKey = factoryKey; - this.queueKey = queueKey; - this.createTime = createTime; - this.nextRunAttemptTime = nextRunAttemptTime; - this.maxBackoff = maxBackoff; - this.runAttempt = runAttempt; - this.maxAttempts = maxAttempts; - this.lifespan = lifespan; - this.maxInstances = maxInstances; - this.serializedData = serializedData; - this.isRunning = isRunning; - } - - public @NonNull String getId() { - return id; - } - - public @NonNull String getFactoryKey() { - return factoryKey; - } - - public @Nullable String getQueueKey() { - return queueKey; - } - - public long getCreateTime() { - return createTime; - } - - public long getNextRunAttemptTime() { - return nextRunAttemptTime; - } - - public int getRunAttempt() { - return runAttempt; - } - - public int getMaxAttempts() { - return maxAttempts; - } - - public long getMaxBackoff() { - return maxBackoff; - } - - public int getMaxInstances() { - return maxInstances; - } - - public long getLifespan() { - return lifespan; - } - - public @NonNull String getSerializedData() { - return serializedData; - } - - public boolean isRunning() { - return isRunning; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - JobSpec jobSpec = (JobSpec) o; - return createTime == jobSpec.createTime && - nextRunAttemptTime == jobSpec.nextRunAttemptTime && - runAttempt == jobSpec.runAttempt && - maxAttempts == jobSpec.maxAttempts && - maxBackoff == jobSpec.maxBackoff && - lifespan == jobSpec.lifespan && - maxInstances == jobSpec.maxInstances && - isRunning == jobSpec.isRunning && - Objects.equals(id, jobSpec.id) && - Objects.equals(factoryKey, jobSpec.factoryKey) && - Objects.equals(queueKey, jobSpec.queueKey) && - Objects.equals(serializedData, jobSpec.serializedData); - } - - @Override - public int hashCode() { - return Objects.hash(id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, lifespan, maxInstances, serializedData, isRunning); - } - - @SuppressLint("DefaultLocale") - @Override - public @NonNull String toString() { - return String.format("id: %s | factoryKey: %s | queueKey: %s | createTime: %d | nextRunAttemptTime: %d | runAttempt: %d | maxAttempts: %d | maxBackoff: %d | maxInstances: %d | lifespan: %d | isRunning: %b | data: %s", - id, factoryKey, queueKey, createTime, nextRunAttemptTime, runAttempt, maxAttempts, maxBackoff, maxInstances, lifespan, isRunning, serializedData); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobStorage.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobStorage.java deleted file mode 100644 index b7c035ac60..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/persistence/JobStorage.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.thoughtcrime.securesms.jobmanager.persistence; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.WorkerThread; - -import java.util.List; - -public interface JobStorage { - - @WorkerThread - void init(); - - @WorkerThread - void insertJobs(@NonNull List fullSpecs); - - @WorkerThread - @Nullable JobSpec getJobSpec(@NonNull String id); - - @WorkerThread - @NonNull List getAllJobSpecs(); - - @WorkerThread - @NonNull List getPendingJobsWithNoDependenciesInCreatedOrder(long currentTime); - - @WorkerThread - int getJobInstanceCount(@NonNull String factoryKey); - - @WorkerThread - void updateJobRunningState(@NonNull String id, boolean isRunning); - - @WorkerThread - void updateJobAfterRetry(@NonNull String id, boolean isRunning, int runAttempt, long nextRunAttemptTime); - - @WorkerThread - void updateAllJobsToBePending(); - - @WorkerThread - void deleteJob(@NonNull String id); - - @WorkerThread - void deleteJobs(@NonNull List ids); - - @WorkerThread - @NonNull List getConstraintSpecs(@NonNull String jobId); - - @WorkerThread - @NonNull List getAllConstraintSpecs(); - - @WorkerThread - @NonNull List getDependencySpecsThatDependOnJob(@NonNull String jobSpecId); - - @WorkerThread - @NonNull List getAllDependencySpecs(); -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt deleted file mode 100644 index 8a71760df3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/LocalBackupJob.kt +++ /dev/null @@ -1,61 +0,0 @@ -package org.thoughtcrime.securesms.jobs - -import android.content.Context -import org.session.libsession.messaging.jobs.Job -import org.session.libsession.messaging.jobs.JobDelegate -import org.session.libsession.messaging.utilities.Data -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.notifications.NotificationChannels -import org.thoughtcrime.securesms.service.GenericForegroundService -import org.thoughtcrime.securesms.util.BackupUtil.createBackupFile -import org.thoughtcrime.securesms.util.BackupUtil.deleteAllBackupFiles - -import network.loki.messenger.R - - -class LocalBackupJob:Job { - override var delegate: JobDelegate? = null - override var id: String? = null - override var failureCount: Int = 0 - override val maxFailureCount: Int = 0 - - lateinit var context: Context - - companion object { - val TAG = LocalBackupJob::class.simpleName - val KEY: String = "LocalBackupJob" - } - - override fun execute(dispatcherName: String) { - Log.i(TAG, "Executing backup job...") - - GenericForegroundService.startForegroundTask( - context, - context.getString(R.string.LocalBackupJob_creating_backup), - NotificationChannels.BACKUPS, - R.drawable.ic_launcher_foreground - ) - - // TODO: Maybe create a new backup icon like ic_signal_backup? - try { - val record = createBackupFile(context) - deleteAllBackupFiles(context, listOf(record)) - } finally { - GenericForegroundService.stopForegroundTask(context) - } - } - - override fun serialize(): Data { - return Data.EMPTY - } - - override fun getFactoryKey(): String { - return KEY - } - - class Factory: Job.Factory { - override fun create(data: Data): LocalBackupJob { - return LocalBackupJob() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt deleted file mode 100644 index 411f01fcde..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/UpdateApkJob.kt +++ /dev/null @@ -1,200 +0,0 @@ -package org.thoughtcrime.securesms.jobs - -import androidx.annotation.Nullable - -import android.app.DownloadManager -import android.content.Context -import android.content.Intent -import android.content.pm.PackageInfo -import android.content.pm.PackageManager -import android.net.Uri -import com.fasterxml.jackson.annotation.JsonProperty -import network.loki.messenger.BuildConfig -import okhttp3.OkHttpClient -import okhttp3.Request -import org.session.libsession.messaging.jobs.Job -import org.session.libsession.messaging.jobs.JobDelegate -import org.session.libsession.messaging.utilities.Data -import org.session.libsession.utilities.FileUtils -import org.session.libsession.utilities.TextSecurePreferences.Companion.getUpdateApkDigest -import org.session.libsession.utilities.TextSecurePreferences.Companion.getUpdateApkDownloadId -import org.session.libsession.utilities.TextSecurePreferences.Companion.setUpdateApkDigest -import org.session.libsession.utilities.TextSecurePreferences.Companion.setUpdateApkDownloadId -import org.session.libsignal.utilities.Hex -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.service.UpdateApkReadyListener -import java.io.FileInputStream -import java.io.IOException -import java.security.MessageDigest - -class UpdateApkJob: Job { - override var delegate: JobDelegate? = null - override var id: String? = null - override var failureCount: Int = 0 - override val maxFailureCount: Int = 0 - - lateinit var context: Context - - companion object { - val TAG = UpdateApkJob::class.simpleName - val KEY: String = "UpdateApkJob" - } - - override fun execute(dispatcherName: String) { - if (!BuildConfig.PLAY_STORE_DISABLED) return - - Log.i(TAG, "Checking for APK update...") - - val client = OkHttpClient() - val request = Request.Builder().url(String.format("%s/latest.json", BuildConfig.NOPLAY_UPDATE_URL)).build() - val response = client.newCall(request).execute() - - if (!response.isSuccessful) { - throw IOException("Bad response: " + response.message()) - } - - val updateDescriptor: UpdateDescriptor = JsonUtil.fromJson( - response.body()!!.string(), - UpdateDescriptor::class.java - ) - val digest = Hex.fromStringCondensed(updateDescriptor.digest) - - Log.i( - TAG, - "Got descriptor: $updateDescriptor" - ) - - if (updateDescriptor.versionCode > getVersionCode()) { - val downloadStatus: DownloadStatus = getDownloadStatus(updateDescriptor.url, digest) - Log.i(TAG, "Download status: " + downloadStatus.status) - if (downloadStatus.status == DownloadStatus.Status.COMPLETE) { - Log.i(TAG, "Download status complete, notifying...") - handleDownloadNotify(downloadStatus.downloadId) - } else if (downloadStatus.status == DownloadStatus.Status.MISSING) { - Log.i(TAG, "Download status missing, starting download...") - handleDownloadStart( - updateDescriptor.url, - updateDescriptor.versionName, - digest - ) - } - } - } - - @Throws(PackageManager.NameNotFoundException::class) - private fun getVersionCode(): Int { - val packageManager: PackageManager = context.getPackageManager() - val packageInfo: PackageInfo = packageManager.getPackageInfo(context.getPackageName(), 0) - return packageInfo.versionCode - } - - private fun getDownloadStatus(uri: String, theirDigest: ByteArray): DownloadStatus { - val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager - val query = DownloadManager.Query() - query.setFilterByStatus(DownloadManager.STATUS_PAUSED or DownloadManager.STATUS_PENDING or DownloadManager.STATUS_RUNNING or DownloadManager.STATUS_SUCCESSFUL) - val pendingDownloadId = getUpdateApkDownloadId(context) - val pendingDigest = getPendingDigest(context) - val cursor = downloadManager.query(query) - return try { - var status = DownloadStatus(DownloadStatus.Status.MISSING, -1) - while (cursor != null && cursor.moveToNext()) { - val jobStatus = - cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS)) - val jobRemoteUri = - cursor.getString(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_URI)) - val downloadId = - cursor.getLong(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID)) - val digest = getDigestForDownloadId(downloadId) - if (jobRemoteUri != null && jobRemoteUri == uri && downloadId == pendingDownloadId) { - if (jobStatus == DownloadManager.STATUS_SUCCESSFUL && digest != null && pendingDigest != null && - MessageDigest.isEqual(pendingDigest, theirDigest) && - MessageDigest.isEqual(digest, theirDigest) - ) { - return DownloadStatus(DownloadStatus.Status.COMPLETE, downloadId) - } else if (jobStatus != DownloadManager.STATUS_SUCCESSFUL) { - status = DownloadStatus(DownloadStatus.Status.PENDING, downloadId) - } - } - } - status - } finally { - cursor?.close() - } - } - - private fun handleDownloadStart(uri: String, versionName: String, digest: ByteArray) { - val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager - val downloadRequest = DownloadManager.Request(Uri.parse(uri)) - downloadRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI) - downloadRequest.setTitle("Downloading Signal update") - downloadRequest.setDescription("Downloading Signal $versionName") - downloadRequest.setVisibleInDownloadsUi(false) - downloadRequest.setDestinationInExternalFilesDir(context, null, "signal-update.apk") - downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN) - val downloadId = downloadManager.enqueue(downloadRequest) - setUpdateApkDownloadId(context, downloadId) - setUpdateApkDigest(context, Hex.toStringCondensed(digest)) - } - - private fun handleDownloadNotify(downloadId: Long) { - val intent = Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE) - intent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId) - UpdateApkReadyListener().onReceive(context, intent) - } - - private fun getDigestForDownloadId(downloadId: Long): ByteArray? { - return try { - val downloadManager = - context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager - val fin = FileInputStream(downloadManager.openDownloadedFile(downloadId).fileDescriptor) - val digest = FileUtils.getFileDigest(fin) - fin.close() - digest - } catch (e: IOException) { - Log.w(TAG, e) - null - } - } - - private fun getPendingDigest(context: Context): ByteArray? { - return try { - val encodedDigest = getUpdateApkDigest(context) ?: return null - Hex.fromStringCondensed(encodedDigest) - } catch (e: IOException) { - Log.w(TAG, e) - null - } - } - - override fun serialize(): Data { - return Data.EMPTY - } - - override fun getFactoryKey(): String { - return KEY - } - - private class UpdateDescriptor( - @JsonProperty("versionCode") @Nullable val versionCode: Int, - @JsonProperty("versionName") @Nullable val versionName: String, - @JsonProperty("url") @Nullable val url: String, - @JsonProperty("sha256sum") @Nullable val digest: String) - { - override fun toString(): String { - return "[$versionCode, $versionName, $url]" - } - } - - private class DownloadStatus(val status: Status, val downloadId: Long) { - enum class Status { - PENDING, COMPLETE, MISSING - } - } - - class Factory: Job.Factory { - override fun create(data: Data): UpdateApkJob { - return UpdateApkJob() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java deleted file mode 100644 index 9cf88f4094..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/LocalBackupListener.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.thoughtcrime.securesms.service; - -import android.content.Context; -import android.content.Intent; - -import org.session.libsession.messaging.jobs.JobQueue; -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobs.LocalBackupJob; -import org.session.libsession.utilities.TextSecurePreferences; - -import java.util.concurrent.TimeUnit; - -public class LocalBackupListener extends PersistentAlarmManagerListener { - - private static final long INTERVAL = TimeUnit.DAYS.toMillis(1); - - @Override - protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getNextBackupTime(context); - } - - @Override - protected long onAlarm(Context context, long scheduledTime) { - if (TextSecurePreferences.isBackupEnabled(context)) { - LocalBackupJob job = new LocalBackupJob(); - job.context = context; - JobQueue.getShared().add(job); - } - - long nextTime = System.currentTimeMillis() + INTERVAL; - TextSecurePreferences.setNextBackupTime(context, nextTime); - - return nextTime; - } - - public static void schedule(Context context) { - if (TextSecurePreferences.isBackupEnabled(context)) { - new LocalBackupListener().onReceive(context, new Intent()); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java deleted file mode 100644 index 01ade94214..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/UpdateApkRefreshListener.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.thoughtcrime.securesms.service; - - -import android.content.Context; -import android.content.Intent; - -import org.session.libsession.messaging.jobs.JobQueue; -import org.session.libsignal.utilities.Log; - -import org.thoughtcrime.securesms.ApplicationContext; -import network.loki.messenger.BuildConfig; -import org.thoughtcrime.securesms.jobs.UpdateApkJob; -import org.session.libsession.utilities.TextSecurePreferences; - -import java.util.concurrent.TimeUnit; - -public class UpdateApkRefreshListener extends PersistentAlarmManagerListener { - - private static final String TAG = UpdateApkRefreshListener.class.getSimpleName(); - - private static final long INTERVAL = TimeUnit.HOURS.toMillis(6); - - @Override - protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getUpdateApkRefreshTime(context); - } - - @Override - protected long onAlarm(Context context, long scheduledTime) { - Log.i(TAG, "onAlarm..."); - - if (scheduledTime != 0 && BuildConfig.PLAY_STORE_DISABLED) { - Log.i(TAG, "Queueing APK update job..."); - UpdateApkJob job = new UpdateApkJob(); - job.context = context; - JobQueue.getShared().add(job); - } - - long newTime = System.currentTimeMillis() + INTERVAL; - TextSecurePreferences.setUpdateApkRefreshTime(context, newTime); - - return newTime; - } - - public static void schedule(Context context) { - new UpdateApkRefreshListener().onReceive(context, new Intent()); - } - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt deleted file mode 100644 index 074278cb92..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/util/BackupUtil.kt +++ /dev/null @@ -1,313 +0,0 @@ -package org.thoughtcrime.securesms.util - -import android.app.Activity -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Build -import android.os.Environment -import android.provider.DocumentsContract -import android.widget.Toast -import androidx.annotation.WorkerThread -import androidx.documentfile.provider.DocumentFile -import androidx.fragment.app.Fragment -import network.loki.messenger.R -import org.greenrobot.eventbus.EventBus -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.utilities.ByteUtil -import org.session.libsignal.utilities.Log -import org.thoughtcrime.securesms.backup.BackupEvent -import org.thoughtcrime.securesms.backup.BackupPassphrase -import org.thoughtcrime.securesms.backup.BackupProtos.SharedPreference -import org.thoughtcrime.securesms.backup.FullBackupExporter -import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.database.BackupFileRecord -import org.thoughtcrime.securesms.dependencies.DatabaseComponent -import java.io.IOException -import java.security.MessageDigest -import java.security.NoSuchAlgorithmException -import java.security.SecureRandom -import java.text.SimpleDateFormat -import java.util.* - -object BackupUtil { - private const val MASTER_SECRET_UTIL_PREFERENCES_NAME = "SecureSMS-Preferences" - private const val TAG = "BackupUtil" - const val BACKUP_FILE_MIME_TYPE = "application/session-backup" - const val BACKUP_PASSPHRASE_LENGTH = 30 - - fun getBackupRecords(context: Context): List { - val prefName = MASTER_SECRET_UTIL_PREFERENCES_NAME - val preferences = context.getSharedPreferences(prefName, 0) - val prefList = LinkedList() - prefList.add(SharedPreference.newBuilder() - .setFile(prefName) - .setKey(IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF) - .setValue(preferences.getString(IdentityKeyUtil.IDENTITY_PUBLIC_KEY_PREF, null)) - .build()) - prefList.add(SharedPreference.newBuilder() - .setFile(prefName) - .setKey(IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF) - .setValue(preferences.getString(IdentityKeyUtil.IDENTITY_PRIVATE_KEY_PREF, null)) - .build()) - if (preferences.contains(IdentityKeyUtil.ED25519_PUBLIC_KEY)) { - prefList.add(SharedPreference.newBuilder() - .setFile(prefName) - .setKey(IdentityKeyUtil.ED25519_PUBLIC_KEY) - .setValue(preferences.getString(IdentityKeyUtil.ED25519_PUBLIC_KEY, null)) - .build()) - } - if (preferences.contains(IdentityKeyUtil.ED25519_SECRET_KEY)) { - prefList.add(SharedPreference.newBuilder() - .setFile(prefName) - .setKey(IdentityKeyUtil.ED25519_SECRET_KEY) - .setValue(preferences.getString(IdentityKeyUtil.ED25519_SECRET_KEY, null)) - .build()) - } - prefList.add(SharedPreference.newBuilder() - .setFile(prefName) - .setKey(IdentityKeyUtil.LOKI_SEED) - .setValue(preferences.getString(IdentityKeyUtil.LOKI_SEED, null)) - .build()) - return prefList - } - - @JvmStatic - fun getLastBackupTimeString(context: Context, locale: Locale): String { - val timestamp = DatabaseComponent.get(context).lokiBackupFilesDatabase().getLastBackupFileTime() - if (timestamp == null) { - return context.getString(R.string.BackupUtil_never) - } - return DateUtils.getDisplayFormattedTimeSpanString(context, locale, timestamp.time) - } - - @JvmStatic - fun getLastBackup(context: Context): BackupFileRecord? { - return DatabaseComponent.get(context).lokiBackupFilesDatabase().getLastBackupFile() - } - - @JvmStatic - fun generateBackupPassphrase(): Array { - val random = ByteArray(BACKUP_PASSPHRASE_LENGTH).also { SecureRandom().nextBytes(it) } - return Array(6) { i -> - String.format("%05d", ByteUtil.byteArray5ToLong(random, i * 5) % 100000) - } - } - - @JvmStatic - fun validateDirAccess(context: Context, dirUri: Uri): Boolean { - val hasWritePermission = context.contentResolver.persistedUriPermissions.any { - it.isWritePermission && it.uri == dirUri - } - if (!hasWritePermission) return false - - val document = DocumentFile.fromTreeUri(context, dirUri) - if (document == null || !document.exists()) { - return false - } - - return true - } - - @JvmStatic - fun getBackupDirUri(context: Context): Uri? { - val dirUriString = TextSecurePreferences.getBackupSaveDir(context) ?: return null - return Uri.parse(dirUriString) - } - - @JvmStatic - fun setBackupDirUri(context: Context, uriString: String?) { - TextSecurePreferences.setBackupSaveDir(context, uriString) - } - - /** - * @return The selected backup directory if it's valid (exists, is writable). - */ - @JvmStatic - fun getSelectedBackupDirIfValid(context: Context): Uri? { - val dirUri = getBackupDirUri(context) - - if (dirUri == null) { - Log.v(TAG, "The backup dir wasn't selected yet.") - return null - } - if (!validateDirAccess(context, dirUri)) { - Log.v(TAG, "Cannot validate the access to the dir $dirUri.") - return null - } - - return dirUri; - } - - @JvmStatic - @WorkerThread - @Throws(IOException::class) - fun createBackupFile(context: Context): BackupFileRecord { - val backupPassword = BackupPassphrase.get(context) - ?: throw IOException("Backup password is null") - - val dirUri = getSelectedBackupDirIfValid(context) - ?: throw IOException("Backup save directory is not selected or invalid") - - val date = Date() - val timestamp = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US).format(date) - val fileName = String.format("session-%s.backup", timestamp) - - val fileUri = DocumentsContract.createDocument( - context.contentResolver, - DocumentFile.fromTreeUri(context, dirUri)!!.uri, - BACKUP_FILE_MIME_TYPE, - fileName) - - if (fileUri == null) { - Toast.makeText(context, "Cannot create writable file in the dir $dirUri", Toast.LENGTH_LONG).show() - throw IOException("Cannot create writable file in the dir $dirUri") - } - - try { - FullBackupExporter.export(context, - AttachmentSecretProvider.getInstance(context).orCreateAttachmentSecret, - DatabaseComponent.get(context).openHelper().readableDatabase, - fileUri, - backupPassword) - } catch (e: Exception) { - // Delete the backup file on any error. - DocumentsContract.deleteDocument(context.contentResolver, fileUri) - throw e - } - - //TODO Use real file size. - val record = DatabaseComponent.get(context).lokiBackupFilesDatabase() - .insertBackupFile(BackupFileRecord(fileUri, -1, date)) - - Log.v(TAG, "A backup file was created: $fileUri") - - return record - } - - @JvmStatic - @JvmOverloads - fun deleteAllBackupFiles(context: Context, except: Collection? = null) { - val db = DatabaseComponent.get(context).lokiBackupFilesDatabase() - db.getBackupFiles().iterator().forEach { record -> - if (except != null && except.contains(record)) return@forEach - - // Try to delete the related file. The operation may fail in many cases - // (the user moved/deleted the file, revoked the write permission, etc), so that's OK. - try { - val result = DocumentsContract.deleteDocument(context.contentResolver, record.uri) - if (!result) { - Log.w(TAG, "Failed to delete backup file: ${record.uri}") - } - } catch (e: Exception) { - Log.w(TAG, "Failed to delete backup file: ${record.uri}", e) - } - - db.deleteBackupFile(record) - - Log.v(TAG, "Backup file was deleted: ${record.uri}") - } - } - - @JvmStatic - fun computeBackupKey(passphrase: String, salt: ByteArray?): ByteArray { - return try { - EventBus.getDefault().post(BackupEvent.createProgress(0)) - val digest = MessageDigest.getInstance("SHA-512") - val input = passphrase.replace(" ", "").toByteArray() - var hash: ByteArray = input - if (salt != null) digest.update(salt) - for (i in 0..249999) { - if (i % 1000 == 0) EventBus.getDefault().post(BackupEvent.createProgress(0)) - digest.update(hash) - hash = digest.digest(input) - } - ByteUtil.trim(hash, 32) - } catch (e: NoSuchAlgorithmException) { - throw AssertionError(e) - } - } -} - -/** - * An utility class to help perform backup directory selection requests. - * - * An instance of this class should be created per an [Activity] or [Fragment] - * and [onActivityResult] should be called appropriately. - */ -class BackupDirSelector(private val contextProvider: ContextProvider) { - - companion object { - private const val REQUEST_CODE_SAVE_DIR = 7844 - } - - private val context: Context get() = contextProvider.getContext() - - private var listener: Listener? = null - - constructor(activity: Activity) : - this(ActivityContextProvider(activity)) - - constructor(fragment: Fragment) : - this(FragmentContextProvider(fragment)) - - /** - * Performs ACTION_OPEN_DOCUMENT_TREE intent to select backup directory URI. - * If the directory is already selected and valid, the request will be skipped. - * @param force if true, the previous selection is ignored and the user is requested to select another directory. - * @param onSelectedListener an optional action to perform once the directory is selected. - */ - fun selectBackupDir(force: Boolean, onSelectedListener: Listener? = null) { - if (!force) { - val dirUri = BackupUtil.getSelectedBackupDirIfValid(context) - if (dirUri != null && onSelectedListener != null) { - onSelectedListener.onBackupDirSelected(dirUri) - } - return - } - - // Let user pick the dir. - val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) - - // Request read/write permission grant for the dir. - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or - Intent.FLAG_GRANT_WRITE_URI_PERMISSION or - Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) - - // Set the default dir. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val dirUri = BackupUtil.getBackupDirUri(context) - intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, dirUri - ?: Uri.fromFile(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS))) - } - - if (onSelectedListener != null) { - this.listener = onSelectedListener - } - - contextProvider.startActivityForResult(intent, REQUEST_CODE_SAVE_DIR) - } - - fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode != REQUEST_CODE_SAVE_DIR) return - - if (resultCode == Activity.RESULT_OK && data != null && data.data != null) { - // Acquire persistent access permissions for the file selected. - val persistentFlags: Int = data.flags and - (Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION) - context.contentResolver.takePersistableUriPermission(data.data!!, persistentFlags) - - BackupUtil.setBackupDirUri(context, data.dataString) - - listener?.onBackupDirSelected(data.data!!) - } - - listener = null - } - - @FunctionalInterface - interface Listener { - fun onBackupDirSelected(uri: Uri) - } -} \ No newline at end of file From 88e788a4060ded3fefb052e68889febeac1d12c0 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Thu, 11 May 2023 12:16:37 +1000 Subject: [PATCH 11/19] clean --- .../java/org/thoughtcrime/securesms/ApplicationContext.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 5a9999a7bc..53141534af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -106,7 +106,6 @@ import dagger.hilt.EntryPoints; import dagger.hilt.android.HiltAndroidApp; import kotlin.Unit; import kotlinx.coroutines.Job; -import network.loki.messenger.BuildConfig; /** * Will be called once when the TextSecure process is created. @@ -158,10 +157,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO return (ApplicationContext) context.getApplicationContext(); } - public TextSecurePreferences getPrefs() { - return textSecurePreferences; - } - public DatabaseComponent getDatabaseComponent() { return EntryPoints.get(getApplicationContext(), DatabaseComponent.class); } From b7744f4f2df259b69621dc756c57ff3b89b83b54 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 30 May 2023 12:43:51 +1000 Subject: [PATCH 12/19] Addressed PR feedback --- .../thoughtcrime/securesms/database/Storage.kt | 10 +--------- .../libsession/database/StorageProtocol.kt | 3 +-- .../messaging/jobs/RetrieveProfileAvatarJob.kt | 16 +++++++++++++--- .../sending_receiving/ReceivedMessageHandler.kt | 3 ++- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 5d338c023b..1dd473d4d0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -69,15 +69,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return Profile(displayName, profileKey, profilePictureUrl) } - override fun setUserProfilePictureURL(newValue: String) { - val ourRecipient = fromSerialized(getUserPublicKey()!!).let { - Recipient.from(context, it, false) - } - TextSecurePreferences.setProfilePictureURL(context, newValue) - JobQueue.shared.add(RetrieveProfileAvatarJob(newValue, ourRecipient.address)) - } - - override fun setProfileAvatar(recipient: Recipient, profileAvatar: String) { + override fun setProfileAvatar(recipient: Recipient, profileAvatar: String?) { val database = DatabaseComponent.get(context).recipientDatabase() database.setProfileAvatar(recipient, profileAvatar) } diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index 21b34454eb..bf4f467d19 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -37,8 +37,7 @@ interface StorageProtocol { fun getUserPublicKey(): String? fun getUserX25519KeyPair(): ECKeyPair fun getUserProfile(): Profile - fun setUserProfilePictureURL(newProfilePicture: String) - fun setProfileAvatar(recipient: Recipient, profileAvatar: String) + fun setProfileAvatar(recipient: Recipient, profileAvatar: String?) // Signal fun getOrGenerateRegistrationID(): Int diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index 8ce397a3a9..7ad76317de 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -9,6 +9,8 @@ import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfi import org.session.libsession.utilities.Util.copy import org.session.libsession.utilities.Util.equals import org.session.libsession.utilities.Address +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.TextSecurePreferences.Companion.setProfilePictureURL import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.streams.ProfileCipherInputStream import org.session.libsignal.utilities.Log @@ -18,7 +20,7 @@ import java.io.FileOutputStream import java.io.InputStream import java.security.SecureRandom -class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: Address): Job { +class RetrieveProfileAvatarJob(val profileAvatar: String?, val recipientAddress: Address): Job { override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 @@ -49,10 +51,16 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: return } - if (TextUtils.isEmpty(profileAvatar)) { + if (profileAvatar.isNullOrEmpty()) { Log.w(TAG, "Removing profile avatar for: " + recipient.address.serialize()) + + if (recipient.isLocalNumber) { + setProfileAvatarId(context, SecureRandom().nextInt()) + setProfilePictureURL(context, null) + } + AvatarHelper.delete(context, recipient.address) - storage.setProfileAvatar(recipient, profileAvatar) + storage.setProfileAvatar(recipient, null) return } @@ -70,7 +78,9 @@ class RetrieveProfileAvatarJob(val profileAvatar: String, val recipientAddress: if (recipient.isLocalNumber) { setProfileAvatarId(context, SecureRandom().nextInt()) + setProfilePictureURL(context, profileAvatar) } + storage.setProfileAvatar(recipient, profileAvatar) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 068d25b447..523ad450b1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -5,6 +5,7 @@ import org.session.libsession.avatars.AvatarHelper import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.BackgroundGroupAddJob import org.session.libsession.messaging.jobs.JobQueue +import org.session.libsession.messaging.jobs.RetrieveProfileAvatarJob import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.messages.control.CallMessage import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage @@ -183,7 +184,7 @@ private fun handleConfigurationMessage(message: ConfigurationMessage) { ProfileKeyUtil.setEncodedProfileKey(context, profileKey) profileManager.setProfileKey(context, recipient, message.profileKey) if (!message.profilePicture.isNullOrEmpty() && TextSecurePreferences.getProfilePictureURL(context) != message.profilePicture) { - storage.setUserProfilePictureURL(message.profilePicture!!) + JobQueue.shared.add(RetrieveProfileAvatarJob(message.profilePicture!!, recipient.address)) } } storage.addContacts(message.contacts) From 8ce6e997aa2bb1924c4fe6990cce3e532201073d Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 30 May 2023 12:50:51 +1000 Subject: [PATCH 13/19] Fixed a potential crash after changing a property to be nullable --- .../libsession/messaging/jobs/RetrieveProfileAvatarJob.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt index 7ad76317de..5c617fbdb0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/RetrieveProfileAvatarJob.kt @@ -20,7 +20,7 @@ import java.io.FileOutputStream import java.io.InputStream import java.security.SecureRandom -class RetrieveProfileAvatarJob(val profileAvatar: String?, val recipientAddress: Address): Job { +class RetrieveProfileAvatarJob(private val profileAvatar: String?, private val recipientAddress: Address): Job { override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 @@ -31,8 +31,8 @@ class RetrieveProfileAvatarJob(val profileAvatar: String?, val recipientAddress: val KEY: String = "RetrieveProfileAvatarJob" // Keys used for database storage - private val PROFILE_AVATAR_KEY = "profileAvatar" - private val RECEIPIENT_ADDRESS_KEY = "recipient" + private const val PROFILE_AVATAR_KEY = "profileAvatar" + private const val RECEIPIENT_ADDRESS_KEY = "recipient" } override fun execute(dispatcherName: String) { @@ -97,7 +97,7 @@ class RetrieveProfileAvatarJob(val profileAvatar: String?, val recipientAddress: class Factory: Job.Factory { override fun create(data: Data): RetrieveProfileAvatarJob { - val profileAvatar = data.getString(PROFILE_AVATAR_KEY) + val profileAvatar = if (data.hasString(PROFILE_AVATAR_KEY)) { data.getString(PROFILE_AVATAR_KEY) } else { null } val recipientAddress = Address.fromSerialized(data.getString(RECEIPIENT_ADDRESS_KEY)) return RetrieveProfileAvatarJob(profileAvatar, recipientAddress) } From 9b7fb3dd8656e38418d4d1b640433f97a3cb5f4d Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 30 May 2023 13:31:36 +1000 Subject: [PATCH 14/19] Removed the JobDatabase since it's no longer used --- .../securesms/database/JobDatabase.java | 71 ------------------- .../database/helpers/SQLCipherOpenHelper.java | 4 -- 2 files changed, 75 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java deleted file mode 100644 index ddef0200e1..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/JobDatabase.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.thoughtcrime.securesms.database; - -import android.content.Context; -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; - -public class JobDatabase extends Database { - - public static final String[] CREATE_TABLE = new String[] { Jobs.CREATE_TABLE, - Constraints.CREATE_TABLE, - Dependencies.CREATE_TABLE }; - - public static final class Jobs { - public static final String TABLE_NAME = "job_spec"; - private static final String ID = "_id"; - private static final String JOB_SPEC_ID = "job_spec_id"; - private static final String FACTORY_KEY = "factory_key"; - private static final String QUEUE_KEY = "queue_key"; - private static final String CREATE_TIME = "create_time"; - private static final String NEXT_RUN_ATTEMPT_TIME = "next_run_attempt_time"; - private static final String RUN_ATTEMPT = "run_attempt"; - private static final String MAX_ATTEMPTS = "max_attempts"; - private static final String MAX_BACKOFF = "max_backoff"; - private static final String MAX_INSTANCES = "max_instances"; - private static final String LIFESPAN = "lifespan"; - private static final String SERIALIZED_DATA = "serialized_data"; - private static final String IS_RUNNING = "is_running"; - - private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + - JOB_SPEC_ID + " TEXT UNIQUE, " + - FACTORY_KEY + " TEXT, " + - QUEUE_KEY + " TEXT, " + - CREATE_TIME + " INTEGER, " + - NEXT_RUN_ATTEMPT_TIME + " INTEGER, " + - RUN_ATTEMPT + " INTEGER, " + - MAX_ATTEMPTS + " INTEGER, " + - MAX_BACKOFF + " INTEGER, " + - MAX_INSTANCES + " INTEGER, " + - LIFESPAN + " INTEGER, " + - SERIALIZED_DATA + " TEXT, " + - IS_RUNNING + " INTEGER)"; - } - - public static final class Constraints { - public static final String TABLE_NAME = "constraint_spec"; - private static final String ID = "_id"; - private static final String JOB_SPEC_ID = "job_spec_id"; - private static final String FACTORY_KEY = "factory_key"; - - private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + - JOB_SPEC_ID + " TEXT, " + - FACTORY_KEY + " TEXT, " + - "UNIQUE(" + JOB_SPEC_ID + ", " + FACTORY_KEY + "))"; - } - - public static final class Dependencies { - public static final String TABLE_NAME = "dependency_spec"; - private static final String ID = "_id"; - private static final String JOB_SPEC_ID = "job_spec_id"; - private static final String DEPENDS_ON_JOB_SPEC_ID = "depends_on_job_spec_id"; - - private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + - JOB_SPEC_ID + " TEXT, " + - DEPENDS_ON_JOB_SPEC_ID + " TEXT, " + - "UNIQUE(" + JOB_SPEC_ID + ", " + DEPENDS_ON_JOB_SPEC_ID + "))"; - } - - - public JobDatabase(Context context, SQLCipherOpenHelper databaseHelper) { - super(context, databaseHelper); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index df69c239fc..8a4473b409 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.database.EmojiSearchDatabase; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupMemberDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase; -import org.thoughtcrime.securesms.database.JobDatabase; import org.thoughtcrime.securesms.database.LokiAPIDatabase; import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase; import org.thoughtcrime.securesms.database.LokiMessageDatabase; @@ -284,9 +283,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { for (String sql : SearchDatabase.CREATE_TABLE) { db.execSQL(sql); } - for (String sql : JobDatabase.CREATE_TABLE) { - db.execSQL(sql); - } db.execSQL(LokiAPIDatabase.getCreateSnodePoolTableCommand()); db.execSQL(LokiAPIDatabase.getCreateOnionRequestPathTableCommand()); db.execSQL(LokiAPIDatabase.getCreateSwarmTableCommand()); From 2b7bd7417ea72f2b5fcf2179a9bdbc2b01c426d9 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 2 Jun 2023 17:00:20 +1000 Subject: [PATCH 15/19] [SES-567] Fixed a couple of issues where the Group poller would be stopped during creation --- .../securesms/database/Storage.kt | 5 ++++ .../libsession/database/StorageProtocol.kt | 1 + .../MessageSenderClosedGroupHandler.kt | 29 ++++++++++++------- .../pollers/ClosedGroupPollerV2.kt | 7 ++++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 1dd473d4d0..6e6995205e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -738,6 +738,11 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, return mmsSmsDb.getConversationCount(threadID) } + override fun deleteConversation(threadId: Long) { + val threadDB = DatabaseComponent.get(context).threadDatabase() + threadDB.deleteConversation(threadId) + } + override fun getAttachmentDataUri(attachmentId: AttachmentId): Uri { diff --git a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt index bf4f467d19..9a88202470 100644 --- a/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/database/StorageProtocol.kt @@ -159,6 +159,7 @@ interface StorageProtocol { fun trimThread(threadID: Long, threadLimit: Int) fun trimThreadBefore(threadID: Long, timestamp: Long) fun getMessageCount(threadID: Long): Long + fun deleteConversation(threadId: Long) // Contacts fun getContactWithSessionID(sessionID: String): Contact? diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt index b8a903539f..f62fd5a93a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt @@ -52,19 +52,10 @@ fun MessageSender.create(name: String, members: Collection): Promise): Promise Date: Mon, 5 Jun 2023 09:39:31 +1000 Subject: [PATCH 16/19] [SES-566] Fixed an issue where the blocked state wasn't syncing --- .../conversation/v2/ConversationActivityV2.kt | 8 ++++---- .../conversation/v2/ConversationViewModel.kt | 17 +++++++++++++++-- .../conversation/v2/dialogs/BlockedDialog.kt | 12 +++++++++++- .../thoughtcrime/securesms/database/Storage.kt | 6 ++++-- .../thoughtcrime/securesms/home/HomeActivity.kt | 4 ++++ .../preferences/BlockedContactsActivity.kt | 2 +- .../preferences/BlockedContactsViewModel.kt | 9 ++++++++- 7 files changed, 47 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 07751cab9a..7844ca4c22 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -576,7 +576,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val name = contact?.displayName(Contact.ContactContext.REGULAR) ?: sessionID binding?.blockedBannerTextView?.text = resources.getString(R.string.activity_conversation_blocked_banner_text, name) binding?.blockedBanner?.isVisible = recipient.isBlocked - binding?.blockedBanner?.setOnClickListener { viewModel.unblock() } + binding?.blockedBanner?.setOnClickListener { viewModel.unblock(this@ConversationActivityV2) } } private fun setUpLinkPreviewObserver() { @@ -972,7 +972,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe .setMessage(message) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.RecipientPreferenceActivity_block) { _, _ -> - viewModel.block() + viewModel.block(this@ConversationActivityV2) if (deleteThread) { viewModel.deleteThread() finish() @@ -1026,7 +1026,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe .setMessage(message) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.ConversationActivity_unblock) { _, _ -> - viewModel.unblock() + viewModel.unblock(this@ConversationActivityV2) }.show() } @@ -1367,7 +1367,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe override fun sendMessage() { val recipient = viewModel.recipient ?: return if (recipient.isContactRecipient && recipient.isBlocked) { - BlockedDialog(recipient).show(supportFragmentManager, "Blocked Dialog") + BlockedDialog(recipient, this).show(supportFragmentManager, "Blocked Dialog") return } val binding = binding ?: return diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt index fc557f7260..b8b460b603 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationViewModel.kt @@ -1,7 +1,9 @@ package org.thoughtcrime.securesms.conversation.v2 +import android.content.Context import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.lifecycle.viewModelScope import com.goterl.lazysodium.utils.KeyPair import dagger.assisted.Assisted @@ -22,6 +24,7 @@ import org.session.libsignal.utilities.Log import org.thoughtcrime.securesms.database.Storage import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.repository.ConversationRepository +import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import java.util.UUID class ConversationViewModel( @@ -78,17 +81,27 @@ class ConversationViewModel( repository.inviteContacts(threadId, contacts) } - fun block() { + fun block(context: Context) { val recipient = recipient ?: return Log.w("Loki", "Recipient was null for block action") if (recipient.isContactRecipient) { repository.setBlocked(recipient, true) + + // TODO: Remove in UserConfig branch + GlobalScope.launch(Dispatchers.IO) { + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) + } } } - fun unblock() { + fun unblock(context: Context) { val recipient = recipient ?: return Log.w("Loki", "Recipient was null for unblock action") if (recipient.isContactRecipient) { repository.setBlocked(recipient, false) + + // TODO: Remove in UserConfig branch + GlobalScope.launch(Dispatchers.IO) { + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt index 39ca7c6913..bcabca98f1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/dialogs/BlockedDialog.kt @@ -1,20 +1,25 @@ package org.thoughtcrime.securesms.conversation.v2.dialogs +import android.content.Context import android.graphics.Typeface import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.StyleSpan import android.view.LayoutInflater import androidx.appcompat.app.AlertDialog +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import network.loki.messenger.R import network.loki.messenger.databinding.DialogBlockedBinding import org.session.libsession.messaging.contacts.Contact import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.conversation.v2.utilities.BaseDialog import org.thoughtcrime.securesms.dependencies.DatabaseComponent +import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities /** Shown upon sending a message to a user that's blocked. */ -class BlockedDialog(private val recipient: Recipient) : BaseDialog() { +class BlockedDialog(private val recipient: Recipient, private val context: Context) : BaseDialog() { override fun setContentView(builder: AlertDialog.Builder) { val binding = DialogBlockedBinding.inflate(LayoutInflater.from(requireContext())) @@ -37,5 +42,10 @@ class BlockedDialog(private val recipient: Recipient) : BaseDialog() { private fun unblock() { DatabaseComponent.get(requireContext()).recipientDatabase().setBlocked(recipient, false) dismiss() + + // TODO: Remove in UserConfig branch + GlobalScope.launch(Dispatchers.IO) { + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) + } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt index 6e6995205e..365c12b839 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -708,8 +708,10 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, recipientDatabase.setApproved(recipient, true) threadDatabase.setHasSent(threadId, true) } - if (contact.isBlocked == true) { - recipientDatabase.setBlocked(recipient, true) + + val contactIsBlocked: Boolean? = contact.isBlocked + if (contactIsBlocked != null && recipient.isBlocked != contactIsBlocked) { + recipientDatabase.setBlocked(recipient, contactIsBlocked) threadDatabase.deleteConversation(threadId) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index 9b1e01a54a..0215040d37 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -495,6 +495,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), .setPositiveButton(R.string.RecipientPreferenceActivity_block) { dialog, _ -> lifecycleScope.launch(Dispatchers.IO) { recipientDatabase.setBlocked(thread.recipient, true) + // TODO: Remove in UserConfig branch + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity) withContext(Dispatchers.Main) { binding.recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() @@ -511,6 +513,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), .setPositiveButton(R.string.RecipientPreferenceActivity_unblock) { dialog, _ -> lifecycleScope.launch(Dispatchers.IO) { recipientDatabase.setBlocked(thread.recipient, false) + // TODO: Remove in UserConfig branch + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(this@HomeActivity) withContext(Dispatchers.Main) { binding.recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsActivity.kt index d2db4fca43..a66dd7428c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsActivity.kt @@ -27,7 +27,7 @@ class BlockedContactsActivity: PassphraseRequiredActionBarActivity() { AlertDialog.Builder(this) .setTitle(title) .setMessage(message) - .setPositiveButton(R.string.continue_2) { _, _ -> viewModel.unblock() } + .setPositiveButton(R.string.continue_2) { _, _ -> viewModel.unblock(this@BlockedContactsActivity) } .setNegativeButton(R.string.cancel) { _, _ -> } .show() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt index b5d7995506..acbba1ebb2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/BlockedContactsViewModel.kt @@ -7,8 +7,10 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.cash.copper.flow.observeQuery import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.collect @@ -21,6 +23,7 @@ import network.loki.messenger.R import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.database.DatabaseContentProviders import org.thoughtcrime.securesms.database.Storage +import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities import org.thoughtcrime.securesms.util.adapter.SelectableItem import javax.inject.Inject @@ -60,9 +63,13 @@ class BlockedContactsViewModel @Inject constructor(private val storage: Storage) return _state } - fun unblock() { + fun unblock(context: Context) { storage.unblock(state.selectedItems) _state.value = state.copy(selectedItems = emptySet()) + // TODO: Remove in UserConfig branch + GlobalScope.launch(Dispatchers.IO) { + ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(context) + } } fun select(selectedItem: Recipient, isSelected: Boolean) { From c92ef09d09bcf21930a8fb5f3f834a13e5fb686d Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 5 Jun 2023 14:31:41 +1000 Subject: [PATCH 17/19] [SES-570] Fixed an issue where quotes weren't using their quoted message media --- .../thoughtcrime/securesms/database/MmsDatabase.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt index 9e854698f5..e8f65dae06 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.kt @@ -60,6 +60,7 @@ import org.thoughtcrime.securesms.database.SmsDatabase.InsertListener import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord +import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord import org.thoughtcrime.securesms.database.model.Quote import org.thoughtcrime.securesms.dependencies.DatabaseComponent.Companion.get @@ -1405,11 +1406,13 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa val retrievedQuote = get(context).mmsSmsDatabase().getMessageFor(quoteId, quoteAuthor) val quoteText = retrievedQuote?.body val quoteMissing = retrievedQuote == null - val attachments = get(context).attachmentDatabase().getAttachment(cursor) - val quoteAttachments: List? = - Stream.of(attachments).filter { obj: DatabaseAttachment? -> obj!!.isQuote } + val quoteDeck = ( + (retrievedQuote as? MmsMessageRecord)?.slideDeck ?: + Stream.of(get(context).attachmentDatabase().getAttachment(cursor)) + .filter { obj: DatabaseAttachment? -> obj!!.isQuote } .toList() - val quoteDeck = SlideDeck(context, quoteAttachments!!) + .let { SlideDeck(context, it) } + ) return Quote( quoteId, fromExternal(context, quoteAuthor), From a6cfe5817dbaa5ecabad1e0223165a93388a16d3 Mon Sep 17 00:00:00 2001 From: andrew Date: Mon, 5 Jun 2023 14:58:56 +0930 Subject: [PATCH 18/19] Change unset profile pic in dialog --- .../securesms/preferences/SettingsActivity.kt | 24 ++++++++++++++---- app/src/main/res/drawable/ic_pictures.xml | 18 +++++++++++++ .../main/res/layout/dialog_change_avatar.xml | 25 +++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/ic_pictures.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index 6b6497982d..5a03cebc37 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -26,8 +26,10 @@ import nl.komponents.kovenant.all import nl.komponents.kovenant.ui.alwaysUi import nl.komponents.kovenant.ui.successUi import org.session.libsession.avatars.AvatarHelper +import org.session.libsession.avatars.ProfileContactPhoto import org.session.libsession.utilities.* import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol +import org.session.libsession.utilities.recipients.Recipient import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.avatar.AvatarSelection import org.thoughtcrime.securesms.components.ProfilePictureView @@ -100,10 +102,12 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { private fun setupProfilePictureView(view: ProfilePictureView) { view.glide = glide - view.publicKey = hexEncodedPublicKey - view.displayName = getDisplayName() - view.isLarge = true - view.update() + view.apply { + publicKey = hexEncodedPublicKey + displayName = getDisplayName() + isLarge = true + update() + } } override fun onSaveInstanceState(outState: Bundle) { @@ -273,7 +277,17 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { } } .show().apply { - findViewById(R.id.profile_picture_view)?.let(::setupProfilePictureView) + val profilePic = findViewById(R.id.profile_picture_view) + ?.also(::setupProfilePictureView) + + val pictureIcon = findViewById(R.id.ic_pictures) + + val recipient = Recipient.from(context, Address.fromSerialized(hexEncodedPublicKey), false) + + val photoSet = (recipient.contactPhoto as ProfileContactPhoto).avatarObject !in setOf("0", "") + + profilePic?.isVisible = photoSet + pictureIcon?.isVisible = !photoSet } } diff --git a/app/src/main/res/drawable/ic_pictures.xml b/app/src/main/res/drawable/ic_pictures.xml new file mode 100644 index 0000000000..967d0a65b0 --- /dev/null +++ b/app/src/main/res/drawable/ic_pictures.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/layout/dialog_change_avatar.xml b/app/src/main/res/layout/dialog_change_avatar.xml index afe3672f15..60705698f1 100644 --- a/app/src/main/res/layout/dialog_change_avatar.xml +++ b/app/src/main/res/layout/dialog_change_avatar.xml @@ -5,6 +5,31 @@ android:layout_height="wrap_content" android:layout_width="match_parent"> + + + + + + + + Date: Mon, 5 Jun 2023 17:15:05 +1000 Subject: [PATCH 19/19] Commented out the plus button on the replace profile modal --- .../main/res/layout/dialog_change_avatar.xml | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/app/src/main/res/layout/dialog_change_avatar.xml b/app/src/main/res/layout/dialog_change_avatar.xml index 2eb8adeebc..8cb97bcf6a 100644 --- a/app/src/main/res/layout/dialog_change_avatar.xml +++ b/app/src/main/res/layout/dialog_change_avatar.xml @@ -23,23 +23,24 @@ android:background="@color/transparent" android:src="@drawable/ic_pictures"/> - - - + + + + + + + + + + + + + + + + + +