/*
 * Copyright (C) 2019 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.contentcaptureservice.cts;

import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
import static android.contentcaptureservice.cts.Helper.NO_ACTIVITIES;
import static android.contentcaptureservice.cts.Helper.OTHER_PACKAGE;
import static android.contentcaptureservice.cts.Helper.await;
import static android.contentcaptureservice.cts.Helper.eventually;
import static android.contentcaptureservice.cts.Helper.toSet;
import static android.view.contentcapture.ContentCaptureCondition.FLAG_IS_REGEX;

import static com.android.compatibility.common.util.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
import static com.android.compatibility.common.util.ActivitiesWatcher.ActivityLifecycle.RESUMED;

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

import android.content.LocusId;
import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.os.Handler;
import android.os.Looper;
import android.platform.test.annotations.AppModeFull;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
import android.view.ViewStructure;
import android.view.WindowManager;
import android.view.autofill.AutofillId;
import android.view.contentcapture.ContentCaptureCondition;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureManager;
import android.view.contentcapture.ContentCaptureSession;
import android.view.contentcapture.ContentCaptureSessionId;

import androidx.annotation.NonNull;
import androidx.test.rule.ActivityTestRule;

import com.android.compatibility.common.util.ActivitiesWatcher.ActivityWatcher;
import com.android.compatibility.common.util.DoubleVisitor;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

@AppModeFull(reason = "BlankWithTitleActivityTest is enough")
public class CustomViewActivityTest extends
        AbstractContentCaptureIntegrationAutoActivityLaunchTest<CustomViewActivity> {

    private static final String TAG = CustomViewActivityTest.class.getSimpleName();

    private static final ActivityTestRule<CustomViewActivity> sActivityRule =
            new ActivityTestRule<>(CustomViewActivity.class, false, false);

    public CustomViewActivityTest() {
        super(CustomViewActivity.class);
    }

    @Override
    protected ActivityTestRule<CustomViewActivity> getActivityTestRule() {
        return sActivityRule;
    }

    /**
     * Baseline / initial check test for the other tests.
     */
    @Test
    public void testLifecycle() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        activity.assertDefaultEvents(session);
    }

    /**
     * Test for session lifecycle events.
     */
    @Test
    public void testSessionLifecycleEvents() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();
        final AtomicReference<CustomView> customViewRef = new AtomicReference<>();

        CustomViewActivity.setCustomViewDelegate((customView, structure) -> {
            customViewRef.set(customView);
            final ContentCaptureSession session = customView.getContentCaptureSession();
            session.notifySessionResumed();
            session.notifySessionPaused();
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);

        final View grandpa1 = (View) activity.mCustomView.getParent();
        final View grandpa2 = (View) grandpa1.getParent();
        final View decorView = activity.getDecorView();
        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        Log.v(TAG, "assertJustInitialViewsAppeared(): grandpa1=" + grandpa1.getAutofillId()
                + ", grandpa2=" + grandpa2.getAutofillId() + ", decor="
                + decorView.getAutofillId() + "customView=" + customViewId);

        final List<ContentCaptureEvent> events = session.getEvents();
        Log.v(TAG, "events(" + events.size() + "): " + events);
        final int additionalEvents = 2;

        new EventsAssertor(events)
                .isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents)
                .assertSessionResumed()
                .assertViewTreeStarted()
                .assertDecorViewAppeared(decorView)
                .assertViewAppeared(grandpa2, decorView.getAutofillId())
                .assertViewAppeared(grandpa1, grandpa2.getAutofillId())
                // Assert for session lifecycle events.
                .assertSessionResumed()
                .assertSessionPaused()
                .assertViewAppeared(session.id, customViewRef.get())
                .assertViewTreeFinished()
                .assertSessionPaused();
    }

    /**
     * Tests when the view has virtual children but it doesn't return right away and calls
     * the session notification methods instead - this is wrong because the main view will be
     * notified last, but we cannot prevent the apps from doing so...
     */
    @Test
    public void testVirtualView_wrongWay() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        CustomViewActivity.setCustomViewDelegate((customView, structure) -> {
            Log.d(TAG, "delegate running on " + Thread.currentThread());
            final AutofillId customViewId = customView.getAutofillId();
            Log.d(TAG, "customViewId: " + customViewId);
            final ContentCaptureSession session = customView.getContentCaptureSession();

            final ViewStructure child = session.newVirtualViewStructure(customViewId, 1);
            child.setText("child");
            final AutofillId childId = child.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(childId);
            Log.d(TAG, "nofifying child appeared: " + childId);
            session.notifyViewAppeared(child);

            Log.d(TAG, "nofifying child disappeared: " + childId);
            session.notifyViewDisappeared(childId);
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);

        final View grandpa1 = (View) activity.mCustomView.getParent();
        final View grandpa2 = (View) grandpa1.getParent();
        final View decorView = activity.getDecorView();
        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        Log.v(TAG, "assertJustInitialViewsAppeared(): grandpa1=" + grandpa1.getAutofillId()
                + ", grandpa2=" + grandpa2.getAutofillId() + ", decor="
                + decorView.getAutofillId() + "customView=" + customViewId);

        final List<ContentCaptureEvent> events = session.getEvents();
        Log.v(TAG, "events(" + events.size() + "): " + events);
        final int additionalEvents = 2;
        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();

        new EventsAssertor(events)
                .isAtLeast(CustomViewActivity.MIN_EVENTS + additionalEvents)
                .assertSessionResumed()
                .assertViewTreeStarted()
                .assertDecorViewAppeared(decorView)
                .assertViewAppeared(grandpa2, decorView.getAutofillId())
                .assertViewAppeared(grandpa1, grandpa2.getAutofillId())
                .assertVirtualViewAppeared(mainSession, customViewId, 1, "child")
                .assertVirtualViewDisappeared(customViewId, mainSession, 1)
                .assertViewAppeared(session.id, activity.mCustomView)
                .assertViewTreeFinished()
                .assertSessionPaused();
    }

    /**
     * Tests when the view has virtual children, but those children are leaf nodes.
     */
    @Test
    public void testVirtualView_oneLevel() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final AtomicReference<AutofillId> child2IdRef = new AtomicReference<>();
        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
            Log.d(TAG, "delegate running on " + Thread.currentThread());
            final AutofillId customViewId = customView.getAutofillId();
            Log.d(TAG, "customViewId: " + customViewId);
            final ContentCaptureSession session = customView.getContentCaptureSession();

            final ViewStructure child1 = session.newVirtualViewStructure(customViewId, 1);
            child1.setText("child1");
            final AutofillId child1Id = child1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
            Log.d(TAG, "nofifying child1 appeared: " + child1Id);
            session.notifyViewAppeared(child1);
            final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
            child2.setText("child2");
            final AutofillId child2Id = child2.getAutofillId();
            child2IdRef.set(child2Id);
            assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
            Log.d(TAG, "nofifying child2 appeared: " + child2Id);
            session.notifyViewAppeared(child2);

            Log.d(TAG, "nofifying child2 text changed");
            session.notifyViewTextChanged(child2Id, "The Times They Are a-Changin'");

            Log.d(TAG, "nofifying child2 disappeared: " + child2Id);
            session.notifyViewDisappeared(child2Id);
            Log.d(TAG, "nofifying child1 disappeared: " + child1Id);
            session.notifyViewDisappeared(child1Id);
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);
        await(asyncLatch, "async onProvide");

        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);

        final int additionalEvents = 3;
        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
                additionalEvents);

        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();

        new EventsAssertor(events)
                .assertVirtualViewAppeared(mainSession, customViewId, 1, "child1")
                .assertVirtualViewAppeared(mainSession, customViewId, 2, "child2")
                .assertViewTextChanged(child2IdRef.get(), "The Times They Are a-Changin'")
                .assertVirtualViewsDisappeared(customViewId, mainSession, 2, 1);
        // TODO(b/122315042): assert views disappeared
    }

    /**
     * Tests when the view has virtual children, and some of those children have children too.
     */
    @Test
    public void testVirtualView_multipleLevels() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
            Log.d(TAG, "delegate running on " + Thread.currentThread());
            final AutofillId customViewId = customView.getAutofillId();
            Log.d(TAG, "customViewId: " + customViewId);
            final ContentCaptureSession session = customView.getContentCaptureSession();

            // Child 1
            final ViewStructure c1 = session.newVirtualViewStructure(customViewId, 1);
            c1.setText("c1");
            final AutofillId c1Id = c1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(c1Id);
            Log.d(TAG, "nofifying c1 appeared: " + c1Id);
            session.notifyViewAppeared(c1);

            // Child 1, grandchildren 1
            final ViewStructure c1g1 = session.newVirtualViewStructure(c1Id, 11);
            c1g1.setText("c1g1");
            final AutofillId c1g1Id = c1g1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 11)).isEqualTo(c1g1Id);
            Log.d(TAG, "nofifying c1g1 appeared: " + c1g1Id);
            session.notifyViewAppeared(c1g1);

            // Child 1, grandchildren 2
            final ViewStructure c1g2 = session.newVirtualViewStructure(c1Id, 12);
            c1g2.setText("c1g2");
            final AutofillId c1g2Id = c1g2.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 12)).isEqualTo(c1g2Id);
            Log.d(TAG, "nofifying c1g2 appeared: " + c1g2Id);
            session.notifyViewAppeared(c1g2);

            final ViewStructure c2 = session.newVirtualViewStructure(customViewId, 2);
            c2.setText("c2");
            final AutofillId c2Id = c2.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(c2Id);
            Log.d(TAG, "nofifying c2 appeared: " + c2Id);
            session.notifyViewAppeared(c2);

            // Child 2, grandchildren 1 - not removed
            final ViewStructure c2g1 = session.newVirtualViewStructure(c2Id, 21);
            c2g1.setText("c2g1");
            final AutofillId c2g1Id = c2g1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 21)).isEqualTo(c2g1Id);
            Log.d(TAG, "nofifying c2g1 appeared: " + c2g1Id);
            session.notifyViewAppeared(c2g1);

            // Child 2, grandchildren 1, grandgrandchild1 (on purpose)
            final ViewStructure c2g1gg1 = session.newVirtualViewStructure(c2g1Id,
                    211);
            c2g1gg1.setText("c2g1gg1");
            final AutofillId c2g1ggt1Id = c2g1gg1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 211)).isEqualTo(c2g1ggt1Id);
            Log.d(TAG, "nofifying c2g1gg1 appeared: " + c2g1ggt1Id);
            session.notifyViewAppeared(c2g1gg1);

            // Child 3 - not removed (on purpose)
            final ViewStructure c3 = session.newVirtualViewStructure(customViewId, 3);
            c3.setText("c3");
            final AutofillId c3Id = c3.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 3)).isEqualTo(c3Id);
            Log.d(TAG, "nofifying c3 appeared: " + c3Id);
            session.notifyViewAppeared(c3);

            // Remove children (although not all of them, on purpose)
            Log.d(TAG, "nofifying c2g1 disappeared: " + c2g1Id);
            session.notifyViewDisappeared(c2g1Id);
            Log.d(TAG, "nofifying c2 disappeared: " + c2Id);
            session.notifyViewDisappeared(c2Id);
            // Remove child1 grandchildren before and after
            Log.d(TAG, "nofifying c1g1 disappeared: " + c1g1Id);
            session.notifyViewDisappeared(c1g1Id);
            Log.d(TAG, "nofifying c1 disappeared: " + c1Id);
            session.notifyViewDisappeared(c1Id);
            Log.d(TAG, "nofifying c1g2 disappeared: " + c1g2Id);
            session.notifyViewDisappeared(c1g2Id);

        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);
        await(asyncLatch, "async onProvide");
        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);

        final int additionalEvents = 7;
        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
                additionalEvents);

        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();

        new EventsAssertor(events)
                .assertVirtualViewAppeared(mainSession, customViewId, 1, "c1")
                .assertVirtualViewAppeared(mainSession, customViewId, 11, "c1g1")
                .assertVirtualViewAppeared(mainSession, customViewId, 12, "c1g2")
                .assertVirtualViewAppeared(mainSession, customViewId, 2, "c2")
                .assertVirtualViewAppeared(mainSession, customViewId, 21, "c2g1")
                .assertVirtualViewAppeared(mainSession, customViewId, 211, "c2g1gg1")
                .assertVirtualViewAppeared(mainSession, customViewId, 3, "c3")
                .assertVirtualViewsDisappeared(customViewId, mainSession, 21, 2, 11, 1, 12);
        // TODO(b/122315042): assert other views disappeared
    }

    // TODO(b/123540602): add tests for multiple sessions

    @Test
    public void testVirtualView_batchDisappear() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
            Log.d(TAG, "delegate running on " + Thread.currentThread());
            final AutofillId customViewId = customView.getAutofillId();
            Log.d(TAG, "customViewId: " + customViewId);
            final ContentCaptureSession session = customView.getContentCaptureSession();

            final ViewStructure child1 = session.newVirtualViewStructure(customViewId, 1);
            child1.setText("child1");
            final AutofillId child1Id = child1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
            Log.d(TAG, "nofifying child1 appeared: " + child1Id);
            session.notifyViewAppeared(child1);

            final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
            child2.setText("child2");
            final AutofillId child2Id = child2.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
            Log.d(TAG, "nofifying child2 appeared: " + child2Id);
            session.notifyViewAppeared(child2);

            final long[] childrenIds = {2, 1};
            Log.d(TAG, "nofifying both children disappeared: " + Arrays.toString(childrenIds));
            session.notifyViewsDisappeared(customViewId, childrenIds);
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);
        await(asyncLatch, "async onProvide");
        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);


        final int additionalEvents = 5;
        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
                additionalEvents);

        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();

        new EventsAssertor(events)
                .assertVirtualViewAppeared(mainSession, customViewId, 1, "child1")
                .assertVirtualViewAppeared(mainSession, customViewId, 2, "child2")
                .assertViewTreeStarted()
                .assertVirtualViewsDisappeared(customViewId, mainSession, 2, 1)
                .assertViewTreeFinished();
        // TODO(b/122315042): assert other views disappeared
    }

    @Test
    public void testVirtualView_batchAppear() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
            Log.d(TAG, "delegate running on " + Thread.currentThread());
            final AutofillId customViewId = customView.getAutofillId();
            Log.d(TAG, "customViewId: " + customViewId);
            final ContentCaptureSession session = customView.getContentCaptureSession();

            final ViewStructure child1 = session.newVirtualViewStructure(customViewId, 1);
            child1.setText("child1");
            final AutofillId child1Id = child1.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);

            final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
            child2.setText("child2");
            final AutofillId child2Id = child2.getAutofillId();
            assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
            Log.d(TAG, "nofifying children appeared");
            final List<ViewStructure> appearedNodes = new ArrayList<>();
            appearedNodes.add(child1);
            appearedNodes.add(child2);
            session.notifyViewsAppeared(appearedNodes);
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);
        await(asyncLatch, "async onProvide");
        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        Log.v(TAG, "session id: " + session.id);

        assertRightActivity(session, session.id, activity);

        final int additionalEvents = 4;
        final List<ContentCaptureEvent> events = activity.assertInitialViewsAppeared(session,
                additionalEvents);

        final AutofillId customViewId = activity.mCustomView.getAutofillId();
        final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();

        new EventsAssertor(events)
                .assertViewTreeStarted()
                .assertVirtualViewAppeared(mainSession, customViewId, 1, "child1")
                .assertVirtualViewAppeared(mainSession, customViewId, 2, "child2")
                .assertViewTreeFinished();
    }

    @Test
    public void testContentCaptureConditions() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final Set<ContentCaptureCondition> conditions = new ArraySet<>(1);
        final LocusId locusId = new LocusId("Locus At me!");
        conditions.add(new ContentCaptureCondition(locusId, FLAG_IS_REGEX));
        service.setContentCaptureConditions(MY_PACKAGE, conditions);

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        final ContentCaptureManager mgr = activity.getContentCaptureManager();
        final Set<ContentCaptureCondition> actualConditions = mgr.getContentCaptureConditions();
        assertThat(actualConditions).isNotNull();
        assertThat(actualConditions).hasSize(1);

        final ContentCaptureCondition actualCondition = actualConditions.iterator().next();
        assertThat(actualCondition).isNotNull();
        assertThat(actualCondition.getLocusId()).isEqualTo(locusId);
        assertThat(actualCondition.getFlags()).isEqualTo(FLAG_IS_REGEX);
    }

    @Test
    public void testContentCaptureConditions_otherPackage() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final Set<ContentCaptureCondition> conditions = new ArraySet<>(1);
        final LocusId locusId = new LocusId("Locus At me!");
        conditions.add(new ContentCaptureCondition(locusId, FLAG_IS_REGEX));
        service.setContentCaptureConditions(OTHER_PACKAGE, conditions);

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        final ContentCaptureManager mgr = activity.getContentCaptureManager();
        final Set<ContentCaptureCondition> actualConditions = mgr.getContentCaptureConditions();
        assertThat(actualConditions).isNull();
    }

    @Test
    public void testContentCaptureEnabled_dynamicFlagSecure() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        final ContentCaptureManager mgr = activity.getContentCaptureManager();
        assertThat(mgr.isContentCaptureEnabled()).isTrue();

        activity.syncRunOnUiThread(() -> {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        });

        eventually("Waiting for flag secure to be disabled",
                () -> mgr.isContentCaptureEnabled() ? null : "not_used");

        activity.syncRunOnUiThread(() -> {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);
        });

        eventually("Waiting for flag secure to be re-enabled",
                () -> mgr.isContentCaptureEnabled() ? "not_used" : null);
    }

    @Test
    public void testDisabledByFlagSecure() throws Exception {
        final CtsContentCaptureService service = enableService();
        final ActivityWatcher watcher = startWatcher();

        CustomViewActivity.onRootView((activity) -> {
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
        });

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        final ContentCaptureManager mgr = activity.getContentCaptureManager();
        assertThat(mgr.isContentCaptureEnabled()).isFalse();

        activity.finish();
        watcher.waitFor(DESTROYED);

        final Session session = service.getOnlyFinishedSession();
        assertThat((session.context.getFlags()
                & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0).isTrue();

        final ContentCaptureSessionId sessionId = session.id;
        assertRightActivity(session, sessionId, activity);

        final List<ContentCaptureEvent> events = session.getEvents();
        assertThat(events).isEmpty();
    }

    @Test
    public void testDisabledAfterLaunched() throws Exception {
        // Explicitly enable package so it doesn't havea a "lite" ContentCaptureOptions
        final CtsContentCaptureService service = enableService(toSet(MY_PACKAGE), NO_ACTIVITIES);
        final ActivityWatcher watcher = startWatcher();

        final CustomViewActivity activity = launchActivity();
        watcher.waitFor(RESUMED);

        final ContentCaptureManager mgr = activity.getContentCaptureManager();
        eventually("isContentCaptureEnabled() is not true yet",
                () -> mgr.isContentCaptureEnabled() ? "not_used" : null);

        service.setContentCaptureWhitelist(/* packages= */ null, /* activities= */ null);

        eventually("isContentCaptureEnabled() is still true",
                () -> mgr.isContentCaptureEnabled() ? null : "not_used");

        activity.finish();
        watcher.waitFor(DESTROYED);
    }

    /**
     * Sets a delegate that will generate the events asynchronously,
     * after {@code onProvideContentCaptureStructure()} returns.
     */
    private CountDownLatch setAsyncDelegate(
            @NonNull DoubleVisitor<CustomView, ViewStructure> delegate) {
        final CountDownLatch asyncLatch = new CountDownLatch(1);
        CustomViewActivity.setCustomViewDelegate(
                (customView, structure) -> new Handler(Looper.getMainLooper())
                        .post(() -> {
                            delegate.visit(customView, structure);
                            asyncLatch.countDown();
                        }));
        return asyncLatch;
    }
}
