chromium/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabHistoryIPHController.java

// Copyright 2024 The Chromium Authors
// 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.customtabs.features.toolbar;

import android.app.Activity;
import android.os.Handler;
import android.os.Looper;
import android.view.View;

import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ActivityTabProvider;
import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
import org.chromium.components.feature_engagement.EventConstants;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.url.GURL;

/** Controls showing IPH for Custom Tabs history. */
public class CustomTabHistoryIPHController {
    private final Activity mActivity;
    private final ActivityTabProvider mTabProvider;
    private final Supplier<Profile> mProfileSupplier;
    private final AppMenuHandler mAppMenuHandler;
    private ActivityTabTabObserver mTabObserver;
    private UserEducationHelper mUserEducationHelper;

    /**
     * Constructs the controller.
     *
     * @param activity The {@link Activity}.
     * @param activityTabProvider The {@link ActivityTabProvider} for this Activity.
     * @param profileSupplier The {@link Supplier} for the current {@link Profile}.
     * @param appMenuHandler The {@link AppMenuHandler} for the tab.
     */
    public CustomTabHistoryIPHController(
            Activity activity,
            ActivityTabProvider activityTabProvider,
            Supplier<Profile> profileSupplier,
            AppMenuHandler appMenuHandler) {
        mActivity = activity;
        mTabProvider = activityTabProvider;
        mProfileSupplier = profileSupplier;
        mAppMenuHandler = appMenuHandler;
        mTabObserver =
                new ActivityTabTabObserver(mTabProvider) {
                    @Override
                    public void onPageLoadStarted(Tab tab, GURL url) {
                        maybeShowIPH();
                    }
                };
    }

    public void destroy() {
        if (mTabObserver != null) {
            mTabObserver.destroy();
            mTabObserver = null;
        }
    }

    public void notifyUserEngaged() {
        if (!mProfileSupplier.hasValue()) return;

        var tracker = TrackerFactory.getTrackerForProfile(mProfileSupplier.get());
        tracker.addOnInitializedCallback(
                success -> tracker.notifyEvent(EventConstants.CCT_HISTORY_MENU_ITEM_CLICKED));
    }

    private void maybeShowIPH() {
        if (!shouldShowIPH()) return;
        if (mUserEducationHelper == null) {
            mUserEducationHelper =
                    new UserEducationHelper(
                            mActivity, mProfileSupplier, new Handler(Looper.getMainLooper()));
        }

        View ctOverflowMenu = mActivity.findViewById(R.id.menu_button_wrapper);
        mUserEducationHelper.requestShowIPH(
                new IPHCommandBuilder(
                                mActivity.getResources(),
                                FeatureConstants.CCT_HISTORY_FEATURE,
                                R.string.custom_tab_history_iph_bubble_text,
                                R.string.custom_tab_history_iph_bubble_text)
                        .setAnchorView(ctOverflowMenu)
                        .setOnShowCallback(this::turnOnHighlightForMenuItem)
                        .setOnDismissCallback(this::turnOffHighlightForMenuItem)
                        .setHighlightParams(new HighlightParams(HighlightShape.CIRCLE))
                        .build());
    }

    private boolean shouldShowIPH() {
        if (!ChromeFeatureList.sAppSpecificHistory.isEnabled()) return false;

        if (mProfileSupplier.get().isOffTheRecord()) return false;

        var tracker = TrackerFactory.getTrackerForProfile(mProfileSupplier.get());
        return (tracker.isInitialized()
                && tracker.wouldTriggerHelpUI(FeatureConstants.CCT_HISTORY_FEATURE));
    }

    private void turnOnHighlightForMenuItem() {
        mAppMenuHandler.setMenuHighlight(R.id.open_history_menu_id);
    }

    private void turnOffHighlightForMenuItem() {
        mAppMenuHandler.clearMenuHighlight();
    }

    ActivityTabTabObserver getTabObserverForTesting() {
        return mTabObserver;
    }

    void setHighlightMenuItemForTesting(boolean on) {
        if (on) {
            turnOnHighlightForMenuItem();
        } else {
            turnOffHighlightForMenuItem();
        }
    }

    void setUserEducationHelperForTesting(UserEducationHelper userEducationHelper) {
        mUserEducationHelper = userEducationHelper;
    }
}