// Copyright 2016 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.webshare; import android.app.Activity; import android.content.ComponentName; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.support.annotation.Nullable; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.content.browser.ContentViewCore; import org.chromium.content_public.browser.WebContents; import org.chromium.mojo.system.MojoException; import org.chromium.ui.base.WindowAndroid; import org.chromium.url.mojom.Url; import org.chromium.webshare.mojom.ShareService; /** * Android implementation of the ShareService service defined in * third_party/WebKit/public/platform/modules/webshare/webshare.mojom. */ public class ShareServiceImpl implements ShareService { private final Activity mActivity; // We no longer show a warning for incognito mode. // TODO(mgiuca): Remove this code (https://crrev.com/420564, https://crbug.com/645007). private static final boolean mIsIncognito = false; // These numbers are written to histograms. Keep in sync with WebShareMethod enum in // histograms.xml, and don't reuse or renumber entries (except for the _COUNT entry). private static final int WEBSHARE_METHOD_SHARE = 0; // Count is technically 1, but recordEnumeratedHistogram requires a boundary of at least 2 // (https://crbug.com/645032). private static final int WEBSHARE_METHOD_COUNT = 2; // These numbers are written to histograms. Keep in sync with WebShareOutcome enum in // histograms.xml, and don't reuse or renumber entries (except for the _COUNT entry). private static final int WEBSHARE_OUTCOME_SUCCESS = 0; private static final int WEBSHARE_OUTCOME_UNKNOWN_FAILURE = 1; private static final int WEBSHARE_OUTCOME_CANCELED = 2; private static final int WEBSHARE_OUTCOME_COUNT = 3; public ShareServiceImpl(@Nullable WebContents webContents) { mActivity = activityFromWebContents(webContents); } @Override public void close() {} @Override public void onConnectionError(MojoException e) {} @Override public void share(String title, String text, Url url, final ShareResponse callback) { RecordHistogram.recordEnumeratedHistogram("WebShare.ApiCount", WEBSHARE_METHOD_SHARE, WEBSHARE_METHOD_COUNT); if (mActivity == null) { RecordHistogram.recordEnumeratedHistogram("WebShare.ShareOutcome", WEBSHARE_OUTCOME_UNKNOWN_FAILURE, WEBSHARE_OUTCOME_COUNT); callback.call("Share failed"); return; } if (mIsIncognito) { // In incognito mode, confirm with the user before sending intent externally. showIncognitoWarningDialog(title, text, url, callback); } else { startShare(title, text, url, callback); } } @Nullable private static Activity activityFromWebContents(@Nullable WebContents webContents) { if (webContents == null) return null; ContentViewCore contentViewCore = ContentViewCore.fromWebContents(webContents); if (contentViewCore == null) return null; WindowAndroid window = contentViewCore.getWindowAndroid(); if (window == null) return null; return window.getActivity().get(); } private void startShare(String title, String text, Url url, final ShareResponse callback) { ShareHelper.TargetChosenCallback innerCallback = new ShareHelper.TargetChosenCallback() { public void onTargetChosen(ComponentName chosenComponent) { RecordHistogram.recordEnumeratedHistogram("WebShare.ShareOutcome", WEBSHARE_OUTCOME_SUCCESS, WEBSHARE_OUTCOME_COUNT); callback.call(null); } public void onCancel() { cancelShare(callback); } }; ShareHelper.share(false, false, mActivity, title, text, url.url, null, null, innerCallback); } private static void cancelShare(ShareResponse callback) { RecordHistogram.recordEnumeratedHistogram("WebShare.ShareOutcome", WEBSHARE_OUTCOME_CANCELED, WEBSHARE_OUTCOME_COUNT); callback.call("Share canceled"); } private void showIncognitoWarningDialog(final String title, final String text, final Url url, final ShareResponse callback) { ExternalNavigationDelegateImpl.showLeaveIncognitoWarningDialog(mActivity, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startShare(title, text, url, callback); } }, new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { cancelShare(callback); } }); } }