Implement instant share browser messages.
Some parts of actions and data in the strings are not finished as it
relies on more information to be plumbed into the message first.
The tests re-use shared test helper logic, which needed to be moved to
be accessible from share code.
Bug: 369163940
Change-Id: I732d2b10195d76a6c49b68794c9f562c1ecc5c82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5906783
Commit-Queue: Shakti Sahu <[email protected]>
Reviewed-by: Calder Kitagawa <[email protected]>
Auto-Submit: Sky Malice <[email protected]>
Reviewed-by: Shakti Sahu <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1364269}
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 576924a..63e128d 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -377,6 +377,7 @@
"//chrome/browser/data_sharing:factory_java",
"//chrome/browser/data_sharing:invitation_dialog_java",
"//chrome/browser/data_sharing:java",
+ "//chrome/browser/data_sharing:messages_java",
"//chrome/browser/data_sharing:shared_image_tiles_java",
"//chrome/browser/data_sharing:tab_group_ui_java",
"//chrome/browser/dependency_injection:java",
@@ -1254,6 +1255,7 @@
"//components/content_relationship_verification/android:junit_test_support",
"//components/content_settings/android:content_settings_enums_java",
"//components/content_settings/android:java",
+ "//components/data_sharing:test_support_java",
"//components/data_sharing/public:public_java",
"//components/device_reauth:device_reauth_java_enums",
"//components/digital_goods/mojom:mojom_java",
diff --git a/chrome/android/features/tab_ui/DEPS b/chrome/android/features/tab_ui/DEPS
index fe1a306..c02c848 100644
--- a/chrome/android/features/tab_ui/DEPS
+++ b/chrome/android/features/tab_ui/DEPS
@@ -15,6 +15,7 @@
"+components/browser_ui/styles/android",
"+components/browser_ui/widget/android",
"+components/data_sharing/public",
+ "+components/data_sharing/test_support",
"+components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement",
"+components/payments/content/android/java/src/org/chromium/components/payments/CurrencyFormatter.java",
"+components/saved_tab_groups/public",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverTestHelper.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverTestHelper.java
deleted file mode 100644
index 681fca0..0000000
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverTestHelper.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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.
-
-package org.chromium.chrome.browser.tasks.tab_management;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.verify;
-
-import org.mockito.ArgumentCaptor;
-
-import org.chromium.base.Callback;
-import org.chromium.components.data_sharing.DataSharingService;
-import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
-import org.chromium.components.data_sharing.GroupData;
-import org.chromium.components.data_sharing.GroupMember;
-import org.chromium.components.data_sharing.PeopleGroupActionFailure;
-import org.chromium.components.data_sharing.member_role.MemberRole;
-import org.chromium.components.tab_group_sync.TabGroupSyncService;
-
-/** Test helpers for {@link SharedGroupObserver} tests. */
-public class SharedGroupObserverTestHelper {
- public static final String EMAIL1 = "[email protected]";
- public static final String EMAIL2 = "[email protected]";
- public static final String GAIA_ID1 = "gaiaId1";
- public static final String GAIA_ID2 = "gaiaId2";
- public static final GroupMember GROUP_MEMBER1 =
- newGroupMember(GAIA_ID1, EMAIL1, MemberRole.OWNER);
- public static final GroupMember GROUP_MEMBER2 =
- newGroupMember(GAIA_ID2, EMAIL2, MemberRole.MEMBER);
-
- private final DataSharingService mDataSharingService;
- private final TabGroupSyncService mTabGroupSyncService;
- private final ArgumentCaptor<Callback<GroupDataOrFailureOutcome>> mReadGroupCallbackCaptor;
-
- /**
- * @param mockDataSharingService A mock {@link DataSharingService}.
- * @param mockTabGroupSyncService A mock {@link TabGroupSyncService}.
- */
- public SharedGroupObserverTestHelper(
- DataSharingService mockDataSharingService,
- TabGroupSyncService mockTabGroupSyncService,
- ArgumentCaptor<Callback<GroupDataOrFailureOutcome>> readGroupCallbackCaptor) {
- mDataSharingService = mockDataSharingService;
- mTabGroupSyncService = mockTabGroupSyncService;
- mReadGroupCallbackCaptor = readGroupCallbackCaptor;
- }
-
- /** Creates a new group member. */
- private static GroupMember newGroupMember(
- String gaiaId, String email, @MemberRole int memberRole) {
- return new GroupMember(
- gaiaId,
- /* displayName= */ null,
- email,
- memberRole,
- /* avatarUrl= */ null,
- /* givenName= */ null);
- }
-
- /** Creates new group data. */
- public static GroupData newGroupData(String collaborationId, GroupMember... members) {
- return new GroupData(
- collaborationId, /* displayName= */ null, members, /* groupToken= */ null);
- }
-
- /** Responds to a readGroup call on the {@link DataSharingService}. */
- public void respondToReadGroup(String collaborationId, GroupMember... members) {
- verify(mDataSharingService, atLeastOnce())
- .readGroup(eq(collaborationId), mReadGroupCallbackCaptor.capture());
- GroupData groupData = newGroupData(collaborationId, members);
- GroupDataOrFailureOutcome outcome =
- new GroupDataOrFailureOutcome(groupData, PeopleGroupActionFailure.UNKNOWN);
- mReadGroupCallbackCaptor.getValue().onResult(outcome);
- }
-}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverUnitTest.java
index bbcb4f9..08463f0 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverUnitTest.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverUnitTest.java
@@ -10,8 +10,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER1;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER1;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER2;
import androidx.annotation.Nullable;
@@ -33,6 +33,7 @@
import org.chromium.components.data_sharing.DataSharingService;
import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
import org.chromium.components.data_sharing.PeopleGroupActionFailure;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
import org.chromium.components.tab_group_sync.LocalTabGroupId;
import org.chromium.components.tab_group_sync.SavedTabGroup;
import org.chromium.components.tab_group_sync.TabGroupSyncService;
@@ -52,13 +53,12 @@
@Captor private ArgumentCaptor<Callback<GroupDataOrFailureOutcome>> mReadGroupCallbackCaptor;
@Captor private ArgumentCaptor<DataSharingService.Observer> mSharingObserverCaptor;
- private SharedGroupObserverTestHelper mSharedGroupObserverTestHelper;
+ private SharedGroupTestHelper mSharedGroupTestHelper;
@Before
public void setUp() {
- mSharedGroupObserverTestHelper =
- new SharedGroupObserverTestHelper(
- mDataSharingService, mTabGroupSyncService, mReadGroupCallbackCaptor);
+ mSharedGroupTestHelper =
+ new SharedGroupTestHelper(mDataSharingService, mReadGroupCallbackCaptor);
}
@Test
@@ -126,7 +126,7 @@
SharedGroupObserver observer =
new SharedGroupObserver(TAB_GROUP_ID, mTabGroupSyncService, mDataSharingService);
- mSharedGroupObserverTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1);
@GroupSharedState int state = observer.getGroupSharedStateSupplier().get();
assertEquals(GroupSharedState.COLLABORATION_ONLY, state);
@@ -142,8 +142,7 @@
SharedGroupObserver observer =
new SharedGroupObserver(TAB_GROUP_ID, mTabGroupSyncService, mDataSharingService);
- mSharedGroupObserverTestHelper.respondToReadGroup(
- COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2);
@GroupSharedState int state = observer.getGroupSharedStateSupplier().get();
assertEquals(GroupSharedState.HAS_OTHER_USERS, state);
@@ -168,9 +167,7 @@
verify(mDataSharingService).addObserver(mSharingObserverCaptor.capture());
mSharingObserverCaptor
.getValue()
- .onGroupAdded(
- SharedGroupObserverTestHelper.newGroupData(
- COLLABORATION_ID1, GROUP_MEMBER1));
+ .onGroupAdded(SharedGroupTestHelper.newGroupData(COLLABORATION_ID1, GROUP_MEMBER1));
verify(mOnSharedGroupStateChanged).onResult(GroupSharedState.COLLABORATION_ONLY);
@Nullable String collaborationId = observer.getCollaborationIdSupplier().get();
@@ -179,7 +176,7 @@
mSharingObserverCaptor
.getValue()
.onGroupChanged(
- SharedGroupObserverTestHelper.newGroupData(
+ SharedGroupTestHelper.newGroupData(
COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2));
verify(mOnSharedGroupStateChanged).onResult(GroupSharedState.HAS_OTHER_USERS);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorViewProviderUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorViewProviderUnitTest.java
index 3e1e3ff..bf34afb 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorViewProviderUnitTest.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupColorViewProviderUnitTest.java
@@ -13,8 +13,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER1;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER1;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER2;
import android.app.Activity;
import android.content.Context;
@@ -39,6 +39,7 @@
import org.chromium.components.data_sharing.DataSharingService;
import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
import org.chromium.components.data_sharing.ServiceStatus;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
import org.chromium.components.tab_group_sync.LocalTabGroupId;
import org.chromium.components.tab_group_sync.SavedTabGroup;
import org.chromium.components.tab_group_sync.TabGroupSyncService;
@@ -65,7 +66,7 @@
@Captor private ArgumentCaptor<DataSharingService.Observer> mSharingObserverCaptor;
@Captor private ArgumentCaptor<Callback<GroupDataOrFailureOutcome>> mReadGroupCallbackCaptor;
- private SharedGroupObserverTestHelper mSharedGroupObserverTestHelper;
+ private SharedGroupTestHelper mSharedGroupTestHelper;
private Context mContext;
private TabGroupColorViewProvider mRegularColorViewProvider;
private TabGroupColorViewProvider mIncognitoColorViewProvider;
@@ -75,9 +76,8 @@
when(mServiceStatus.isAllowedToJoin()).thenReturn(true);
when(mDataSharingService.getServiceStatus()).thenReturn(mServiceStatus);
- mSharedGroupObserverTestHelper =
- new SharedGroupObserverTestHelper(
- mDataSharingService, mTabGroupSyncService, mReadGroupCallbackCaptor);
+ mSharedGroupTestHelper =
+ new SharedGroupTestHelper(mDataSharingService, mReadGroupCallbackCaptor);
mActivityScenarioRule.getScenario().onActivity(this::onActivityCreated);
}
@@ -193,7 +193,7 @@
mSharingObserverCaptor
.getValue()
.onGroupAdded(
- SharedGroupObserverTestHelper.newGroupData(
+ SharedGroupTestHelper.newGroupData(
COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2));
}
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TransitiveSharedGroupObserverUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TransitiveSharedGroupObserverUnitTest.java
index a4055aa..21d122b 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TransitiveSharedGroupObserverUnitTest.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TransitiveSharedGroupObserverUnitTest.java
@@ -9,8 +9,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER1;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER1;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER2;
import org.junit.Before;
import org.junit.Rule;
@@ -27,6 +27,7 @@
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.components.data_sharing.DataSharingService;
import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
import org.chromium.components.tab_group_sync.LocalTabGroupId;
import org.chromium.components.tab_group_sync.SavedTabGroup;
import org.chromium.components.tab_group_sync.TabGroupSyncService;
@@ -49,13 +50,12 @@
@Captor private ArgumentCaptor<Callback<GroupDataOrFailureOutcome>> mReadGroupCallbackCaptor;
- private SharedGroupObserverTestHelper mSharedGroupObserverTestHelper;
+ private SharedGroupTestHelper mSharedGroupTestHelper;
@Before
public void setUp() {
- mSharedGroupObserverTestHelper =
- new SharedGroupObserverTestHelper(
- mDataSharingService, mTabGroupSyncService, mReadGroupCallbackCaptor);
+ mSharedGroupTestHelper =
+ new SharedGroupTestHelper(mDataSharingService, mReadGroupCallbackCaptor);
}
@Test
@@ -90,15 +90,14 @@
savedTabGroup.collaborationId = COLLABORATION_ID_1;
when(mTabGroupSyncService.getGroup(any(LocalTabGroupId.class))).thenReturn(savedTabGroup);
observer.setTabGroupId(TAB_GROUP_ID_1);
- mSharedGroupObserverTestHelper.respondToReadGroup(COLLABORATION_ID_1, GROUP_MEMBER1);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID_1, GROUP_MEMBER1);
verify(mOnSharedGroupStateChanged).onResult(GroupSharedState.COLLABORATION_ONLY);
verify(mOnSharedGroupCollaborationIdChanged).onResult(COLLABORATION_ID_1);
savedTabGroup.collaborationId = COLLABORATION_ID_2;
observer.setTabGroupId(TAB_GROUP_ID_2);
- mSharedGroupObserverTestHelper.respondToReadGroup(
- COLLABORATION_ID_2, GROUP_MEMBER1, GROUP_MEMBER2);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID_2, GROUP_MEMBER1, GROUP_MEMBER2);
verify(mOnSharedGroupStateChanged).onResult(GroupSharedState.HAS_OTHER_USERS);
verify(mOnSharedGroupCollaborationIdChanged).onResult(COLLABORATION_ID_2);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java
index 7d277d4..3b4afac 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediatorUnitTest.java
@@ -34,10 +34,10 @@
import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER;
import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.EMAIL2;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GAIA_ID2;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER1;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.EMAIL2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GAIA_ID2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER1;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER2;
import android.app.Activity;
import android.graphics.Rect;
@@ -100,6 +100,7 @@
import org.chromium.components.data_sharing.DataSharingService;
import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
import org.chromium.components.data_sharing.GroupMember;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.identitymanager.IdentityManager;
import org.chromium.components.tab_group_sync.LocalTabGroupId;
@@ -184,7 +185,7 @@
private Activity mActivity;
private PropertyModel mModel;
private TabGridDialogMediator mMediator;
- private SharedGroupObserverTestHelper mSharedGroupObserverTestHelper;
+ private SharedGroupTestHelper mSharedGroupTestHelper;
@Before
public void setUp() {
@@ -198,9 +199,8 @@
when(mIdentityServicesProvider.getIdentityManager(any())).thenReturn(mIdentityManager);
TabGroupSyncServiceFactory.setForTesting(mTabGroupSyncService);
DataSharingServiceFactory.setForTesting(mDataSharingService);
- mSharedGroupObserverTestHelper =
- new SharedGroupObserverTestHelper(
- mDataSharingService, mTabGroupSyncService, mReadGroupCallbackCaptor);
+ mSharedGroupTestHelper =
+ new SharedGroupTestHelper(mDataSharingService, mReadGroupCallbackCaptor);
mTab1 = prepareTab(TAB1_ID, TAB1_TITLE);
mTab2 = prepareTab(TAB2_ID, TAB2_TITLE);
@@ -1707,7 +1707,7 @@
mMediator.onReset(tabGroup);
if (isShared) {
- mSharedGroupObserverTestHelper.respondToReadGroup(COLLABORATION_ID1, members);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID1, members);
}
}
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
index 863909a6..5e87024 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediatorUnitTest.java
@@ -26,8 +26,8 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER1;
-import static org.chromium.chrome.browser.tasks.tab_management.SharedGroupObserverTestHelper.GROUP_MEMBER2;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER1;
+import static org.chromium.components.data_sharing.SharedGroupTestHelper.GROUP_MEMBER2;
import android.content.Context;
import android.content.res.Resources;
@@ -91,6 +91,7 @@
import org.chromium.components.browser_ui.styles.SemanticColorUtils;
import org.chromium.components.data_sharing.DataSharingService;
import org.chromium.components.data_sharing.DataSharingService.GroupDataOrFailureOutcome;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
import org.chromium.components.tab_group_sync.LocalTabGroupId;
import org.chromium.components.tab_group_sync.SavedTabGroup;
import org.chromium.components.tab_group_sync.TabGroupSyncService;
@@ -182,7 +183,7 @@
private OneshotSupplierImpl<LayoutStateProvider> mLayoutStateProviderSupplier =
new OneshotSupplierImpl<>();
private LazyOneshotSupplier<TabGridDialogMediator.DialogController> mDialogControllerSupplier;
- private SharedGroupObserverTestHelper mSharedGroupObserverTestHelper;
+ private SharedGroupTestHelper mSharedGroupTestHelper;
private Tab prepareTab(int tabId, int rootId) {
Tab tab = TabUiUnitTestUtils.prepareTab(tabId, rootId);
@@ -293,9 +294,8 @@
doReturn(true).when(mTabGroupSyncFeaturesJniMock).isTabGroupSyncEnabled(mProfile);
TabGroupSyncServiceFactory.setForTesting(mTabGroupSyncService);
DataSharingServiceFactory.setForTesting(mDataSharingService);
- mSharedGroupObserverTestHelper =
- new SharedGroupObserverTestHelper(
- mDataSharingService, mTabGroupSyncService, mReadGroupCallbackCaptor);
+ mSharedGroupTestHelper =
+ new SharedGroupTestHelper(mDataSharingService, mReadGroupCallbackCaptor);
// Set up Tabs
mTab1 = prepareTab(TAB1_ID, TAB1_ROOT_ID);
@@ -1159,8 +1159,7 @@
setupSyncedGroup(/* isShared= */ true);
initAndAssertProperties(mTab2);
- mSharedGroupObserverTestHelper.respondToReadGroup(
- COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1, GROUP_MEMBER2);
assertFalse(mModel.get(TabGroupUiProperties.SHOW_GROUP_DIALOG_BUTTON_VISIBLE));
assertTrue(mModel.get(TabGroupUiProperties.IMAGE_TILES_CONTAINER_VISIBLE));
@@ -1180,7 +1179,7 @@
setupSyncedGroup(/* isShared= */ true);
initAndAssertProperties(mTab2);
- mSharedGroupObserverTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1);
+ mSharedGroupTestHelper.respondToReadGroup(COLLABORATION_ID1, GROUP_MEMBER1);
assertTrue(mModel.get(TabGroupUiProperties.SHOW_GROUP_DIALOG_BUTTON_VISIBLE));
assertFalse(mModel.get(TabGroupUiProperties.IMAGE_TILES_CONTAINER_VISIBLE));
diff --git a/chrome/android/features/tab_ui/tab_management_java_sources.gni b/chrome/android/features/tab_ui/tab_management_java_sources.gni
index 193e37e..eb26f1a 100644
--- a/chrome/android/features/tab_ui/tab_management_java_sources.gni
+++ b/chrome/android/features/tab_ui/tab_management_java_sources.gni
@@ -215,7 +215,6 @@
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CloseAllTabsHelperUnitTest.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/CollaborationActivityMessageCardViewModelUnitTest.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IncognitoTabSwitcherPaneUnitTest.java",
- "//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverTestHelper.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/SharedGroupObserverUnitTest.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/StrictButtonPressControllerUnitTest.java",
"//chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabArchiveSettingsFragmentUnitTest.java",
diff --git a/chrome/browser/data_sharing/BUILD.gn b/chrome/browser/data_sharing/BUILD.gn
index 0093dc9..f095ab8 100644
--- a/chrome/browser/data_sharing/BUILD.gn
+++ b/chrome/browser/data_sharing/BUILD.gn
@@ -20,6 +20,7 @@
deps = [
":java",
+ ":messages_java",
"//base:base_java",
"//base:service_loader_java",
"//build/android:build_java",
@@ -84,7 +85,6 @@
sources = [
"android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingImplFactory.java",
"android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingNotificationManager.java",
- "android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java",
"android/java/src/org/chromium/chrome/browser/data_sharing/MemberPickerListenerImpl.java",
"android/java/src/org/chromium/chrome/browser/data_sharing/NoOpDataSharingSDKDelegateImpl.java",
]
@@ -96,21 +96,15 @@
"//chrome/browser/notifications:java",
"//chrome/browser/profiles/android:java",
"//chrome/browser/tab:java",
- "//chrome/browser/tab_group:java",
- "//chrome/browser/tab_group_sync/messaging/android:factory_java",
"//chrome/browser/ui/android/strings:ui_strings_grd",
"//components/browser_ui/notifications/android:java",
"//components/browser_ui/styles/android:java_resources",
"//components/data_sharing/public:public_java",
"//components/data_sharing/public/protocol:proto_java",
- "//components/messages/android:java",
- "//components/saved_tab_groups/messaging/android:java",
"//third_party/android_deps:protobuf_lite_runtime_java",
"//third_party/android_sdk:android_window_extensions_java",
"//third_party/androidx:androidx_annotation_annotation_java",
- "//third_party/androidx:androidx_core_core_java",
"//third_party/jni_zero:jni_zero_java",
- "//ui/android:ui_java",
"//url:url_java",
]
}
@@ -139,6 +133,29 @@
]
}
+ android_library("messages_java") {
+ resources_package = "org.chromium.chrome.browser.data_sharing"
+ sources = [ "android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java" ]
+
+ deps = [
+ ":java_resources",
+ "//base:base_java",
+ "//base:supplier_java",
+ "//chrome/android:chrome_app_java_resources",
+ "//chrome/browser/profiles/android:java",
+ "//chrome/browser/tab:java",
+ "//chrome/browser/tab_group:java",
+ "//chrome/browser/tab_group_sync/messaging/android:factory_java",
+ "//components/data_sharing/public:public_java",
+ "//components/messages/android:java",
+ "//components/saved_tab_groups/messaging/android:java",
+ "//components/saved_tab_groups/public:java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ "//third_party/androidx:androidx_core_core_java",
+ "//ui/android:ui_java",
+ ]
+ }
+
android_library("invitation_dialog_java") {
resources_package =
"org.chromium.chrome.browser.data_sharing.ui.invitation_dialog"
@@ -159,21 +176,30 @@
sources = [
"android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingNotificationManagerUnitTest.java",
"android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingTabGroupUtilsUnitTest.java",
+ "android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java",
"android/java/src/org/chromium/chrome/browser/data_sharing/ui/shared_image_tiles/SharedImageTilesCoordinatorUnitTest.java",
]
deps = [
":java",
+ ":messages_java",
":shared_image_tiles_java",
"//base:base_java",
"//base:base_junit_test_support",
"//chrome/browser/notifications:java",
"//chrome/browser/profiles/android:java",
"//chrome/browser/tab:java",
+ "//chrome/browser/tab_group:java",
"//chrome/browser/tab_group_sync:factory_java",
+ "//chrome/browser/tab_group_sync/messaging/android:factory_java",
"//chrome/browser/tabmodel:java",
"//chrome/test/android:chrome_java_unit_test_support",
"//components/browser_ui/notifications/android:java",
+ "//components/data_sharing:test_support_java",
"//components/data_sharing/public:public_java",
+ "//components/messages/android:factory_java",
+ "//components/messages/android:java",
+ "//components/messages/android:manager_java",
+ "//components/saved_tab_groups/messaging/android:java",
"//components/saved_tab_groups/public:java",
"//content/public/android:content_full_java",
"//third_party/android_deps:robolectric_all_java",
diff --git a/chrome/browser/data_sharing/android/DEPS b/chrome/browser/data_sharing/android/DEPS
index c66e922..94b38565 100644
--- a/chrome/browser/data_sharing/android/DEPS
+++ b/chrome/browser/data_sharing/android/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+components/browser_ui/share",
+ "+components/saved_tab_groups/messaging",
]
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java
index fdbcbb0..f4d9744b 100644
--- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java
+++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java
@@ -4,20 +4,33 @@
package org.chromium.chrome.browser.data_sharing;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import androidx.core.util.Pair;
+import org.chromium.base.Token;
+import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tab_group_sync.messaging.MessagingBackendServiceFactory;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
+import org.chromium.components.messages.MessageBannerProperties;
import org.chromium.components.messages.MessageDispatcher;
import org.chromium.components.messages.MessageDispatcherProvider;
+import org.chromium.components.messages.MessageIdentifier;
+import org.chromium.components.messages.PrimaryActionClickBehavior;
import org.chromium.components.tab_group_sync.messaging.InstantMessage;
import org.chromium.components.tab_group_sync.messaging.InstantNotificationLevel;
-import org.chromium.components.tab_group_sync.messaging.InstantNotificationType;
+import org.chromium.components.tab_group_sync.messaging.MessageAttribution;
import org.chromium.components.tab_group_sync.messaging.MessagingBackendService;
import org.chromium.components.tab_group_sync.messaging.MessagingBackendService.InstantMessageDelegate;
import org.chromium.components.tab_group_sync.messaging.UserAction;
import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.modelutil.PropertyModel;
import java.util.ArrayList;
import java.util.List;
@@ -28,8 +41,7 @@
* scoped by profile. This class should be attached/detached by all windows.
*/
public class InstantMessageDelegateImpl implements InstantMessageDelegate {
- private final List<Pair<MessageDispatcher, TabGroupModelFilter>> mAttachedWindows =
- new ArrayList<>();
+ private final List<Pair<WindowAndroid, TabGroupModelFilter>> mAttachList = new ArrayList<>();
/**
* @param profile The current profile to get dependencies with.
@@ -45,42 +57,199 @@
* @param windowAndroid The window that can be used for showing messages.
* @param tabGroupModelFilter The tab model and group filter for the given window.
*/
- public void attachWindow(WindowAndroid windowAndroid, TabGroupModelFilter tabGroupModelFilter) {
- MessageDispatcher messageDispatcher = MessageDispatcherProvider.from(windowAndroid);
- mAttachedWindows.add(new Pair<>(messageDispatcher, tabGroupModelFilter));
+ public void attachWindow(
+ @NonNull WindowAndroid windowAndroid,
+ @NonNull TabGroupModelFilter tabGroupModelFilter) {
+ assert windowAndroid != null;
+ assert tabGroupModelFilter != null;
+ assert !tabGroupModelFilter.isIncognito();
+ mAttachList.add(new Pair<>(windowAndroid, tabGroupModelFilter));
}
/**
* @param windowAndroid The window that is no longer usable for showing messages.
*/
- public void detachWindow(WindowAndroid windowAndroid) {
- MessageDispatcher messageDispatcher = MessageDispatcherProvider.from(windowAndroid);
- mAttachedWindows.removeIf(p -> Objects.equals(p.first, messageDispatcher));
+ public void detachWindow(@NonNull WindowAndroid windowAndroid) {
+ assert windowAndroid != null;
+ mAttachList.removeIf(wa -> Objects.equals(wa.first, windowAndroid));
}
@Override
public void displayInstantaneousMessage(InstantMessage message) {
- @InstantNotificationType int type = message.type;
- if (type == InstantNotificationType.CONFLICT_TAB_REMOVED) {
- // TODO(https://crbug.com/369164214): Implement (or move below).
- }
if (message.level == InstantNotificationLevel.SYSTEM) {
// TODO(https://crbug.com/369164214): Implement.
} else if (message.level == InstantNotificationLevel.BROWSER) {
- if (mAttachedWindows.size() == 0) {
- return;
- }
+ @Nullable
+ Pair<WindowAndroid, TabGroupModelFilter> attach = getAttach(message.attribution);
+ if (attach == null) return;
+ @NonNull WindowAndroid windowAndroid = attach.first;
+ @NonNull TabGroupModelFilter tabGroupModelFilter = attach.second;
+ @Nullable
+ MessageDispatcher messageDispatcher = MessageDispatcherProvider.from(windowAndroid);
+ @Nullable Context context = windowAndroid.getContext().get();
+ if (messageDispatcher == null || context == null) return;
@UserAction int userAction = message.action;
if (userAction == UserAction.TAB_REMOVED) {
- // TODO(https://crbug.com/369163940): Implement.
+ showTabRemoved(message, context, messageDispatcher, tabGroupModelFilter);
} else if (userAction == UserAction.TAB_NAVIGATED) {
- // TODO(https://crbug.com/369163940): Implement.
+ showTabChange(message, context, messageDispatcher, tabGroupModelFilter);
} else if (userAction == UserAction.COLLABORATION_USER_JOINED) {
- // TODO(https://crbug.com/369163940): Implement.
+ showCollaborationUserJoined(message, context, messageDispatcher);
} else if (userAction == UserAction.COLLABORATION_REMOVED) {
- // TODO(https://crbug.com/369163940): Implement.
+ showCollaborationRemoved(message, context, messageDispatcher);
}
}
}
+
+ private Pair<WindowAndroid, TabGroupModelFilter> getAttach(
+ MessageAttribution messageAttribution) {
+ if (mAttachList.size() == 0) {
+ return null;
+ }
+
+ if (messageAttribution == null
+ || messageAttribution.localTabGroupId == null
+ || messageAttribution.localTabGroupId.tabGroupId == null) {
+ // Message doesn't link to a window, show it arbitrarily.
+ return mAttachList.get(0);
+ }
+
+ @NonNull Token tabGroupId = messageAttribution.localTabGroupId.tabGroupId;
+ for (Pair<WindowAndroid, TabGroupModelFilter> attach : mAttachList) {
+ TabGroupModelFilter tabGroupModelFilter = attach.second;
+ int rootId = tabGroupModelFilter.getRootIdFromStableId(tabGroupId);
+ if (rootId == Tab.INVALID_TAB_ID) continue;
+
+ // If we had a valid rootId, this is the right window.
+ return attach;
+ }
+
+ // Tab group was deleted or window not active.
+ return null;
+ }
+
+ private String givenNameFromMessage(InstantMessage message) {
+ return message.attribution.triggeringUser.givenName;
+ }
+
+ private String tabTitleFromMessage(InstantMessage message) {
+ // TODO(https://crbug.com/369163940): Once the message stores this, we can return it.
+ return "ph1";
+ }
+
+ private String tabGroupTitleFromMessage(InstantMessage message) {
+ // TODO(https://crbug.com/369163940): Once the message stores this, we can return it.
+ return "ph2";
+ }
+
+ private Drawable iconFromMessage(InstantMessage message, Context context) {
+ // TODO(https://crbug.com/369163940): Fetch this, potentially async.
+ return ContextCompat.getDrawable(context, R.drawable.ic_features_24dp);
+ }
+
+ private void showTabRemoved(
+ InstantMessage message,
+ Context context,
+ MessageDispatcher messageDispatcher,
+ TabGroupModelFilter tabGroupModelFilter) {
+ String givenName = givenNameFromMessage(message);
+ String tabTitle = tabTitleFromMessage(message);
+ String title =
+ context.getString(
+ R.string.data_sharing_browser_message_removed_tab, givenName, tabTitle);
+ String buttonText = context.getString(R.string.data_sharing_browser_message_reopen);
+ Drawable icon = iconFromMessage(message, context);
+ // TODO(https://crbug.com/369163940): Once the message has the url, we can restore.
+ showGenericMessage(
+ messageDispatcher,
+ MessageIdentifier.TAB_REMOVED_THROUGH_COLLABORATION,
+ title,
+ buttonText,
+ icon,
+ () -> {});
+ }
+
+ private void showTabChange(
+ InstantMessage message,
+ Context context,
+ MessageDispatcher messageDispatcher,
+ TabGroupModelFilter tabGroupModelFilter) {
+ String givenName = givenNameFromMessage(message);
+ String tabTitle = tabTitleFromMessage(message);
+ String title =
+ context.getString(
+ R.string.data_sharing_browser_message_changed_tab, givenName, tabTitle);
+ String buttonText = context.getString(R.string.data_sharing_browser_message_reopen);
+ Drawable icon = iconFromMessage(message, context);
+ // TODO(https://crbug.com/369163940): Once the message has the url, we can restore.
+ showGenericMessage(
+ messageDispatcher,
+ MessageIdentifier.TAB_NAVIGATED_THROUGH_COLLABORATION,
+ title,
+ buttonText,
+ icon,
+ () -> {});
+ }
+
+ private void showCollaborationUserJoined(
+ InstantMessage message, Context context, MessageDispatcher messageDispatcher) {
+ String givenName = givenNameFromMessage(message);
+ String tabGroupTitle = tabGroupTitleFromMessage(message);
+ String title =
+ context.getString(
+ R.string.data_sharing_browser_message_joined_tab_group,
+ givenName,
+ tabGroupTitle);
+ String buttonText = context.getString(R.string.data_sharing_browser_message_manage);
+ Drawable icon = iconFromMessage(message, context);
+ // TODO(https://crbug.com/369163940): Action should open manage sheet.
+ showGenericMessage(
+ messageDispatcher,
+ MessageIdentifier.COLLABORATION_USER_JOINED,
+ title,
+ buttonText,
+ icon,
+ () -> {});
+ }
+
+ private void showCollaborationRemoved(
+ InstantMessage message, Context context, MessageDispatcher messageDispatcher) {
+ String tabGroupTitle = tabGroupTitleFromMessage(message);
+ String title =
+ context.getString(
+ R.string.data_sharing_browser_message_not_available, tabGroupTitle);
+ String buttonText = context.getString(R.string.data_sharing_invitation_failure_button);
+ Drawable icon = ContextCompat.getDrawable(context, R.drawable.ic_features_24dp);
+ showGenericMessage(
+ messageDispatcher,
+ MessageIdentifier.COLLABORATION_REMOVED,
+ title,
+ buttonText,
+ icon,
+ () -> {});
+ }
+
+ private void showGenericMessage(
+ MessageDispatcher messageDispatcher,
+ @MessageIdentifier int messageIdentifier,
+ String title,
+ String buttonText,
+ Drawable icon,
+ Runnable action) {
+ Supplier<Integer> onPrimary =
+ () -> {
+ action.run();
+ return PrimaryActionClickBehavior.DISMISS_IMMEDIATELY;
+ };
+ PropertyModel propertyModel =
+ new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS)
+ .with(MessageBannerProperties.MESSAGE_IDENTIFIER, messageIdentifier)
+ .with(MessageBannerProperties.TITLE, title)
+ .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, buttonText)
+ .with(MessageBannerProperties.ICON, icon)
+ .with(MessageBannerProperties.ON_PRIMARY_ACTION, onPrimary)
+ .build();
+ messageDispatcher.enqueueWindowScopedMessage(propertyModel, /* highPriority= */ false);
+ }
}
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java
new file mode 100644
index 0000000..942f66e5
--- /dev/null
+++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java
@@ -0,0 +1,159 @@
+// 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.
+
+package org.chromium.chrome.browser.data_sharing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static org.chromium.components.messages.MessageBannerProperties.MESSAGE_IDENTIFIER;
+import static org.chromium.components.messages.MessageBannerProperties.TITLE;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import org.chromium.base.Token;
+import org.chromium.base.UnownedUserDataHost;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab_group_sync.messaging.MessagingBackendServiceFactory;
+import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
+import org.chromium.components.data_sharing.SharedGroupTestHelper;
+import org.chromium.components.messages.ManagedMessageDispatcher;
+import org.chromium.components.messages.MessageIdentifier;
+import org.chromium.components.messages.MessagesFactory;
+import org.chromium.components.tab_group_sync.LocalTabGroupId;
+import org.chromium.components.tab_group_sync.messaging.InstantMessage;
+import org.chromium.components.tab_group_sync.messaging.InstantNotificationLevel;
+import org.chromium.components.tab_group_sync.messaging.MessageAttribution;
+import org.chromium.components.tab_group_sync.messaging.MessagingBackendService;
+import org.chromium.components.tab_group_sync.messaging.UserAction;
+import org.chromium.ui.base.WindowAndroid;
+import org.chromium.ui.modelutil.PropertyModel;
+
+import java.lang.ref.WeakReference;
+
+/** Unit tests for {@link InstantMessageDelegateImpl}. */
+@RunWith(BaseRobolectricTestRunner.class)
+public class InstantMessageDelegateImplUnitTest {
+ private static final Token TAB_GROUP_ID = new Token(1L, 2L);
+ private static final int TAB_ID = 1;
+
+ @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock private Profile mProfile;
+ @Mock private MessagingBackendService mMessagingBackendService;
+ @Mock private ManagedMessageDispatcher mManagedMessageDispatcher;
+ @Mock private WindowAndroid mWindowAndroid;
+ @Mock private TabGroupModelFilter mTabGroupModelFilter;
+
+ @Captor private ArgumentCaptor<PropertyModel> mPropertyModelCaptor;
+
+ private InstantMessageDelegateImpl mDelegate;
+
+ @Before
+ public void setUp() {
+ MessagingBackendServiceFactory.setForTesting(mMessagingBackendService);
+ when(mWindowAndroid.getUnownedUserDataHost()).thenReturn(new UnownedUserDataHost());
+ MessagesFactory.attachMessageDispatcher(mWindowAndroid, mManagedMessageDispatcher);
+ when(mWindowAndroid.getContext())
+ .thenReturn(new WeakReference<>(ApplicationProvider.getApplicationContext()));
+ when(mTabGroupModelFilter.getRootIdFromStableId(TAB_GROUP_ID)).thenReturn(TAB_ID);
+
+ mDelegate = new InstantMessageDelegateImpl(mProfile);
+ mDelegate.attachWindow(mWindowAndroid, mTabGroupModelFilter);
+ }
+
+ private InstantMessage newInstantMessage(@UserAction int action) {
+ MessageAttribution attribution = new MessageAttribution();
+ attribution.localTabGroupId = new LocalTabGroupId(TAB_GROUP_ID);
+ attribution.triggeringUser = SharedGroupTestHelper.GROUP_MEMBER1;
+ InstantMessage instantMessage = new InstantMessage();
+ instantMessage.attribution = attribution;
+ instantMessage.action = action;
+ instantMessage.level = InstantNotificationLevel.BROWSER;
+ return instantMessage;
+ }
+
+ @Test
+ public void testDisplayInstantaneousMessage_NotAttached() {
+ mDelegate.detachWindow(mWindowAndroid);
+ mDelegate.displayInstantaneousMessage(newInstantMessage(UserAction.TAB_REMOVED));
+ verify(mManagedMessageDispatcher, never()).enqueueWindowScopedMessage(any(), anyBoolean());
+ }
+
+ @Test
+ public void testDisplayInstantaneousMessage_NotInTabModel() {
+ when(mTabGroupModelFilter.getRootIdFromStableId(TAB_GROUP_ID))
+ .thenReturn(Tab.INVALID_TAB_ID);
+ mDelegate.displayInstantaneousMessage(newInstantMessage(UserAction.TAB_REMOVED));
+ verify(mManagedMessageDispatcher, never()).enqueueWindowScopedMessage(any(), anyBoolean());
+ }
+
+ @Test
+ public void testTabRemoved() {
+ mDelegate.displayInstantaneousMessage(newInstantMessage(UserAction.TAB_REMOVED));
+
+ verify(mManagedMessageDispatcher)
+ .enqueueWindowScopedMessage(mPropertyModelCaptor.capture(), anyBoolean());
+ PropertyModel propertyModel = mPropertyModelCaptor.getValue();
+ @MessageIdentifier int messageIdentifier = propertyModel.get(MESSAGE_IDENTIFIER);
+ assertEquals(MessageIdentifier.TAB_REMOVED_THROUGH_COLLABORATION, messageIdentifier);
+ String title = propertyModel.get(TITLE);
+ assertTrue(title.contains(SharedGroupTestHelper.GIVEN_NAME1));
+ }
+
+ @Test
+ public void testTabNavigated() {
+ mDelegate.displayInstantaneousMessage(newInstantMessage(UserAction.TAB_NAVIGATED));
+
+ verify(mManagedMessageDispatcher)
+ .enqueueWindowScopedMessage(mPropertyModelCaptor.capture(), anyBoolean());
+ PropertyModel propertyModel = mPropertyModelCaptor.getValue();
+ @MessageIdentifier int messageIdentifier = propertyModel.get(MESSAGE_IDENTIFIER);
+ assertEquals(MessageIdentifier.TAB_NAVIGATED_THROUGH_COLLABORATION, messageIdentifier);
+ String title = propertyModel.get(TITLE);
+ assertTrue(title.contains(SharedGroupTestHelper.GIVEN_NAME1));
+ }
+
+ @Test
+ public void testCollaborationUserJoined() {
+ mDelegate.displayInstantaneousMessage(
+ newInstantMessage(UserAction.COLLABORATION_USER_JOINED));
+
+ verify(mManagedMessageDispatcher)
+ .enqueueWindowScopedMessage(mPropertyModelCaptor.capture(), anyBoolean());
+ PropertyModel propertyModel = mPropertyModelCaptor.getValue();
+ @MessageIdentifier int messageIdentifier = propertyModel.get(MESSAGE_IDENTIFIER);
+ assertEquals(MessageIdentifier.COLLABORATION_USER_JOINED, messageIdentifier);
+ String title = propertyModel.get(TITLE);
+ assertTrue(title.contains(SharedGroupTestHelper.GIVEN_NAME1));
+ }
+
+ @Test
+ public void testCollaborationRemoved() {
+ mDelegate.displayInstantaneousMessage(newInstantMessage(UserAction.COLLABORATION_REMOVED));
+
+ verify(mManagedMessageDispatcher)
+ .enqueueWindowScopedMessage(mPropertyModelCaptor.capture(), anyBoolean());
+ PropertyModel propertyModel = mPropertyModelCaptor.getValue();
+ @MessageIdentifier int messageIdentifier = propertyModel.get(MESSAGE_IDENTIFIER);
+ assertEquals(MessageIdentifier.COLLABORATION_REMOVED, messageIdentifier);
+ }
+}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index fdd1ea69..68c9bd51 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -6751,6 +6751,24 @@
<message name="IDS_DATA_SHARING_GENERIC_FAILURE_DESCRIPTION" desc="The body text the dialog shown when some share backend call fails, for example when leaving a group.">
There was an error. Try again.
</message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_CHANGED_TAB" desc="The text in a pop up message that occurs when someone else navigates the tab that was being shown.">
+ <ph name="GIVEN_NAME">%1$s<ex>Jane</ex></ph> changed tab “<ph name="TAB_NAME">%2$s<ex>Example Domain</ex></ph>”
+ </message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_REMOVED_TAB" desc="The text in a pop up message that occurs when someone else removes the tab that was being shown.">
+ <ph name="GIVEN_NAME">%1$s<ex>Jane</ex></ph> removed tab “<ph name="TAB_NAME">%2$s<ex>Example Domain</ex></ph>”
+ </message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_JOINED_TAB_GROUP" desc="The text in a pop up message that occurs when someone joins a shared tab group.">
+ <ph name="GIVEN_NAME">%1$s<ex>Jane</ex></ph> joined “<ph name="TAB_GROUP_NAME">%2$s<ex>Shopping</ex></ph>” tab group
+ </message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_NOT_AVAILABLE" desc="The text in a pop up message that occurs when you lose access to a shared tab group.">
+ The “<ph name="TAB_GROUP_NAME">%1$s<ex>Shopping</ex></ph>” tab group is no longer available
+ </message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_REOPEN" desc="The action button text on a pop up message to create a tab to the URL a tab previously had.">
+ Reopen
+ </message>
+ <message name="IDS_DATA_SHARING_BROWSER_MESSAGE_MANAGE" desc="The action button text on a pop up message to manage a tab group members.">
+ Manage
+ </message>
<!-- Interstitial shown prior to making digital identity request to wallet -->
<message name="IDS_DIGITAL_IDENTITY_INTERSTITIAL_DIALOG_TITLE" translateable="false">
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_CHANGED_TAB.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_CHANGED_TAB.png.sha1
new file mode 100644
index 0000000..cb66232
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_CHANGED_TAB.png.sha1
@@ -0,0 +1 @@
+9f7b843f37299a1488e11661ecad8bbdb6057837
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_JOINED_TAB_GROUP.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_JOINED_TAB_GROUP.png.sha1
new file mode 100644
index 0000000..349506a
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_JOINED_TAB_GROUP.png.sha1
@@ -0,0 +1 @@
+cb0233fbf68460abcef4b91d54e324fa2ac9742c
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_MANAGE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_MANAGE.png.sha1
new file mode 100644
index 0000000..349506a
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_MANAGE.png.sha1
@@ -0,0 +1 @@
+cb0233fbf68460abcef4b91d54e324fa2ac9742c
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_NOT_AVAILABLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_NOT_AVAILABLE.png.sha1
new file mode 100644
index 0000000..43452cf
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_NOT_AVAILABLE.png.sha1
@@ -0,0 +1 @@
+f9a296d280c077a5b7a3caf846b14bdddd915661
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REMOVED_TAB.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REMOVED_TAB.png.sha1
new file mode 100644
index 0000000..7b0a016
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REMOVED_TAB.png.sha1
@@ -0,0 +1 @@
+e2f03aa2d45c132c22064a3f34047c81e827e27d
\ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REOPEN.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REOPEN.png.sha1
new file mode 100644
index 0000000..cb66232
--- /dev/null
+++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_DATA_SHARING_BROWSER_MESSAGE_REOPEN.png.sha1
@@ -0,0 +1 @@
+9f7b843f37299a1488e11661ecad8bbdb6057837
\ No newline at end of file