Commit 45758185 authored by Sophey Dong's avatar Sophey Dong Committed by Commit Bot

[SharingHub] Filter Chrome-provided options by share content type.

Bug: 1079467
Change-Id: Ied01eab041229533706b9bcf2a6164476b4d65bd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2219147
Commit-Queue: Sophey Dong <sophey@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarTanya Gupta <tgupta@chromium.org>
Reviewed-by: default avatarKyle Milka <kmilka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775802}
parent 328382da
...@@ -258,8 +258,8 @@ public class TabGridDialogMediator { ...@@ -258,8 +258,8 @@ public class TabGridDialogMediator {
public void onCancel() {} public void onCancel() {}
}) })
.build(); .build();
mShareDelegateSupplier.get().share(shareParams, mShareDelegateSupplier.get().share(
new ChromeShareExtras(/*saveLastUsed=*/true, /*shareDirectly=*/false)); shareParams, new ChromeShareExtras.Builder().setSaveLastUsed(true).build());
} }
}; };
......
...@@ -650,8 +650,8 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { ...@@ -650,8 +650,8 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator {
recordContextMenuSelection(params, ContextMenuUma.Action.SHARE_LINK); recordContextMenuSelection(params, ContextMenuUma.Action.SHARE_LINK);
ShareParams linkShareParams = ShareParams linkShareParams =
new ShareParams.Builder(getWindow(), params.getUrl(), params.getUrl()).build(); new ShareParams.Builder(getWindow(), params.getUrl(), params.getUrl()).build();
mShareDelegateSupplier.get().share(linkShareParams, mShareDelegateSupplier.get().share(
new ChromeShareExtras(/*saveLastUsed=*/true, /*shareDirectly=*/false)); linkShareParams, new ChromeShareExtras.Builder().setSaveLastUsed(true).build());
} else if (itemId == R.id.contextmenu_search_with_google_lens) { } else if (itemId == R.id.contextmenu_search_with_google_lens) {
recordContextMenuSelection(params, ContextMenuUma.Action.SEARCH_WITH_GOOGLE_LENS); recordContextMenuSelection(params, ContextMenuUma.Action.SEARCH_WITH_GOOGLE_LENS);
searchWithGoogleLens(params, renderFrameHost, mDelegate.isIncognito()); searchWithGoogleLens(params, renderFrameHost, mDelegate.isIncognito());
......
...@@ -21,7 +21,7 @@ import org.chromium.chrome.browser.preferences.Pref; ...@@ -21,7 +21,7 @@ import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.printing.TabPrinter; import org.chromium.chrome.browser.printing.TabPrinter;
import org.chromium.chrome.browser.send_tab_to_self.SendTabToSelfShareActivity; import org.chromium.chrome.browser.send_tab_to_self.SendTabToSelfShareActivity;
import org.chromium.chrome.browser.share.ShareSheetCoordinator.ContentType; import org.chromium.chrome.browser.share.ShareSheetPropertyModelBuilder.ContentType;
import org.chromium.chrome.browser.share.qrcode.QrCodeCoordinator; import org.chromium.chrome.browser.share.qrcode.QrCodeCoordinator;
import org.chromium.chrome.browser.share.screenshot.ScreenshotCoordinator; import org.chromium.chrome.browser.share.screenshot.ScreenshotCoordinator;
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
......
...@@ -26,9 +26,16 @@ public class ChromeShareExtras { ...@@ -26,9 +26,16 @@ public class ChromeShareExtras {
*/ */
private final boolean mShareDirectly; private final boolean mShareDirectly;
public ChromeShareExtras(boolean saveLastUsed, boolean shareDirectly) { /**
* Whether the URL is of the current visible page.
*/
private final boolean mIsUrlOfVisiblePage;
private ChromeShareExtras(
boolean saveLastUsed, boolean shareDirectly, boolean isUrlOfVisiblePage) {
mSaveLastUsed = saveLastUsed; mSaveLastUsed = saveLastUsed;
mShareDirectly = shareDirectly; mShareDirectly = shareDirectly;
mIsUrlOfVisiblePage = isUrlOfVisiblePage;
} }
/** /**
...@@ -45,4 +52,49 @@ public class ChromeShareExtras { ...@@ -45,4 +52,49 @@ public class ChromeShareExtras {
public boolean shareDirectly() { public boolean shareDirectly() {
return mShareDirectly; return mShareDirectly;
} }
/**
* @return Whether the URL is of the current visible page.
*/
public boolean isUrlOfVisiblePage() {
return mIsUrlOfVisiblePage;
}
/**
* The builder for {@link ChromeShareExtras} objects.
*/
public static class Builder {
private boolean mSaveLastUsed;
private boolean mShareDirectly;
private boolean mIsUrlOfVisiblePage;
/**
* Sets whether to save the chosen activity for future direct sharing.
*/
public Builder setSaveLastUsed(boolean saveLastUsed) {
mSaveLastUsed = saveLastUsed;
return this;
}
/**
* Sets whether it should share directly with the activity that was most recently used to
* share.
*/
public Builder setShareDirectly(boolean shareDirectly) {
mShareDirectly = shareDirectly;
return this;
}
/**
* Sets whether the URL is of the current visible page.
*/
public Builder setIsUrlOfVisiblePage(boolean isUrlOfVisiblePage) {
mIsUrlOfVisiblePage = isUrlOfVisiblePage;
return this;
}
public ChromeShareExtras build() {
return new ChromeShareExtras(mSaveLastUsed, mShareDirectly, mIsUrlOfVisiblePage);
}
}
} }
...@@ -53,9 +53,9 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -53,9 +53,9 @@ public class ShareDelegateImpl implements ShareDelegate {
/** /**
* Constructs a new {@link ShareDelegateImpl}. * Constructs a new {@link ShareDelegateImpl}.
* *
* @param controller The BottomSheetController for the current activity. * @param controller The BottomSheetController for the current activity.
* @param tabProvider Supplier for the current activity tab. * @param tabProvider Supplier for the current activity tab.
* @param delegate The ShareSheetDelegate for the current activity. * @param delegate The ShareSheetDelegate for the current activity.
*/ */
public ShareDelegateImpl(BottomSheetController controller, Supplier<Tab> tabProvider, public ShareDelegateImpl(BottomSheetController controller, Supplier<Tab> tabProvider,
ShareSheetDelegate delegate) { ShareSheetDelegate delegate) {
...@@ -88,8 +88,8 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -88,8 +88,8 @@ public class ShareDelegateImpl implements ShareDelegate {
* This creates and shows a share intent picker dialog or starts a share intent directly. * This creates and shows a share intent picker dialog or starts a share intent directly.
* *
* @param shareDirectly Whether it should share directly with the activity that was most * @param shareDirectly Whether it should share directly with the activity that was most
* recently used to share. * recently used to share.
* @param isIncognito Whether currentTab is incognito. * @param isIncognito Whether currentTab is incognito.
*/ */
private void onShareSelected( private void onShareSelected(
Activity activity, Tab currentTab, boolean shareDirectly, boolean isIncognito) { Activity activity, Tab currentTab, boolean shareDirectly, boolean isIncognito) {
...@@ -118,7 +118,7 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -118,7 +118,7 @@ public class ShareDelegateImpl implements ShareDelegate {
triggerShare(currentTab, shareDirectly, isIncognito); triggerShare(currentTab, shareDirectly, isIncognito);
} }
protected void triggerShare( private void triggerShare(
final Tab currentTab, final boolean shareDirectly, boolean isIncognito) { final Tab currentTab, final boolean shareDirectly, boolean isIncognito) {
ScreenshotTabObserver tabObserver = ScreenshotTabObserver.from(currentTab); ScreenshotTabObserver tabObserver = ScreenshotTabObserver.from(currentTab);
if (tabObserver != null) { if (tabObserver != null) {
...@@ -128,7 +128,7 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -128,7 +128,7 @@ public class ShareDelegateImpl implements ShareDelegate {
OfflinePageUtils.maybeShareOfflinePage(currentTab, (ShareParams p) -> { OfflinePageUtils.maybeShareOfflinePage(currentTab, (ShareParams p) -> {
if (p != null) { if (p != null) {
share(p, new ChromeShareExtras(/*saveLastUsed=*/false, /*shareDirectly=*/false)); share(p, new ChromeShareExtras.Builder().setIsUrlOfVisiblePage(true).build());
} else { } else {
WindowAndroid window = currentTab.getWindowAndroid(); WindowAndroid window = currentTab.getWindowAndroid();
// Could not share as an offline page. // Could not share as an offline page.
...@@ -165,7 +165,12 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -165,7 +165,12 @@ public class ShareDelegateImpl implements ShareDelegate {
ShareParams.Builder builder = ShareParams.Builder builder =
new ShareParams.Builder(window, title, getUrlToShare(visibleUrl, canonicalUrl)) new ShareParams.Builder(window, title, getUrlToShare(visibleUrl, canonicalUrl))
.setScreenshotUri(blockingUri); .setScreenshotUri(blockingUri);
share(builder.build(), new ChromeShareExtras(!shareDirectly, shareDirectly)); share(builder.build(),
new ChromeShareExtras.Builder()
.setSaveLastUsed(!shareDirectly)
.setShareDirectly(shareDirectly)
.setIsUrlOfVisiblePage(true)
.build());
if (shareDirectly) { if (shareDirectly) {
RecordUserAction.record("MobileMenuDirectShare"); RecordUserAction.record("MobileMenuDirectShare");
} else { } else {
...@@ -268,8 +273,7 @@ public class ShareDelegateImpl implements ShareDelegate { ...@@ -268,8 +273,7 @@ public class ShareDelegateImpl implements ShareDelegate {
ContextUtils.getApplicationContext().getPackageManager()), ContextUtils.getApplicationContext().getPackageManager()),
PrefServiceBridge.getInstance()); PrefServiceBridge.getInstance());
// TODO(crbug/1009124): open custom share sheet. // TODO(crbug/1009124): open custom share sheet.
coordinator.showShareSheet( coordinator.showShareSheet(params, chromeShareExtras, shareStartTime);
params, chromeShareExtras.saveLastUsed(), shareStartTime);
} else { } else {
ShareHelper.showDefaultShareUi(params, chromeShareExtras.saveLastUsed()); ShareHelper.showDefaultShareUi(params, chromeShareExtras.saveLastUsed());
} }
......
...@@ -6,7 +6,6 @@ package org.chromium.chrome.browser.share; ...@@ -6,7 +6,6 @@ package org.chromium.chrome.browser.share;
import android.app.Activity; import android.app.Activity;
import androidx.annotation.IntDef;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.content.res.AppCompatResources;
...@@ -20,12 +19,9 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; ...@@ -20,12 +19,9 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.share.ShareParams; import org.chromium.components.browser_ui.share.ShareParams;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* Coordinator for displaying the share sheet. * Coordinator for displaying the share sheet.
...@@ -41,11 +37,11 @@ class ShareSheetCoordinator { ...@@ -41,11 +37,11 @@ class ShareSheetCoordinator {
/** /**
* Constructs a new ShareSheetCoordinator. * Constructs a new ShareSheetCoordinator.
* *
* @param controller The {@link BottomSheetController} for the current activity. * @param controller The {@link BottomSheetController} for the current activity.
* @param tabProvider Supplier for the current activity tab. * @param tabProvider Supplier for the current activity tab.
* @param modelBuilder The {@link ShareSheetPropertyModelBuilder} for the share sheet. * @param modelBuilder The {@link ShareSheetPropertyModelBuilder} for the share sheet.
* @param prefServiceBridge The {@link PrefServiceBridge} singleton. This provides preferences * @param prefServiceBridge The {@link PrefServiceBridge} singleton. This provides preferences
* for the Chrome-provided property models. * for the Chrome-provided property models.
*/ */
ShareSheetCoordinator(BottomSheetController controller, Supplier<Tab> tabProvider, ShareSheetCoordinator(BottomSheetController controller, Supplier<Tab> tabProvider,
ShareSheetPropertyModelBuilder modelBuilder, PrefServiceBridge prefServiceBridge) { ShareSheetPropertyModelBuilder modelBuilder, PrefServiceBridge prefServiceBridge) {
...@@ -56,7 +52,8 @@ class ShareSheetCoordinator { ...@@ -56,7 +52,8 @@ class ShareSheetCoordinator {
mPrefServiceBridge = prefServiceBridge; mPrefServiceBridge = prefServiceBridge;
} }
void showShareSheet(ShareParams params, boolean saveLastUsed, long shareStartTime) { void showShareSheet(
ShareParams params, ChromeShareExtras chromeShareExtras, long shareStartTime) {
Activity activity = params.getWindow().getActivity().get(); Activity activity = params.getWindow().getActivity().get();
if (activity == null) { if (activity == null) {
return; return;
...@@ -66,9 +63,11 @@ class ShareSheetCoordinator { ...@@ -66,9 +63,11 @@ class ShareSheetCoordinator {
mShareStartTime = shareStartTime; mShareStartTime = shareStartTime;
List<PropertyModel> chromeFeatures = List<PropertyModel> chromeFeatures =
createTopRowPropertyModels(bottomSheet, activity, params); createTopRowPropertyModels(bottomSheet, activity, params,
List<PropertyModel> thirdPartyApps = ShareSheetPropertyModelBuilder.getContentTypes(
createBottomRowPropertyModels(bottomSheet, activity, params, saveLastUsed); params, chromeShareExtras.isUrlOfVisiblePage()));
List<PropertyModel> thirdPartyApps = createBottomRowPropertyModels(
bottomSheet, activity, params, chromeShareExtras.saveLastUsed());
bottomSheet.createRecyclerViews(chromeFeatures, thirdPartyApps); bottomSheet.createRecyclerViews(chromeFeatures, thirdPartyApps);
...@@ -82,13 +81,13 @@ class ShareSheetCoordinator { ...@@ -82,13 +81,13 @@ class ShareSheetCoordinator {
// Used by first party features to share with only non-chrome apps. // Used by first party features to share with only non-chrome apps.
protected void showThirdPartyShareSheet( protected void showThirdPartyShareSheet(
ShareParams params, boolean saveLastUsed, long shareStartTime) { ShareParams params, ChromeShareExtras chromeShareExtras, long shareStartTime) {
mExcludeFirstParty = true; mExcludeFirstParty = true;
showShareSheet(params, saveLastUsed, shareStartTime); showShareSheet(params, chromeShareExtras, shareStartTime);
} }
List<PropertyModel> createTopRowPropertyModels( List<PropertyModel> createTopRowPropertyModels(ShareSheetBottomSheetContent bottomSheet,
ShareSheetBottomSheetContent bottomSheet, Activity activity, ShareParams shareParams) { Activity activity, ShareParams shareParams, Set<Integer> contentTypes) {
if (mExcludeFirstParty) { if (mExcludeFirstParty) {
return new ArrayList<>(); return new ArrayList<>();
} }
...@@ -96,9 +95,8 @@ class ShareSheetCoordinator { ...@@ -96,9 +95,8 @@ class ShareSheetCoordinator {
new ChromeProvidedSharingOptionsProvider(activity, mTabProvider, new ChromeProvidedSharingOptionsProvider(activity, mTabProvider,
mBottomSheetController, bottomSheet, mPrefServiceBridge, shareParams, mBottomSheetController, bottomSheet, mPrefServiceBridge, shareParams,
mShareStartTime); mShareStartTime);
return chromeProvidedSharingOptionsProvider.createPropertyModels(new HashSet<>(
Arrays.asList(ContentType.LINK_PAGE_VISIBLE, ContentType.LINK_PAGE_NOT_VISIBLE, return chromeProvidedSharingOptionsProvider.createPropertyModels(contentTypes);
ContentType.TEXT, ContentType.IMAGE, ContentType.OTHER_FILE_TYPE)));
} }
@VisibleForTesting @VisibleForTesting
...@@ -126,15 +124,4 @@ class ShareSheetCoordinator { ...@@ -126,15 +124,4 @@ class ShareSheetCoordinator {
protected void disableFirstPartyFeaturesForTesting() { protected void disableFirstPartyFeaturesForTesting() {
mExcludeFirstParty = true; mExcludeFirstParty = true;
} }
@IntDef({ContentType.LINK_PAGE_VISIBLE, ContentType.LINK_PAGE_NOT_VISIBLE, ContentType.TEXT,
ContentType.IMAGE, ContentType.OTHER_FILE_TYPE})
@Retention(RetentionPolicy.SOURCE)
@interface ContentType {
int LINK_PAGE_VISIBLE = 0;
int LINK_PAGE_NOT_VISIBLE = 1;
int TEXT = 2;
int IMAGE = 3;
int OTHER_FILE_TYPE = 4;
}
} }
...@@ -10,8 +10,11 @@ import android.content.pm.ActivityInfo; ...@@ -10,8 +10,11 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import androidx.annotation.IntDef;
import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.metrics.RecordUserAction;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
...@@ -19,9 +22,13 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController; ...@@ -19,9 +22,13 @@ import org.chromium.chrome.browser.widget.bottomsheet.BottomSheetController;
import org.chromium.components.browser_ui.share.ShareParams; import org.chromium.components.browser_ui.share.ShareParams;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* Handles displaying the share sheet. The version used depends on several * Handles displaying the share sheet. The version used depends on several
...@@ -31,10 +38,25 @@ import java.util.List; ...@@ -31,10 +38,25 @@ import java.util.List;
* #chrome-sharing-hub enabled: custom share sheet * #chrome-sharing-hub enabled: custom share sheet
*/ */
class ShareSheetPropertyModelBuilder { class ShareSheetPropertyModelBuilder {
private final BottomSheetController mBottomSheetController; @IntDef({ContentType.LINK_PAGE_VISIBLE, ContentType.LINK_PAGE_NOT_VISIBLE, ContentType.TEXT,
private final PackageManager mPackageManager; ContentType.IMAGE, ContentType.OTHER_FILE_TYPE})
@Retention(RetentionPolicy.SOURCE)
@interface ContentType {
int LINK_PAGE_VISIBLE = 0;
int LINK_PAGE_NOT_VISIBLE = 1;
int TEXT = 2;
int IMAGE = 3;
int OTHER_FILE_TYPE = 4;
}
private static final int MAX_NUM_APPS = 7; private static final int MAX_NUM_APPS = 7;
private static final String IMAGE_TYPE = "image/";
// Variations parameter name for the comma-separated list of third-party activity names.
private static final String PARAM_SHARING_HUB_THIRD_PARTY_APPS = "sharing-hub-third-party-apps";
static final HashSet<Integer> ALL_CONTENT_TYPES = new HashSet<>(
Arrays.asList(ContentType.LINK_PAGE_VISIBLE, ContentType.LINK_PAGE_NOT_VISIBLE,
ContentType.TEXT, ContentType.IMAGE, ContentType.OTHER_FILE_TYPE));
private static final ArrayList<String> FALLBACK_ACTIVITIES = private static final ArrayList<String> FALLBACK_ACTIVITIES =
new ArrayList(Arrays.asList("com.whatsapp.ContactPicker", new ArrayList(Arrays.asList("com.whatsapp.ContactPicker",
"com.facebook.composer.shareintent.ImplicitShareIntentHandlerDefaultAlias", "com.facebook.composer.shareintent.ImplicitShareIntentHandlerDefaultAlias",
...@@ -52,8 +74,8 @@ class ShareSheetPropertyModelBuilder { ...@@ -52,8 +74,8 @@ class ShareSheetPropertyModelBuilder {
"com.yahoo.mail.ui.activities.ComposeActivity", "com.yahoo.mail.ui.activities.ComposeActivity",
"org.telegram.ui.LaunchActivity", "com.tencent.mm.ui.tools.ShareImgUI")); "org.telegram.ui.LaunchActivity", "com.tencent.mm.ui.tools.ShareImgUI"));
/** Variations parameter name for the comma-separated list of third-party activity names. */ private final BottomSheetController mBottomSheetController;
private static final String PARAM_SHARING_HUB_THIRD_PARTY_APPS = "sharing-hub-third-party-apps"; private final PackageManager mPackageManager;
ShareSheetPropertyModelBuilder( ShareSheetPropertyModelBuilder(
BottomSheetController bottomSheetController, PackageManager packageManager) { BottomSheetController bottomSheetController, PackageManager packageManager) {
...@@ -61,6 +83,48 @@ class ShareSheetPropertyModelBuilder { ...@@ -61,6 +83,48 @@ class ShareSheetPropertyModelBuilder {
mPackageManager = packageManager; mPackageManager = packageManager;
} }
/**
* Returns a set of {@link ShareSheetCoordinator.ContentType}s for the current share.
*
* <p>If {@link ChromeFeatureList.CHROME_SHARING_HUB_V15} is not enabled, this returns a set of
* all of the {@link ContentType}s. Otherwise, it adds {@link ContentType}s according to the
* following logic:
*
* <ul>
* <li>If a URL is present, {@code isUrlOfVisiblePage} determines whether to add
* {@link ContentType.LINK_PAGE_VISIBLE} or {@link ContentType.LINK_PAGE_NOT_VISIBLE}.
* <li>If the text being shared is not the same as the URL, add {@link ContentType.TEXT}
* <li>If the share contains files and the {@code fileContentType} is an image, add
* {@link ContentType.IMAGE}. Otherwise, add {@link ContentType.OTHER_FILE_TYPE}.
* </ul>
*/
static Set<Integer> getContentTypes(ShareParams params, boolean isUrlOfVisiblePage) {
if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CHROME_SHARING_HUB_V15)) {
return ALL_CONTENT_TYPES;
}
Set<Integer> contentTypes = new HashSet<>();
if (!TextUtils.isEmpty(params.getUrl())) {
if (isUrlOfVisiblePage) {
contentTypes.add(ContentType.LINK_PAGE_VISIBLE);
} else {
contentTypes.add(ContentType.LINK_PAGE_NOT_VISIBLE);
}
}
if (!TextUtils.isEmpty(params.getText())
&& !TextUtils.equals(params.getUrl(), params.getText())) {
contentTypes.add(ContentType.TEXT);
}
if (params.getFileUris() != null) {
if (!TextUtils.isEmpty(params.getFileContentType())
&& params.getFileContentType().startsWith(IMAGE_TYPE)) {
contentTypes.add(ContentType.IMAGE);
} else {
contentTypes.add(ContentType.OTHER_FILE_TYPE);
}
}
return contentTypes;
}
ArrayList<PropertyModel> selectThirdPartyApps(ShareSheetBottomSheetContent bottomSheet, ArrayList<PropertyModel> selectThirdPartyApps(ShareSheetBottomSheetContent bottomSheet,
ShareParams params, boolean saveLastUsed, long shareStartTime) { ShareParams params, boolean saveLastUsed, long shareStartTime) {
List<String> thirdPartyActivityNames = getThirdPartyActivityNames(); List<String> thirdPartyActivityNames = getThirdPartyActivityNames();
......
...@@ -34,8 +34,8 @@ public class ShareServiceImplementationFactory implements InterfaceFactory<Share ...@@ -34,8 +34,8 @@ public class ShareServiceImplementationFactory implements InterfaceFactory<Share
public void share(ShareParams params) { public void share(ShareParams params) {
ChromeActivity<?> activity = ChromeActivity<?> activity =
(ChromeActivity<?>) params.getWindow().getActivity().get(); (ChromeActivity<?>) params.getWindow().getActivity().get();
activity.getShareDelegateSupplier().get().share(params, activity.getShareDelegateSupplier().get().share(
new ChromeShareExtras(/*saveLastUsed=*/false, /*shareDirectly=*/false)); params, new ChromeShareExtras.Builder().build());
} }
}; };
......
...@@ -27,7 +27,7 @@ import org.mockito.MockitoAnnotations; ...@@ -27,7 +27,7 @@ import org.mockito.MockitoAnnotations;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.share.ShareSheetCoordinator.ContentType; import org.chromium.chrome.browser.share.ShareSheetPropertyModelBuilder.ContentType;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.share; package org.chromium.chrome.browser.share;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
...@@ -12,7 +13,6 @@ import android.app.Activity; ...@@ -12,7 +13,6 @@ import android.app.Activity;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule; import android.support.test.rule.ActivityTestRule;
import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
...@@ -50,6 +50,8 @@ public final class ShareSheetCoordinatorTest { ...@@ -50,6 +50,8 @@ public final class ShareSheetCoordinatorTest {
@Mock @Mock
private ShareSheetPropertyModelBuilder mPropertyModelBuilder; private ShareSheetPropertyModelBuilder mPropertyModelBuilder;
private ShareSheetCoordinator mShareSheetCoordinator;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
...@@ -71,46 +73,45 @@ public final class ShareSheetCoordinatorTest { ...@@ -71,46 +73,45 @@ public final class ShareSheetCoordinatorTest {
Mockito.when(mPropertyModelBuilder.selectThirdPartyApps( Mockito.when(mPropertyModelBuilder.selectThirdPartyApps(
any(), any(), anyBoolean(), anyLong())) any(), any(), anyBoolean(), anyLong()))
.thenReturn(thirdPartyPropertyModels); .thenReturn(thirdPartyPropertyModels);
mShareSheetCoordinator = new ShareSheetCoordinator(null, null, mPropertyModelBuilder, null);
} }
@Test @Test
@MediumTest @MediumTest
public void disableFirstPartyFeatures() { public void disableFirstPartyFeatures() {
ShareSheetCoordinator coordinator = mShareSheetCoordinator.disableFirstPartyFeaturesForTesting();
new ShareSheetCoordinator(null, null, mPropertyModelBuilder, null);
coordinator.disableFirstPartyFeaturesForTesting();
Activity activity = mActivityTestRule.getActivity(); Activity activity = mActivityTestRule.getActivity();
ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity); ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity);
List<PropertyModel> propertyModels = List<PropertyModel> propertyModels =
coordinator.createTopRowPropertyModels(bottomSheet, activity, /*shareParams=*/null); mShareSheetCoordinator.createTopRowPropertyModels(bottomSheet, activity,
Assert.assertEquals("Property model list should be empty.", 0, propertyModels.size()); /*shareParams=*/null, ShareSheetPropertyModelBuilder.ALL_CONTENT_TYPES);
assertEquals("Property model list should be empty.", 0, propertyModels.size());
} }
@Test @Test
@MediumTest @MediumTest
public void testCreateBottomRowPropertyModels() { public void testCreateBottomRowPropertyModels() {
ShareSheetCoordinator coordinator =
new ShareSheetCoordinator(null, null, mPropertyModelBuilder, null);
Activity activity = mActivityTestRule.getActivity(); Activity activity = mActivityTestRule.getActivity();
ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity); ShareSheetBottomSheetContent bottomSheet = new ShareSheetBottomSheetContent(activity);
List<PropertyModel> propertyModels = coordinator.createBottomRowPropertyModels( List<PropertyModel> propertyModels = mShareSheetCoordinator.createBottomRowPropertyModels(
bottomSheet, activity, /*shareParams=*/null, /*saveLastUsed=*/false); bottomSheet, activity, /*shareParams=*/null, /*saveLastUsed=*/false);
Assert.assertEquals("Incorrect number of property models.", 3, propertyModels.size()); assertEquals("Incorrect number of property models.", 3, propertyModels.size());
Assert.assertEquals("First property model isn't testModel1.", "testModel1", assertEquals("First property model isn't testModel1.", "testModel1",
propertyModels.get(0).get(ShareSheetItemViewProperties.LABEL)); propertyModels.get(0).get(ShareSheetItemViewProperties.LABEL));
Assert.assertEquals("First property model is marked as first party.", false, assertEquals("First property model is marked as first party.", false,
propertyModels.get(0).get(ShareSheetItemViewProperties.IS_FIRST_PARTY)); propertyModels.get(0).get(ShareSheetItemViewProperties.IS_FIRST_PARTY));
Assert.assertEquals("Second property model isn't testModel2.", "testModel2", assertEquals("Second property model isn't testModel2.", "testModel2",
propertyModels.get(1).get(ShareSheetItemViewProperties.LABEL)); propertyModels.get(1).get(ShareSheetItemViewProperties.LABEL));
Assert.assertEquals("Second property model is marked as first party.", false, assertEquals("Second property model is marked as first party.", false,
propertyModels.get(1).get(ShareSheetItemViewProperties.IS_FIRST_PARTY)); propertyModels.get(1).get(ShareSheetItemViewProperties.IS_FIRST_PARTY));
Assert.assertEquals("Third property model isn't More.", assertEquals("Third property model isn't More.",
activity.getResources().getString(R.string.sharing_more_icon_label), activity.getResources().getString(R.string.sharing_more_icon_label),
propertyModels.get(2).get(ShareSheetItemViewProperties.LABEL)); propertyModels.get(2).get(ShareSheetItemViewProperties.LABEL));
Assert.assertEquals("Thired property model isn't marked as first party.", true, assertEquals("Third property model isn't marked as first party.", true,
propertyModels.get(2).get(ShareSheetItemViewProperties.IS_FIRST_PARTY)); propertyModels.get(2).get(ShareSheetItemViewProperties.IS_FIRST_PARTY));
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.share; package org.chromium.chrome.browser.share;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyString;
...@@ -12,13 +13,18 @@ import static org.mockito.Mockito.when; ...@@ -12,13 +13,18 @@ import static org.mockito.Mockito.when;
import android.app.Activity; import android.app.Activity;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule; import android.support.test.rule.ActivityTestRule;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
...@@ -26,40 +32,48 @@ import org.mockito.MockitoAnnotations; ...@@ -26,40 +32,48 @@ import org.mockito.MockitoAnnotations;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.share.ShareSheetPropertyModelBuilder.ContentType;
import org.chromium.chrome.test.ChromeBrowserTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.components.browser_ui.share.ShareParams; import org.chromium.components.browser_ui.share.ShareParams;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.test.util.DummyUiActivity; import org.chromium.ui.test.util.DummyUiActivity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
/** /**
* Tests {@link ShareSheetPropertyModelBuilder}. * Tests {@link ShareSheetPropertyModelBuilder}.
*/ */
@RunWith(ChromeJUnit4ClassRunner.class) @RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB})
public final class ShareSheetPropertyModelBuilderTest { public final class ShareSheetPropertyModelBuilderTest {
@Rule
public final ChromeBrowserTestRule mBrowserTestRule = new ChromeBrowserTestRule();
@Rule @Rule
public ActivityTestRule<DummyUiActivity> mActivityTestRule = public ActivityTestRule<DummyUiActivity> mActivityTestRule =
new ActivityTestRule<>(DummyUiActivity.class); new ActivityTestRule<>(DummyUiActivity.class);
@Rule
public TestRule mFeatureProcessor = new Features.JUnitProcessor();
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock @Mock
private ShareParams mParams; private ShareParams mParams;
@Mock @Mock
private ResolveInfo mResolveInfo1; private ResolveInfo mResolveInfo1;
@Mock @Mock
private ResolveInfo mResolveInfo2; private ResolveInfo mResolveInfo2;
@Mock @Mock
private ResolveInfo mResolveInfo3; private ResolveInfo mResolveInfo3;
private static final String IMAGE_TYPE = "image/jpeg";
private static final String URL = "http://www.google.com/";
private ArrayList<ResolveInfo> mResolveInfoList; private ArrayList<ResolveInfo> mResolveInfoList;
private Activity mActivity; private Activity mActivity;
...@@ -95,11 +109,139 @@ public final class ShareSheetPropertyModelBuilderTest { ...@@ -95,11 +109,139 @@ public final class ShareSheetPropertyModelBuilderTest {
when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(mResolveInfoList); when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(mResolveInfoList);
when(mPackageManager.getResourcesForApplication(anyString())) when(mPackageManager.getResourcesForApplication(anyString()))
.thenReturn(mActivity.getResources()); .thenReturn(mActivity.getResources());
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15Enabled_hasCorrectLinkContentType() {
ShareParams shareParams = new ShareParams.Builder(null, "", URL).build();
assertEquals("Should contain LINK_PAGE_NOT_VISIBLE.",
ImmutableSet.of(ContentType.LINK_PAGE_NOT_VISIBLE),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
assertEquals("Should contain LINK_PAGE_VISIBLE.",
ImmutableSet.of(ContentType.LINK_PAGE_VISIBLE),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
true));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15EnabledAndNoUrl_hasNoLinkContentType() {
ShareParams shareParams = new ShareParams.Builder(null, "", "").build();
assertEquals("Should not contain LINK_PAGE_NOT_VISIBLE", ImmutableSet.of(),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
assertEquals("Should not contain LINK_PAGE_VISIBLE.", ImmutableSet.of(),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
true));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15EnabledAndUrlDifferentFromText_hasTextContentType() {
ShareParams shareParams = new ShareParams.Builder(null, "", "").setText("testText").build();
assertEquals("Should contain TEXT.", ImmutableSet.of(ContentType.TEXT),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15EnabledAndTextIsNull_hasNoTextContentType() {
ShareParams shareParams = new ShareParams.Builder(null, "", "").build();
// Explicitly add the test feature so the call to getFieldTrialParamByFeature returns an assertEquals("Should not contain TEXT.", ImmutableSet.of(),
// empty string. ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
ChromeFeatureList.setTestFeatures( false));
Collections.singletonMap(ChromeFeatureList.CHROME_SHARING_HUB, true)); }
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15Enabled_hasImageContentType() {
ShareParams shareParams = new ShareParams.Builder(null, "", "")
.setFileUris(new ArrayList<>(ImmutableSet.of(Uri.EMPTY)))
.setFileContentType(IMAGE_TYPE)
.build();
assertEquals("Should contain IMAGE.", ImmutableSet.of(ContentType.IMAGE),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15EnabledAndNoFiles_hasNoImageContentType() {
ShareParams shareParams =
new ShareParams.Builder(null, "", "").setFileContentType(IMAGE_TYPE).build();
assertEquals("Should not contain IMAGE.", ImmutableSet.of(),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15Enabled_hasOtherFileContentType() {
ShareParams shareParams =
new ShareParams.Builder(null, "", "")
.setFileUris(new ArrayList<>(ImmutableList.of(Uri.EMPTY, Uri.EMPTY)))
.setFileContentType("*/*")
.build();
assertEquals("Should contain OTHER_FILE_TYPE.",
ImmutableSet.of(ContentType.OTHER_FILE_TYPE),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15EnabledAndNoFiles_hasNoFileContentType() {
ShareParams shareParams =
new ShareParams.Builder(null, "", "").setFileContentType("*/*").build();
assertEquals("Should not contain OTHER_FILE_TYPE.", ImmutableSet.of(),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.EnableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15Enabled_hasMultipleContentTypes() {
ShareParams shareParams =
new ShareParams.Builder(null, "", URL)
.setText("testText")
.setFileUris(new ArrayList<>(ImmutableList.of(Uri.EMPTY, Uri.EMPTY)))
.setFileContentType("*/*")
.build();
assertEquals("Should contain correct content types.",
ImmutableSet.of(ContentType.LINK_PAGE_NOT_VISIBLE, ContentType.OTHER_FILE_TYPE,
ContentType.TEXT),
ShareSheetPropertyModelBuilder.getContentTypes(shareParams, /*isUrlOfPageVisible=*/
false));
}
@Test
@MediumTest
@Features.DisableFeatures({ChromeFeatureList.CHROME_SHARING_HUB_V15})
public void getContentTypes_sharingHub15Disabled_returnsAllContentTypes() {
assertEquals("Should contain all content types.",
ShareSheetPropertyModelBuilder.ALL_CONTENT_TYPES,
ShareSheetPropertyModelBuilder.getContentTypes(null, false));
} }
@Test @Test
......
...@@ -145,8 +145,6 @@ public class ShareParams { ...@@ -145,8 +145,6 @@ public class ShareParams {
/** The builder for {@link ShareParams} objects. */ /** The builder for {@link ShareParams} objects. */
public static class Builder { public static class Builder {
private boolean mShareDirectly;
private boolean mSaveLastUsed;
private WindowAndroid mWindow; private WindowAndroid mWindow;
private String mTitle; private String mTitle;
private String mText; private String mText;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment