// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/saved_tab_groups/android/tab_group_sync_conversions_bridge.h"
#include <optional>
#include <vector>
#include "base/android/jni_string.h"
#include "base/android/token_android.h"
#include "base/uuid.h"
#include "components/saved_tab_groups/android/tab_group_sync_conversions_utils.h"
#include "components/saved_tab_groups/saved_tab_group.h"
#include "components/saved_tab_groups/saved_tab_group_tab.h"
#include "url/android/gurl_android.h"
// Must come after all headers that specialize FromJniType() / ToJniType().
#include "components/saved_tab_groups/jni_headers/TabGroupSyncConversionsBridge_jni.h"
using base::android::ConvertUTF16ToJavaString;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;
using base::android::TokenAndroid;
namespace tab_groups {
namespace {
// Unspecified tab position is represented as -1 in Java.
int kInvalidTabPosition = -1;
// Converts collaboration group ID to Java. If the collaboration group ID is
// not present, null is returned.
ScopedJavaLocalRef<jstring> ToJavaCollaborationId(
JNIEnv* env,
const std::optional<std::string>& collaboration_id) {
return collaboration_id.has_value()
? ConvertUTF8ToJavaString(env, collaboration_id.value())
: ScopedJavaLocalRef<jstring>();
}
// Helper method to create a Java SavedTabGroupTab, and optionally add it to
// a group if a non-null |j_tab_group| is specified.
ScopedJavaLocalRef<jobject>
JNI_TabGroupSyncConversionsBridge_createTabAndMaybeAddToGroup(
JNIEnv* env,
const SavedTabGroupTab& tab,
ScopedJavaLocalRef<jobject>& j_tab_group) {
auto j_sync_tab_id = UuidToJavaString(env, tab.saved_tab_guid());
auto j_local_tab_id = ToJavaTabId(tab.local_tab_id());
auto j_sync_group_id = UuidToJavaString(env, tab.saved_group_guid());
auto j_url = url::GURLAndroid::FromNativeGURL(env, tab.url());
auto j_creator_cache_guid = ConvertUTF8ToJavaString(
env, tab.creator_cache_guid().value_or(std::string()));
auto j_last_updater_cache_guid = ConvertUTF8ToJavaString(
env, tab.last_updater_cache_guid().value_or(std::string()));
return Java_TabGroupSyncConversionsBridge_createTabAndMaybeAddToGroup(
env, j_sync_tab_id, j_local_tab_id, j_sync_group_id,
static_cast<int32_t>(tab.position().value_or(kInvalidTabPosition)), j_url,
ConvertUTF16ToJavaString(env, tab.title()),
tab.creation_time_windows_epoch_micros().InMillisecondsSinceUnixEpoch(),
tab.update_time_windows_epoch_micros().InMillisecondsSinceUnixEpoch(),
j_creator_cache_guid, j_last_updater_cache_guid, j_tab_group);
}
// Helper method to create a Java SavedTabGroup. This doesn't include the tabs.
ScopedJavaLocalRef<jobject> JNI_TabGroupSyncConversionsBridge_createGroup(
JNIEnv* env,
const SavedTabGroup& group) {
auto j_sync_id = UuidToJavaString(env, group.saved_guid());
auto j_local_id = TabGroupSyncConversionsBridge::ToJavaTabGroupId(
env, group.local_group_id());
auto j_creator_cache_guid = ConvertUTF8ToJavaString(
env, group.creator_cache_guid().value_or(std::string()));
auto j_last_updater_cache_guid = ConvertUTF8ToJavaString(
env, group.last_updater_cache_guid().value_or(std::string()));
auto j_collaboration_id =
ToJavaCollaborationId(env, group.collaboration_id());
return Java_TabGroupSyncConversionsBridge_createGroup(
env, j_sync_id, j_local_id, ConvertUTF16ToJavaString(env, group.title()),
static_cast<int32_t>(group.color()),
group.creation_time_windows_epoch_micros().InMillisecondsSinceUnixEpoch(),
group.update_time_windows_epoch_micros().InMillisecondsSinceUnixEpoch(),
j_creator_cache_guid, j_last_updater_cache_guid, j_collaboration_id);
}
} // namespace
// static
ScopedJavaLocalRef<jobject> TabGroupSyncConversionsBridge::CreateGroup(
JNIEnv* env,
const SavedTabGroup& group) {
auto j_tab_group = JNI_TabGroupSyncConversionsBridge_createGroup(env, group);
for (const auto& tab : group.saved_tabs()) {
JNI_TabGroupSyncConversionsBridge_createTabAndMaybeAddToGroup(env, tab,
j_tab_group);
}
return j_tab_group;
}
// static
LocalTabGroupID TabGroupSyncConversionsBridge::FromJavaTabGroupId(
JNIEnv* env,
const JavaParamRef<jobject>& j_group_id) {
auto j_token =
Java_TabGroupSyncConversionsBridge_getNativeTabGroupId(env, j_group_id);
return TokenAndroid::FromJavaToken(env, j_token);
}
// static
ScopedJavaLocalRef<jobject> TabGroupSyncConversionsBridge::ToJavaTabGroupId(
JNIEnv* env,
const std::optional<LocalTabGroupID>& group_id) {
return group_id.has_value()
? Java_TabGroupSyncConversionsBridge_createJavaTabGroupId(
env, TokenAndroid::Create(env, group_id.value()))
: ScopedJavaLocalRef<jobject>();
}
} // namespace tab_groups