blob: 4927ae672dfb3947ff642176bcee8966cfd6ac57 [file] [log] [blame]
// Copyright 2019 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.weblayer_private;
import android.app.SearchManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import androidx.annotation.Nullable;
import org.chromium.base.PackageManagerUtils;
import org.chromium.content_public.browser.ActionModeCallbackHelper;
import org.chromium.content_public.browser.SelectionPopupController;
import org.chromium.content_public.browser.WebContents;
import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.ActionModeItemType;
import org.chromium.weblayer_private.interfaces.ITabClient;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
/**
* A class that handles selection action mode for WebLayer.
*/
public final class ActionModeCallback implements ActionMode.Callback {
private final ActionModeCallbackHelper mHelper;
// Can be null during init.
private @Nullable ITabClient mTabClient;
// Bitfield of @ActionModeItemType values.
private int mActionModeOverride;
// Convert from content ActionModeCallbackHelper.MENU_ITEM_* values to
// @ActionModeItemType values.
private static int contentToWebLayerType(int contentType) {
switch (contentType) {
case ActionModeCallbackHelper.MENU_ITEM_SHARE:
return ActionModeItemType.SHARE;
case ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH:
return ActionModeItemType.WEB_SEARCH;
case ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT:
case 0:
return 0;
default:
assert false;
return 0;
}
}
public ActionModeCallback(WebContents webContents) {
mHelper =
SelectionPopupController.fromWebContents(webContents).getActionModeCallbackHelper();
}
public void setTabClient(ITabClient tabClient) {
mTabClient = tabClient;
}
public void setOverride(int actionModeItemTypes) {
mActionModeOverride = actionModeItemTypes;
}
@Override
public final boolean onCreateActionMode(ActionMode mode, Menu menu) {
int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT
| ActionModeCallbackHelper.MENU_ITEM_SHARE;
if ((mActionModeOverride & ActionModeItemType.WEB_SEARCH) != 0 || isWebSearchAvailable()) {
allowedActionModes |= ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH;
}
mHelper.setAllowedMenuItems(allowedActionModes);
mHelper.onCreateActionMode(mode, menu);
return true;
}
private boolean isWebSearchAvailable() {
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
return !PackageManagerUtils.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
.isEmpty();
}
@Override
public final boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return mHelper.onPrepareActionMode(mode, menu);
}
@Override
public final boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int menuItemType = contentToWebLayerType(mHelper.getAllowedMenuItemIfAny(mode, item));
if ((menuItemType & mActionModeOverride) == 0) {
return mHelper.onActionItemClicked(mode, item);
}
assert WebLayerFactoryImpl.getClientMajorVersion() >= 88;
try {
mTabClient.onActionItemClicked(
menuItemType, ObjectWrapper.wrap(mHelper.getSelectedText()));
} catch (RemoteException e) {
throw new APICallException(e);
}
mode.finish();
return true;
}
@Override
public final void onDestroyActionMode(ActionMode mode) {
mHelper.onDestroyActionMode();
}
}