/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.translation.cts;

import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
import static android.content.Context.TRANSLATION_MANAGER_SERVICE;
import static android.provider.Settings.Global.ANIMATOR_DURATION_SCALE;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME;
import static android.translation.cts.Helper.ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_START;
import static android.translation.cts.Helper.ACTION_REGISTER_UI_TRANSLATION_CALLBACK;
import static android.translation.cts.Helper.ACTION_UNREGISTER_UI_TRANSLATION_CALLBACK;
import static android.translation.cts.Helper.EXTRA_FINISH_COMMAND;
import static android.translation.cts.Helper.EXTRA_SOURCE_LOCALE;
import static android.translation.cts.Helper.EXTRA_TARGET_LOCALE;
import static android.translation.cts.Helper.EXTRA_VERIFY_RESULT;
import static android.view.translation.TranslationResponseValue.STATUS_SUCCESS;

import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;

import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.icu.util.ULocale;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.provider.Settings;
import android.service.contentcapture.ContentCaptureService;
import android.service.translation.TranslationService;
import android.translation.cts.views.CustomTextView;
import android.translation.cts.views.ResponseNotSetTextView;
import android.translation.cts.views.VirtualContainerView;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Pair;
import android.view.View;
import android.view.autofill.AutofillId;
import android.view.contentcapture.ContentCaptureContext;
import android.view.inputmethod.InputMethodManager;
import android.view.translation.TranslationRequest;
import android.view.translation.TranslationResponse;
import android.view.translation.TranslationResponseValue;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationManager;
import android.view.translation.UiTranslationSpec;
import android.view.translation.UiTranslationStateCallback;
import android.view.translation.ViewTranslationCallback;
import android.view.translation.ViewTranslationRequest;
import android.view.translation.ViewTranslationResponse;
import android.widget.TextView;

import androidx.lifecycle.Lifecycle;
import androidx.test.core.app.ActivityScenario;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.FlakyTest;
import androidx.test.runner.AndroidJUnit4;
import androidx.test.uiautomator.UiObject2;

import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.RequiredServiceRule;
import com.android.compatibility.common.util.SystemUtil;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicReference;


/**
 * Tests for {@link UiTranslationManager} related APIs.
 *
 * <p>
 * {@link UiTranslationManager} needs a token that reports by {@link ContentCaptureService}. We use
 * a non pre-configured {@link ContentCaptureService} and a {@link TranslationService} temporary
 * service for CTS tests that is set via shell command. The test will get the token from the
 * {@link ContentCaptureService} then uses this token in {@link UiTranslationManager} APIs.</p>
 */

@AppModeFull(reason = "TODO(b/182330968): disable instant mode. Re-enable after we decouple the "
        + "service from the test package.")
@RunWith(AndroidJUnit4.class)
public class UiTranslationManagerTest {

    private static final String TAG = "UiTranslationManagerTest";

    private static final long UI_WAIT_TIMEOUT = 2000;

    // TODO: Use fw definition when it becomes public or testapi
    private static final String ID_CONTENT_DESCRIPTION = "android:content_description";

    private static Context sContext;
    private static CtsTranslationService.TranslationReplier sTranslationReplier;

    private CtsContentCaptureService.ServiceWatcher mContentCaptureServiceWatcher;
    private CtsTranslationService.ServiceWatcher mTranslationServiceServiceWatcher;
    private ActivityScenario<SimpleActivity> mActivityScenario;
    private ActivityScenario<VirtualContainerViewActivity> mVirtualContainerViewActivityScenario;
    private ActivityScenario<CustomTextViewActivity> mCustomTextViewActivityScenario;

    private VirtualContainerView mVirtualContainerView;
    private ResponseNotSetTextView mResponseNotSetTextView;
    private CustomTextView mCustomTextView;
    private TextView mTextView;
    private static String sOriginalLogTag;

    @Rule
    public final RequiredServiceRule mContentCaptureServiceRule =
            new RequiredServiceRule(CONTENT_CAPTURE_MANAGER_SERVICE);

    @Rule
    public final RequiredServiceRule mTranslationServiceRule =
            new RequiredServiceRule(TRANSLATION_MANAGER_SERVICE);

    @BeforeClass
    public static void oneTimeSetup() {
        sContext = ApplicationProvider.getApplicationContext();
        sTranslationReplier = CtsTranslationService.getTranslationReplier();
        sOriginalLogTag = Helper.enableDebugLog();

        Helper.allowSelfForContentCapture(sContext);
        Helper.setDefaultContentCaptureServiceEnabled(/* enabled= */ false);
    }

