Move background to global settings.

This commit is contained in:
John Preston 2020-06-19 19:14:55 +04:00
parent 5433c16244
commit 2635ca33f8
16 changed files with 359 additions and 264 deletions

View file

@ -2896,8 +2896,12 @@ void ApiWrap::refreshFileReference(
MTPmessages_GetSavedGifs(MTP_int(0)), MTPmessages_GetSavedGifs(MTP_int(0)),
[=] { crl::on_main(_session, [=] { local().writeSavedGifs(); }); }); [=] { crl::on_main(_session, [=] { local().writeSavedGifs(); }); });
}, [&](Data::FileOriginWallpaper data) { }, [&](Data::FileOriginWallpaper data) {
request(MTPaccount_GetWallPaper( const auto useSlug = data.ownerId
MTP_inputWallPaper( && (data.ownerId != session().userId())
&& !data.slug.isEmpty();
request(MTPaccount_GetWallPaper(useSlug
? MTP_inputWallPaperSlug(MTP_string(data.slug))
: MTP_inputWallPaper(
MTP_long(data.paperId), MTP_long(data.paperId),
MTP_long(data.accessHash)))); MTP_long(data.accessHash))));
}, [&](Data::FileOriginTheme data) { }, [&](Data::FileOriginTheme data) {

View file

@ -174,7 +174,7 @@ void BackgroundBox::removePaper(const Data::WallPaper &paper) {
} }
session->data().removeWallpaper(paper); session->data().removeWallpaper(paper);
session->api().request(MTPaccount_SaveWallPaper( session->api().request(MTPaccount_SaveWallPaper(
paper.mtpInput(), paper.mtpInput(session),
MTP_bool(true), MTP_bool(true),
paper.mtpSettings() paper.mtpSettings()
)).send(); )).send();

View file

@ -506,7 +506,7 @@ void BackgroundPreviewBox::apply() {
_controller->content()->setChatBackground(_paper, std::move(_full)); _controller->content()->setChatBackground(_paper, std::move(_full));
if (install) { if (install) {
_controller->session().api().request(MTPaccount_InstallWallPaper( _controller->session().api().request(MTPaccount_InstallWallPaper(
_paper.mtpInput(), _paper.mtpInput(&_controller->session()),
_paper.mtpSettings() _paper.mtpSettings()
)).send(); )).send();
} }

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/send_files_box.h" #include "boxes/send_files_box.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "storage/serialize_common.h" #include "storage/serialize_common.h"
#include "window/themes/window_theme.h"
#include "facades.h" #include "facades.h"
namespace Core { namespace Core {
@ -87,8 +88,9 @@ QByteArray Settings::serialize() const {
stream << quint64(i); stream << quint64(i);
} }
stream stream
<< qint32(_autoDownloadDictionaries.current() ? 1 : 0); << qint32(_autoDownloadDictionaries.current() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
} }
return result; return result;
} }

View file

