diff --git a/chrome/android/java/res/layout/share_sheet_content.xml b/chrome/android/java/res/layout/share_sheet_content.xml index ea16ebe365b33b..99a9da9b37320c 100644 --- a/chrome/android/java/res/layout/share_sheet_content.xml +++ b/chrome/android/java/res/layout/share_sheet_content.xml @@ -9,6 +9,16 @@ android:layout_height="wrap_content" android:minHeight="@dimen/min_touch_target_size" android:orientation="vertical"> + { RecordUserAction.record("SharingHubAndroid.LinkToTextSelected"); recordTimeToShare(mShareStartTime); + LinkToTextCoordinator linkToTextCoordinator = new LinkToTextCoordinator( + mActivity, mTabProvider.get().getWindowAndroid(), + mChromeOptionShareCallback, mShareParams.getUrl(), + mShareParams.getText()); mBottomSheetController.hideContent(mBottomSheetContent, true); - // TODO(1102382): Init and call link-to-text feature. }, /*isFirstParty=*/true); return new FirstPartyOption( diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java index 247a86f0503172..f2cb68dff88aff 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetBottomSheetContent.java @@ -61,9 +61,16 @@ private void createContentView() { * @param activity The activity the share sheet belongs to. * @param topRowModels The PropertyModels used to build the top row. * @param bottomRowModels The PropertyModels used to build the bottom row. + * @param message The message to show on top of the share sheet. */ void createRecyclerViews( - List topRowModels, List bottomRowModels) { + List topRowModels, List bottomRowModels, String message) { + if (!message.isEmpty()) { + TextView messageView = this.getContentView().findViewById(R.id.message); + messageView.setVisibility(View.VISIBLE); + messageView.setText(message); + } + RecyclerView topRow = this.getContentView().findViewById(R.id.share_sheet_chrome_apps); if (topRowModels != null && topRowModels.size() > 0) { View divider = this.getContentView().findViewById(R.id.share_sheet_divider); diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java index 29622b18cc64a0..c1122061c8fced 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinator.java @@ -37,6 +37,7 @@ // TODO(crbug/1022172): Should be package-protected once modularization is complete. public class ShareSheetCoordinator implements ActivityStateObserver, ChromeOptionShareCallback, View.OnLayoutChangeListener { + private static final String NO_SHARE_SHEET_MESSAGE = ""; private final BottomSheetController mBottomSheetController; private final Supplier mTabProvider; private final ShareSheetPropertyModelBuilder mPropertyModelBuilder; @@ -87,6 +88,12 @@ protected void destroy() { // TODO(crbug/1022172): Should be package-protected once modularization is complete. public void showShareSheet( ShareParams params, ChromeShareExtras chromeShareExtras, long shareStartTime) { + showShareSheetWithMessage( + NO_SHARE_SHEET_MESSAGE, params, chromeShareExtras, shareStartTime); + } + + void showShareSheetWithMessage(String message, ShareParams params, + ChromeShareExtras chromeShareExtras, long shareStartTime) { Activity activity = params.getWindow().getActivity().get(); if (activity == null) return; @@ -107,7 +114,7 @@ public void showShareSheet( List thirdPartyApps = createBottomRowPropertyModels( activity, params, contentTypes, chromeShareExtras.saveLastUsed()); - mBottomSheet.createRecyclerViews(chromeFeatures, thirdPartyApps); + mBottomSheet.createRecyclerViews(chromeFeatures, thirdPartyApps, message); boolean shown = mBottomSheetController.requestShowContent(mBottomSheet, true); if (shown) { @@ -125,6 +132,14 @@ public void showThirdPartyShareSheet( showShareSheet(params, chromeShareExtras, shareStartTime); } + // Used by first party features to share with only non-chrome apps along with a message. + @Override + public void showThirdPartyShareSheetWithMessage(String message, ShareParams params, + ChromeShareExtras chromeShareExtras, long shareStartTime) { + mExcludeFirstParty = true; + showShareSheetWithMessage(message, params, chromeShareExtras, shareStartTime); + } + List createTopRowPropertyModels(Activity activity, ShareParams shareParams, ChromeShareExtras chromeShareExtras, Set contentTypes) { if (mExcludeFirstParty) { diff --git a/chrome/browser/share/android/java_sources.gni b/chrome/browser/share/android/java_sources.gni index efdd8d191fbaca..3786a337953670 100644 --- a/chrome/browser/share/android/java_sources.gni +++ b/chrome/browser/share/android/java_sources.gni @@ -7,6 +7,7 @@ share_java_sources = [ "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/BitmapDownloadRequest.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/clipboard/ClipboardImageFileProvider.java", + "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinator.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QRCodeGenerationRequest.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeCoordinator.java", "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/qrcode/QrCodeDialog.java", diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java new file mode 100644 index 00000000000000..e1b063d4264932 --- /dev/null +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java @@ -0,0 +1,89 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// 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.share.link_to_text; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.verify; + +import android.content.Context; +import android.support.test.rule.ActivityTestRule; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.ui.base.WindowAndroid; +import org.chromium.ui.test.util.DummyUiActivity; + +/** + * Tests for {@link LinkToTextCoordinator}. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class LinkToTextCoordinatorTest { + @Rule + public ActivityTestRule mActivityTestRule = + new ActivityTestRule<>(DummyUiActivity.class); + + @Mock + private ChromeOptionShareCallback mShareCallback; + + @Mock + private WindowAndroid mWindow; + + private Context mContext; + private static final String SELECTED_TEXT = "selection"; + private static final String VISIBLE_URL = "www.example.com"; + + @Before + public void setUp() { + mContext = mActivityTestRule.getActivity(); + + MockitoAnnotations.initMocks(this); + doNothing() + .when(mShareCallback) + .showThirdPartyShareSheetWithMessage(anyString(), any(), any(), anyLong()); + } + + @Test + @SmallTest + public void getTextToShareTest() { + String selector = "selector"; + String expectedTextToShare = "\"selection\"\nwww.example.com:~:text=selector"; + LinkToTextCoordinator coordinator = new LinkToTextCoordinator( + mContext, mWindow, mShareCallback, VISIBLE_URL, SELECTED_TEXT); + Assert.assertEquals(expectedTextToShare, coordinator.getTextToShare(selector)); + } + + @Test + @SmallTest + public void getTextToShareTest_EmptySelector() { + String selector = ""; + String expectedTextToShare = "\"selection\"\nwww.example.com"; + LinkToTextCoordinator coordinator = new LinkToTextCoordinator( + mContext, mWindow, mShareCallback, VISIBLE_URL, SELECTED_TEXT); + Assert.assertEquals(expectedTextToShare, coordinator.getTextToShare(selector)); + } + + @Test + @SmallTest + public void onSelectorReadyTest() { + LinkToTextCoordinator coordinator = new LinkToTextCoordinator( + mContext, mWindow, mShareCallback, VISIBLE_URL, SELECTED_TEXT); + // OnSelectorReady should call back the share sheet. + verify(mShareCallback) + .showThirdPartyShareSheetWithMessage(anyString(), any(), any(), anyLong()); + } +} diff --git a/chrome/browser/share/android/test_java_sources.gni b/chrome/browser/share/android/test_java_sources.gni index b7e09b1aa256a5..06054fee7bbd6e 100644 --- a/chrome/browser/share/android/test_java_sources.gni +++ b/chrome/browser/share/android/test_java_sources.gni @@ -5,6 +5,7 @@ # TODO(crbug.com/1022172): This should be a separate build target when circular dependencies are removed. share_test_java_sources = [ "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/clipboard/ClipboardImageFileProviderTest.java", + "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/link_to_text/LinkToTextCoordinatorTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/screenshot/ScreenshotShareSheetViewTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java", "//chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ShareSheetCoordinatorTest.java", diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index b5749d56c48731..f8c5f82053b626 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd @@ -3861,6 +3861,14 @@ To change this setting, <resetlink>reset sync

%1$s1582667748515 + + Share link to the highlighted text in an app + + + + Can't create link to text. Share link to page in an app. + + Edit diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_FAILURE_MESSAGE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_FAILURE_MESSAGE.png.sha1 new file mode 100644 index 00000000000000..873110baa1466e --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_FAILURE_MESSAGE.png.sha1 @@ -0,0 +1 @@ +5b5898eac5894e51f40d95d28448f26400679b22 \ No newline at end of file diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_SUCCESS_MESSAGE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_SUCCESS_MESSAGE.png.sha1 new file mode 100644 index 00000000000000..5a51f40599ed12 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LINK_TO_TEXT_SUCCESS_MESSAGE.png.sha1 @@ -0,0 +1 @@ +bb68f939991be1e938f3fceafc7f127aadf23e07 \ No newline at end of file diff --git a/ui/android/java/res/values-v17/styles.xml b/ui/android/java/res/values-v17/styles.xml index 8c5a49041ecc57..00f83d91d7d709 100644 --- a/ui/android/java/res/values-v17/styles.xml +++ b/ui/android/java/res/values-v17/styles.xml @@ -295,6 +295,9 @@ +