Skip to content

Commit

Permalink
Add schedule and retain settings to backups
Browse files Browse the repository at this point in the history
Closes #34
  • Loading branch information
valldrac committed Jun 21, 2021
1 parent be0ad62 commit d1ad2c2
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
Expand All @@ -10,13 +11,14 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.NumberPicker;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AlertDialog;
import androidx.core.text.HtmlCompat;
import androidx.fragment.app.Fragment;

Expand All @@ -32,11 +34,14 @@
import org.thoughtcrime.securesms.jobs.LocalBackupJob;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.service.LocalBackupListener;
import org.thoughtcrime.securesms.util.BackupUtil;
import org.thoughtcrime.securesms.util.StorageUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;

import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

public class BackupsPreferenceFragment extends Fragment {

Expand All @@ -51,6 +56,10 @@ public class BackupsPreferenceFragment extends Fragment {
private TextView info;
private TextView summary;
private TextView folderName;
private View schedule;
private TextView scheduleSummary;
private View maxFiles;
private TextView maxFilesSummary;
private ProgressBar progress;
private TextView progressSummary;

Expand All @@ -68,11 +77,17 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
info = view.findViewById(R.id.fragment_backup_info);
summary = view.findViewById(R.id.fragment_backup_create_summary);
folderName = view.findViewById(R.id.fragment_backup_folder_name);
schedule = view.findViewById(R.id.fragment_backup_schedule);
scheduleSummary = view.findViewById(R.id.fragment_backup_schedule_summary);
maxFiles = view.findViewById(R.id.fragment_backup_max_files);
maxFilesSummary = view.findViewById(R.id.fragment_backup_max_files_summary);
progress = view.findViewById(R.id.fragment_backup_progress);
progressSummary = view.findViewById(R.id.fragment_backup_progress_summary);

toggle.setOnClickListener(unused -> onToggleClicked());
create.setOnClickListener(unused -> onCreateClicked());
schedule.setOnClickListener(unused -> onScheduleClicked());
maxFiles.setOnClickListener(unused -> onMaxFilesClicked());
verify.setOnClickListener(unused -> BackupDialog.showVerifyBackupPassphraseDialog(requireContext()));

EventBus.getDefault().register(this);
Expand All @@ -86,6 +101,8 @@ public void onResume() {
setBackupStatus();
setBackupSummary();
setInfo();
setScheduleSummary();
setMaxFilesSummary();
}

@Override
Expand Down Expand Up @@ -179,6 +196,23 @@ private void setInfo() {
info.setMovementMethod(LinkMovementMethod.getInstance());
}

private void setScheduleSummary() {
final long interval = TextSecurePreferences.getBackupInternal(requireContext());

if (interval == TimeUnit.DAYS.toMillis(1)) {
scheduleSummary.setText(R.string.arrays__daily);
} else if (interval == TimeUnit.DAYS.toMillis(7)) {
scheduleSummary.setText(R.string.arrays__weekly);
} else {
Log.e(TAG, "Unknown schedule interval: " + interval);
scheduleSummary.setText("");
}
}

private void setMaxFilesSummary() {
maxFilesSummary.setText(String.valueOf(TextSecurePreferences.getBackupMaxFiles(requireContext())));
}

private void onToggleClicked() {
if (BackupUtil.isUserSelectionRequired(requireContext())) {
onToggleClickedApi29();
Expand Down Expand Up @@ -219,6 +253,45 @@ private void onCreateClicked() {
}
}

private void onScheduleClicked() {
new AlertDialog.Builder(requireContext())
.setTitle(R.string.BackupsPreferenceFragment__change_schedule)
.setItems(R.array.backup_intervals, (dialog, which) -> {
Context context = requireContext();

if (which == 1) {
TextSecurePreferences.setBackupInternal(context, TimeUnit.DAYS.toMillis(7));
} else {
TextSecurePreferences.setBackupInternal(context, TimeUnit.DAYS.toMillis(1));
}

LocalBackupListener.setNextBackupTimeToIntervalFromNow(context);
LocalBackupListener.schedule(context);
setScheduleSummary();
})
.create()
.show();
}

private void onMaxFilesClicked() {
final View view = getLayoutInflater().inflate(R.layout.backup_max_files_selector_view, null);
final NumberPicker picker = (NumberPicker) view.findViewById(R.id.picker);
picker.setMinValue(1);
picker.setMaxValue(10);
picker.setValue(TextSecurePreferences.getBackupMaxFiles(requireContext()));
picker.setWrapSelectorWheel(false);
new AlertDialog.Builder(requireContext())
.setTitle(R.string.BackupsPreferenceFragment__number_of_backups_to_retain)
.setView(view)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
TextSecurePreferences.setBackupMaxFiles(requireContext(), picker.getValue());
setMaxFilesSummary();
})
.create()
.show();
}

@RequiresApi(29)
private void onCreateClickedApi29() {
Log.i(TAG, "Queing backup...");
Expand All @@ -240,6 +313,8 @@ private void onCreateClickedLegacy() {
private void setBackupsEnabled() {
toggle.setText(R.string.BackupsPreferenceFragment__turn_off);
create.setVisibility(View.VISIBLE);
schedule.setVisibility(View.VISIBLE);
maxFiles.setVisibility(View.VISIBLE);
verify.setVisibility(View.VISIBLE);
setBackupFolderName();
}
Expand All @@ -248,6 +323,8 @@ private void setBackupsDisabled() {
toggle.setText(R.string.BackupsPreferenceFragment__turn_on);
create.setVisibility(View.GONE);
folder.setVisibility(View.GONE);
schedule.setVisibility(View.GONE);
maxFiles.setVisibility(View.GONE);
verify.setVisibility(View.GONE);
ApplicationDependencies.getJobManager().cancelAllInQueue(LocalBackupJob.QUEUE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,8 @@
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.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);
Expand All @@ -37,7 +33,7 @@ public static void schedule(Context context) {
}

public static long setNextBackupTimeToIntervalFromNow(@NonNull Context context) {
long nextTime = System.currentTimeMillis() + INTERVAL;
long nextTime = System.currentTimeMillis() + TextSecurePreferences.getBackupInternal(context);
TextSecurePreferences.setNextBackupTime(context, nextTime);

return nextTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,14 @@ public static void deleteAllBackups() {
}

public static void deleteOldBackups() {
Log.i(TAG, "Deleting older backups");
int maxFiles = TextSecurePreferences.getBackupMaxFiles(ApplicationDependencies.getApplication());

Log.i(TAG, "Deleting older backups. Keep " + maxFiles + " max.");

try {
List<BackupInfo> backups = getAllBackupsNewestFirst();

for (int i = 2; i < backups.size(); i++) {
for (int i = maxFiles; i < backups.size(); i++) {
backups.get(i).delete();
}
} catch (NoExternalStorageException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class TextSecurePreferences {

Expand Down Expand Up @@ -127,6 +128,8 @@ public class TextSecurePreferences {
private static final String BACKUP_PASSPHRASE = "pref_backup_passphrase";
private static final String ENCRYPTED_BACKUP_PASSPHRASE = "pref_encrypted_backup_passphrase";
private static final String BACKUP_TIME = "pref_backup_next_time";
private static final String BACKUP_INTERVAL = "pref_backup_interval";
private static final String BACKUP_MAX_FILES = "pref_backup_max_files";

public static final String TRANSFER = "pref_transfer";

Expand Down Expand Up @@ -427,6 +430,22 @@ public static long getNextBackupTime(@NonNull Context context) {
return getLongPreference(context, BACKUP_TIME, -1);
}

public static void setBackupInternal(@NonNull Context context, long value) {
setLongPreference(context, BACKUP_INTERVAL, value);
}

public static long getBackupInternal(@NonNull Context context) {
return getLongPreference(context, BACKUP_INTERVAL, TimeUnit.DAYS.toMillis(1));
}

public static void setBackupMaxFiles(@NonNull Context context, int value) {
setIntegerPrefrence(context, BACKUP_MAX_FILES, value);
}

public static int getBackupMaxFiles(@NonNull Context context) {
return getIntegerPreference(context, BACKUP_MAX_FILES, 2);
}

public static int getNextPreKeyId(@NonNull Context context) {
return getIntegerPreference(context, NEXT_PRE_KEY_ID, new SecureRandom().nextInt(Medium.MAX_VALUE));
}
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/res/layout/backup_max_files_selector_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center">

<NumberPicker
android:id="@+id/picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp" />

</LinearLayout>
58 changes: 58 additions & 0 deletions app/src/main/res/layout/fragment_backups.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,64 @@
android:textColor="@color/signal_text_secondary" />
</LinearLayout>

<LinearLayout
android:id="@+id/fragment_backup_schedule"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightLarge"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/BackupsPreferenceFragment__schedule"
android:textAppearance="@style/Signal.Text.Body"
android:textColor="@color/signal_text_primary" />

<TextView
android:id="@+id/fragment_backup_schedule_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/Signal.Text.Preview"
android:textColor="@color/signal_text_secondary" />
</LinearLayout>

<LinearLayout
android:id="@+id/fragment_backup_max_files"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightLarge"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@string/BackupsPreferenceFragment__number_of_backups_to_retain"
android:textAppearance="@style/Signal.Text.Body"
android:textColor="@color/signal_text_primary" />

<TextView
android:id="@+id/fragment_backup_max_files_summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/Signal.Text.Preview"
android:textColor="@color/signal_text_secondary" />
</LinearLayout>

<LinearLayout
android:id="@+id/fragment_backup_verify"
android:layout_width="match_parent"
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@
<item>@string/MediaOverviewActivity_Storage_used</item>
</string-array>

<string-array name="backup_intervals">
<item>@string/arrays__daily</item>
<item>@string/arrays__weekly</item>
</string-array>

<string-array name="ExpireTimerSettingsFragment__labels">
<item>@string/ExpireTimerSettingsFragment__off</item>
<item>@string/ExpireTimerSettingsFragment__4_weeks</item>
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/strings2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@
<string name="DonateMegaphone_we_maintain_molly_with_your_support_consider_donating_at_open_collective">We maintain Molly with your support! Consider donating at Open Collective.</string>
<string name="Megaphones_automatic_check_for_updates">Automatic check for updates</string>
<string name="BlockUnblockDialog_block_and_delete">Block and Delete</string>
<string name="BackupsPreferenceFragment__schedule">Schedule</string>
<string name="arrays__daily">Daily</string>
<string name="arrays__weekly">Weekly</string>
<string name="BackupsPreferenceFragment__change_schedule">Change schedule</string>
<string name="BackupsPreferenceFragment__number_of_backups_to_retain">Number of backups to retain</string>
</resources>

0 comments on commit d1ad2c2

Please sign in to comment.