@ -61,13 +61,21 @@ struct FileOriginSavedGifs {
}; };
struct FileOriginWallpaper { struct FileOriginWallpaper {
FileOriginWallpaper(uint64 paperId, uint64 accessHash) FileOriginWallpaper(
uint64 paperId,
uint64 accessHash,
UserId ownerId,
const QString &slug)
: paperId(paperId) : paperId(paperId)
, accessHash(accessHash) { , accessHash(accessHash)
, ownerId(ownerId)
, slug(slug) {
} }
uint64 paperId = 0; uint64 paperId = 0;
uint64 accessHash = 0; uint64 accessHash = 0;
UserId ownerId = 0;
QString slug;
inline bool operator<(const FileOriginWallpaper &other) const { inline bool operator<(const FileOriginWallpaper &other) const {
return paperId < other.paperId; return paperId < other.paperId;

View file

@ -196,11 +196,17 @@ void WallPaper::loadDocument() const {
} }
FileOrigin WallPaper::fileOrigin() const { FileOrigin WallPaper::fileOrigin() const {
return FileOriginWallpaper(_id, _accessHash); return FileOriginWallpaper(_id, _accessHash, _ownerId, _slug);
} }
MTPInputWallPaper WallPaper::mtpInput() const { UserId WallPaper::ownerId() const {
return MTP_inputWallPaper(MTP_long(_id), MTP_long(_accessHash)); return _ownerId;
}
MTPInputWallPaper WallPaper::mtpInput(not_null<Main::Session*> session) const {
return (_ownerId && _ownerId != session->userId() && !_slug.isEmpty())
? MTP_inputWallPaperSlug(MTP_string(_slug))
: MTP_inputWallPaper(MTP_long(_id), MTP_long(_accessHash));
} }
MTPWallPaperSettings WallPaper::mtpSettings() const { MTPWallPaperSettings WallPaper::mtpSettings() const {
@ -324,6 +330,7 @@ std::optional<WallPaper> WallPaper::Create(
} }
auto result = WallPaper(data.vid().v); auto result = WallPaper(data.vid().v);
result._accessHash = data.vaccess_hash().v; result._accessHash = data.vaccess_hash().v;
result._ownerId = session->userId();
result._flags = data.vflags().v; result._flags = data.vflags().v;
result._slug = qs(data.vslug()); result._slug = qs(data.vslug());
result._document = document; result._document = document;
@ -372,7 +379,8 @@ QByteArray WallPaper::serialize() const {
<< _slug << _slug
<< qint32(_settings) << qint32(_settings)
<< SerializeMaybeColor(_backgroundColor) << SerializeMaybeColor(_backgroundColor)
<< qint32(_intensity); << qint32(_intensity)
<< qint32(_ownerId);
} }
return result; return result;
} }
@ -385,6 +393,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
auto id = quint64(); auto id = quint64();
auto accessHash = quint64(); auto accessHash = quint64();
auto ownerId = qint32();
auto flags = qint32(); auto flags = qint32();
auto slug = QString(); auto slug = QString();
auto settings = qint32(); auto settings = qint32();
@ -401,6 +410,9 @@ std::optional<WallPaper> WallPaper::FromSerialized(
>> settings >> settings
>> backgroundColor >> backgroundColor
>> intensity; >> intensity;
if (!stream.atEnd()) {
stream >> ownerId;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
return std::nullopt; return std::nullopt;
} else if (intensity < 0 || intensity > 100) { } else if (intensity < 0 || intensity > 100) {
@ -408,6 +420,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
} }
auto result = WallPaper(id); auto result = WallPaper(id);
result._accessHash = accessHash; result._accessHash = accessHash;
result._ownerId = ownerId;
result._flags = MTPDwallPaper::Flags::from_raw(flags); result._flags = MTPDwallPaper::Flags::from_raw(flags);
result._slug = slug; result._slug = slug;
result._settings = MTPDwallPaperSettings::Flags::from_raw(settings); result._settings = MTPDwallPaperSettings::Flags::from_raw(settings);

View file

@ -41,7 +41,9 @@ public:
void loadDocumentThumbnail() const; void loadDocumentThumbnail() const;
[[nodiscard]] FileOrigin fileOrigin() const; [[nodiscard]] FileOrigin fileOrigin() const;
[[nodiscard]] MTPInputWallPaper mtpInput() const; [[nodiscard]] UserId ownerId() const;
[[nodiscard]] MTPInputWallPaper mtpInput(
not_null<Main::Session*> session) const;
[[nodiscard]] MTPWallPaperSettings mtpSettings() const; [[nodiscard]] MTPWallPaperSettings mtpSettings() const;
[[nodiscard]] WallPaper withUrlParams( [[nodiscard]] WallPaper withUrlParams(
@ -77,6 +79,7 @@ private:
WallPaperId _id = WallPaperId(); WallPaperId _id = WallPaperId();
uint64 _accessHash = 0; uint64 _accessHash = 0;
UserId _ownerId = 0;
MTPDwallPaper::Flags _flags; MTPDwallPaper::Flags _flags;
QString _slug; QString _slug;

View file

@ -38,9 +38,7 @@ Storage::StartResult Domain::start(const QByteArray &passcode) {
const auto result = _local->start(passcode); const auto result = _local->start(passcode);
if (result == Storage::StartResult::Success) { if (result == Storage::StartResult::Success) {
activateAfterStarting(); activateAfterStarting();
if (Local::oldSettingsVersion() < AppVersion) { Local::rewriteSettingsIfNeeded();
Local::writeSettings();
}
} else { } else {
Assert(!started()); Assert(!started());
} }

View file

@ -577,6 +577,16 @@ bool ReadSetting(
Window::Theme::SetNightModeValue(nightMode == 1); Window::Theme::SetNightModeValue(nightMode == 1);
} break; } break;
case dbiBackgroundKey: {
quint64 keyDay = 0, keyNight = 0;
stream >> keyDay >> keyNight;
if (!CheckStreamStatus(stream)) return false;
context.backgroundKeyDay = keyDay;
context.backgroundKeyNight = keyNight;
context.backgroundKeysRead = true;
} break;
case dbiLangPackKey: { case dbiLangPackKey: {
quint64 langPackKey = 0; quint64 langPackKey = 0;
stream >> langPackKey; stream >> langPackKey;
@ -733,14 +743,15 @@ bool ReadSetting(
stream >> v; stream >> v;
if (!CheckStreamStatus(stream)) return false; if (!CheckStreamStatus(stream)) return false;
bool tile = (version < 8005 && !context.hasCustomDayBackground) bool tile = (version < 8005 && !context.legacyHasCustomDayBackground)
? false ? false
: (v == 1); : (v == 1);
if (Window::Theme::IsNightMode()) { if (Window::Theme::IsNightMode()) {
context.tileNight = tile;
} else {
context.tileDay = tile; context.tileDay = tile;
} else {
context.tileNight = tile;
} }
context.tileRead = true;
} break; } break;
case dbiTileBackground: { case dbiTileBackground: {
@ -748,8 +759,9 @@ bool ReadSetting(
stream >> tileDay >> tileNight; stream >> tileDay >> tileNight;
if (!CheckStreamStatus(stream)) return false; if (!CheckStreamStatus(stream)) return false;
context.tileDay = (tileDay == 1); context.tileDay = tileDay;
context.tileNight = (tileNight == 1); context.tileNight = tileNight;
context.tileRead = true;
} break; } break;
case dbiAdaptiveForWideOld: { case dbiAdaptiveForWideOld: {

View file

@ -28,7 +28,7 @@ struct ReadSettingsContext {
} }
// This field is read in ReadSetting. // This field is read in ReadSetting.
bool hasCustomDayBackground = false; bool legacyHasCustomDayBackground = false;
// Those fields are written in ReadSetting. // Those fields are written in ReadSetting.
MTP::DcOptions fallbackConfigLegacyDcOptions MTP::DcOptions fallbackConfigLegacyDcOptions
@ -51,6 +51,12 @@ struct ReadSettingsContext {
FileKey themeKeyLegacy = 0; FileKey themeKeyLegacy = 0;
FileKey themeKeyDay = 0; FileKey themeKeyDay = 0;
FileKey themeKeyNight = 0; FileKey themeKeyNight = 0;
FileKey backgroundKeyDay = 0;
FileKey backgroundKeyNight = 0;
bool backgroundKeysRead = false;
bool tileDay = false;
bool tileNight = true;
bool tileRead = false;
FileKey langPackKey = 0; FileKey langPackKey = 0;
FileKey languagesKey = 0; FileKey languagesKey = 0;
@ -58,9 +64,6 @@ struct ReadSettingsContext {
std::vector<std::shared_ptr<MTP::AuthKey>> mtpLegacyKeys; std::vector<std::shared_ptr<MTP::AuthKey>> mtpLegacyKeys;
qint32 mtpLegacyMainDcId = 0; qint32 mtpLegacyMainDcId = 0;
qint32 mtpLegacyUserId = 0; qint32 mtpLegacyUserId = 0;
bool tileDay = false;
bool tileNight = true;
}; };
[[nodiscard]] bool ReadSetting( [[nodiscard]] bool ReadSetting(
@ -159,6 +162,7 @@ enum {
dbiApplicationSettings = 0x5e, dbiApplicationSettings = 0x5e,
dbiDialogsFiltersOld = 0x5f, dbiDialogsFiltersOld = 0x5f,
dbiFallbackProductionConfig = 0x60, dbiFallbackProductionConfig = 0x60,
dbiBackgroundKey = 0x61,
dbiEncryptedWithSalt = 333, dbiEncryptedWithSalt = 333,
dbiEncrypted = 444, dbiEncrypted = 444,

View file

@ -43,6 +43,11 @@ namespace {
constexpr auto kThemeFileSizeLimit = 5 * 1024 * 1024; constexpr auto kThemeFileSizeLimit = 5 * 1024 * 1024;
constexpr auto kFileLoaderQueueStopTimeout = crl::time(5000); constexpr auto kFileLoaderQueueStopTimeout = crl::time(5000);
constexpr auto kSavedBackgroundFormat = QImage::Format_ARGB32_Premultiplied;
constexpr auto kWallPaperLegacySerializeTagId = int32(-111);
constexpr auto kWallPaperSerializeTagId = int32(-112);
constexpr auto kWallPaperSidesLimit = 10'000;
const auto kThemeNewPathRelativeTag = qstr("special://new_tag"); const auto kThemeNewPathRelativeTag = qstr("special://new_tag");
using namespace Storage::details; using namespace Storage::details;
@ -70,7 +75,14 @@ FileKey _themeKeyLegacy = 0;
FileKey _langPackKey = 0; FileKey _langPackKey = 0;
FileKey _languagesKey = 0; FileKey _languagesKey = 0;
FileKey _backgroundKeyDay = 0;
FileKey _backgroundKeyNight = 0;
bool _useGlobalBackgroundKeys = false;
bool _backgroundCanWrite = true;
bool _backgroundMigrated = false;
int32 _oldSettingsVersion = 0; int32 _oldSettingsVersion = 0;
bool _settingsRewritten;
enum class WriteMapWhen { enum class WriteMapWhen {
Now, Now,
@ -120,8 +132,16 @@ void applyReadContext(ReadSettingsContext &&context) {
_themeKeyLegacy = context.themeKeyLegacy; _themeKeyLegacy = context.themeKeyLegacy;
_themeKeyDay = context.themeKeyDay; _themeKeyDay = context.themeKeyDay;
_themeKeyNight = context.themeKeyNight; _themeKeyNight = context.themeKeyNight;
_backgroundKeyDay = context.backgroundKeyDay;
_backgroundKeyNight = context.backgroundKeyNight;
_useGlobalBackgroundKeys = context.backgroundKeysRead;
_langPackKey = context.langPackKey; _langPackKey = context.langPackKey;
_languagesKey = context.languagesKey; _languagesKey = context.languagesKey;
if (context.tileRead && _useGlobalBackgroundKeys) {
Window::Theme::Background()->setTileDayValue(context.tileDay);
Window::Theme::Background()->setTileNightValue(context.tileNight);
}
} }
bool _readOldSettings(bool remove, ReadSettingsContext &context) { bool _readOldSettings(bool remove, ReadSettingsContext &context) {
@ -436,6 +456,7 @@ void writeSettings() {
// Theme keys and night mode. // Theme keys and night mode.
size += sizeof(quint32) + sizeof(quint64) * 2 + sizeof(quint32); size += sizeof(quint32) + sizeof(quint64) * 2 + sizeof(quint32);
size += sizeof(quint32) + sizeof(quint64) * 2;
if (_langPackKey) { if (_langPackKey) {
size += sizeof(quint32) + sizeof(quint64); size += sizeof(quint32) + sizeof(quint64);
} }
@ -471,6 +492,16 @@ void writeSettings() {
<< quint64(_themeKeyDay) << quint64(_themeKeyDay)
<< quint64(_themeKeyNight) << quint64(_themeKeyNight)
<< quint32(Window::Theme::IsNightMode() ? 1 : 0); << quint32(Window::Theme::IsNightMode() ? 1 : 0);
if (_useGlobalBackgroundKeys) {
data.stream
<< quint32(dbiBackgroundKey)
<< quint64(_backgroundKeyDay)
<< quint64(_backgroundKeyNight);
data.stream
<< quint32(dbiTileBackground)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
}
if (_langPackKey) { if (_langPackKey) {
data.stream << quint32(dbiLangPackKey) << quint64(_langPackKey); data.stream << quint32(dbiLangPackKey) << quint64(_langPackKey);
} }
@ -487,6 +518,15 @@ void writeSettings() {
settings.writeEncrypted(data, SettingsKey); settings.writeEncrypted(data, SettingsKey);
} }
void rewriteSettingsIfNeeded() {
if (_settingsRewritten
|| (_oldSettingsVersion == AppVersion && !_backgroundMigrated)) {
return;
}
_settingsRewritten = true;
writeSettings();
}
const QString &AutoupdatePrefix(const QString &replaceWith = {}) { const QString &AutoupdatePrefix(const QString &replaceWith = {}) {
Expects(!Core::UpdaterDisabled()); Expects(!Core::UpdaterDisabled());
@ -547,6 +587,207 @@ QString readAutoupdatePrefix() {
return result.replace(QRegularExpression("/+$"), QString()); return result.replace(QRegularExpression("/+$"), QString());
} }
void writeBackground(const Data::WallPaper &paper, const QImage &image) {
if (!_backgroundCanWrite) {
return;
}
_useGlobalBackgroundKeys = true;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
auto imageData = QByteArray();
if (!image.isNull()) {
const auto width = qint32(image.width());
const auto height = qint32(image.height());
const auto perpixel = (image.depth() >> 3);
const auto srcperline = image.bytesPerLine();
const auto srcsize = srcperline * height;
const auto dstperline = width * perpixel;
const auto dstsize = dstperline * height;
const auto copy = (image.format() != kSavedBackgroundFormat)
? image.convertToFormat(kSavedBackgroundFormat)
: image;
imageData.resize(2 * sizeof(qint32) + dstsize);
auto dst = bytes::make_detached_span(imageData);
bytes::copy(dst, bytes::object_as_span(&width));
dst = dst.subspan(sizeof(qint32));
bytes::copy(dst, bytes::object_as_span(&height));
dst = dst.subspan(sizeof(qint32));
const auto src = bytes::make_span(image.constBits(), srcsize);
if (srcsize == dstsize) {
bytes::copy(dst, src);
} else {
for (auto y = 0; y != height; ++y) {
bytes::copy(dst, src.subspan(y * srcperline, dstperline));
dst = dst.subspan(dstperline);
}
}
}
if (!backgroundKey) {
backgroundKey = GenerateKey(_basePath);
writeSettings();
}
const auto serialized = paper.serialize();
quint32 size = sizeof(qint32)
+ Serialize::bytearraySize(serialized)
+ Serialize::bytearraySize(imageData);
EncryptedDescriptor data(size);
data.stream
<< qint32(kWallPaperSerializeTagId)
<< serialized
<< imageData;
FileWriteDescriptor file(backgroundKey, _basePath);
file.writeEncrypted(data, SettingsKey);
}
bool readBackground() {
FileReadDescriptor bg;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
if (!ReadEncryptedFile(bg, backgroundKey, _basePath, SettingsKey)) {
if (backgroundKey) {
ClearKey(backgroundKey, _basePath);
backgroundKey = 0;
writeSettings();
}
return false;
}
qint32 legacyId = 0;
bg.stream >> legacyId;
const auto paper = [&] {
if (legacyId == kWallPaperLegacySerializeTagId) {
quint64 id = 0;
quint64 accessHash = 0;
quint32 flags = 0;
QString slug;
bg.stream
>> id
>> accessHash
>> flags
>> slug;
return Data::WallPaper::FromLegacySerialized(
id,
accessHash,
flags,
slug);
} else if (legacyId == kWallPaperSerializeTagId) {
QByteArray serialized;
bg.stream >> serialized;
return Data::WallPaper::FromSerialized(serialized);
} else {
return Data::WallPaper::FromLegacyId(legacyId);
}
}();
if (bg.stream.status() != QDataStream::Ok || !paper) {
return false;
}
QByteArray imageData;
bg.stream >> imageData;
const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok);
if (isOldEmptyImage
|| Data::IsLegacy1DefaultWallPaper(*paper)
|| Data::IsDefaultWallPaper(*paper)) {
_backgroundCanWrite = false;
if (isOldEmptyImage || bg.version < 8005) {
Window::Theme::Background()->set(Data::DefaultWallPaper());
Window::Theme::Background()->setTile(false);
} else {
Window::Theme::Background()->set(*paper);
}
_backgroundCanWrite = true;
return true;
} else if (Data::IsThemeWallPaper(*paper) && imageData.isEmpty()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper);
_backgroundCanWrite = true;
return true;
}
auto image = QImage();
if (legacyId == kWallPaperSerializeTagId) {
const auto perpixel = 4;
auto src = bytes::make_span(imageData);
auto width = qint32();
auto height = qint32();
if (src.size() > 2 * sizeof(qint32)) {
bytes::copy(
bytes::object_as_span(&width),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
bytes::copy(
bytes::object_as_span(&height),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
if (width + height <= kWallPaperSidesLimit
&& src.size() == width * height * perpixel) {
image = QImage(
width,
height,
QImage::Format_ARGB32_Premultiplied);
if (!image.isNull()) {
const auto srcperline = width * perpixel;
const auto srcsize = srcperline * height;
const auto dstperline = image.bytesPerLine();
const auto dstsize = dstperline * height;
Assert(srcsize == dstsize);
bytes::copy(
bytes::make_span(image.bits(), dstsize),
src);
}
}
}
} else {
auto buffer = QBuffer(&imageData);
auto reader = QImageReader(&buffer);
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&image)) {
image = QImage();
}
}
if (!image.isNull() || paper->backgroundColor()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper, std::move(image));
_backgroundCanWrite = true;
return true;
}
return false;
}
void moveLegacyBackground(
const QString &fromBasePath,
const MTP::AuthKeyPtr &fromLocalKey,
uint64 legacyBackgroundKeyDay,
uint64 legacyBackgroundKeyNight) {
if (_useGlobalBackgroundKeys
|| (!legacyBackgroundKeyDay && !legacyBackgroundKeyNight)) {
return;
}
const auto move = [&](uint64 from, FileKey &to) {
if (!from || to) {
return;
}
to = GenerateKey(_basePath);
FileReadDescriptor read;
if (!ReadEncryptedFile(read, from, fromBasePath, fromLocalKey)) {
return;
}
EncryptedDescriptor data;
data.data = read.data;
FileWriteDescriptor write(to, _basePath);
write.writeEncrypted(data, SettingsKey);
};
move(legacyBackgroundKeyDay, _backgroundKeyDay);
move(legacyBackgroundKeyNight, _backgroundKeyNight);
_backgroundMigrated = true;
}
void reset() { void reset() {
if (_localLoader) { if (_localLoader) {
_localLoader->stop(); _localLoader->stop();

View file

@ -41,16 +41,30 @@ namespace Export {
struct Settings; struct Settings;
} // namespace Export } // namespace Export
namespace MTP {
class AuthKey;
using AuthKeyPtr = std::shared_ptr<AuthKey>;
} // namespace MTP
namespace Local { namespace Local {
void start(); void start();
void finish(); void finish();
void writeSettings(); void writeSettings();
void rewriteSettingsIfNeeded();
void writeAutoupdatePrefix(const QString &prefix); void writeAutoupdatePrefix(const QString &prefix);
QString readAutoupdatePrefix(); QString readAutoupdatePrefix();
void writeBackground(const Data::WallPaper &paper, const QImage &image);
bool readBackground();
void moveLegacyBackground(
const QString &fromBasePath,
const MTP::AuthKeyPtr &fromLocalKey,
uint64 legacyBackgroundKeyDay,
uint64 legacyBackgroundKeyNight);
void reset(); void reset();
enum ClearManagerTask { enum ClearManagerTask {

View file

@ -39,17 +39,12 @@ using namespace details;
using Database = Cache::Database; using Database = Cache::Database;
constexpr auto kDelayedWriteTimeout = crl::time(1000); constexpr auto kDelayedWriteTimeout = crl::time(1000);
constexpr auto kSavedBackgroundFormat = QImage::Format_ARGB32_Premultiplied;
constexpr auto kStickersVersionTag = quint32(-1); constexpr auto kStickersVersionTag = quint32(-1);
constexpr auto kStickersSerializeVersion = 1; constexpr auto kStickersSerializeVersion = 1;
constexpr auto kMaxSavedStickerSetsCount = 1000; constexpr auto kMaxSavedStickerSetsCount = 1000;
constexpr auto kDefaultStickerInstallDate = TimeId(1); constexpr auto kDefaultStickerInstallDate = TimeId(1);
constexpr auto kWallPaperLegacySerializeTagId = int32(-111);
constexpr auto kWallPaperSerializeTagId = int32(-112);
constexpr auto kWallPaperSidesLimit = 10'000;
constexpr auto kSinglePeerTypeUser = qint32(1); constexpr auto kSinglePeerTypeUser = qint32(1);
constexpr auto kSinglePeerTypeChat = qint32(2); constexpr auto kSinglePeerTypeChat = qint32(2);
constexpr auto kSinglePeerTypeChannel = qint32(3); constexpr auto kSinglePeerTypeChannel = qint32(3);
@ -65,7 +60,7 @@ enum { // Local Storage Keys
lskLegacyStickerImages = 0x05, // legacy lskLegacyStickerImages = 0x05, // legacy
lskLegacyAudios = 0x06, // legacy lskLegacyAudios = 0x06, // legacy
lskRecentStickersOld = 0x07, // no data lskRecentStickersOld = 0x07, // no data
lskBackgroundOld = 0x08, // no data lskBackgroundOldOld = 0x08, // no data
lskUserSettings = 0x09, // no data lskUserSettings = 0x09, // no data
lskRecentHashtagsAndBots = 0x0a, // no data lskRecentHashtagsAndBots = 0x0a, // no data
lskStickersOld = 0x0b, // no data lskStickersOld = 0x0b, // no data
@ -77,7 +72,7 @@ enum { // Local Storage Keys
lskTrustedBots = 0x11, // no data lskTrustedBots = 0x11, // no data
lskFavedStickers = 0x12, // no data lskFavedStickers = 0x12, // no data
lskExportSettings = 0x13, // no data lskExportSettings = 0x13, // no data
lskBackground = 0x14, // no data lskBackgroundOld = 0x14, // no data
lskSelfSerialized = 0x15, // serialized self lskSelfSerialized = 0x15, // serialized self
}; };
@ -173,8 +168,8 @@ base::flat_set<QString> Account::collectGoodNames() const {
_archivedStickersKey, _archivedStickersKey,
_recentStickersKeyOld, _recentStickersKeyOld,
_savedGifsKey, _savedGifsKey,
_backgroundKeyNight, _legacyBackgroundKeyNight,
_backgroundKeyDay, _legacyBackgroundKeyDay,
_recentHashtagsAndBotsKey, _recentHashtagsAndBotsKey,
_exportSettingsKey, _exportSettingsKey,
_trustedBotsKey, _trustedBotsKey,
@ -259,7 +254,7 @@ Account::ReadMapResult Account::readMapWith(
quint64 recentStickersKeyOld = 0; quint64 recentStickersKeyOld = 0;
quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0; quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
quint64 savedGifsKey = 0; quint64 savedGifsKey = 0;
quint64 backgroundKeyDay = 0, backgroundKeyNight = 0; quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0;
quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0; quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0;
while (!map.stream.atEnd()) { while (!map.stream.atEnd()) {
quint32 keyType; quint32 keyType;
@ -315,13 +310,13 @@ Account::ReadMapResult Account::readMapWith(
case lskRecentStickersOld: { case lskRecentStickersOld: {
map.stream >> recentStickersKeyOld; map.stream >> recentStickersKeyOld;
} break; } break;
case lskBackgroundOld: { case lskBackgroundOldOld: {
map.stream >> (Window::Theme::IsNightMode() map.stream >> (Window::Theme::IsNightMode()
? backgroundKeyNight ? legacyBackgroundKeyNight
: backgroundKeyDay); : legacyBackgroundKeyDay);
} break; } break;
case lskBackground: { case lskBackgroundOld: {
map.stream >> backgroundKeyDay >> backgroundKeyNight; map.stream >> legacyBackgroundKeyDay >> legacyBackgroundKeyNight;
} break; } break;
case lskUserSettings: { case lskUserSettings: {
map.stream >> userSettingsKey; map.stream >> userSettingsKey;
@ -376,8 +371,8 @@ Account::ReadMapResult Account::readMapWith(
_favedStickersKey = favedStickersKey; _favedStickersKey = favedStickersKey;
_archivedStickersKey = archivedStickersKey; _archivedStickersKey = archivedStickersKey;
_savedGifsKey = savedGifsKey; _savedGifsKey = savedGifsKey;
_backgroundKeyDay = backgroundKeyDay; _legacyBackgroundKeyDay = legacyBackgroundKeyDay;
_backgroundKeyNight = backgroundKeyNight; _legacyBackgroundKeyNight = legacyBackgroundKeyNight;
_settingsKey = userSettingsKey; _settingsKey = userSettingsKey;
_recentHashtagsAndBotsKey = recentHashtagsAndBotsKey; _recentHashtagsAndBotsKey = recentHashtagsAndBotsKey;
_exportSettingsKey = exportSettingsKey; _exportSettingsKey = exportSettingsKey;
@ -392,6 +387,13 @@ Account::ReadMapResult Account::readMapWith(
if (_locationsKey) { if (_locationsKey) {
readLocations(); readLocations();
} }
if (_legacyBackgroundKeyDay || _legacyBackgroundKeyNight) {
Local::moveLegacyBackground(
_basePath,
_localKey,
_legacyBackgroundKeyDay,
_legacyBackgroundKeyNight);
}
auto stored = readSessionSettings(); auto stored = readSessionSettings();
readMtpData(); readMtpData();
@ -403,6 +405,7 @@ Account::ReadMapResult Account::readMapWith(
_oldMapVersion); _oldMapVersion);
LOG(("Map read time: %1").arg(crl::now() - ms)); LOG(("Map read time: %1").arg(crl::now() - ms));
return ReadMapResult::Success; return ReadMapResult::Success;
} }
@ -469,7 +472,6 @@ void Account::writeMap() {
} }
if (_favedStickersKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_favedStickersKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_savedGifsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_savedGifsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_backgroundKeyDay || _backgroundKeyNight) mapSize += sizeof(quint32) + sizeof(quint64) + sizeof(quint64);
if (_settingsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_settingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_recentHashtagsAndBotsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_recentHashtagsAndBotsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_exportSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64); if (_exportSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
@ -509,12 +511,6 @@ void Account::writeMap() {
if (_savedGifsKey) { if (_savedGifsKey) {
mapData.stream << quint32(lskSavedGifs) << quint64(_savedGifsKey); mapData.stream << quint32(lskSavedGifs) << quint64(_savedGifsKey);
} }
if (_backgroundKeyDay || _backgroundKeyNight) {
mapData.stream
<< quint32(lskBackground)
<< quint64(_backgroundKeyDay)
<< quint64(_backgroundKeyNight);
}
if (_settingsKey) { if (_settingsKey) {
mapData.stream << quint32(lskUserSettings) << quint64(_settingsKey); mapData.stream << quint32(lskUserSettings) << quint64(_settingsKey);
} }
@ -542,7 +538,7 @@ void Account::reset() {
_favedStickersKey = 0; _favedStickersKey = 0;
_archivedStickersKey = 0; _archivedStickersKey = 0;
_savedGifsKey = 0; _savedGifsKey = 0;
_backgroundKeyDay = _backgroundKeyNight = 0; _legacyBackgroundKeyDay = _legacyBackgroundKeyNight = 0;
_settingsKey = _recentHashtagsAndBotsKey = _exportSettingsKey = 0; _settingsKey = _recentHashtagsAndBotsKey = _exportSettingsKey = 0;
_oldMapVersion = 0; _oldMapVersion = 0;
_fileLocations.clear(); _fileLocations.clear();
@ -764,10 +760,6 @@ void Account::writeSessionSettings(Main::SessionSettings *stored) {
} }
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream
<< quint32(dbiTileBackground)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer()); data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer());
data.stream << quint32(dbiCacheSettings) << qint64(_cacheTotalSizeLimit) << qint32(_cacheTotalTimeLimit) << qint64(_cacheBigFileTotalSizeLimit) << qint32(_cacheBigFileTotalTimeLimit); data.stream << quint32(dbiCacheSettings) << qint64(_cacheTotalSizeLimit) << qint32(_cacheTotalTimeLimit) << qint64(_cacheBigFileTotalSizeLimit) << qint32(_cacheBigFileTotalTimeLimit);
if (!userData.isEmpty()) { if (!userData.isEmpty()) {
@ -783,7 +775,7 @@ void Account::writeSessionSettings(Main::SessionSettings *stored) {
ReadSettingsContext Account::prepareReadSettingsContext() const { ReadSettingsContext Account::prepareReadSettingsContext() const {
return ReadSettingsContext{ return ReadSettingsContext{
.hasCustomDayBackground = (_backgroundKeyDay != 0) .legacyHasCustomDayBackground = (_legacyBackgroundKeyDay != 0)
}; };
} }
@ -845,9 +837,10 @@ std::unique_ptr<Main::SessionSettings> Account::applyReadContext(
} }
} }
// #TODO multi if (context.tileRead) {
//Window::Theme::Background()->setTileDayValue(context.tileDay); Window::Theme::Background()->setTileDayValue(context.tileDay);
//Window::Theme::Background()->setTileNightValue(context.tileNight); Window::Theme::Background()->setTileNightValue(context.tileNight);
}
return std::move(context.sessionSettingsStorage); return std::move(context.sessionSettingsStorage);
} }
@ -1955,185 +1948,6 @@ void Account::readSavedGifs() {
} }
} }
void Account::writeBackground(
const Data::WallPaper &paper,
const QImage &image) {
if (!_backgroundCanWrite) {
return;
}
if (!_localKey) {
LOG(("App Error: localkey not created in writeBackground()"));
return;
}
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
auto imageData = QByteArray();
if (!image.isNull()) {
const auto width = qint32(image.width());
const auto height = qint32(image.height());
const auto perpixel = (image.depth() >> 3);
const auto srcperline = image.bytesPerLine();
const auto srcsize = srcperline * height;
const auto dstperline = width * perpixel;
const auto dstsize = dstperline * height;
const auto copy = (image.format() != kSavedBackgroundFormat)
? image.convertToFormat(kSavedBackgroundFormat)
: image;
imageData.resize(2 * sizeof(qint32) + dstsize);
auto dst = bytes::make_detached_span(imageData);
bytes::copy(dst, bytes::object_as_span(&width));
dst = dst.subspan(sizeof(qint32));
bytes::copy(dst, bytes::object_as_span(&height));
dst = dst.subspan(sizeof(qint32));
const auto src = bytes::make_span(image.constBits(), srcsize);
if (srcsize == dstsize) {
bytes::copy(dst, src);
} else {
for (auto y = 0; y != height; ++y) {
bytes::copy(dst, src.subspan(y * srcperline, dstperline));
dst = dst.subspan(dstperline);
}
}
}
if (!backgroundKey) {
backgroundKey = GenerateKey(_basePath);
writeMapQueued();
}
const auto serialized = paper.serialize();
quint32 size = sizeof(qint32)
+ Serialize::bytearraySize(serialized)
+ Serialize::bytearraySize(imageData);
EncryptedDescriptor data(size);
data.stream
<< qint32(kWallPaperSerializeTagId)
<< serialized
<< imageData;
FileWriteDescriptor file(backgroundKey, _basePath);
file.writeEncrypted(data, _localKey);
}
bool Account::readBackground() {
FileReadDescriptor bg;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
if (!ReadEncryptedFile(bg, backgroundKey, _basePath, _localKey)) {
if (backgroundKey) {
ClearKey(backgroundKey, _basePath);
backgroundKey = 0;
writeMapDelayed();
}
return false;
}
qint32 legacyId = 0;
bg.stream >> legacyId;
const auto paper = [&] {
if (legacyId == kWallPaperLegacySerializeTagId) {
quint64 id = 0;
quint64 accessHash = 0;
quint32 flags = 0;
QString slug;
bg.stream
>> id
>> accessHash
>> flags
>> slug;
return Data::WallPaper::FromLegacySerialized(
id,
accessHash,
flags,
slug);
} else if (legacyId == kWallPaperSerializeTagId) {
QByteArray serialized;
bg.stream >> serialized;
return Data::WallPaper::FromSerialized(serialized);
} else {
return Data::WallPaper::FromLegacyId(legacyId);
}
}();
if (bg.stream.status() != QDataStream::Ok || !paper) {
return false;
}
QByteArray imageData;
bg.stream >> imageData;
const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok);
if (isOldEmptyImage
|| Data::IsLegacy1DefaultWallPaper(*paper)
|| Data::IsDefaultWallPaper(*paper)) {
_backgroundCanWrite = false;
if (isOldEmptyImage || bg.version < 8005) {
Window::Theme::Background()->set(Data::DefaultWallPaper());
Window::Theme::Background()->setTile(false);
} else {
Window::Theme::Background()->set(*paper);
}
_backgroundCanWrite = true;
return true;
} else if (Data::IsThemeWallPaper(*paper) && imageData.isEmpty()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper);
_backgroundCanWrite = true;
return true;
}
auto image = QImage();
if (legacyId == kWallPaperSerializeTagId) {
const auto perpixel = 4;
auto src = bytes::make_span(imageData);
auto width = qint32();
auto height = qint32();
if (src.size() > 2 * sizeof(qint32)) {
bytes::copy(
bytes::object_as_span(&width),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
bytes::copy(
bytes::object_as_span(&height),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
if (width + height <= kWallPaperSidesLimit
&& src.size() == width * height * perpixel) {
image = QImage(
width,
height,
QImage::Format_ARGB32_Premultiplied);
if (!image.isNull()) {
const auto srcperline = width * perpixel;
const auto srcsize = srcperline * height;
const auto dstperline = image.bytesPerLine();
const auto dstsize = dstperline * height;
Assert(srcsize == dstsize);
bytes::copy(
bytes::make_span(image.bits(), dstsize),
src);
}
}
}
} else {
auto buffer = QBuffer(&imageData);
auto reader = QImageReader(&buffer);
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&image)) {
image = QImage();
}
}
if (!image.isNull() || paper->backgroundColor()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper, std::move(image));
_backgroundCanWrite = true;
return true;
}
return false;
}
void Account::writeRecentHashtagsAndBots() { void Account::writeRecentHashtagsAndBots() {
const auto &write = cRecentWriteHashtags(); const auto &write = cRecentWriteHashtags();
const auto &search = cRecentSearchHashtags(); const auto &search = cRecentSearchHashtags();

View file

@ -71,9 +71,6 @@ public:
void writeMtpData(); void writeMtpData();
void writeMtpConfig(); void writeMtpConfig();
void writeBackground(const Data::WallPaper &paper, const QImage &image);
bool readBackground();
void writeDrafts(not_null<History*> history); void writeDrafts(not_null<History*> history);
void writeDrafts( void writeDrafts(
const PeerId &peer, const PeerId &peer,
@ -232,8 +229,8 @@ private:
FileKey _archivedStickersKey = 0; FileKey _archivedStickersKey = 0;
FileKey _savedGifsKey = 0; FileKey _savedGifsKey = 0;
FileKey _recentStickersKeyOld = 0; FileKey _recentStickersKeyOld = 0;
FileKey _backgroundKeyDay = 0; FileKey _legacyBackgroundKeyDay = 0;
FileKey _backgroundKeyNight = 0; FileKey _legacyBackgroundKeyNight = 0;
FileKey _settingsKey = 0; FileKey _settingsKey = 0;
FileKey _recentHashtagsAndBotsKey = 0; FileKey _recentHashtagsAndBotsKey = 0;
FileKey _exportSettingsKey = 0; FileKey _exportSettingsKey = 0;
@ -245,7 +242,6 @@ private:
base::flat_set<uint64> _trustedBots; base::flat_set<uint64> _trustedBots;
bool _trustedBotsRead = false; bool _trustedBotsRead = false;
bool _backgroundCanWrite = true;
bool _readingUserSettings = false; bool _readingUserSettings = false;
bool _recentHashtagsAndBotsWereRead = false; bool _recentHashtagsAndBotsWereRead = false;

View file

@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h" #include "main/main_session.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "storage/storage_account.h"
#include "storage/localimageloader.h" #include "storage/localimageloader.h"
#include "storage/file_upload.h" #include "storage/file_upload.h"
#include "base/parse_helper.h" #include "base/parse_helper.h"
@ -531,10 +530,6 @@ ChatBackground::ChatBackground() : _adjustableColors({
}); });
} }
Storage::Account &ChatBackground::local() const {
return Core::App().activeAccount().local();
}
void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) { void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
_themeImage = validateBackgroundImage(std::move(themeImage)); _themeImage = validateBackgroundImage(std::move(themeImage));
_themeTile = themeTile; _themeTile = themeTile;
@ -544,7 +539,7 @@ void ChatBackground::start() {
if (!Data::details::IsUninitializedWallPaper(_paper)) { if (!Data::details::IsUninitializedWallPaper(_paper)) {
return; return;
} }
if (!local().readBackground()) { if (!Local::readBackground()) {
set(Data::ThemeWallPaper()); set(Data::ThemeWallPaper());
} }
@ -659,7 +654,7 @@ void ChatBackground::set(const Data::WallPaper &paper, QImage image) {
setPaper(Data::DefaultWallPaper().withParamsFrom(_paper)); setPaper(Data::DefaultWallPaper().withParamsFrom(_paper));
image.load(qsl(":/gui/art/bg.jpg")); image.load(qsl(":/gui/art/bg.jpg"));
} }
local().writeBackground( Local::writeBackground(
_paper, _paper,
((Data::IsDefaultWallPaper(_paper) ((Data::IsDefaultWallPaper(_paper)
|| Data::IsLegacy1DefaultWallPaper(_paper)) || Data::IsLegacy1DefaultWallPaper(_paper))
@ -875,7 +870,7 @@ void ChatBackground::setTile(bool tile) {
if (this->tile() != old) { if (this->tile() != old) {
if (!Data::details::IsTestingThemeWallPaper(_paper) if (!Data::details::IsTestingThemeWallPaper(_paper)
&& !Data::details::IsTestingDefaultWallPaper(_paper)) { && !Data::details::IsTestingDefaultWallPaper(_paper)) {
local().writeSessionSettings(); Local::writeSettings();
} }
notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile)); notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile));
} }
@ -1030,9 +1025,9 @@ bool ChatBackground::isNonDefaultBackground() {
void ChatBackground::writeNewBackgroundSettings() { void ChatBackground::writeNewBackgroundSettings() {
if (tile() != _tileForRevert) { if (tile() != _tileForRevert) {
local().writeSessionSettings(); Local::writeSettings();
} }
local().writeBackground( Local::writeBackground(
_paper, _paper,
((Data::IsThemeWallPaper(_paper) ((Data::IsThemeWallPaper(_paper)
|| Data::IsDefaultWallPaper(_paper)) || Data::IsDefaultWallPaper(_paper))
@ -1116,13 +1111,10 @@ void ChatBackground::reapplyWithNightMode(
} }
ClearApplying(); ClearApplying();
keepApplied(saved.object, settingExactTheme); keepApplied(saved.object, settingExactTheme);
if (tile() != _tileForRevert) { if (tile() != _tileForRevert || nightModeChanged) {
local().writeSessionSettings();
}
if (nightModeChanged) {
Local::writeSettings(); Local::writeSettings();
} }
if (!settingExactTheme && !local().readBackground()) { if (!settingExactTheme && !Local::readBackground()) {
set(Data::ThemeWallPaper()); set(Data::ThemeWallPaper());
} }
}; };

View file

@ -14,10 +14,6 @@ namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
namespace Storage {
class Account;
} // namespace Storage
namespace Window { namespace Window {
namespace Theme { namespace Theme {
@ -181,8 +177,6 @@ private:
QColor original; QColor original;
}; };
Storage::Account &local() const;
void ensureStarted(); void ensureStarted();
void saveForRevert(); void saveForRevert();
void setPreparedImage(QImage original, QImage prepared); void setPreparedImage(QImage original, QImage prepared);