Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc595f57 authored by Evan Severson's avatar Evan Severson
Browse files

Use framework resources for paste menuId

For paste menu IDs we override the given title, content decription,
icon, and tooltip text  with the framework's resources for those
actions. This way apps are unable to trick the user as somethign else.

We also apply localization correctly, even though Configuration is sent
and the LocaleList is identical the system drawn, even when inflated
with the new configuration context,  TextView somehow ignores any app
specific locale and falls back to the sysetm configuredlocales. This
might be a TextView bug.

Test: Manual
Bug: 363318732
Fixes: 404562081
Flag: android.permission.flags.system_selection_toolbar_enabled

Change-Id: I8b24d21d1ca2089604586a5836fd134616c0f6e1
parent 11d2834d
Loading
Loading
Loading
Loading
+48 −7
Original line number Diff line number Diff line
@@ -166,7 +166,7 @@ final class RemoteSelectionToolbar {
    RemoteSelectionToolbar(Context context, long selectionToolbarToken, ShowInfo showInfo,
            SelectionToolbarRenderService.RemoteCallbackWrapper callbackWrapper,
            SelectionToolbarRenderService.TransferTouchListener transferTouchListener) {
        mContext = applyDefaultTheme(context, showInfo.isLightTheme);
        mContext = wrapContext(context, showInfo);
        mSelectionToolbarToken = selectionToolbarToken;
        mCallbackWrapper = callbackWrapper;
        mTransferTouchListener = transferTouchListener;
@@ -317,7 +317,7 @@ final class RemoteSelectionToolbar {
        debugLog("show() for " + showInfo);

        mSequenceNumber = showInfo.sequenceNumber;
        mMenuItems = showInfo.menuItems;
        mMenuItems = transformMenuItems(mContext, showInfo.menuItems);
        mViewPortOnScreen.set(showInfo.viewPortOnScreen);

        debugLog("show(): layoutRequired=" + showInfo.layoutRequired);
@@ -804,6 +804,7 @@ final class RemoteSelectionToolbar {
    }

    private boolean isInRtlMode() {
        // TODO STOPSHIP b/411457891 the context might not have the right information
        return mContext.getApplicationInfo().hasRtlSupport()
                && mContext.getResources().getConfiguration().getLayoutDirection()
                == View.LAYOUT_DIRECTION_RTL;
@@ -1274,6 +1275,45 @@ final class RemoteSelectionToolbar {
        }
    }

    private static List<ToolbarMenuItem> transformMenuItems(Context context,
            List<ToolbarMenuItem> menuItems) {
        ArrayList<ToolbarMenuItem> transformedMenuItems = new ArrayList<>(menuItems.size());
        for (int i = 0; i < menuItems.size(); i++) {
            ToolbarMenuItem menuItem = menuItems.get(i);

            transformedMenuItems.add(switch (menuItem.itemId) {
                case android.R.id.paste -> {
                    ToolbarMenuItem newMenuItem = new ToolbarMenuItem();

                    newMenuItem.groupId = menuItem.groupId;
                    newMenuItem.priority = menuItem.priority;

                    newMenuItem.itemId = android.R.id.paste;
                    newMenuItem.title = context.getString(R.string.paste);
                    newMenuItem.contentDescription = context.getString(R.string.paste);

                    yield newMenuItem;
                }
                case android.R.id.pasteAsPlainText -> {
                    ToolbarMenuItem newMenuItem = new ToolbarMenuItem();

                    newMenuItem.groupId = menuItem.groupId;
                    newMenuItem.priority = menuItem.priority;

                    newMenuItem.itemId = android.R.id.pasteAsPlainText;
                    newMenuItem.title = context.getString(R.string.paste_as_plain_text);
                    newMenuItem.contentDescription = context.getString(
                            R.string.paste_as_plain_text);

                    yield newMenuItem;
                }
                default -> menuItem;
            });
        }

        return transformedMenuItems;
    }

    /**
     * Creates and returns a menu button for the specified menu item.
     */
@@ -1364,14 +1404,15 @@ final class RemoteSelectionToolbar {
    /**
     * Returns a re-themed context with controlled look and feel for views.
     */
    private static Context applyDefaultTheme(Context originalContext, boolean isLightTheme) {
        int themeId =
                isLightTheme ? R.style.Theme_DeviceDefault_Light : R.style.Theme_DeviceDefault;
        return new ContextThemeWrapper(originalContext, themeId);
    private static Context wrapContext(Context originalContext, ShowInfo showInfo) {
        int themeId = showInfo.isLightTheme ? R.style.Theme_DeviceDefault_Light
                : R.style.Theme_DeviceDefault;
        return new ContextThemeWrapper(originalContext, themeId)
                .createConfigurationContext(showInfo.configuration);
    }

    private static void debugLog(String message) {
        if (Log.isLoggable(FloatingToolbar.FLOATING_TOOLBAR_TAG, Log.DEBUG)) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, message);
        }
    }
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view.selectiontoolbar;

import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.selectiontoolbar.ToolbarMenuItem;
@@ -74,4 +75,9 @@ parcelable ShowInfo {
     * If the host application uses light theme.
     */
    boolean isLightTheme;

    /**
     * Configuration used by the context that created the toolbar.
     */
    Configuration configuration;
}
+5 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ public final class RemoteFloatingToolbarPopup implements FloatingToolbarPopup {
    public @interface ToolbarState {
    }

    @NonNull
    private final Context mContext;

    @NonNull
    private final SelectionToolbarManager mSelectionToolbarManager;
    // Parent for the popup window.
@@ -128,6 +131,7 @@ public final class RemoteFloatingToolbarPopup implements FloatingToolbarPopup {
    private final int[] mCoordsOnWindow = new int[2];

    public RemoteFloatingToolbarPopup(Context context, View parent) {
        mContext = context;
        mParent = Objects.requireNonNull(parent);
        mPopupWindow = createPopupWindow(context);
        mSelectionToolbarManager = context.getSystemService(SelectionToolbarManager.class);
@@ -186,6 +190,7 @@ public final class RemoteFloatingToolbarPopup implements FloatingToolbarPopup {
        showInfo.viewPortOnScreen = mScreenViewPort;
        showInfo.hostInputToken = mParent.getViewRootImpl().getInputToken();
        showInfo.isLightTheme = mIsLightTheme;
        showInfo.configuration = mContext.getResources().getConfiguration();
        if (DEBUG) {
            Log.v(FloatingToolbar.FLOATING_TOOLBAR_TAG,
                    "RemoteFloatingToolbarPopup.show() for " + showInfo);