Chromium changes: https://chromium.googlesource.com/chromium/src/+/448b9a0247edbe13101ad734f58b0e9792d6064b commit 448b9a0247edbe13101ad734f58b0e9792d6064b Author: Tanmoy Mollik <triploblastic@google.com> Date: Thu Apr 2 05:25:50 2026 -0700 Remove unused method param in SyncUserSettings Bug: 347710361 Change-Id: Ie08884a8a8d4d37d1f6e8b91f2200f1d4d6bf948 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7715580 Commit-Queue: Tanmoy Mollik <triploblastic@google.com> Reviewed-by: Marc Treib <treib@chromium.org> Cr-Commit-Position: refs/heads/main@{#1609128}
535 lines
18 KiB
C++
535 lines
18 KiB
C++
/* Copyright (c) 2019 The Brave Authors. All rights reserved.
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "brave/browser/android/brave_sync_worker.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "base/android/jni_android.h"
|
|
#include "base/android/jni_string.h"
|
|
#include "base/check.h"
|
|
#include "base/check_op.h"
|
|
#include "base/json/json_writer.h"
|
|
#include "base/logging.h"
|
|
#include "base/path_service.h"
|
|
#include "base/strings/string_number_conversions.h"
|
|
#include "brave/components/brave_sync/brave_sync_prefs.h"
|
|
#include "brave/components/brave_sync/crypto/crypto.h"
|
|
#include "brave/components/brave_sync/qr_code_data.h"
|
|
#include "brave/components/brave_sync/qr_code_validator.h"
|
|
#include "brave/components/brave_sync/sync_service_impl_helper.h"
|
|
#include "brave/components/brave_sync/time_limited_words.h"
|
|
#include "brave/components/sync/service/brave_sync_service_impl.h"
|
|
#include "chrome/android/chrome_jni_headers/BraveSyncWorker_jni.h"
|
|
#include "chrome/browser/profiles/profile.h"
|
|
#include "chrome/browser/profiles/profile_manager.h"
|
|
#include "chrome/browser/sync/device_info_sync_service_factory.h"
|
|
#include "chrome/browser/sync/sync_service_factory.h"
|
|
#include "components/sync/service/sync_service.h"
|
|
#include "components/sync/service/sync_user_settings.h"
|
|
#include "components/unified_consent/unified_consent_metrics.h"
|
|
#include "content/public/browser/browser_thread.h"
|
|
#include "ui/base/l10n/time_format.h"
|
|
|
|
// TODO(alexeybarabash): consider use of java SyncServiceImpl methods:
|
|
// addSyncStateChangedListener
|
|
// removeSyncStateChangedListener
|
|
// requestStart
|
|
// requestStop
|
|
// setInitialSyncFeatureSetupComplete
|
|
// isInitialSyncFeatureSetupComplete
|
|
|
|
using base::android::ConvertUTF8ToJavaString;
|
|
using brave_sync::TimeLimitedWords;
|
|
using content::BrowserThread;
|
|
|
|
namespace {
|
|
static const size_t SEED_BYTES_COUNT = 32u;
|
|
} // namespace
|
|
|
|
namespace chrome {
|
|
namespace android {
|
|
|
|
BraveSyncWorker::BraveSyncWorker(JNIEnv* env,
|
|
const base::android::JavaRef<jobject>& obj)
|
|
: weak_java_brave_sync_worker_(env, obj) {
|
|
Java_BraveSyncWorker_setNativePtr(env, obj, reinterpret_cast<intptr_t>(this));
|
|
|
|
profile_ = ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
|
|
DCHECK_NE(profile_, nullptr);
|
|
}
|
|
|
|
BraveSyncWorker::~BraveSyncWorker() {}
|
|
|
|
void BraveSyncWorker::Destroy(JNIEnv* env) {
|
|
delete this;
|
|
}
|
|
|
|
base::android::ScopedJavaLocalRef<jstring> BraveSyncWorker::GetSyncCodeWords(
|
|
JNIEnv* env) {
|
|
auto* sync_service = GetSyncService();
|
|
std::string sync_code;
|
|
if (sync_service)
|
|
sync_code = sync_service->GetOrCreateSyncCode();
|
|
|
|
CHECK(brave_sync::crypto::IsPassphraseValid(sync_code));
|
|
|
|
return ConvertUTF8ToJavaString(env, sync_code);
|
|
}
|
|
|
|
void BraveSyncWorker::SaveCodeWords(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& passphrase) {
|
|
std::string str_passphrase =
|
|
base::android::ConvertJavaStringToUTF8(passphrase);
|
|
|
|
auto* sync_service = GetSyncService();
|
|
if (!sync_service || !sync_service->SetSyncCode(str_passphrase)) {
|
|
LOG(ERROR) << (sync_service ? "invalid sync code"
|
|
: "sync service is not available");
|
|
return;
|
|
}
|
|
|
|
passphrase_ = str_passphrase;
|
|
}
|
|
|
|
syncer::BraveSyncServiceImpl* BraveSyncWorker::GetSyncService() const {
|
|
return SyncServiceFactory::IsSyncAllowed(profile_)
|
|
? static_cast<syncer::BraveSyncServiceImpl*>(
|
|
SyncServiceFactory::GetForProfile(profile_))
|
|
: nullptr;
|
|
}
|
|
|
|
// Most of methods below were taken from by PeopleHandler class to
|
|
// bring the logic of enabling / disabling sync from deskop to Android
|
|
|
|
void BraveSyncWorker::RequestSync(JNIEnv* env) {
|
|
syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile_);
|
|
|
|
if (service && !sync_service_observer_.IsObservingSource(service)) {
|
|
sync_service_observer_.AddObservation(service);
|
|
}
|
|
|
|
// Upstream shows the notification when passphrase is required but not set,
|
|
// see SyncErrorNotifier.computeGoalNotificationState .
|
|
// Brave always set the passphrase eventually, so we don't need this
|
|
// notification. The same for scanning QR code and using the codewords.
|
|
service->GetUserSettings()
|
|
->MarkPassphrasePromptMutedForCurrentProductVersion();
|
|
}
|
|
|
|
void BraveSyncWorker::MarkFirstSetupComplete() {
|
|
syncer::SyncService* service = GetSyncService();
|
|
|
|
// The sync service may be nullptr if it has been just disabled by policy.
|
|
if (!service)
|
|
return;
|
|
|
|
// If the first-time setup is already complete, there's nothing else to do.
|
|
if (service->GetUserSettings()->IsInitialSyncFeatureSetupComplete()) {
|
|
return;
|
|
}
|
|
|
|
unified_consent::metrics::RecordSyncSetupDataTypesHistrogam(
|
|
service->GetUserSettings());
|
|
|
|
// We're done configuring, so notify SyncService that it is OK to start
|
|
// syncing.
|
|
service->GetUserSettings()->SetInitialSyncFeatureSetupComplete();
|
|
}
|
|
|
|
void BraveSyncWorker::FinalizeSyncSetup(JNIEnv* env) {
|
|
MarkFirstSetupComplete();
|
|
}
|
|
|
|
bool BraveSyncWorker::IsInitialSyncFeatureSetupComplete(JNIEnv* env) {
|
|
syncer::SyncService* sync_service = GetSyncService();
|
|
return sync_service &&
|
|
sync_service->GetUserSettings()->IsInitialSyncFeatureSetupComplete();
|
|
}
|
|
|
|
void BraveSyncWorker::ResetSync(JNIEnv* env) {
|
|
auto* sync_service = GetSyncService();
|
|
|
|
if (!sync_service)
|
|
return;
|
|
|
|
auto* device_info_sync_service =
|
|
DeviceInfoSyncServiceFactory::GetForProfile(profile_);
|
|
brave_sync::ResetSync(sync_service, device_info_sync_service,
|
|
base::BindOnce(&BraveSyncWorker::OnResetDone,
|
|
weak_ptr_factory_.GetWeakPtr()));
|
|
}
|
|
|
|
void BraveSyncWorker::OnResetDone() {
|
|
syncer::SyncService* sync_service = GetSyncService();
|
|
if (sync_service) {
|
|
if (sync_service_observer_.IsObservingSource(sync_service)) {
|
|
sync_service_observer_.RemoveObservation(sync_service);
|
|
}
|
|
}
|
|
}
|
|
|
|
void BraveSyncWorker::SetEncryptionPassphrase(syncer::SyncService* service) {
|
|
DCHECK(service);
|
|
DCHECK(service->IsEngineInitialized());
|
|
DCHECK(!this->passphrase_.empty());
|
|
|
|
syncer::SyncUserSettings* sync_user_settings = service->GetUserSettings();
|
|
DCHECK(!sync_user_settings->IsPassphraseRequired());
|
|
|
|
if (sync_user_settings->IsCustomPassphraseAllowed() &&
|
|
!sync_user_settings->IsUsingExplicitPassphrase() &&
|
|
!sync_user_settings->IsTrustedVaultKeyRequired()) {
|
|
sync_user_settings->SetEncryptionPassphrase(this->passphrase_);
|
|
}
|
|
}
|
|
|
|
void BraveSyncWorker::SetDecryptionPassphrase(syncer::SyncService* service) {
|
|
DCHECK(service);
|
|
DCHECK(service->IsEngineInitialized());
|
|
DCHECK(!this->passphrase_.empty());
|
|
syncer::SyncUserSettings* sync_user_settings = service->GetUserSettings();
|
|
DCHECK(sync_user_settings->IsPassphraseRequired());
|
|
|
|
bool set_decryption_result =
|
|
sync_user_settings->SetDecryptionPassphrase(this->passphrase_);
|
|
DCHECK(set_decryption_result);
|
|
VLOG_IF(3, !set_decryption_result)
|
|
<< "[BraveSync] " << __func__ << " SetDecryptionPassphrase failed";
|
|
}
|
|
|
|
void BraveSyncWorker::OnStateChanged(syncer::SyncService* service) {
|
|
// If the sync engine has shutdown for some reason, just give up
|
|
if (!service || !service->IsEngineInitialized()) {
|
|
VLOG(3) << "[BraveSync] " << __func__ << " sync engine is not initialized";
|
|
return;
|
|
}
|
|
|
|
if (this->passphrase_.empty()) {
|
|
VLOG(3) << "[BraveSync] " << __func__ << " empty passphrase";
|
|
return;
|
|
}
|
|
|
|
if (service->GetUserSettings()->IsPassphraseRequired()) {
|
|
SetDecryptionPassphrase(service);
|
|
} else {
|
|
SetEncryptionPassphrase(service);
|
|
}
|
|
}
|
|
|
|
void BraveSyncWorker::OnSyncShutdown(syncer::SyncService* sync) {
|
|
if (sync_service_observer_.IsObservingSource(sync)) {
|
|
sync_service_observer_.RemoveObservation(sync);
|
|
}
|
|
}
|
|
|
|
namespace {
|
|
std::string GetErrorDescription(
|
|
const syncer::SyncProtocolError& sync_protocol_error) {
|
|
if (sync_protocol_error.error_type == syncer::SYNC_SUCCESS) {
|
|
return std::string();
|
|
} else if (sync_protocol_error.error_type != syncer::SYNC_SUCCESS &&
|
|
sync_protocol_error.error_description.empty()) {
|
|
return GetSyncErrorTypeString(sync_protocol_error.error_type);
|
|
} else {
|
|
return sync_protocol_error.error_description;
|
|
}
|
|
}
|
|
|
|
void NativePermanentlyDeleteAccountCallback(
|
|
JNIEnv* env,
|
|
const base::android::ScopedJavaGlobalRef<jobject>& callback,
|
|
const syncer::SyncProtocolError& sync_protocol_error) {
|
|
std::string error_description = GetErrorDescription(sync_protocol_error);
|
|
|
|
Java_BraveSyncWorker_onPermanentlyDeleteAccountResult(
|
|
env, callback, ConvertUTF8ToJavaString(env, error_description));
|
|
}
|
|
} // namespace
|
|
|
|
void BraveSyncWorker::PermanentlyDeleteAccount(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jobject>& callback) {
|
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
auto* sync_service = GetSyncService();
|
|
CHECK_NE(sync_service, nullptr);
|
|
|
|
base::android::ScopedJavaGlobalRef<jobject> java_callback;
|
|
java_callback.Reset(env, callback);
|
|
|
|
sync_service->PermanentlyDeleteAccount(base::BindOnce(
|
|
&NativePermanentlyDeleteAccountCallback, env, java_callback));
|
|
}
|
|
|
|
namespace {
|
|
|
|
base::android::ScopedJavaLocalRef<jobject> GetJavaBoolean(
|
|
JNIEnv* env,
|
|
const bool& native_bool) {
|
|
jclass booleanClass = env->FindClass("java/lang/Boolean");
|
|
jmethodID methodID = env->GetMethodID(booleanClass, "<init>", "(Z)V");
|
|
jobject booleanObject = env->NewObject(booleanClass, methodID, native_bool);
|
|
|
|
return base::android::ScopedJavaLocalRef<jobject>::Adopt(env, booleanObject);
|
|
}
|
|
|
|
void NativeJoinSyncChainCallback(
|
|
JNIEnv* env,
|
|
const base::android::ScopedJavaGlobalRef<jobject>& callback,
|
|
bool result) {
|
|
Java_BraveSyncWorker_onJoinSyncChainResult(env, callback,
|
|
GetJavaBoolean(env, result));
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void BraveSyncWorker::SetJoinSyncChainCallback(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jobject>& callback) {
|
|
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
auto* sync_service = GetSyncService();
|
|
CHECK_NE(sync_service, nullptr);
|
|
|
|
base::android::ScopedJavaGlobalRef<jobject> java_callback;
|
|
java_callback.Reset(env, callback);
|
|
|
|
sync_service->SetJoinChainResultCallback(
|
|
base::BindOnce(&NativeJoinSyncChainCallback, env, java_callback));
|
|
}
|
|
|
|
void BraveSyncWorker::ClearAccountDeletedNoticePending(JNIEnv* env) {
|
|
Profile* profile =
|
|
ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
|
|
brave_sync::Prefs brave_sync_prefs(profile->GetPrefs());
|
|
brave_sync_prefs.SetSyncAccountDeletedNoticePending(false);
|
|
}
|
|
|
|
bool BraveSyncWorker::IsAccountDeletedNoticePending(JNIEnv* env) {
|
|
Profile* profile =
|
|
ProfileManager::GetActiveUserProfile()->GetOriginalProfile();
|
|
brave_sync::Prefs brave_sync_prefs(profile->GetPrefs());
|
|
return brave_sync_prefs.IsSyncAccountDeletedNoticePending();
|
|
}
|
|
|
|
static void JNI_BraveSyncWorker_Init(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jobject>& jcaller) {
|
|
new BraveSyncWorker(env, jcaller);
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetSeedHexFromWords(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& seed_words) {
|
|
std::string str_seed_words =
|
|
base::android::ConvertJavaStringToUTF8(seed_words);
|
|
DCHECK(!str_seed_words.empty());
|
|
|
|
std::string sync_code_hex;
|
|
std::vector<uint8_t> bytes;
|
|
if (brave_sync::crypto::PassphraseToBytes32(str_seed_words, &bytes)) {
|
|
DCHECK_EQ(bytes.size(), SEED_BYTES_COUNT);
|
|
sync_code_hex = base::HexEncode(bytes);
|
|
} else {
|
|
VLOG(1) << __func__ << " PassphraseToBytes32 failed";
|
|
}
|
|
|
|
return ConvertUTF8ToJavaString(env, sync_code_hex);
|
|
}
|
|
|
|
std::string GetWordsFromSeedHex(const std::string& str_seed_hex) {
|
|
DCHECK(!str_seed_hex.empty());
|
|
|
|
std::vector<uint8_t> bytes;
|
|
std::string sync_code_words;
|
|
if (base::HexStringToBytes(str_seed_hex, &bytes)) {
|
|
DCHECK_EQ(bytes.size(), SEED_BYTES_COUNT);
|
|
if (bytes.size() == SEED_BYTES_COUNT) {
|
|
sync_code_words = brave_sync::crypto::PassphraseFromBytes32(bytes);
|
|
if (sync_code_words.empty()) {
|
|
VLOG(1) << __func__ << " PassphraseFromBytes32 failed";
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "wrong seed bytes " << bytes.size();
|
|
}
|
|
DCHECK_NE(sync_code_words, "");
|
|
} else {
|
|
VLOG(1) << __func__ << " HexStringToBytes failed for seed hex";
|
|
}
|
|
|
|
return sync_code_words;
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetWordsFromSeedHex(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& seed_hex) {
|
|
std::string str_seed_hex = base::android::ConvertJavaStringToUTF8(seed_hex);
|
|
std::string sync_code_words = GetWordsFromSeedHex(str_seed_hex);
|
|
return ConvertUTF8ToJavaString(env, sync_code_words);
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetQrDataJson(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& seed_hex) {
|
|
std::string str_seed_hex = base::android::ConvertJavaStringToUTF8(seed_hex);
|
|
DCHECK(!str_seed_hex.empty());
|
|
|
|
const std::string qr_code_string =
|
|
brave_sync::QrCodeData::CreateWithActualDate(str_seed_hex)->ToJson();
|
|
|
|
return ConvertUTF8ToJavaString(env, qr_code_string);
|
|
}
|
|
|
|
int JNI_BraveSyncWorker_GetQrCodeValidationResult(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& json_qr) {
|
|
std::string str_json_qr = base::android::ConvertJavaStringToUTF8(json_qr);
|
|
DCHECK(!str_json_qr.empty());
|
|
return static_cast<int>(
|
|
brave_sync::QrCodeDataValidator::ValidateQrDataJson(str_json_qr));
|
|
}
|
|
|
|
int JNI_BraveSyncWorker_GetWordsValidationResult(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& time_limited_words) {
|
|
std::string str_time_limited_words =
|
|
base::android::ConvertJavaStringToUTF8(time_limited_words);
|
|
DCHECK(!str_time_limited_words.empty());
|
|
|
|
auto pure_words_with_status = TimeLimitedWords::Parse(str_time_limited_words);
|
|
|
|
if (pure_words_with_status.has_value()) {
|
|
using ValidationStatus = TimeLimitedWords::ValidationStatus;
|
|
return static_cast<int>(ValidationStatus::kValid);
|
|
}
|
|
return static_cast<int>(pure_words_with_status.error());
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetPureWordsFromTimeLimited(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& time_limited_words) {
|
|
std::string str_time_limited_words =
|
|
base::android::ConvertJavaStringToUTF8(time_limited_words);
|
|
DCHECK(!str_time_limited_words.empty());
|
|
|
|
auto pure_words_with_status = TimeLimitedWords::Parse(str_time_limited_words);
|
|
DCHECK(pure_words_with_status.has_value());
|
|
|
|
return base::android::ConvertUTF8ToJavaString(env,
|
|
pure_words_with_status.value());
|
|
}
|
|
|
|
static int64_t JNI_BraveSyncWorker_GetNotAfterFromFromTimeLimitedWords(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& time_limited_words) {
|
|
std::string str_time_limited_words =
|
|
base::android::ConvertJavaStringToUTF8(time_limited_words);
|
|
DCHECK(!str_time_limited_words.empty());
|
|
|
|
auto not_after = TimeLimitedWords::GetNotAfter(str_time_limited_words);
|
|
|
|
return not_after.InMillisecondsSinceUnixEpoch() / 1000;
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetFormattedTimeDelta(JNIEnv* env, jlong seconds) {
|
|
auto delta = base::Seconds(seconds);
|
|
|
|
using ui::TimeFormat;
|
|
std::u16string duration_string;
|
|
if (delta.InDays() > 0) {
|
|
duration_string += TimeFormat::Detailed(TimeFormat::FORMAT_DURATION,
|
|
TimeFormat::LENGTH_LONG, 0,
|
|
base::Days(delta.InDays()));
|
|
duration_string += u" ";
|
|
}
|
|
|
|
int remaining_hours =
|
|
delta.InHours() - delta.InDays() * base::Time::kHoursPerDay;
|
|
if (remaining_hours > 0) {
|
|
duration_string += TimeFormat::Detailed(TimeFormat::FORMAT_DURATION,
|
|
TimeFormat::LENGTH_LONG, 0,
|
|
base::Hours(remaining_hours));
|
|
duration_string += u" ";
|
|
}
|
|
|
|
int remaining_minutes =
|
|
delta.InMinutes() - delta.InHours() * base::Time::kMinutesPerHour;
|
|
if (remaining_minutes > 0) {
|
|
duration_string += TimeFormat::Detailed(TimeFormat::FORMAT_DURATION,
|
|
TimeFormat::LENGTH_LONG, 0,
|
|
base::Minutes(remaining_minutes));
|
|
duration_string += u" ";
|
|
}
|
|
|
|
int remaining_seconds =
|
|
delta.InSeconds() - delta.InMinutes() * base::Time::kSecondsPerMinute;
|
|
if (remaining_seconds > 0) {
|
|
duration_string += TimeFormat::Detailed(TimeFormat::FORMAT_DURATION,
|
|
TimeFormat::LENGTH_LONG, 0,
|
|
base::Seconds(remaining_seconds));
|
|
duration_string += u" ";
|
|
}
|
|
|
|
if (!duration_string.empty()) {
|
|
duration_string.resize(duration_string.length() - 1);
|
|
}
|
|
|
|
return base::android::ConvertUTF16ToJavaString(env, duration_string);
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetTimeLimitedWordsFromPure(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& pure_words) {
|
|
std::string str_pure_words =
|
|
base::android::ConvertJavaStringToUTF8(pure_words);
|
|
DCHECK(!str_pure_words.empty());
|
|
|
|
auto time_limited_words = TimeLimitedWords::GenerateForNow(str_pure_words);
|
|
|
|
DCHECK(time_limited_words.has_value());
|
|
return base::android::ConvertUTF8ToJavaString(env,
|
|
time_limited_words.value());
|
|
}
|
|
|
|
static base::android::ScopedJavaLocalRef<jstring>
|
|
JNI_BraveSyncWorker_GetSeedHexFromQrJson(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& json_qr) {
|
|
std::string str_json_qr = base::android::ConvertJavaStringToUTF8(json_qr);
|
|
DCHECK(!str_json_qr.empty());
|
|
|
|
auto qr_data = brave_sync::QrCodeData::FromJson(str_json_qr);
|
|
|
|
std::string result;
|
|
if (qr_data) {
|
|
result = qr_data->sync_code_hex;
|
|
} else {
|
|
result = str_json_qr;
|
|
}
|
|
|
|
DCHECK(!GetWordsFromSeedHex(result).empty());
|
|
|
|
return ConvertUTF8ToJavaString(env, result);
|
|
}
|
|
|
|
static int JNI_BraveSyncWorker_GetWordsCount(
|
|
JNIEnv* env,
|
|
const base::android::JavaRef<jstring>& words) {
|
|
return TimeLimitedWords::GetWordsCount(
|
|
base::android::ConvertJavaStringToUTF8(words));
|
|
}
|
|
|
|
} // namespace android
|
|
} // namespace chrome
|
|
|
|
DEFINE_JNI(BraveSyncWorker)
|