kopia lustrzana https://github.com/ryukoposting/Signal-Android
Migrate legacy color palette.
We don't store non-user-selected colors in the database. That means that when we update the palette, we still have to hash based off of the legacy palette when generating a color if we want to migrate to a similar-looking color. Unfortunately, because the new palette is smaller, some colors are "overloaded", meaning that when we hash based off of the legacy palette, some colors will be more/less common than others. To fix this, we simply persist all current colors in the database, then switch our hashing list to what we really want.fork-5.53.8
rodzic
5eec3c9541
commit
547b7a3c6f
|
@ -30,6 +30,8 @@ import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
import org.thoughtcrime.securesms.jobmanager.JobManager;
|
||||||
import org.thoughtcrime.securesms.jobmanager.persistence.JavaJobSerializer;
|
import org.thoughtcrime.securesms.jobmanager.persistence.JavaJobSerializer;
|
||||||
import org.thoughtcrime.securesms.jobmanager.persistence.PersistentStorage;
|
import org.thoughtcrime.securesms.jobmanager.persistence.PersistentStorage;
|
||||||
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
|
import org.thoughtcrime.securesms.contacts.avatars.ContactColorsLegacy;
|
||||||
import org.thoughtcrime.securesms.logging.Log;
|
import org.thoughtcrime.securesms.logging.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
@ -50,6 +52,7 @@ import org.thoughtcrime.securesms.jobs.PushDecryptJob;
|
||||||
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob;
|
||||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||||
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
import org.thoughtcrime.securesms.notifications.MessageNotifier;
|
||||||
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||||
import org.thoughtcrime.securesms.util.FileUtils;
|
import org.thoughtcrime.securesms.util.FileUtils;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
@ -91,6 +94,7 @@ public class DatabaseUpgradeActivity extends BaseActivity {
|
||||||
public static final int BAD_IMPORT_CLEANUP = 373;
|
public static final int BAD_IMPORT_CLEANUP = 373;
|
||||||
public static final int IMAGE_CACHE_CLEANUP = 406;
|
public static final int IMAGE_CACHE_CLEANUP = 406;
|
||||||
public static final int WORKMANAGER_MIGRATION = 408;
|
public static final int WORKMANAGER_MIGRATION = 408;
|
||||||
|
public static final int COLOR_MIGRATION = 412;
|
||||||
|
|
||||||
private static final SortedSet<Integer> UPGRADE_VERSIONS = new TreeSet<Integer>() {{
|
private static final SortedSet<Integer> UPGRADE_VERSIONS = new TreeSet<Integer>() {{
|
||||||
add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
|
add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
|
||||||
|
@ -115,6 +119,7 @@ public class DatabaseUpgradeActivity extends BaseActivity {
|
||||||
add(BAD_IMPORT_CLEANUP);
|
add(BAD_IMPORT_CLEANUP);
|
||||||
add(IMAGE_CACHE_CLEANUP);
|
add(IMAGE_CACHE_CLEANUP);
|
||||||
add(WORKMANAGER_MIGRATION);
|
add(WORKMANAGER_MIGRATION);
|
||||||
|
add(COLOR_MIGRATION);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private MasterSecret masterSecret;
|
private MasterSecret masterSecret;
|
||||||
|
@ -337,6 +342,22 @@ public class DatabaseUpgradeActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params[0] < COLOR_MIGRATION) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
DatabaseFactory.getRecipientDatabase(context).updateSystemContactColors((name, color) -> {
|
||||||
|
if (color != null) {
|
||||||
|
try {
|
||||||
|
return MaterialColor.fromSerialized(color);
|
||||||
|
} catch (MaterialColor.UnknownColorException e) {
|
||||||
|
Log.w(TAG, "Encountered an unknown color during legacy color migration.", e);
|
||||||
|
return ContactColorsLegacy.generateFor(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ContactColorsLegacy.generateFor(name);
|
||||||
|
});
|
||||||
|
Log.i(TAG, "Color migration took " + (System.currentTimeMillis() - startTime) + " ms");
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public enum MaterialColor {
|
||||||
|
|
||||||
private static final Map<String, MaterialColor> COLOR_MATCHES = new HashMap<String, MaterialColor>() {{
|
private static final Map<String, MaterialColor> COLOR_MATCHES = new HashMap<String, MaterialColor>() {{
|
||||||
put("red", CRIMSON);
|
put("red", CRIMSON);
|
||||||
put("deep_orange", VERMILLION);
|
put("deep_orange", CRIMSON);
|
||||||
put("orange", VERMILLION);
|
put("orange", VERMILLION);
|
||||||
put("amber", VERMILLION);
|
put("amber", VERMILLION);
|
||||||
put("brown", BURLAP);
|
put("brown", BURLAP);
|
||||||
|
|
|
@ -5,35 +5,30 @@ import android.support.annotation.NonNull;
|
||||||
import org.thoughtcrime.securesms.color.MaterialColor;
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
import org.thoughtcrime.securesms.color.MaterialColors;
|
import org.thoughtcrime.securesms.color.MaterialColors;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ContactColors {
|
public class ContactColors {
|
||||||
|
|
||||||
public static final MaterialColor UNKNOWN_COLOR = MaterialColor.STEEL;
|
public static final MaterialColor UNKNOWN_COLOR = MaterialColor.STEEL;
|
||||||
|
|
||||||
private static final String[] LEGACY_PALETTE = new String[] {
|
private static final List<MaterialColor> CONVERSATION_PALETTE = new ArrayList<>(Arrays.asList(
|
||||||
"red",
|
MaterialColor.PLUM,
|
||||||
"pink",
|
MaterialColor.CRIMSON,
|
||||||
"purple",
|
MaterialColor.VERMILLION,
|
||||||
"deep_purple",
|
MaterialColor.VIOLET,
|
||||||
"indigo",
|
MaterialColor.BLUE,
|
||||||
"blue",
|
MaterialColor.INDIGO,
|
||||||
"light_blue",
|
MaterialColor.FOREST,
|
||||||
"cyan",
|
MaterialColor.WINTERGREEN,
|
||||||
"teal",
|
MaterialColor.TEAL,
|
||||||
"green",
|
MaterialColor.BURLAP,
|
||||||
"light_green",
|
MaterialColor.TAUPE,
|
||||||
"orange",
|
MaterialColor.STEEL
|
||||||
"deep_orange",
|
));
|
||||||
"amber",
|
|
||||||
"blue_grey"
|
|
||||||
};
|
|
||||||
|
|
||||||
public static MaterialColor generateFor(@NonNull String name) {
|
public static MaterialColor generateFor(@NonNull String name) {
|
||||||
String serialized = LEGACY_PALETTE[Math.abs(name.hashCode()) % LEGACY_PALETTE.length];
|
return CONVERSATION_PALETTE.get(Math.abs(name.hashCode()) % CONVERSATION_PALETTE.size());
|
||||||
try {
|
|
||||||
return MaterialColor.fromSerialized(serialized);
|
|
||||||
} catch (MaterialColor.UnknownColorException e) {
|
|
||||||
return MaterialColors.CONVERSATION_PALETTE.get(Math.abs(name.hashCode()) % MaterialColors.CONVERSATION_PALETTE.size());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.thoughtcrime.securesms.contacts.avatars;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.color.MaterialColor;
|
||||||
|
import org.thoughtcrime.securesms.color.MaterialColors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for migrating legacy colors to modern colors. For normal color generation, use
|
||||||
|
* {@link ContactColors}.
|
||||||
|
*/
|
||||||
|
public class ContactColorsLegacy {
|
||||||
|
|
||||||
|
private static final String[] LEGACY_PALETTE = new String[] {
|
||||||
|
"red",
|
||||||
|
"pink",
|
||||||
|
"purple",
|
||||||
|
"deep_purple",
|
||||||
|
"indigo",
|
||||||
|
"blue",
|
||||||
|
"light_blue",
|
||||||
|
"cyan",
|
||||||
|
"teal",
|
||||||
|
"green",
|
||||||
|
"light_green",
|
||||||
|
"orange",
|
||||||
|
"deep_orange",
|
||||||
|
"amber",
|
||||||
|
"blue_grey"
|
||||||
|
};
|
||||||
|
|
||||||
|
public static MaterialColor generateFor(@NonNull String name) {
|
||||||
|
String serialized = LEGACY_PALETTE[Math.abs(name.hashCode()) % LEGACY_PALETTE.length];
|
||||||
|
try {
|
||||||
|
return MaterialColor.fromSerialized(serialized);
|
||||||
|
} catch (MaterialColor.UnknownColorException e) {
|
||||||
|
return ContactColors.generateFor(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class RecipientDatabase extends Database {
|
public class RecipientDatabase extends Database {
|
||||||
|
|
||||||
|
@ -150,7 +151,6 @@ public class RecipientDatabase extends Database {
|
||||||
return new RecipientReader(context, cursor);
|
return new RecipientReader(context, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Optional<RecipientSettings> getRecipientSettings(@NonNull Address address) {
|
public Optional<RecipientSettings> getRecipientSettings(@NonNull Address address) {
|
||||||
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
SQLiteDatabase database = databaseHelper.getReadableDatabase();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
@ -410,6 +410,35 @@ public class RecipientDatabase extends Database {
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateSystemContactColors(@NonNull ColorUpdater updater) {
|
||||||
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
|
Map<Address, MaterialColor> updates = new HashMap<>();
|
||||||
|
|
||||||
|
db.beginTransaction();
|
||||||
|
try (Cursor cursor = db.query(TABLE_NAME, new String[] {ADDRESS, COLOR, SYSTEM_DISPLAY_NAME}, SYSTEM_DISPLAY_NAME + " IS NOT NULL AND " + SYSTEM_DISPLAY_NAME + " != \"\"", null, null, null, null)) {
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS)));
|
||||||
|
MaterialColor newColor = updater.update(cursor.getString(cursor.getColumnIndexOrThrow(SYSTEM_DISPLAY_NAME)),
|
||||||
|
cursor.getString(cursor.getColumnIndexOrThrow(COLOR)));
|
||||||
|
|
||||||
|
ContentValues contentValues = new ContentValues(1);
|
||||||
|
contentValues.put(COLOR, newColor.serialize());
|
||||||
|
db.update(TABLE_NAME, contentValues, ADDRESS + " = ?", new String[]{address.serialize()});
|
||||||
|
|
||||||
|
updates.put(address, newColor);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
db.setTransactionSuccessful();
|
||||||
|
db.endTransaction();
|
||||||
|
|
||||||
|
Stream.of(updates.entrySet()).forEach(entry -> {
|
||||||
|
Recipient.applyCached(entry.getKey(), recipient -> {
|
||||||
|
recipient.setColor(entry.getValue());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX This shouldn't be here, and is just a temporary workaround
|
// XXX This shouldn't be here, and is just a temporary workaround
|
||||||
public RegisteredState isRegistered(@NonNull Address address) {
|
public RegisteredState isRegistered(@NonNull Address address) {
|
||||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||||
|
@ -472,6 +501,10 @@ public class RecipientDatabase extends Database {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ColorUpdater {
|
||||||
|
MaterialColor update(@NonNull String name, @Nullable String color);
|
||||||
|
}
|
||||||
|
|
||||||
public static class RecipientSettings {
|
public static class RecipientSettings {
|
||||||
private final boolean blocked;
|
private final boolean blocked;
|
||||||
private final long muteUntil;
|
private final long muteUntil;
|
||||||
|
@ -633,7 +666,7 @@ public class RecipientDatabase extends Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Recipient getNext() {
|
public @Nullable Recipient getNext() {
|
||||||
if (!cursor.moveToNext()) {
|
if (cursor != null && !cursor.moveToNext()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue