mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Update target API to 33
This commit is contained in:
committed by
Nicholas Tinsley
parent
b9449a798b
commit
a3e36d2453
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.registration.fragments
|
||||
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import org.signal.core.ui.Buttons
|
||||
import org.signal.core.ui.theme.SignalTheme
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.permissions.Permissions
|
||||
import org.thoughtcrime.securesms.registration.viewmodel.RegistrationViewModel
|
||||
import org.thoughtcrime.securesms.util.BackupUtil
|
||||
|
||||
/**
|
||||
* Fragment displayed during registration which allows a user to read through
|
||||
* what permissions are granted to Signal and why, and a means to either skip
|
||||
* granting those permissions or continue to grant via system dialogs.
|
||||
*/
|
||||
class GrantPermissionsFragment : ComposeFragment() {
|
||||
|
||||
private val args by navArgs<GrantPermissionsFragmentArgs>()
|
||||
private val viewModel by activityViewModels<RegistrationViewModel>()
|
||||
private val isSearchingForBackup = mutableStateOf(false)
|
||||
|
||||
@Composable
|
||||
override fun FragmentContent() {
|
||||
val isSearchingForBackup by this.isSearchingForBackup
|
||||
|
||||
GrantPermissionsScreen(
|
||||
deviceBuildVersion = Build.VERSION.SDK_INT,
|
||||
isSearchingForBackup = isSearchingForBackup,
|
||||
isBackupSelectionRequired = BackupUtil.isUserSelectionRequired(LocalContext.current),
|
||||
onNextClicked = this::onNextClicked,
|
||||
onNotNowClicked = this::onNotNowClicked
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults)
|
||||
}
|
||||
|
||||
private fun onNextClicked() {
|
||||
when (args.welcomeAction) {
|
||||
WelcomeAction.CONTINUE -> {
|
||||
WelcomeFragment.continueClicked(
|
||||
this,
|
||||
viewModel,
|
||||
{ isSearchingForBackup.value = true },
|
||||
{ isSearchingForBackup.value = false },
|
||||
GrantPermissionsFragmentDirections.actionSkipRestore(),
|
||||
GrantPermissionsFragmentDirections.actionRestore()
|
||||
)
|
||||
}
|
||||
|
||||
WelcomeAction.RESTORE_BACKUP -> {
|
||||
WelcomeFragment.restoreFromBackupClicked(
|
||||
this,
|
||||
viewModel,
|
||||
GrantPermissionsFragmentDirections.actionTransferOrRestore()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNotNowClicked() {
|
||||
when (args.welcomeAction) {
|
||||
WelcomeAction.CONTINUE -> {
|
||||
WelcomeFragment.gatherInformationAndContinue(
|
||||
this,
|
||||
viewModel,
|
||||
{ isSearchingForBackup.value = true },
|
||||
{ isSearchingForBackup.value = false },
|
||||
GrantPermissionsFragmentDirections.actionSkipRestore(),
|
||||
GrantPermissionsFragmentDirections.actionRestore()
|
||||
)
|
||||
}
|
||||
|
||||
WelcomeAction.RESTORE_BACKUP -> {
|
||||
WelcomeFragment.gatherInformationAndChooseBackup(
|
||||
this,
|
||||
viewModel,
|
||||
GrantPermissionsFragmentDirections.actionTransferOrRestore()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Which welcome action the user selected which prompted this
|
||||
* screen.
|
||||
*/
|
||||
enum class WelcomeAction {
|
||||
CONTINUE,
|
||||
RESTORE_BACKUP
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun GrantPermissionsScreenPreview() {
|
||||
SignalTheme(isDarkMode = false) {
|
||||
GrantPermissionsScreen(
|
||||
deviceBuildVersion = 33,
|
||||
isBackupSelectionRequired = true,
|
||||
isSearchingForBackup = true,
|
||||
{},
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun GrantPermissionsScreen(
|
||||
deviceBuildVersion: Int,
|
||||
isBackupSelectionRequired: Boolean,
|
||||
isSearchingForBackup: Boolean,
|
||||
onNextClicked: () -> Unit,
|
||||
onNotNowClicked: () -> Unit
|
||||
) {
|
||||
Surface {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.padding(top = 40.dp, bottom = 24.dp)
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(id = R.string.GrantPermissionsFragment__allow_permissions),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Text(
|
||||
text = stringResource(id = R.string.GrantPermissionsFragment__to_help_you_message_people_you_know),
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.padding(top = 12.dp, bottom = 41.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (deviceBuildVersion >= 33) {
|
||||
item {
|
||||
PermissionRow(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.permission_notification),
|
||||
title = stringResource(id = R.string.GrantPermissionsFragment__notifications),
|
||||
subtitle = stringResource(id = R.string.GrantPermissionsFragment__get_notified_when)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
PermissionRow(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.permission_contact),
|
||||
title = stringResource(id = R.string.GrantPermissionsFragment__contacts),
|
||||
subtitle = stringResource(id = R.string.GrantPermissionsFragment__find_people_you_know)
|
||||
)
|
||||
}
|
||||
|
||||
if (deviceBuildVersion < 29 || !isBackupSelectionRequired) {
|
||||
item {
|
||||
PermissionRow(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.permission_file),
|
||||
title = stringResource(id = R.string.GrantPermissionsFragment__storage),
|
||||
subtitle = stringResource(id = R.string.GrantPermissionsFragment__send_photos_videos_and_files)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
PermissionRow(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.permission_phone),
|
||||
title = stringResource(id = R.string.GrantPermissionsFragment__phone_calls),
|
||||
subtitle = stringResource(id = R.string.GrantPermissionsFragment__make_registering_easier)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
TextButton(onClick = onNotNowClicked) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.GrantPermissionsFragment__not_now)
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
if (isSearchingForBackup) {
|
||||
Box {
|
||||
NextButton(
|
||||
isSearchingForBackup = true,
|
||||
onNextClicked = onNextClicked
|
||||
)
|
||||
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
NextButton(
|
||||
isSearchingForBackup = false,
|
||||
onNextClicked = onNextClicked
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PermissionRowPreview() {
|
||||
PermissionRow(
|
||||
imageVector = ImageVector.vectorResource(id = R.drawable.permission_notification),
|
||||
title = stringResource(id = R.string.GrantPermissionsFragment__notifications),
|
||||
subtitle = stringResource(id = R.string.GrantPermissionsFragment__get_notified_when)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun PermissionRow(
|
||||
imageVector: ImageVector,
|
||||
title: String,
|
||||
subtitle: String
|
||||
) {
|
||||
Row(modifier = Modifier.padding(bottom = 32.dp)) {
|
||||
Image(
|
||||
imageVector = imageVector,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleSmall
|
||||
)
|
||||
|
||||
Text(
|
||||
text = subtitle,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.size(32.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NextButton(
|
||||
isSearchingForBackup: Boolean,
|
||||
onNextClicked: () -> Unit
|
||||
) {
|
||||
val alpha = if (isSearchingForBackup) {
|
||||
0f
|
||||
} else {
|
||||
1f
|
||||
}
|
||||
|
||||
Buttons.LargeTonal(
|
||||
onClick = onNextClicked,
|
||||
enabled = !isSearchingForBackup,
|
||||
modifier = Modifier.alpha(alpha)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.GrantPermissionsFragment__next)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,11 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.navigation.ActivityNavigator;
|
||||
import androidx.navigation.NavDirections;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.navigation.fragment.NavHostFragment;
|
||||
|
||||
@@ -49,29 +49,6 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
|
||||
private static final String TAG = Log.tag(WelcomeFragment.class);
|
||||
|
||||
private static final String[] PERMISSIONS = { Manifest.permission.WRITE_CONTACTS,
|
||||
Manifest.permission.READ_CONTACTS,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_PHONE_STATE };
|
||||
@RequiresApi(26)
|
||||
private static final String[] PERMISSIONS_API_26 = { Manifest.permission.WRITE_CONTACTS,
|
||||
Manifest.permission.READ_CONTACTS,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.READ_PHONE_STATE,
|
||||
Manifest.permission.READ_PHONE_NUMBERS };
|
||||
@RequiresApi(26)
|
||||
private static final String[] PERMISSIONS_API_29 = { Manifest.permission.WRITE_CONTACTS,
|
||||
Manifest.permission.READ_CONTACTS,
|
||||
Manifest.permission.READ_PHONE_STATE,
|
||||
Manifest.permission.READ_PHONE_NUMBERS };
|
||||
|
||||
private static final @StringRes int RATIONALE = R.string.RegistrationActivity_signal_needs_access_to_your_contacts_and_media_in_order_to_connect_with_friends;
|
||||
private static final @StringRes int RATIONALE_API_29 = R.string.RegistrationActivity_signal_needs_access_to_your_contacts_in_order_to_connect_with_friends;
|
||||
private static final int[] HEADERS = { R.drawable.ic_contacts_white_48dp, R.drawable.ic_folder_white_48dp };
|
||||
private static final int[] HEADERS_API_29 = { R.drawable.ic_contacts_white_48dp };
|
||||
|
||||
private CircularProgressMaterialButton continueButton;
|
||||
private RegistrationViewModel viewModel;
|
||||
|
||||
@@ -97,7 +74,7 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeNumber();
|
||||
initializeNumber(requireContext(), viewModel);
|
||||
|
||||
Log.i(TAG, "Skipping restore because this is a reregistration.");
|
||||
viewModel.setWelcomeSkippedOnRestore();
|
||||
@@ -109,10 +86,10 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
setDebugLogSubmitMultiTapView(view.findViewById(R.id.title));
|
||||
|
||||
continueButton = view.findViewById(R.id.welcome_continue_button);
|
||||
continueButton.setOnClickListener(this::continueClicked);
|
||||
continueButton.setOnClickListener(v -> onContinueClicked());
|
||||
|
||||
Button restoreFromBackup = view.findViewById(R.id.welcome_transfer_or_restore);
|
||||
restoreFromBackup.setOnClickListener(this::restoreFromBackupClicked);
|
||||
restoreFromBackup.setOnClickListener(v -> onRestoreFromBackupClicked());
|
||||
|
||||
TextView welcomeTermsButton = view.findViewById(R.id.welcome_terms_button);
|
||||
welcomeTermsButton.setOnClickListener(v -> onTermsClicked());
|
||||
@@ -139,70 +116,116 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void continueClicked(@NonNull View view) {
|
||||
boolean isUserSelectionRequired = BackupUtil.isUserSelectionRequired(requireContext());
|
||||
private void onContinueClicked() {
|
||||
if (Permissions.isRuntimePermissionsRequired()) {
|
||||
NavHostFragment.findNavController(this)
|
||||
.navigate(WelcomeFragmentDirections.actionWelcomeFragmentToGrantPermissionsFragment(GrantPermissionsFragment.WelcomeAction.CONTINUE));
|
||||
} else {
|
||||
gatherInformationAndContinue(
|
||||
this,
|
||||
viewModel,
|
||||
() -> continueButton.setSpinning(),
|
||||
() -> continueButton.cancelSpinning(),
|
||||
WelcomeFragmentDirections.actionSkipRestore(),
|
||||
WelcomeFragmentDirections.actionRestore()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Permissions.with(this)
|
||||
.request(getContinuePermissions(isUserSelectionRequired))
|
||||
private void onRestoreFromBackupClicked() {
|
||||
if (Permissions.isRuntimePermissionsRequired()) {
|
||||
NavHostFragment.findNavController(this)
|
||||
.navigate(WelcomeFragmentDirections.actionWelcomeFragmentToGrantPermissionsFragment(GrantPermissionsFragment.WelcomeAction.RESTORE_BACKUP));
|
||||
} else {
|
||||
gatherInformationAndChooseBackup(this, viewModel, WelcomeFragmentDirections.actionTransferOrRestore());
|
||||
}
|
||||
}
|
||||
|
||||
static void continueClicked(@NonNull Fragment fragment,
|
||||
@NonNull RegistrationViewModel viewModel,
|
||||
@NonNull Runnable onSearchForBackupStarted,
|
||||
@NonNull Runnable onSearchForBackupFinished,
|
||||
@NonNull NavDirections actionSkipRestore,
|
||||
@NonNull NavDirections actionRestore)
|
||||
{
|
||||
boolean isUserSelectionRequired = BackupUtil.isUserSelectionRequired(fragment.requireContext());
|
||||
|
||||
Permissions.with(fragment)
|
||||
.request(WelcomePermissions.getWelcomePermissions(isUserSelectionRequired))
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(getContinueRationale(isUserSelectionRequired)), getContinueHeaders(isUserSelectionRequired))
|
||||
.onAnyResult(() -> gatherInformationAndContinue(continueButton))
|
||||
.onAnyResult(() -> gatherInformationAndContinue(fragment,
|
||||
viewModel,
|
||||
onSearchForBackupStarted,
|
||||
onSearchForBackupFinished,
|
||||
actionSkipRestore,
|
||||
actionRestore))
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void restoreFromBackupClicked(@NonNull View view) {
|
||||
boolean isUserSelectionRequired = BackupUtil.isUserSelectionRequired(requireContext());
|
||||
static void restoreFromBackupClicked(@NonNull Fragment fragment,
|
||||
@NonNull RegistrationViewModel viewModel,
|
||||
@NonNull NavDirections actionTransferOrRestore)
|
||||
{
|
||||
boolean isUserSelectionRequired = BackupUtil.isUserSelectionRequired(fragment.requireContext());
|
||||
|
||||
Permissions.with(this)
|
||||
.request(getContinuePermissions(isUserSelectionRequired))
|
||||
Permissions.with(fragment)
|
||||
.request(WelcomePermissions.getWelcomePermissions(isUserSelectionRequired))
|
||||
.ifNecessary()
|
||||
.withRationaleDialog(getString(getContinueRationale(isUserSelectionRequired)), getContinueHeaders(isUserSelectionRequired))
|
||||
.onAnyResult(() -> gatherInformationAndChooseBackup(continueButton))
|
||||
.onAnyResult(() -> gatherInformationAndChooseBackup(fragment, viewModel, actionTransferOrRestore))
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void gatherInformationAndContinue(@NonNull View view) {
|
||||
continueButton.setSpinning();
|
||||
static void gatherInformationAndContinue(
|
||||
@NonNull Fragment fragment,
|
||||
@NonNull RegistrationViewModel viewModel,
|
||||
@NonNull Runnable onSearchForBackupStarted,
|
||||
@NonNull Runnable onSearchForBackupFinished,
|
||||
@NonNull NavDirections actionSkipRestore,
|
||||
@NonNull NavDirections actionRestore
|
||||
) {
|
||||
onSearchForBackupStarted.run();
|
||||
|
||||
RestoreBackupFragment.searchForBackup(backup -> {
|
||||
Context context = getContext();
|
||||
Context context = fragment.getContext();
|
||||
if (context == null) {
|
||||
Log.i(TAG, "No context on fragment, must have navigated away.");
|
||||
return;
|
||||
}
|
||||
|
||||
TextSecurePreferences.setHasSeenWelcomeScreen(requireContext(), true);
|
||||
TextSecurePreferences.setHasSeenWelcomeScreen(fragment.requireContext(), true);
|
||||
|
||||
initializeNumber();
|
||||
initializeNumber(fragment.requireContext(), viewModel);
|
||||
|
||||
continueButton.cancelSpinning();
|
||||
onSearchForBackupFinished.run();
|
||||
|
||||
if (backup == null) {
|
||||
Log.i(TAG, "Skipping backup. No backup found, or no permission to look.");
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(this),
|
||||
WelcomeFragmentDirections.actionSkipRestore());
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(fragment),
|
||||
actionSkipRestore);
|
||||
} else {
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(this),
|
||||
WelcomeFragmentDirections.actionRestore());
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(fragment),
|
||||
actionRestore);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void gatherInformationAndChooseBackup(@NonNull View view) {
|
||||
TextSecurePreferences.setHasSeenWelcomeScreen(requireContext(), true);
|
||||
static void gatherInformationAndChooseBackup(@NonNull Fragment fragment,
|
||||
@NonNull RegistrationViewModel viewModel,
|
||||
@NonNull NavDirections actionTransferOrRestore) {
|
||||
TextSecurePreferences.setHasSeenWelcomeScreen(fragment.requireContext(), true);
|
||||
|
||||
initializeNumber();
|
||||
initializeNumber(fragment.requireContext(), viewModel);
|
||||
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(this),
|
||||
WelcomeFragmentDirections.actionTransferOrRestore());
|
||||
SafeNavigation.safeNavigate(NavHostFragment.findNavController(fragment),
|
||||
actionTransferOrRestore);
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private void initializeNumber() {
|
||||
private static void initializeNumber(@NonNull Context context, @NonNull RegistrationViewModel viewModel) {
|
||||
Optional<Phonenumber.PhoneNumber> localNumber = Optional.empty();
|
||||
|
||||
if (Permissions.hasAll(requireContext(), Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS)) {
|
||||
localNumber = Util.getDeviceNumber(requireContext());
|
||||
if (Permissions.hasAll(context, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_PHONE_NUMBERS)) {
|
||||
localNumber = Util.getDeviceNumber(context);
|
||||
} else {
|
||||
Log.i(TAG, "No phone permission");
|
||||
}
|
||||
@@ -215,7 +238,7 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
viewModel.onNumberDetected(phoneNumber.getCountryCode(), nationalNumber);
|
||||
} else {
|
||||
Log.i(TAG, "No number detected");
|
||||
Optional<String> simCountryIso = Util.getSimCountryIso(requireContext());
|
||||
Optional<String> simCountryIso = Util.getSimCountryIso(context);
|
||||
|
||||
if (simCountryIso.isPresent() && !TextUtils.isEmpty(simCountryIso.get())) {
|
||||
viewModel.onNumberDetected(PhoneNumberUtil.getInstance().getCountryCodeForRegion(simCountryIso.get()), "");
|
||||
@@ -232,23 +255,4 @@ public final class WelcomeFragment extends LoggingFragment {
|
||||
!viewModel.isReregister() &&
|
||||
!SignalStore.settings().isBackupEnabled();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
private static String[] getContinuePermissions(boolean isUserSelectionRequired) {
|
||||
if (isUserSelectionRequired) {
|
||||
return PERMISSIONS_API_29;
|
||||
} else if (Build.VERSION.SDK_INT >= 26) {
|
||||
return PERMISSIONS_API_26;
|
||||
} else {
|
||||
return PERMISSIONS;
|
||||
}
|
||||
}
|
||||
|
||||
private static @StringRes int getContinueRationale(boolean isUserSelectionRequired) {
|
||||
return isUserSelectionRequired ? RATIONALE_API_29 : RATIONALE;
|
||||
}
|
||||
|
||||
private static int[] getContinueHeaders(boolean isUserSelectionRequired) {
|
||||
return isUserSelectionRequired ? HEADERS_API_29 : HEADERS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.thoughtcrime.securesms.registration.fragments
|
||||
|
||||
import android.Manifest
|
||||
import android.os.Build
|
||||
|
||||
/**
|
||||
* Handles welcome permissions instead of having to do weird giant if statements.
|
||||
*/
|
||||
object WelcomePermissions {
|
||||
private enum class Permissions {
|
||||
POST_NOTIFICATIONS {
|
||||
override fun getPermissions(isUserBackupSelectionRequired: Boolean): List<String> {
|
||||
return if (Build.VERSION.SDK_INT >= 33) {
|
||||
listOf(Manifest.permission.POST_NOTIFICATIONS)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
},
|
||||
CONTACTS {
|
||||
override fun getPermissions(isUserBackupSelectionRequired: Boolean): List<String> {
|
||||
return listOf(Manifest.permission.WRITE_CONTACTS, Manifest.permission.READ_CONTACTS)
|
||||
}
|
||||
},
|
||||
STORAGE {
|
||||
override fun getPermissions(isUserBackupSelectionRequired: Boolean): List<String> {
|
||||
return if (Build.VERSION.SDK_INT < 29 || !isUserBackupSelectionRequired) {
|
||||
listOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
},
|
||||
PHONE {
|
||||
override fun getPermissions(isUserBackupSelectionRequired: Boolean): List<String> {
|
||||
return listOf(Manifest.permission.READ_PHONE_STATE) +
|
||||
(if (Build.VERSION.SDK_INT >= 26) listOf(Manifest.permission.READ_PHONE_NUMBERS) else emptyList())
|
||||
}
|
||||
};
|
||||
|
||||
abstract fun getPermissions(isUserBackupSelectionRequired: Boolean): List<String>
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getWelcomePermissions(isUserBackupSelectionRequired: Boolean): Array<String> {
|
||||
return Permissions.values().map { it.getPermissions(isUserBackupSelectionRequired) }.flatten().toTypedArray()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user