mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-15 22:43:19 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
643dd0b679 | ||
|
|
2b45b3caa2 | ||
|
|
b7282589de | ||
|
|
6bc7f2a5a4 | ||
|
|
3731e2a74a | ||
|
|
bb40f38124 | ||
|
|
f0e5aa312e | ||
|
|
ceafb0d130 | ||
|
|
70c2a863cc | ||
|
|
d813275f42 | ||
|
|
5650a02cfb | ||
|
|
0503c9eea5 | ||
|
|
abae419853 | ||
|
|
71ccbf2a1b | ||
|
|
92a64f59a4 | ||
|
|
6d56447de2 | ||
|
|
e189fff856 |
@@ -257,8 +257,8 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionCode 361
|
||||
versionName "4.20.3"
|
||||
versionCode 364
|
||||
versionName "4.20.6"
|
||||
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 25
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle" >
|
||||
<solid android:color="@color/grey_200"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:top="1dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<solid android:color="?attr/search_background" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/Base.TextAppearance.AppCompat.Body2"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="8dp"
|
||||
android:background="@drawable/header_search_background"
|
||||
tools:text="Conversations">
|
||||
|
||||
</TextView>
|
||||
@@ -266,7 +266,8 @@ public class ConversationFragment extends Fragment
|
||||
|
||||
menu.findItem(R.id.menu_context_forward).setVisible(!actionMessage);
|
||||
menu.findItem(R.id.menu_context_details).setVisible(!actionMessage);
|
||||
menu.findItem(R.id.menu_context_reply).setVisible(!messageRecord.isPending() &&
|
||||
menu.findItem(R.id.menu_context_reply).setVisible(!actionMessage &&
|
||||
!messageRecord.isPending() &&
|
||||
!messageRecord.isFailed() &&
|
||||
messageRecord.isSecure());
|
||||
}
|
||||
|
||||
@@ -315,11 +315,17 @@ public class ConversationListItem extends RelativeLayout
|
||||
unreadIndicator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private Spanned getHighlightedSpan(@NonNull Locale locale,
|
||||
private Spanned getHighlightedSpan(@NonNull Locale locale,
|
||||
@Nullable String value,
|
||||
@Nullable String highlight)
|
||||
{
|
||||
if (value == null || highlight == null) {
|
||||
if (value == null) {
|
||||
return new SpannableString("");
|
||||
}
|
||||
|
||||
value = value.replaceAll("\n", " ");
|
||||
|
||||
if (highlight == null) {
|
||||
return new SpannableString(value);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsColumns;
|
||||
import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase;
|
||||
import org.thoughtcrime.securesms.database.SearchDatabase;
|
||||
import org.thoughtcrime.securesms.database.SessionDatabase;
|
||||
import org.thoughtcrime.securesms.database.SignedPreKeyDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
@@ -76,9 +77,11 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
count = exportTable(table, input, outputStream, cursor -> cursor.getInt(cursor.getColumnIndexOrThrow(MmsSmsColumns.EXPIRES_IN)) <= 0, null, count);
|
||||
} else if (table.equals(AttachmentDatabase.TABLE_NAME)) {
|
||||
count = exportTable(table, input, outputStream, null, cursor -> exportAttachment(attachmentSecret, cursor, outputStream), count);
|
||||
} else if (!table.equals(SignedPreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(OneTimePreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(SessionDatabase.TABLE_NAME))
|
||||
} else if (!table.equals(SignedPreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(OneTimePreKeyDatabase.TABLE_NAME) &&
|
||||
!table.equals(SessionDatabase.TABLE_NAME) &&
|
||||
!table.startsWith(SearchDatabase.SMS_FTS_TABLE_NAME) &&
|
||||
!table.startsWith(SearchDatabase.MMS_FTS_TABLE_NAME))
|
||||
{
|
||||
count = exportTable(table, input, outputStream, null, null, count);
|
||||
}
|
||||
@@ -111,14 +114,17 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
String type = cursor.getString(2);
|
||||
|
||||
if (sql != null) {
|
||||
if ("table".equals(type)) {
|
||||
outputStream.write(BackupProtos.SqlStatement.newBuilder().setStatement("DROP TABLE IF EXISTS " + name).build());
|
||||
tables.add(name);
|
||||
} else if ("index".equals(type)) {
|
||||
outputStream.write(BackupProtos.SqlStatement.newBuilder().setStatement("DROP INDEX IF EXISTS " + name).build());
|
||||
}
|
||||
|
||||
outputStream.write(BackupProtos.SqlStatement.newBuilder().setStatement(cursor.getString(0)).build());
|
||||
boolean isSmsFtsSecretTable = name != null && !name.equals(SearchDatabase.SMS_FTS_TABLE_NAME) && name.startsWith(SearchDatabase.SMS_FTS_TABLE_NAME);
|
||||
boolean isMmsFtsSecretTable = name != null && !name.equals(SearchDatabase.MMS_FTS_TABLE_NAME) && name.startsWith(SearchDatabase.MMS_FTS_TABLE_NAME);
|
||||
|
||||
if (!isSmsFtsSecretTable && !isMmsFtsSecretTable) {
|
||||
if ("table".equals(type)) {
|
||||
tables.add(name);
|
||||
}
|
||||
|
||||
outputStream.write(BackupProtos.SqlStatement.newBuilder().setStatement(cursor.getString(0)).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
@@ -20,6 +22,7 @@ import org.thoughtcrime.securesms.crypto.AttachmentSecret;
|
||||
import org.thoughtcrime.securesms.crypto.ModernEncryptingPartOutputStream;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.database.SearchDatabase;
|
||||
import org.thoughtcrime.securesms.profiles.AvatarHelper;
|
||||
import org.thoughtcrime.securesms.util.Conversions;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
@@ -36,6 +39,7 @@ import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -62,6 +66,8 @@ public class FullBackupImporter extends FullBackupBase {
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
dropAllTables(db);
|
||||
|
||||
BackupFrame frame;
|
||||
|
||||
while (!(frame = inputStream.readFrame()).getEnd()) {
|
||||
@@ -87,6 +93,14 @@ public class FullBackupImporter extends FullBackupBase {
|
||||
}
|
||||
|
||||
private static void processStatement(@NonNull SQLiteDatabase db, SqlStatement statement) {
|
||||
boolean isForSmsFtsSecretTable = statement.getStatement().contains(SearchDatabase.SMS_FTS_TABLE_NAME + "_");
|
||||
boolean isForMmsFtsSecretTable = statement.getStatement().contains(SearchDatabase.MMS_FTS_TABLE_NAME + "_");
|
||||
|
||||
if (isForSmsFtsSecretTable || isForMmsFtsSecretTable) {
|
||||
Log.i(TAG, "Ignoring import for statement: " + statement.getStatement());
|
||||
return;
|
||||
}
|
||||
|
||||
List<Object> parameters = new LinkedList<>();
|
||||
|
||||
for (SqlStatement.SqlParameter parameter : statement.getParametersList()) {
|
||||
@@ -131,6 +145,19 @@ public class FullBackupImporter extends FullBackupBase {
|
||||
preferences.edit().putString(preference.getKey(), preference.getValue()).commit();
|
||||
}
|
||||
|
||||
private static void dropAllTables(@NonNull SQLiteDatabase db) {
|
||||
try (Cursor cursor = db.rawQuery("SELECT name, type FROM sqlite_master", null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
String name = cursor.getString(0);
|
||||
String type = cursor.getString(1);
|
||||
|
||||
if ("table".equals(type)) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class BackupRecordInputStream extends BackupStream {
|
||||
|
||||
private final InputStream in;
|
||||
|
||||
@@ -11,19 +11,23 @@ import android.text.SpannableStringBuilder;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ViewTreeObserver;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
|
||||
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
|
||||
public class EmojiTextView extends AppCompatTextView {
|
||||
|
||||
private final boolean scaleEmojis;
|
||||
|
||||
private CharSequence source;
|
||||
private CharSequence previousText;
|
||||
private BufferType previousBufferType;
|
||||
private float originalFontSize;
|
||||
private boolean useSystemEmoji;
|
||||
private boolean sizeChangeInProgress;
|
||||
|
||||
public EmojiTextView(Context context) {
|
||||
this(context, null);
|
||||
@@ -46,67 +50,102 @@ public class EmojiTextView extends AppCompatTextView {
|
||||
}
|
||||
|
||||
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
||||
EmojiProvider provider = EmojiProvider.getInstance(getContext());
|
||||
EmojiProvider provider = EmojiProvider.getInstance(getContext());
|
||||
EmojiParser.CandidateList candidates = provider.getCandidates(text);
|
||||
|
||||
if (scaleEmojis && candidates != null && candidates.allEmojis) {
|
||||
int emojis = candidates.size();
|
||||
float scale = 1.0f;
|
||||
int emojis = candidates.size();
|
||||
float scale = 1.0f;
|
||||
|
||||
if (emojis <= 8) scale += 0.25f;
|
||||
if (emojis <= 6) scale += 0.25f;
|
||||
if (emojis <= 4) scale += 0.25f;
|
||||
if (emojis <= 2) scale += 0.25f;
|
||||
|
||||
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, originalFontSize * scale);
|
||||
} else if (scaleEmojis) {
|
||||
super.setTextSize(TypedValue.COMPLEX_UNIT_PX, originalFontSize);
|
||||
}
|
||||
|
||||
if (useSystemEmoji()) {
|
||||
super.setText(text, type);
|
||||
if (unchanged(text, type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
source = EmojiProvider.getInstance(getContext()).emojify(candidates, text, this);
|
||||
super.setText(source, BufferType.SPANNABLE);
|
||||
previousText = text;
|
||||
previousBufferType = type;
|
||||
useSystemEmoji = useSystemEmoji();
|
||||
|
||||
if (useSystemEmoji || candidates == null || candidates.size() == 0) {
|
||||
super.setText(text, BufferType.NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
CharSequence emojified = provider.emojify(candidates, text, this);
|
||||
super.setText(emojified, BufferType.SPANNABLE);
|
||||
|
||||
// Android fails to ellipsize spannable strings. (https://issuetracker.google.com/issues/36991688)
|
||||
// We ellipsize them ourselves by manually truncating the appropriate section.
|
||||
if (getEllipsize() == TextUtils.TruncateAt.END) {
|
||||
post(() -> {
|
||||
int maxLines = TextViewCompat.getMaxLines(EmojiTextView.this);
|
||||
if (maxLines <= 0) {
|
||||
return;
|
||||
}
|
||||
int lineCount = getLineCount();
|
||||
if (lineCount > maxLines) {
|
||||
int overflowStart = getLayout().getLineStart(maxLines - 1);
|
||||
CharSequence overflow = getText().subSequence(overflowStart, getText().length());
|
||||
CharSequence ellipsized = TextUtils.ellipsize(overflow, getPaint(), getWidth(), TextUtils.TruncateAt.END);
|
||||
|
||||
SpannableStringBuilder newContent = new SpannableStringBuilder();
|
||||
newContent.append(getText().subSequence(0, overflowStart))
|
||||
.append(ellipsized);
|
||||
super.setText(newContent);
|
||||
}
|
||||
});
|
||||
ellipsize();
|
||||
}
|
||||
}
|
||||
|
||||
private void ellipsize() {
|
||||
post(() -> {
|
||||
if (getLayout() == null) {
|
||||
ellipsize();
|
||||
return;
|
||||
}
|
||||
|
||||
int maxLines = TextViewCompat.getMaxLines(EmojiTextView.this);
|
||||
if (maxLines <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lineCount = getLineCount();
|
||||
if (lineCount > maxLines) {
|
||||
int overflowStart = getLayout().getLineStart(maxLines - 1);
|
||||
CharSequence overflow = getText().subSequence(overflowStart, getText().length());
|
||||
CharSequence ellipsized = TextUtils.ellipsize(overflow, getPaint(), getWidth(), TextUtils.TruncateAt.END);
|
||||
|
||||
SpannableStringBuilder newContent = new SpannableStringBuilder();
|
||||
newContent.append(getText().subSequence(0, overflowStart))
|
||||
.append(ellipsized.subSequence(0, ellipsized.length()));
|
||||
|
||||
EmojiParser.CandidateList newCandidates = EmojiProvider.getInstance(getContext()).getCandidates(newContent);
|
||||
CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this);
|
||||
|
||||
super.setText(emojified, BufferType.SPANNABLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean unchanged(CharSequence text, BufferType bufferType) {
|
||||
return Util.equals(previousText, text) &&
|
||||
Util.equals(previousBufferType, bufferType) &&
|
||||
useSystemEmoji == useSystemEmoji() &&
|
||||
!sizeChangeInProgress;
|
||||
}
|
||||
|
||||
private boolean useSystemEmoji() {
|
||||
return TextSecurePreferences.isSystemEmojiPreferred(getContext());
|
||||
}
|
||||
|
||||
@Override public void invalidateDrawable(@NonNull Drawable drawable) {
|
||||
if (drawable instanceof EmojiDrawable) invalidate();
|
||||
else super.invalidateDrawable(drawable);
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
|
||||
if (!sizeChangeInProgress) {
|
||||
sizeChangeInProgress = true;
|
||||
setText(previousText, previousBufferType);
|
||||
sizeChangeInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
if (changed && !useSystemEmoji()) {
|
||||
super.setText(source, BufferType.SPANNABLE);
|
||||
}
|
||||
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
@Override
|
||||
public void invalidateDrawable(@NonNull Drawable drawable) {
|
||||
if (drawable instanceof EmojiDrawable) invalidate();
|
||||
else super.invalidateDrawable(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -63,6 +63,7 @@ public class ContactsCursorLoader extends CursorLoader {
|
||||
ContactsDatabase.LABEL_COLUMN,
|
||||
ContactsDatabase.CONTACT_TYPE_COLUMN};
|
||||
|
||||
private static final int RECENT_CONVERSATION_MAX = 25;
|
||||
|
||||
private final String filter;
|
||||
private final int mode;
|
||||
@@ -163,8 +164,8 @@ public class ContactsCursorLoader extends CursorLoader {
|
||||
private Cursor getRecentConversationsCursor() {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(getContext());
|
||||
|
||||
MatrixCursor recentConversations = new MatrixCursor(CONTACT_PROJECTION, 5);
|
||||
try (Cursor rawConversations = threadDatabase.getRecentConversationList(5)) {
|
||||
MatrixCursor recentConversations = new MatrixCursor(CONTACT_PROJECTION, RECENT_CONVERSATION_MAX);
|
||||
try (Cursor rawConversations = threadDatabase.getRecentConversationList(RECENT_CONVERSATION_MAX)) {
|
||||
ThreadDatabase.Reader reader = threadDatabase.readerFor(rawConversations);
|
||||
ThreadRecord threadRecord;
|
||||
while ((threadRecord = reader.getNext()) != null) {
|
||||
|
||||
@@ -30,8 +30,6 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
public CursorList(@NonNull Cursor cursor, @NonNull ModelBuilder<T> modelBuilder) {
|
||||
this.cursor = cursor;
|
||||
this.modelBuilder = modelBuilder;
|
||||
|
||||
this.cursor.moveToFirst();
|
||||
}
|
||||
|
||||
public static <T> CursorList<T> emptyList() {
|
||||
@@ -58,6 +56,8 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
int index = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return cursor.getCount() > 0 && !cursor.isLast();
|
||||
@@ -65,9 +65,8 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
T model = modelBuilder.build(cursor);
|
||||
cursor.moveToNext();
|
||||
return model;
|
||||
cursor.moveToPosition(index++);
|
||||
return modelBuilder.build(cursor);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -179,7 +178,7 @@ public class CursorList<T> implements List<T>, Closeable {
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (cursor != null) {
|
||||
if (!cursor.isClosed()) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,7 @@ public class SearchDatabase extends Database {
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ADDRESS + ", " +
|
||||
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
SmsDatabase.TABLE_NAME + "." + SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
MmsSmsColumns.THREAD_ID + ", " +
|
||||
"bm25(" + SMS_FTS_TABLE_NAME + ") AS " + RANK + " " +
|
||||
MmsSmsColumns.THREAD_ID + " " +
|
||||
"FROM " + SmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + SMS_FTS_TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + ID + " = " + SmsDatabase.TABLE_NAME + "." + SmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + SmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
@@ -67,13 +66,12 @@ public class SearchDatabase extends Database {
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ADDRESS + ", " +
|
||||
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
MmsSmsColumns.THREAD_ID + ", " +
|
||||
"bm25(" + MMS_FTS_TABLE_NAME + ") AS " + RANK + " " +
|
||||
MmsSmsColumns.THREAD_ID + " " +
|
||||
"FROM " + MmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + MmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? " +
|
||||
"ORDER BY rank " +
|
||||
"ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC " +
|
||||
"LIMIT 500";
|
||||
|
||||
public SearchDatabase(@NonNull Context context, @NonNull SQLCipherOpenHelper databaseHelper) {
|
||||
|
||||
@@ -52,7 +52,7 @@ public class LocalBackupJob extends ContextJob {
|
||||
|
||||
try {
|
||||
String backupPassword = TextSecurePreferences.getBackupPassphrase(context);
|
||||
File backupDirectory = StorageUtil.getBackupCacheDirectory(context);
|
||||
File backupDirectory = StorageUtil.getBackupDirectory(context);
|
||||
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US).format(new Date());
|
||||
String fileName = String.format("signal-%s.backup", timestamp);
|
||||
File backupFile = new File(backupDirectory, fileName);
|
||||
@@ -65,7 +65,7 @@ public class LocalBackupJob extends ContextJob {
|
||||
throw new IOException("Backup password is null");
|
||||
}
|
||||
|
||||
File tempFile = File.createTempFile("backup", "tmp", context.getExternalCacheDir());
|
||||
File tempFile = File.createTempFile("backup", "tmp", StorageUtil.getBackupCacheDirectory(context));
|
||||
|
||||
FullBackupExporter.export(context,
|
||||
AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(),
|
||||
|
||||
@@ -97,7 +97,7 @@ class SearchListAdapter extends RecyclerView.Adapter<SearchListAdapter.Search
|
||||
@Override
|
||||
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.header_search_result, parent, false));
|
||||
.inflate(R.layout.contact_selection_list_divider, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -199,7 +199,7 @@ class SearchListAdapter extends RecyclerView.Adapter<SearchListAdapter.Search
|
||||
|
||||
public HeaderViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
titleView = (TextView) itemView;
|
||||
titleView = itemView.findViewById(R.id.label);
|
||||
}
|
||||
|
||||
public void bind(int headerType) {
|
||||
|
||||
@@ -47,6 +47,7 @@ class SearchViewModel extends ViewModel {
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
debouncer.clear();
|
||||
searchResult.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,4 +29,8 @@ public class Debouncer {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
handler.postDelayed(runnable, threshold);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
handler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,7 @@ import org.thoughtcrime.securesms.database.NoExternalStorageException;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class StorageUtil
|
||||
{
|
||||
public class StorageUtil {
|
||||
|
||||
public static File getBackupDirectory(Context context) throws NoExternalStorageException {
|
||||
File storage = null;
|
||||
@@ -43,7 +42,6 @@ public class StorageUtil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return backups;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user