    @AfterClass
    public static void oneTimeReset() {
        Helper.unAllowSelfForContentCapture(sContext);
        Helper.setDefaultContentCaptureServiceEnabled(/* enabled= */ true);
        Helper.disableDebugLog(sOriginalLogTag);
    }

    @Before
    public void setup() throws Exception {
        CtsContentCaptureService.resetStaticState();
        CtsTranslationService.resetStaticState();
    }

    @After
    public void cleanup() throws Exception {
        if (mActivityScenario != null) {
            mActivityScenario.moveToState(Lifecycle.State.DESTROYED);
        }
        if (mVirtualContainerViewActivityScenario != null) {
            mVirtualContainerViewActivityScenario.moveToState(Lifecycle.State.DESTROYED);
        }
        Helper.resetTemporaryContentCaptureService();
        Helper.resetTemporaryTranslationService();
    }

    @Test
    public void testUiTranslation() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();

        final CharSequence originalText = mTextView.getText();
        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        final String translatedText = "success";
        final UiObject2 helloText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
                SimpleActivity.HELLO_TEXT_ID);
        assertThat(helloText).isNotNull();
        // Set response
        final TranslationResponse response = createViewsTranslationResponse(views, translatedText);
        sTranslationReplier.addResponse(response);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        // Check request
        final TranslationRequest request = sTranslationReplier.getNextTranslationRequest();
        final List<ViewTranslationRequest> requests = request.getViewTranslationRequests();
        final ViewTranslationRequest viewRequest = requests.get(0);
        assertThat(viewRequest.getAutofillId()).isEqualTo(views.get(0));
        assertThat(viewRequest.getKeys().size()).isEqualTo(1);
        assertThat(viewRequest.getKeys()).containsExactly(ViewTranslationRequest.ID_TEXT);
        assertThat(viewRequest.getValue(ViewTranslationRequest.ID_TEXT).getText())
                .isEqualTo(originalText.toString());

        assertThat(helloText.getText()).isEqualTo(translatedText);
        assertThat(mTextView.getViewTranslationResponse())
                .isEqualTo(response.getViewTranslationResponses().get(0));

        pauseUiTranslation(contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(originalText.toString());

        resumeUiTranslation(contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(translatedText);

        finishUiTranslation(contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(originalText.toString());

        // Check the Translation session is destroyed after calling finishTranslation()
        CtsTranslationService translationService =
                mTranslationServiceServiceWatcher.getService();
        translationService.awaitSessionDestroyed();

        // Test re-translating.
        sTranslationReplier.addResponse(createViewsTranslationResponse(views, translatedText));

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(translatedText);

        // Also make sure pausing still works.
        pauseUiTranslation(contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(originalText.toString());
    }

    @Test
    public void testUiTranslationWithoutAnimation() throws Throwable {
        final float[] originalAnimationDurationScale = new float[1];
        try {
            // Disable animation
            SystemUtil.runWithShellPermissionIdentity(() -> {
                ContentResolver resolver =
                        ApplicationProvider.getApplicationContext().getContentResolver();
                originalAnimationDurationScale[0] =
                        Settings.Global.getFloat(resolver, ANIMATOR_DURATION_SCALE, 1f);
                Settings.Global.putFloat(resolver, ANIMATOR_DURATION_SCALE, 0);
            });

            final Pair<List<AutofillId>, ContentCaptureContext> result =
                    enableServicesAndStartActivityForTranslation();

            final CharSequence originalText = mTextView.getText();
            final List<AutofillId> views = result.first;
            final ContentCaptureContext contentCaptureContext = result.second;

            final String translatedText = "success";
            final UiObject2 helloText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
                    SimpleActivity.HELLO_TEXT_ID);
            assertThat(helloText).isNotNull();
            // Set response
            final TranslationResponse response =
                    createViewsTranslationResponse(views, translatedText);
            sTranslationReplier.addResponse(response);

            startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

            assertThat(helloText.getText()).isEqualTo(translatedText);

            pauseUiTranslation(contentCaptureContext);

            assertThat(helloText.getText()).isEqualTo(originalText.toString());

            resumeUiTranslation(contentCaptureContext);

            assertThat(helloText.getText()).isEqualTo(translatedText);

            finishUiTranslation(contentCaptureContext);

            assertThat(helloText.getText()).isEqualTo(originalText.toString());
        } finally {
            // restore animation
            SystemUtil.runWithShellPermissionIdentity(() -> {
                Settings.Global.putFloat(
                        ApplicationProvider.getApplicationContext().getContentResolver(),
                        ANIMATOR_DURATION_SCALE, originalAnimationDurationScale[0]);
            });
        }
    }

    @Test
    public void testPauseUiTranslationThenStartUiTranslation() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();

        final CharSequence originalText = mTextView.getText();
        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        final String translatedText = "success";
        final UiObject2 helloText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
                SimpleActivity.HELLO_TEXT_ID);
        assertThat(helloText).isNotNull();
        // Set response
        final TranslationResponse response =
                createViewsTranslationResponse(views, translatedText);
        sTranslationReplier.addResponse(response);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(translatedText);

        pauseUiTranslation(contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(originalText.toString());

        sTranslationReplier.addResponse(createViewsTranslationResponse(views, translatedText));

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        assertThat(helloText.getText()).isEqualTo(translatedText);
    }

    @Test
    public void testUiTranslation_CustomViewTranslationCallback() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();
        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        // Set ViewTranslationCallback
        ViewTranslationCallback mockCallback = Mockito.mock(ViewTranslationCallback.class);
        mTextView.setViewTranslationCallback(mockCallback);
        // Set response
        sTranslationReplier.addResponse(createViewsTranslationResponse(views, "success"));

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        ArgumentCaptor<View> viewArgumentCaptor = ArgumentCaptor.forClass(View.class);
        Mockito.verify(mockCallback, Mockito.times(1)).onShowTranslation(viewArgumentCaptor.capture());
        TextView capturedView = (TextView) viewArgumentCaptor.getValue();
        assertThat(capturedView.getAutofillId()).isEqualTo(mTextView.getAutofillId());

        pauseUiTranslation(contentCaptureContext);

        Mockito.verify(mockCallback, Mockito.times(1)).onHideTranslation(viewArgumentCaptor.capture());
        capturedView = (TextView) viewArgumentCaptor.getValue();
        assertThat(capturedView.getAutofillId()).isEqualTo(mTextView.getAutofillId());

        resumeUiTranslation(contentCaptureContext);

        Mockito.verify(mockCallback, Mockito.times(2)).onShowTranslation(viewArgumentCaptor.capture());
        capturedView = (TextView) viewArgumentCaptor.getValue();
        assertThat(capturedView.getAutofillId()).isEqualTo(mTextView.getAutofillId());

        // Clear callback
        mTextView.clearViewTranslationCallback();

        finishUiTranslation(contentCaptureContext);

        // Verify callback does not be called, keep the latest state
        Mockito.verify(mockCallback, Mockito.never()).onClearTranslation(any(View.class));

        // Finally, verify that no unexpected interactions occurred. We cannot use
        // verifyNoMoreInteractions as the callback has some hidden methods.
        Mockito.verify(mockCallback, Mockito.times(2)).onShowTranslation(any());
        Mockito.verify(mockCallback, Mockito.times(1)).onHideTranslation(any());
    }

    @Test
    @FlakyTest(bugId = 192418800)
    public void testUiTranslation_ViewTranslationCallback_paddingText() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();
        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        // Set response
        final CharSequence originalText = mTextView.getText();
        final CharSequence translatedText = "Translated World";
        sTranslationReplier.addResponse(
                createViewsTranslationResponse(views, translatedText.toString()));

        // Use TextView default ViewTranslationCallback implementation
        startUiTranslation(/* shouldPadContent */ true, views, contentCaptureContext);

        CharSequence currentText = mTextView.getText();
        assertThat(currentText.length()).isNotEqualTo(originalText.length());
        assertThat(currentText.length()).isEqualTo(translatedText.length());

        finishUiTranslation(contentCaptureContext);

        // Set Customized ViewTranslationCallback
        ViewTranslationCallback mockCallback = Mockito.mock(ViewTranslationCallback.class);
        mTextView.setViewTranslationCallback(mockCallback);

        startUiTranslation(/* shouldPadContent */ true, views, contentCaptureContext);

        assertThat(mTextView.getText().length()).isEqualTo(originalText.length());
    }

    @Test
    public void testUiTranslation_hasContentDescription() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();
        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        // Set response
        final CharSequence translatedText = "Translated World";
        final CharSequence originalDescription = "Hello Description";
        mActivityScenario.onActivity(activity -> {
            mTextView.setContentDescription(originalDescription);
        });
        sTranslationReplier.addResponse(
                createViewsTranslationResponse(views, translatedText.toString()));

        // Use TextView default ViewTranslationCallback implementation
        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        assertThat(mTextView.getContentDescription().toString())
                .isEqualTo(translatedText.toString());

        // Check request to make sure the content description key doesn't be changed
        final TranslationRequest request = sTranslationReplier.getNextTranslationRequest();
        final List<ViewTranslationRequest> requests = request.getViewTranslationRequests();
        final ViewTranslationRequest viewRequest = requests.get(0);
        assertThat(viewRequest.getAutofillId()).isEqualTo(views.get(0));
        assertThat(viewRequest.getKeys().size()).isEqualTo(2);
        assertThat(viewRequest.getKeys()).containsExactly(ID_CONTENT_DESCRIPTION,
                ViewTranslationRequest.ID_TEXT);
        assertThat(viewRequest.getValue(ID_CONTENT_DESCRIPTION).getText())
                .isEqualTo(originalDescription);

        pauseUiTranslation(contentCaptureContext);

        assertThat(mTextView.getContentDescription().toString())
                .isEqualTo(originalDescription.toString());

        resumeUiTranslation(contentCaptureContext);

        assertThat(mTextView.getContentDescription().toString())
                .isEqualTo(translatedText.toString());

        finishUiTranslation(contentCaptureContext);

        assertThat(mTextView.getContentDescription().toString())
                .isEqualTo(originalDescription.toString());
    }

    @Test
    public void testIMEUiTranslationStateCallback() throws Throwable {
        try (ImeSession imeSession = new ImeSession(
                new ComponentName(CtsTestIme.IME_SERVICE_PACKAGE, CtsTestIme.class.getName()))) {

            final Pair<List<AutofillId>, ContentCaptureContext> result =
                    enableServicesAndStartActivityForTranslation();
            final List<AutofillId> views = result.first;
            final ContentCaptureContext contentCaptureContext = result.second;
            sTranslationReplier.addResponse(createViewsTranslationResponse(views, "success"));

            // Send broadcast to request IME to register callback
            BlockingBroadcastReceiver registerResultReceiver =
                    sendCommandToIme(ACTION_REGISTER_UI_TRANSLATION_CALLBACK, false);
            // Get result
            registerResultReceiver.awaitForBroadcast();
            registerResultReceiver.unregisterQuietly();

            startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

            // Send broadcast to request IME to check the onStarted() result
            BlockingBroadcastReceiver onStartResultReceiver = sendCommandToIme(
                    ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_START, true);
            // Get result to check the onStarted() was called
            Intent onStartIntent = onStartResultReceiver.awaitForBroadcast();
            ULocale receivedSource =
                    (ULocale) onStartIntent.getSerializableExtra(EXTRA_SOURCE_LOCALE);
            ULocale receivedTarget =
                    (ULocale) onStartIntent.getSerializableExtra(EXTRA_TARGET_LOCALE);
            assertThat(receivedSource).isEqualTo(ULocale.ENGLISH);
            assertThat(receivedTarget).isEqualTo(ULocale.FRENCH);
            onStartResultReceiver.unregisterQuietly();

            pauseUiTranslation(contentCaptureContext);

            // Send broadcast to request IME to check the onPaused() result
            BlockingBroadcastReceiver onPausedResultReceiver = sendCommandToIme(
                    ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_PAUSE, true);
            // Get result to check the onPaused() was called
            Intent onPausedIntent = onPausedResultReceiver.awaitForBroadcast();
            boolean onPausedVerifyResult =
                    onPausedIntent.getBooleanExtra(EXTRA_VERIFY_RESULT, false);
            assertThat(onPausedVerifyResult).isTrue();
            onPausedResultReceiver.unregisterQuietly();

            resumeUiTranslation(contentCaptureContext);

            // Send broadcast to request IME to check the onResumed result
            BlockingBroadcastReceiver onResumedResultReceiver = sendCommandToIme(
                    ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_RESUME, true);
            // Get result to check the onResumed was called
            Intent onResumedIntent = onResumedResultReceiver.awaitForBroadcast();
            boolean onResumedVerifyResult =
                    onResumedIntent.getBooleanExtra(EXTRA_VERIFY_RESULT, false);
            assertThat(onResumedVerifyResult).isTrue();
            onResumedResultReceiver.unregisterQuietly();

            // Send broadcast to request IME to unregister callback
            BlockingBroadcastReceiver unRegisterResultReceiver
                    = sendCommandToIme(ACTION_UNREGISTER_UI_TRANSLATION_CALLBACK, false);
            unRegisterResultReceiver.awaitForBroadcast();
            unRegisterResultReceiver.unregisterQuietly();

            finishUiTranslation(contentCaptureContext);

            BlockingBroadcastReceiver onFinishResultReceiver =
                    sendCommandToIme(ACTION_ASSERT_UI_TRANSLATION_CALLBACK_ON_FINISH, true);
            // Get result to check onFinish() didn't be called.
            Intent onFinishIntent = onFinishResultReceiver.awaitForBroadcast();
            boolean onFinishVerifyResult =
                    onFinishIntent.getBooleanExtra(EXTRA_VERIFY_RESULT, true);
            assertThat(onFinishVerifyResult).isFalse();
            onFinishResultReceiver.unregisterQuietly();

            // TODO(b/191417938): add tests for the Activity destroyed for IME package callback
        }
    }

    @Test
    public void testNonIMEUiTranslationStateCallback() throws Throwable {
        final Pair<List<AutofillId>, ContentCaptureContext> result =
                enableServicesAndStartActivityForTranslation();

        final List<AutofillId> views = result.first;
        final ContentCaptureContext contentCaptureContext = result.second;

        UiTranslationManager manager =
                sContext.getSystemService(UiTranslationManager.class);
        // Set response
        sTranslationReplier.addResponse(createViewsTranslationResponse(views, "success"));

        // Register callback
        final Executor executor = Executors.newSingleThreadExecutor();
        UiTranslationStateCallback mockCallback = Mockito.mock(UiTranslationStateCallback.class);
        manager.registerUiTranslationStateCallback(executor, mockCallback);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        // TODO(b/191417938): add tests for the Activity isn't the same package of the
        //  registered callback app
        Mockito.verify(mockCallback, Mockito.times(1))
                .onStarted(any(ULocale.class), any(ULocale.class));

        finishUiTranslation(contentCaptureContext);

        Mockito.verify(mockCallback, Mockito.times(1))
                .onFinished();

        // Make sure onFinished will not be called twice.
        mActivityScenario.moveToState(Lifecycle.State.DESTROYED);
        mActivityScenario = null;
        Mockito.verify(mockCallback, Mockito.times(1))
                .onFinished();

        // TODO(b/191417938): add a test to verify startUiTranslation + Activity destroyed.
    }

    @Test
    public void testVirtualViewUiTranslation() throws Throwable {
        // Enable CTS ContentCaptureService
        CtsContentCaptureService contentcaptureService = enableContentCaptureService();

        // Start Activity and get needed information
        final List<AutofillId> views = startVirtualContainerViewActivityAndGetViewsForTranslation();
        ViewTranslationCallback mockCallback = Mockito.mock(ViewTranslationCallback.class);
        mVirtualContainerView.setViewTranslationCallback(mockCallback);

        // Wait session created and get the ContentCaptureContext from ContentCaptureService
        final ContentCaptureContext contentCaptureContext =
                getContentCaptureContextFromContentCaptureService(contentcaptureService);

        // enable CTS TranslationService
        mTranslationServiceServiceWatcher = CtsTranslationService.setServiceWatcher();
        Helper.setTemporaryTranslationService(CtsTranslationService.SERVICE_NAME);

        final String translatedText = "success";
        final UiTranslationManager manager = sContext.getSystemService(UiTranslationManager.class);
        // Set response
        final TranslationResponse expectedResponse =
                createViewsTranslationResponse(views, translatedText);
        sTranslationReplier.addResponse(expectedResponse);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        // Check request
        final TranslationRequest request = sTranslationReplier.getNextTranslationRequest();
        final List<ViewTranslationRequest> requests = request.getViewTranslationRequests();
        assertThat(requests.size()).isEqualTo(views.size());
        // 1st virtual child in container
        final ViewTranslationRequest viewRequest1 = requests.get(0);
        assertThat(viewRequest1.getAutofillId()).isEqualTo(views.get(0));
        assertThat(viewRequest1.getKeys()).containsExactly(ViewTranslationRequest.ID_TEXT);
        assertThat(viewRequest1.getValue(ViewTranslationRequest.ID_TEXT).getText().toString())
                .isEqualTo("Hello 0");
        // 2nd virtual child in container
        final ViewTranslationRequest viewRequest2 = requests.get(1);
        assertThat(viewRequest2.getAutofillId()).isEqualTo(views.get(1));
        assertThat(viewRequest2.getKeys()).containsExactly(ViewTranslationRequest.ID_TEXT);
        assertThat(viewRequest2.getValue(ViewTranslationRequest.ID_TEXT).getText().toString())
                .isEqualTo("Hello 1");

        // Check responses
        final LongSparseArray<ViewTranslationResponse> responses
                = mVirtualContainerView.getViewTranslationResponseForCustomView();
        assertThat(responses).isNotNull();
        assertThat(responses.size()).isEqualTo(2);
        assertThat(responses.valueAt(0))
                .isEqualTo(expectedResponse.getViewTranslationResponses().valueAt(0));
        assertThat(responses.valueAt(1))
                .isEqualTo(expectedResponse.getViewTranslationResponses().valueAt(1));

        ArgumentCaptor<View> viewArgumentCaptor = ArgumentCaptor.forClass(View.class);
        Mockito.verify(mockCallback, Mockito.times(1))
                .onShowTranslation(viewArgumentCaptor.capture());
        VirtualContainerView capturedView = (VirtualContainerView) viewArgumentCaptor.getValue();
        assertThat(capturedView.getAutofillId()).isEqualTo(mVirtualContainerView.getAutofillId());

        pauseUiTranslation(contentCaptureContext);

        Mockito.verify(mockCallback, Mockito.times(1)).onHideTranslation(any(View.class));

        finishUiTranslation(contentCaptureContext);

        Mockito.verify(mockCallback, Mockito.times(1)).onClearTranslation(any(View.class));
    }

    @Test
    public void testUiTranslation_translationResponseNotSetForCustomTextView() throws Throwable {
        // Enable CTS ContentCaptureService
        CtsContentCaptureService contentcaptureService = enableContentCaptureService();
        // Start Activity and get needed information
        final List<AutofillId> views = startCustomTextViewActivityAndGetViewsForTranslation();

        // Wait session created and get the ConttCaptureContext from ContentCaptureService
        final ContentCaptureContext contentCaptureContext =
                getContentCaptureContextFromContentCaptureService(contentcaptureService);

        // enable CTS TranslationService
        mTranslationServiceServiceWatcher = CtsTranslationService.setServiceWatcher();
        Helper.setTemporaryTranslationService(CtsTranslationService.SERVICE_NAME);

        // Set response
        final TranslationResponse expectedResponse =
                createViewsTranslationResponse(views, "success");
        sTranslationReplier.addResponse(expectedResponse);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        // Verify result. Translation response doesn't set, it should show original text
        assertThat(mResponseNotSetTextView.getSavedResponse()).isNotNull();
        final UiObject2 responseNotSetText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
                CustomTextViewActivity.ID_RESPONSE_NOT_SET_TEXT);
        assertThat(responseNotSetText).isNotNull();
        assertThat(responseNotSetText.getText()).isEqualTo("Hello World 1");
    }

    @Test
    @FlakyTest(bugId = 192418800)
    public void testUiTranslation_customTextView() throws Throwable {
        // Enable CTS ContentCaptureService
        CtsContentCaptureService contentcaptureService = enableContentCaptureService();
        // Start Activity and get needed information
        final List<AutofillId> views = startCustomTextViewActivityAndGetViewsForTranslation();

        // Wait session created and get the ConttCaptureContext from ContentCaptureService
        final ContentCaptureContext contentCaptureContext =
                getContentCaptureContextFromContentCaptureService(contentcaptureService);

        // enable CTS TranslationService
        mTranslationServiceServiceWatcher = CtsTranslationService.setServiceWatcher();
        Helper.setTemporaryTranslationService(CtsTranslationService.SERVICE_NAME);

        final String translatedText = "success";
        // Set response
        final TranslationResponse expectedResponse =
                createViewsTranslationResponse(views, translatedText);
        sTranslationReplier.addResponse(expectedResponse);

        startUiTranslation(/* shouldPadContent */ false, views, contentCaptureContext);

        // Verify result.
        assertThat(mCustomTextView.isMyTagTranslationSupported()).isTrue();
        final UiObject2 customText = Helper.findObjectByResId(Helper.ACTIVITY_PACKAGE,
                CustomTextViewActivity.ID_CUSTOM_TEXT);
        assertThat(customText).isNotNull();
        assertThat(customText.getText()).isEqualTo(translatedText);

        finishUiTranslation(contentCaptureContext);

        assertThat(customText.getText()).isEqualTo("Hello World 2");
    }

    private void startUiTranslation(boolean shouldPadContent, List<AutofillId> views,
            ContentCaptureContext contentCaptureContext) {
        final UiTranslationManager manager = sContext.getSystemService(UiTranslationManager.class);
        runWithShellPermissionIdentity(() -> {
            // Call startTranslation API
            manager.startTranslation(
                    new TranslationSpec(ULocale.ENGLISH,
                            TranslationSpec.DATA_FORMAT_TEXT),
                    new TranslationSpec(ULocale.FRENCH,
                            TranslationSpec.DATA_FORMAT_TEXT),
                    views, contentCaptureContext.getActivityId(),
                    shouldPadContent ? new UiTranslationSpec.Builder().setShouldPadContentForCompat(
                            true).build() : new UiTranslationSpec.Builder().build());
            SystemClock.sleep(UI_WAIT_TIMEOUT);
        });
    }

    private void pauseUiTranslation(ContentCaptureContext contentCaptureContext) {
        final UiTranslationManager manager = sContext.getSystemService(UiTranslationManager.class);
        runWithShellPermissionIdentity(() -> {
            // Call pauseTranslation API
            manager.pauseTranslation(contentCaptureContext.getActivityId());
            SystemClock.sleep(UI_WAIT_TIMEOUT);
        });
    }

    private void resumeUiTranslation(ContentCaptureContext contentCaptureContext) {
        final UiTranslationManager manager = sContext.getSystemService(UiTranslationManager.class);
        // Call resume Translation API
        runWithShellPermissionIdentity(() -> {
            manager.resumeTranslation(contentCaptureContext.getActivityId());
            SystemClock.sleep(UI_WAIT_TIMEOUT);
        });
    }

    private void finishUiTranslation(ContentCaptureContext contentCaptureContext) {
        final UiTranslationManager manager = sContext.getSystemService(UiTranslationManager.class);
        runWithShellPermissionIdentity(() -> {
            // Call finishTranslation API
            manager.finishTranslation(contentCaptureContext.getActivityId());
            SystemClock.sleep(UI_WAIT_TIMEOUT);
        });
    }

    private List<AutofillId> startCustomTextViewActivityAndGetViewsForTranslation() {
        // Start CustomTextViewActivity and get needed information
        Intent intent = new Intent(sContext, CustomTextViewActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        AtomicReference<List<AutofillId>> viewAutofillIdsRef = new AtomicReference<>();

        mCustomTextViewActivityScenario = ActivityScenario.launch(intent);
        mCustomTextViewActivityScenario.onActivity(activity -> {
            mResponseNotSetTextView = activity.getResponseNotSetText();
            mCustomTextView = activity.getCustomText();
           // Get the views that need to be translated.
            viewAutofillIdsRef.set(activity.getViewsForTranslation());
        });
        return viewAutofillIdsRef.get();
    }

    private List<AutofillId> startVirtualContainerViewActivityAndGetViewsForTranslation() {
        // Start VirtualContainerViewActivity and get needed information
        Intent intent = new Intent(sContext, VirtualContainerViewActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        AtomicReference<List<AutofillId>> viewAutofillIdsRef = new AtomicReference<>();

        mVirtualContainerViewActivityScenario = ActivityScenario.launch(intent);
        mVirtualContainerViewActivityScenario.onActivity(activity -> {
            mVirtualContainerView = activity.getVirtualContainerView();
            // Get the views that need to be translated.
            viewAutofillIdsRef.set(activity.getViewsForTranslation());
        });
        return viewAutofillIdsRef.get();
    }

    private BlockingBroadcastReceiver sendCommandToIme(String action, boolean mutable) {
        final String actionImeServiceCommandDone = action + "_" + SystemClock.uptimeMillis();
        final BlockingBroadcastReceiver receiver = new BlockingBroadcastReceiver(sContext,
                actionImeServiceCommandDone);
        receiver.register();
        final Intent commandIntent = new Intent(action);
        final PendingIntent pendingIntent =
                PendingIntent.getBroadcast(
                        sContext,
                        0,
                        new Intent(actionImeServiceCommandDone),
                        mutable ? PendingIntent.FLAG_MUTABLE : PendingIntent.FLAG_IMMUTABLE);
        commandIntent.putExtra(EXTRA_FINISH_COMMAND, pendingIntent);
        sContext.sendBroadcast(commandIntent);
        return receiver;
    }

    private CtsContentCaptureService enableContentCaptureService() throws Exception {
        mContentCaptureServiceWatcher = CtsContentCaptureService.setServiceWatcher();
        Helper.setTemporaryContentCaptureService(CtsContentCaptureService.SERVICE_NAME);
        mContentCaptureServiceWatcher.setAllowSelf();
        return mContentCaptureServiceWatcher.waitOnConnected();
    }

    private ContentCaptureContext getContentCaptureContextFromContentCaptureService(
            CtsContentCaptureService service) {
        service.awaitSessionCreated(CtsContentCaptureService.GENERIC_TIMEOUT_MS);
        final ContentCaptureContext contentCaptureContext = service.getContentCaptureContext();
        Log.d(TAG, "contentCaptureContext = " + contentCaptureContext);

        assertThat(contentCaptureContext).isNotNull();
        assertThat(contentCaptureContext.getActivityId()).isNotNull();

        return contentCaptureContext;
    }

    private TranslationResponse createViewsTranslationResponse(List<AutofillId> viewAutofillIds,
            String translatedText) {
        final TranslationResponse.Builder responseBuilder =
                new TranslationResponse.Builder(TranslationResponse.TRANSLATION_STATUS_SUCCESS);
        for (int i = 0; i < viewAutofillIds.size(); i++) {
            ViewTranslationResponse.Builder responseDataBuilder =
                    new ViewTranslationResponse.Builder(viewAutofillIds.get(i))
                            .setValue(ViewTranslationRequest.ID_TEXT,
                                    new TranslationResponseValue.Builder(STATUS_SUCCESS)
                                            .setText(translatedText).build())
                            .setValue(Helper.CUSTOM_TRANSLATION_ID_MY_TAG,
                                    new TranslationResponseValue.Builder(STATUS_SUCCESS)
                                            .setText(translatedText).build())
                            .setValue(ID_CONTENT_DESCRIPTION,
                                    new TranslationResponseValue.Builder(STATUS_SUCCESS)
                                            .setText(translatedText).build());
            responseBuilder.setViewTranslationResponse(i, responseDataBuilder.build());
        }
        return responseBuilder.build();
    }

    private Pair<List<AutofillId>, ContentCaptureContext>
            enableServicesAndStartActivityForTranslation() throws Exception {
        // Enable CTS ContentCaptureService
        CtsContentCaptureService contentcaptureService = enableContentCaptureService();

        // Start Activity and get needed information
        Intent intent = new Intent(sContext, SimpleActivity.class)
                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        AtomicReference<CharSequence> originalTextRef = new AtomicReference<>();
        AtomicReference<List<AutofillId>> viewAutofillIdsRef = new AtomicReference<>();

        mActivityScenario = ActivityScenario.launch(intent);
        mActivityScenario.onActivity(activity -> {
            mTextView = activity.getHelloText();
            originalTextRef.set(activity.getHelloText().getText());
            viewAutofillIdsRef.set(activity.getViewsForTranslation());
        });
        CharSequence originalText = originalTextRef.get();
        // Get the views that need to be translated.
        List<AutofillId> views = viewAutofillIdsRef.get();

        // Wait session created and get the ContentCaptureContext from ContentCaptureService
        ContentCaptureContext contentCaptureContext =
                getContentCaptureContextFromContentCaptureService(contentcaptureService);

        // enable CTS TranslationService
        mTranslationServiceServiceWatcher = CtsTranslationService.setServiceWatcher();
        Helper.setTemporaryTranslationService(CtsTranslationService.SERVICE_NAME);

        // TODO(b/184617863): use separate methods not use Pair here.
        return new Pair(views, contentCaptureContext);
    }

    private static class ImeSession implements AutoCloseable {

        private static final long TIMEOUT = 2000;
        private final ComponentName mImeName;

        ImeSession(ComponentName ime) throws Exception {
            mImeName = ime;
            runShellCommand("ime reset");
            // TODO(b/184617863): get IME component from InputMethodManager#getInputMethodList
            runShellCommand("ime enable " + ime.flattenToShortString());
            runShellCommand("ime set " + ime.flattenToShortString());
            PollingCheck.check("Make sure that MockIME becomes available", TIMEOUT,
                    () -> ime.equals(getCurrentInputMethodId()));
        }

        @Override
        public void close() throws Exception {
            runShellCommand("ime reset");
            PollingCheck.check("Make sure that MockIME becomes unavailable", TIMEOUT, () ->
                    sContext.getSystemService(InputMethodManager.class)
                            .getEnabledInputMethodList()
                            .stream()
                            .noneMatch(info -> mImeName.equals(info.getComponent())));
        }

        private ComponentName getCurrentInputMethodId() {
            return ComponentName.unflattenFromString(
                    Settings.Secure.getString(sContext.getContentResolver(),
                            Settings.Secure.DEFAULT_INPUT_METHOD));
        }
    }
}
