chromium/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsFeatureUsageTest.java

// Copyright 2022 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;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;

import androidx.browser.customtabs.CustomTabsSessionToken;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.lifecycle.Stage;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.ThreadUtils;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.util.ApplicationTestUtils;
import org.chromium.base.test.util.DoNotBatch;
import org.chromium.base.test.util.Features.EnableFeatures;
import org.chromium.chrome.browser.customtabs.CustomTabsFeatureUsage.CustomTabsFeature;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.ui.test.util.BlankUiTestActivity;

/** Instrumentation tests for app menu, context menu, and toolbar of a {@link CustomTabActivity}. */
@RunWith(ChromeJUnit4ClassRunner.class)
@DoNotBatch(
        reason =
                "Some tests are Testing CCT start up behavior. "
                        + "Unit test conversion tracked in crbug.com/1217031")
public class CustomTabsFeatureUsageTest {
    private static final String TEST_PAGE = "/chrome/test/data/android/google.html";

    @Rule
    public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();

    @Rule
    public IncognitoCustomTabActivityTestRule mIncognitoCustomTabActivityTestRule =
            new IncognitoCustomTabActivityTestRule();

    private String mTestPage;
    private EmbeddedTestServer mTestServer;

    @Before
    public void setUp() throws Exception {
        ThreadUtils.runOnUiThreadBlocking(() -> FirstRunStatus.setFirstRunFlowComplete(true));

        Context appContext =
                InstrumentationRegistry.getInstrumentation()
                        .getTargetContext()
                        .getApplicationContext();
        mTestServer = EmbeddedTestServer.createAndStartServer(appContext);
        mTestPage = mTestServer.getURL(TEST_PAGE);
    }

    @After
    public void tearDown() {
        ThreadUtils.runOnUiThreadBlocking(() -> FirstRunStatus.setFirstRunFlowComplete(false));
    }

    private Activity startBlankUiTestActivity() {
        Context context = ApplicationProvider.getApplicationContext();
        Intent emptyIntent = new Intent(context, BlankUiTestActivity.class);
        emptyIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        return InstrumentationRegistry.getInstrumentation().startActivitySync(emptyIntent);
    }

    private void assertHistogramEnumRecorded(
            @CustomTabsFeature int featureEnum, boolean umaRecorded) {
        Assert.assertEquals(
                String.format("CustomTabs Feature enum <%s> not recorded correctly:", featureEnum),
                umaRecorded ? 1 : 0,
                RecordHistogram.getHistogramValueCountForTesting(
                        "CustomTabs.FeatureUsage", featureEnum));
    }

    @Test
    @SmallTest
    @EnableFeatures({ChromeFeatureList.CCT_FEATURE_USAGE})
    public void testNormalFeatureUsage() throws Exception {
        Activity emptyActivity = startBlankUiTestActivity();
        Intent intent =
                CustomTabsIntentTestUtils.createCustomTabIntent(
                        ApplicationProvider.getApplicationContext(),
                        mTestPage,
                        false,
                        builder -> {});
        CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
        CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
        connection.newSession(token);
        intent.setData(Uri.parse(mTestPage));

        CustomTabActivity cctActivity =
                ApplicationTestUtils.waitForActivityWithClass(
                        CustomTabActivity.class,
                        Stage.CREATED,
                        () -> emptyActivity.startActivity(intent));
        mCustomTabActivityTestRule.setActivity(cctActivity);
        mCustomTabActivityTestRule.waitForActivityCompletelyLoaded();

        assertHistogramEnumRecorded(CustomTabsFeature.CTF_SESSIONS, true);
        assertHistogramEnumRecorded(CustomTabsFeature.EXTRA_OPEN_NEW_INCOGNITO_TAB, false);
        assertHistogramEnumRecorded(CustomTabsFeature.CTF_PACKAGE_NAME, true);
    }

    @Test
    @SmallTest
    @EnableFeatures({ChromeFeatureList.CCT_FEATURE_USAGE})
    public void testNormalFeatureUsageIncognito() throws Exception {
        startBlankUiTestActivity();
        Intent intent =
                CustomTabsIntentTestUtils.createMinimalIncognitoCustomTabIntent(
                        ApplicationProvider.getApplicationContext(), mTestPage);
        mIncognitoCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent);
        CustomTabsConnection connection = CustomTabsTestUtils.warmUpAndWait();
        CustomTabsSessionToken token = CustomTabsSessionToken.getSessionTokenFromIntent(intent);
        connection.newSession(token);
        intent.setData(Uri.parse(mTestPage));

        /*
        TODO(donnd): why is this section needed in the test above but not here?
        CustomTabActivity cctActivity = ApplicationTestUtils.waitForActivityWithClass(
            CustomTabActivity.class, Stage.CREATED, () -> emptyActivity.startActivity(intent));
        mCustomTabActivityTestRule.setActivity(cctActivity);
        mCustomTabActivityTestRule.waitForActivityCompletelyLoaded();
        */

        assertHistogramEnumRecorded(CustomTabsFeature.CTF_SESSIONS, true);
        assertHistogramEnumRecorded(CustomTabsFeature.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
        assertHistogramEnumRecorded(CustomTabsFeature.CTF_PACKAGE_NAME, true);
    }
}