Add test restore flow to staging reg.
This commit is contained in:
parent
9d46b52786
commit
742c348998
5 changed files with 218 additions and 1 deletions
|
@ -216,6 +216,7 @@ android {
|
||||||
buildConfigField("String", "BADGE_STATIC_ROOT", "\"https://updates2.signal.org/static/badges/\"")
|
buildConfigField("String", "BADGE_STATIC_ROOT", "\"https://updates2.signal.org/static/badges/\"")
|
||||||
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_live_6cmGZopuTsV8novGgJJW9JpC00vLIgtQ1D\"")
|
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_live_6cmGZopuTsV8novGgJJW9JpC00vLIgtQ1D\"")
|
||||||
buildConfigField("boolean", "TRACING_ENABLED", "false")
|
buildConfigField("boolean", "TRACING_ENABLED", "false")
|
||||||
|
buildConfigField("boolean", "MESSAGE_BACKUP_RESTORE_ENABLED", "false")
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||||
|
@ -390,6 +391,7 @@ android {
|
||||||
|
|
||||||
buildConfigField("String", "BUILD_ENVIRONMENT_TYPE", "\"Staging\"")
|
buildConfigField("String", "BUILD_ENVIRONMENT_TYPE", "\"Staging\"")
|
||||||
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_test_sngOd8FnXNkpce9nPXawKrJD00kIDngZkD\"")
|
buildConfigField("String", "STRIPE_PUBLISHABLE_KEY", "\"pk_test_sngOd8FnXNkpce9nPXawKrJD00kIDngZkD\"")
|
||||||
|
buildConfigField("boolean", "MESSAGE_BACKUP_RESTORE_ENABLED", "true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -961,6 +961,10 @@
|
||||||
android:windowSoftInputMode="stateVisible|adjustResize"
|
android:windowSoftInputMode="stateVisible|adjustResize"
|
||||||
android:exported="false"/>
|
android:exported="false"/>
|
||||||
|
|
||||||
|
<activity android:name=".backup.v2.ui.MessageBackupsTestRestoreActivity"
|
||||||
|
android:theme="@style/TextSecure.LightRegistrationTheme"
|
||||||
|
android:exported="false"/>
|
||||||
|
|
||||||
<activity android:name=".profiles.manage.EditProfileActivity"
|
<activity android:name=".profiles.manage.EditProfileActivity"
|
||||||
android:theme="@style/TextSecure.LightTheme"
|
android:theme="@style/TextSecure.LightTheme"
|
||||||
android:windowSoftInputMode="stateVisible|adjustResize"
|
android:windowSoftInputMode="stateVisible|adjustResize"
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.backup.v2.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.compose.setContent
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.activity.viewModels
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import org.signal.core.ui.Buttons
|
||||||
|
import org.signal.core.ui.Dividers
|
||||||
|
import org.signal.core.util.getLength
|
||||||
|
import org.thoughtcrime.securesms.BaseActivity
|
||||||
|
import org.thoughtcrime.securesms.MainActivity
|
||||||
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||||
|
import org.thoughtcrime.securesms.jobs.ProfileUploadJob
|
||||||
|
import org.thoughtcrime.securesms.profiles.AvatarHelper
|
||||||
|
import org.thoughtcrime.securesms.profiles.edit.CreateProfileActivity
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
|
import org.thoughtcrime.securesms.registration.RegistrationUtil
|
||||||
|
|
||||||
|
class MessageBackupsTestRestoreActivity : BaseActivity() {
|
||||||
|
companion object {
|
||||||
|
fun getIntent(context: Context): Intent {
|
||||||
|
return Intent(context, MessageBackupsTestRestoreActivity::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val viewModel: MessageBackupsTestRestoreViewModel by viewModels()
|
||||||
|
private lateinit var importFileLauncher: ActivityResultLauncher<Intent>
|
||||||
|
|
||||||
|
private fun onPlaintextClicked() {
|
||||||
|
viewModel.onPlaintextToggled()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
importFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
|
if (result.resultCode == RESULT_OK) {
|
||||||
|
result.data?.data?.let { uri ->
|
||||||
|
contentResolver.getLength(uri)?.let { length ->
|
||||||
|
viewModel.import(length) { contentResolver.openInputStream(uri)!! }
|
||||||
|
}
|
||||||
|
} ?: Toast.makeText(this, "No URI selected", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setContent {
|
||||||
|
val state by viewModel.state
|
||||||
|
Surface {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
StateLabel(text = "Plaintext?")
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Switch(
|
||||||
|
checked = state.plaintext,
|
||||||
|
onCheckedChange = { onPlaintextClicked() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Buttons.LargePrimary(
|
||||||
|
onClick = {
|
||||||
|
val intent = Intent().apply {
|
||||||
|
action = Intent.ACTION_GET_CONTENT
|
||||||
|
type = "application/octet-stream"
|
||||||
|
addCategory(Intent.CATEGORY_OPENABLE)
|
||||||
|
}
|
||||||
|
|
||||||
|
importFileLauncher.launch(intent)
|
||||||
|
},
|
||||||
|
enabled = !state.importState.inProgress
|
||||||
|
) {
|
||||||
|
Text("Import from file")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
Dividers.Default()
|
||||||
|
|
||||||
|
Buttons.LargeTonal(
|
||||||
|
onClick = { continueRegistration() },
|
||||||
|
enabled = !state.importState.inProgress
|
||||||
|
) {
|
||||||
|
Text("Continue Reg Flow")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun continueRegistration() {
|
||||||
|
if (Recipient.self().profileName.isEmpty || !AvatarHelper.hasAvatar(this, Recipient.self().id)) {
|
||||||
|
val main = MainActivity.clearTop(this)
|
||||||
|
val profile = CreateProfileActivity.getIntentForUserProfile(this)
|
||||||
|
profile.putExtra("next_intent", main)
|
||||||
|
startActivity(profile)
|
||||||
|
} else {
|
||||||
|
RegistrationUtil.maybeMarkRegistrationComplete()
|
||||||
|
ApplicationDependencies.getJobManager().add(ProfileUploadJob())
|
||||||
|
startActivity(MainActivity.clearTop(this))
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun StateLabel(text: String) {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
textAlign = TextAlign.Center
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.thoughtcrime.securesms.backup.v2.ui
|
||||||
|
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.rxjava3.core.Single
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||||
|
import org.signal.libsignal.zkgroup.profiles.ProfileKey
|
||||||
|
import org.thoughtcrime.securesms.backup.v2.BackupRepository
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient
|
||||||
|
import java.io.InputStream
|
||||||
|
|
||||||
|
class MessageBackupsTestRestoreViewModel : ViewModel() {
|
||||||
|
val disposables = CompositeDisposable()
|
||||||
|
|
||||||
|
private val _state: MutableState<ScreenState> = mutableStateOf(ScreenState(importState = ImportState.NONE, plaintext = false))
|
||||||
|
val state: State<ScreenState> = _state
|
||||||
|
|
||||||
|
fun import(length: Long, inputStreamFactory: () -> InputStream) {
|
||||||
|
_state.value = _state.value.copy(importState = ImportState.IN_PROGRESS)
|
||||||
|
|
||||||
|
val self = Recipient.self()
|
||||||
|
val selfData = BackupRepository.SelfData(self.aci.get(), self.pni.get(), self.e164.get(), ProfileKey(self.profileKey))
|
||||||
|
|
||||||
|
disposables += Single.fromCallable { BackupRepository.import(length, inputStreamFactory, selfData, plaintext = _state.value.plaintext) }
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribeBy {
|
||||||
|
_state.value = _state.value.copy(importState = ImportState.NONE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onPlaintextToggled() {
|
||||||
|
_state.value = _state.value.copy(plaintext = !_state.value.plaintext)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCleared() {
|
||||||
|
disposables.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
data class ScreenState(
|
||||||
|
val importState: ImportState,
|
||||||
|
val plaintext: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
enum class ImportState(val inProgress: Boolean = false) {
|
||||||
|
NONE, IN_PROGRESS(true)
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,9 +23,11 @@ import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
|
import org.thoughtcrime.securesms.BuildConfig;
|
||||||
import org.thoughtcrime.securesms.LoggingFragment;
|
import org.thoughtcrime.securesms.LoggingFragment;
|
||||||
import org.thoughtcrime.securesms.MainActivity;
|
import org.thoughtcrime.securesms.MainActivity;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.backup.v2.ui.MessageBackupsTestRestoreActivity;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
|
import org.thoughtcrime.securesms.jobs.ProfileUploadJob;
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
|
@ -236,7 +238,9 @@ public class PinRestoreEntryFragment extends LoggingFragment {
|
||||||
|
|
||||||
Activity activity = requireActivity();
|
Activity activity = requireActivity();
|
||||||
|
|
||||||
if (Recipient.self().getProfileName().isEmpty() || !AvatarHelper.hasAvatar(activity, Recipient.self().getId())) {
|
if (BuildConfig.MESSAGE_BACKUP_RESTORE_ENABLED) {
|
||||||
|
startActivity(MessageBackupsTestRestoreActivity.Companion.getIntent(activity));
|
||||||
|
} else if (Recipient.self().getProfileName().isEmpty() || !AvatarHelper.hasAvatar(activity, Recipient.self().getId())) {
|
||||||
final Intent main = MainActivity.clearTop(activity);
|
final Intent main = MainActivity.clearTop(activity);
|
||||||
final Intent profile = CreateProfileActivity.getIntentForUserProfile(activity);
|
final Intent profile = CreateProfileActivity.getIntentForUserProfile(activity);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue