/*
 * Copyright (C) 2014 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.media.tv.cts;

import static androidx.test.ext.truth.view.MotionEventSubject.assertThat;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Instrumentation;
import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.PlaybackParams;
import android.media.tv.AitInfo;
import android.media.tv.TvContentRating;
import android.media.tv.TvContract;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvRecordingClient;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingRecordingSession;
import android.media.tv.cts.TvInputServiceTest.CountingTvInputService.CountingSession;
import android.media.tv.interactive.TvInteractiveAppServiceInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.View;
import android.widget.LinearLayout;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.compatibility.common.util.PollingCheck;
import com.android.compatibility.common.util.RequiredFeatureRule;
import com.google.common.truth.Truth;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Test {@link android.media.tv.TvInputService}.
 */
@RunWith(AndroidJUnit4.class)
public class TvInputServiceTest {

    private static final String TAG = "TvInputServiceTest";

    @Rule
    public RequiredFeatureRule featureRule = new RequiredFeatureRule(
            PackageManager.FEATURE_LIVE_TV);

    @Rule
    public ActivityScenarioRule<TvViewStubActivity> activityRule =
            new ActivityScenarioRule(TvViewStubActivity.class);


    private static final Uri CHANNEL_0 = TvContract.buildChannelUri(0);
    /** The maximum time to wait for an operation. */
    private static final long TIME_OUT = 5000L;
    private static final TvTrackInfo TEST_TV_TRACK =
            new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "testTrackId")
                    .setVideoWidth(1920)
                    .setVideoHeight(1080)
                    .setLanguage("und")
                    .build();

    private TvRecordingClient mTvRecordingClient;
    private Instrumentation mInstrumentation;
    private Context mContext;
    private TvInputManager mManager;
    private TvInputInfo mStubInfo;
    private TvInputInfo mFaultyStubInfo;
    private final StubCallback mCallback = new StubCallback();
    private final StubTimeShiftPositionCallback mTimeShiftPositionCallback =
            new StubTimeShiftPositionCallback();
    private final StubRecordingCallback mRecordingCallback = new StubRecordingCallback();

    private static class StubCallback extends TvView.TvInputCallback {
        private int mChannelRetunedCount;
        private int mVideoAvailableCount;
        private int mVideoUnavailableCount;
        private int mTrackSelectedCount;
        private int mTrackChangedCount;
        private int mVideoSizeChanged;
        private int mContentAllowedCount;
        private int mContentBlockedCount;
        private int mTimeShiftStatusChangedCount;
        private int mAitInfoUpdatedCount;

        private Uri mChannelRetunedUri;
        private Integer mVideoUnavailableReason;
        private Integer mTrackSelectedType;
        private String mTrackSelectedTrackId;
        private List<TvTrackInfo> mTracksChangedTrackList;
        private TvContentRating mContentBlockedRating;
        private Integer mTimeShiftStatusChangedStatus;
        private AitInfo mAitInfo;

        @Override
        public void onChannelRetuned(String inputId, Uri channelUri) {
            mChannelRetunedCount++;
            mChannelRetunedUri = channelUri;
        }

        @Override
        public void onVideoAvailable(String inputId) {
            mVideoAvailableCount++;
        }

        @Override
        public void onVideoUnavailable(String inputId, int reason) {
            mVideoUnavailableCount++;
            mVideoUnavailableReason = reason;
        }

        @Override
        public void onTrackSelected(String inputId, int type, String trackId) {
            mTrackSelectedCount++;
            mTrackSelectedType = type;
            mTrackSelectedTrackId = trackId;
        }

        @Override
        public void onTracksChanged(String inputId, List<TvTrackInfo> trackList) {
            mTrackChangedCount++;
            mTracksChangedTrackList = trackList;
        }

        @Override
        public void onVideoSizeChanged(String inputId, int width, int height) {
            mVideoSizeChanged++;
        }

        @Override
        public void onContentAllowed(String inputId) {
            mContentAllowedCount++;
        }

        @Override
        public void onContentBlocked(String inputId, TvContentRating rating) {
            mContentBlockedCount++;
            mContentBlockedRating = rating;
        }

        @Override
        public void onTimeShiftStatusChanged(String inputId, int status) {
            mTimeShiftStatusChangedCount++;
            mTimeShiftStatusChangedStatus = status;
        }

        public void onAitInfoUpdated(String inputId, AitInfo aitInfo) {
            mAitInfoUpdatedCount++;
            mAitInfo = aitInfo;
        }

        public void resetCounts() {
            mChannelRetunedCount = 0;
            mVideoAvailableCount = 0;
            mVideoUnavailableCount = 0;
            mTrackSelectedCount = 0;
            mTrackChangedCount = 0;
            mContentAllowedCount = 0;
            mContentBlockedCount = 0;
            mTimeShiftStatusChangedCount = 0;
            mAitInfoUpdatedCount = 0;
        }

        public void resetPassedValues() {
            mChannelRetunedUri = null;
            mVideoUnavailableReason = null;
            mTrackSelectedType = null;
            mTrackSelectedTrackId = null;
            mTracksChangedTrackList = null;
            mContentBlockedRating = null;
            mTimeShiftStatusChangedStatus = null;
            mAitInfo = null;
        }
    }

    private static class StubTimeShiftPositionCallback extends TvView.TimeShiftPositionCallback {
        private int mTimeShiftStartPositionChanged;
        private int mTimeShiftCurrentPositionChanged;

        @Override
        public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
            mTimeShiftStartPositionChanged++;
        }

        @Override
        public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
            mTimeShiftCurrentPositionChanged++;
        }

        public void resetCounts() {
            mTimeShiftStartPositionChanged = 0;
            mTimeShiftCurrentPositionChanged = 0;
        }
    }

    private static Bundle createTestBundle() {
        Bundle b = new Bundle();
        b.putString("stringKey", new String("Test String"));
        return b;
    }

    @Before
    public void setUp() {
        mInstrumentation = InstrumentationRegistry
                .getInstrumentation();
        mContext = mInstrumentation.getTargetContext();
        mTvRecordingClient =
                new TvRecordingClient(mContext, "TvInputServiceTest", mRecordingCallback, null);
        mManager = (TvInputManager) mContext.getSystemService(Context.TV_INPUT_SERVICE);
        for (TvInputInfo info : mManager.getTvInputList()) {
            if (info.getServiceInfo().name.equals(CountingTvInputService.class.getName())) {
                mStubInfo = info;
            }
            if (info.getServiceInfo().name.equals(FaultyTvInputService.class.getName())) {
                mFaultyStubInfo = info;
            }
            if (mStubInfo != null && mFaultyStubInfo != null) {
                break;
            }
        }
        assertThat(mStubInfo).isNotNull();

        CountingTvInputService.sSession = null;
        resetCounts();
        resetPassedValues();
    }

    @After
    public void tearDown() {
        activityRule.getScenario().onActivity(activity -> {
            activity.getTvView().reset();
        });
    }

    @Test
    public void verifyCommandTuneForRecording() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);

        assertThat(session.mSessionId).isNotEmpty();
        assertThat(session.mTuneCount).isEqualTo(1);
        assertThat(session.mTunedChannelUri).isEqualTo(CHANNEL_0);
    }

    @Test
    public void verifyCommandTuneForRecordingWithBundle() {
        final Bundle bundle = createTestBundle();

        final CountingRecordingSession session = tuneForRecording(CHANNEL_0, bundle);

        assertThat(session.mSessionId).isNotEmpty();
        assertThat(session.mTuneCount).isEqualTo(1);
        assertThat(session.mTuneWithBundleCount).isEqualTo(1);
        assertThat(session.mTunedChannelUri).isEqualTo(CHANNEL_0);
        assertBundlesAreEqual(session.mTuneWithBundleData, bundle);
    }

    @Test
    public void verifyCommandRelease() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);

        mTvRecordingClient.release();

        PollingCheck.waitFor(TIME_OUT, () -> session.mReleaseCount > 0);
        assertThat(session.mReleaseCount).isEqualTo(1);
    }

    @Test
    public void verifyCommandStartRecording() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);

        mTvRecordingClient.startRecording(CHANNEL_0);

        PollingCheck.waitFor(TIME_OUT, () -> session.mStartRecordingCount > 0);
        assertThat(session.mStartRecordingCount).isEqualTo(1);
        assertThat(session.mProgramHint).isEqualTo(CHANNEL_0);
    }

    @Test
    public void verifyCommandStartRecordingWithBundle() {
        Bundle bundle = createTestBundle();
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0, bundle);
        notifyTuned(CHANNEL_0);

        mTvRecordingClient.startRecording(CHANNEL_0, bundle);
        PollingCheck.waitFor(TIME_OUT, () -> session.mStartRecordingWithBundleCount > 0);

        assertThat(session.mStartRecordingCount).isEqualTo(1);
        assertThat(session.mStartRecordingWithBundleCount).isEqualTo(1);
        assertThat(session.mProgramHint).isEqualTo(CHANNEL_0);
        assertBundlesAreEqual(session.mStartRecordingWithBundleData, bundle);
    }

    @Test
    public void verifyCommandPauseResumeRecordingWithBundle() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);
        mTvRecordingClient.startRecording(CHANNEL_0);

        final Bundle bundle = createTestBundle();
        mTvRecordingClient.pauseRecording(bundle);
        PollingCheck.waitFor(TIME_OUT, () -> session.mPauseRecordingWithBundleCount > 0);

        assertThat(session.mPauseRecordingWithBundleCount).isEqualTo(1);

        mTvRecordingClient.resumeRecording(bundle);
        PollingCheck.waitFor(TIME_OUT, () -> session.mResumeRecordingWithBundleCount > 0);

        assertThat(session.mResumeRecordingWithBundleCount).isEqualTo(1);
        assertBundlesAreEqual(session.mResumeRecordingWithBundleData, bundle);

    }

    @Test
    public void verifyCommandPauseResumeRecording() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);
        mTvRecordingClient.startRecording(CHANNEL_0);

        mTvRecordingClient.pauseRecording();
        PollingCheck.waitFor(TIME_OUT, () -> session.mPauseRecordingWithBundleCount > 0);

        assertThat(session.mPauseRecordingWithBundleCount).isEqualTo(1);

        mTvRecordingClient.resumeRecording();
        PollingCheck.waitFor(TIME_OUT, () -> session.mResumeRecordingWithBundleCount > 0);

        assertThat(session.mPauseRecordingWithBundleCount).isEqualTo(1);
        assertBundlesAreEqual(session.mResumeRecordingWithBundleData, Bundle.EMPTY);
    }

    @Test
    public void verifyCommandStopRecording() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);
        mTvRecordingClient.startRecording(CHANNEL_0);

        mTvRecordingClient.stopRecording();
        PollingCheck.waitFor(TIME_OUT, () -> session.mStopRecordingCount > 0);

        assertThat(session.mStopRecordingCount).isEqualTo(1);
    }

    @Test
    public void verifyCommandSendAppPrivateCommandForRecording() {
        Bundle bundle = createTestBundle();
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        final String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";

        mTvRecordingClient.sendAppPrivateCommand(action, bundle);
        PollingCheck.waitFor(TIME_OUT, () -> session.mAppPrivateCommandCount > 0);

        assertThat(session.mAppPrivateCommandCount).isEqualTo(1);
        assertBundlesAreEqual(session.mAppPrivateCommandData, bundle);
        assertThat(session.mAppPrivateCommandAction).isEqualTo(action);
    }

    @Test
    public void verifyCallbackTuned() {
        tuneForRecording(CHANNEL_0);

        notifyTuned(CHANNEL_0);

        assertThat(mRecordingCallback.mTunedCount).isEqualTo(1);
        assertThat(mRecordingCallback.mTunedChannelUri).isEqualTo(CHANNEL_0);
    }


    @Test
    public void verifyCallbackError() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);
        mTvRecordingClient.startRecording(CHANNEL_0);
        final int error = TvInputManager.RECORDING_ERROR_UNKNOWN;

        session.notifyError(error);
        PollingCheck.waitFor(TIME_OUT, () -> mRecordingCallback.mErrorCount > 0);

        assertThat(mRecordingCallback.mErrorCount).isEqualTo(1);
        assertThat(mRecordingCallback.mError).isEqualTo(error);
    }

    @Test
    public void verifyCallbackRecordingStopped() {
        final CountingRecordingSession session = tuneForRecording(CHANNEL_0);
        notifyTuned(CHANNEL_0);
        mTvRecordingClient.startRecording(CHANNEL_0);

        session.notifyRecordingStopped(CHANNEL_0);
        PollingCheck.waitFor(TIME_OUT, () -> mRecordingCallback.mRecordingStoppedCount > 0);

        assertThat(mRecordingCallback.mRecordingStoppedCount).isEqualTo(1);
        assertThat(mRecordingCallback.mRecordedProgramUri).isEqualTo(CHANNEL_0);
    }

    @Test
    public void verifyCallbackConnectionFailed() {
        resetCounts();

        mTvRecordingClient.tune("invalid_input_id", CHANNEL_0);
        PollingCheck.waitFor(TIME_OUT, () -> mRecordingCallback.mConnectionFailedCount > 0);

        assertThat(mRecordingCallback.mConnectionFailedCount).isEqualTo(1);
    }

    @Test
    @Ignore("b/216866512")
    public void verifyCallbackDisconnected() {
        resetCounts();

        mTvRecordingClient.tune(mFaultyStubInfo.getId(), CHANNEL_0);

        PollingCheck.waitFor(TIME_OUT, () -> mRecordingCallback.mDisconnectedCount > 0);
    }

    @Test
    public void verifyCommandTune() {
        resetCounts();
        resetPassedValues();

        final CountingSession session = tune(CHANNEL_0);

        assertWithMessage("session").that(session).isNotNull();
        assertWithMessage("tvInputSessionId").that(session.mSessionId).isNotEmpty();
        assertWithMessage("mTuneCount").that(session.mTuneCount).isGreaterThan(0);
        assertWithMessage("mCreateOverlayView").that(session.mCreateOverlayView).isGreaterThan(0);
        assertWithMessage("mTunedChannelUri").that(session.mTunedChannelUri).isEqualTo(CHANNEL_0);
    }

    @Test
    public void verifyCommandTuneWithBundle() {
        Bundle bundle = createTestBundle();
        resetCounts();
        resetPassedValues();

        onTvView(tvView -> tvView.tune(mStubInfo.getId(), CHANNEL_0, bundle));
        final CountingSession session = waitForSessionCheck(s -> s.mTuneWithBundleCount > 0);

        assertThat(session.mTuneCount).isEqualTo(1);
        assertThat(session.mTuneWithBundleCount).isEqualTo(1);
        assertThat(session.mTunedChannelUri).isEqualTo(CHANNEL_0);
        assertBundlesAreEqual(session.mTuneWithBundleData, bundle);
    }

    @Test
    public void verifyCommandSetStreamVolume() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final float volume = 0.8f;

        onTvView(tvView -> tvView.setStreamVolume(volume));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mSetStreamVolumeCount > 0);

        assertThat(session.mSetStreamVolumeCount).isEqualTo(1);
        assertThat(session.mStreamVolume).isEqualTo(volume);
    }

    @Test
    public void verifyCommandSetCaptionEnabled() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final boolean enable = true;
        onTvView(tvView -> tvView.setCaptionEnabled(enable));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mSetCaptionEnabledCount > 0);
        assertThat(session.mSetCaptionEnabledCount).isEqualTo(1);
        assertThat(session.mCaptionEnabled).isEqualTo(enable);
    }

    @Test
    public void verifyCommandSelectTrack() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        verifyCallbackTracksChanged();
        final int dummyTrackType = TEST_TV_TRACK.getType();
        final String dummyTrackId = TEST_TV_TRACK.getId();

        onTvView(tvView -> tvView.selectTrack(dummyTrackType, dummyTrackId));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mSelectTrackCount > 0);

        assertThat(session.mSelectTrackCount).isEqualTo(1);
        assertThat(session.mSelectTrackType).isEqualTo(dummyTrackType);
        assertThat(session.mSelectTrackId).isEqualTo(dummyTrackId);
    }

    @Test
    public void verifyCommandDispatchKeyDown() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int keyCode = KeyEvent.KEYCODE_Q;
        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);

        onTvView(tvView -> tvView.dispatchKeyEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mKeyDownCount > 0);

        assertThat(session.mKeyDownCount).isEqualTo(1);
        assertThat(session.mKeyDownCode).isEqualTo(keyCode);
        assertKeyEventEquals(session.mKeyDownEvent, event);
    }

    @Test
    public void verifyCommandDispatchKeyMultiple() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int keyCode = KeyEvent.KEYCODE_Q;
        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_MULTIPLE, keyCode);

        onTvView(tvView -> tvView.dispatchKeyEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mKeyMultipleCount > 0);

        assertThat(session.mKeyMultipleCount).isEqualTo(1);
        assertKeyEventEquals(session.mKeyMultipleEvent, event);
        assertThat(session.mKeyMultipleNumber).isEqualTo(event.getRepeatCount());
    }

    @Test
    public void verifyCommandDispatchKeyUp() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int keyCode = KeyEvent.KEYCODE_Q;
        final KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, keyCode);

        onTvView(tvView -> tvView.dispatchKeyEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mKeyUpCount > 0);

        assertThat(session.mKeyUpCount).isEqualTo(1);
        assertThat(session.mKeyUpCode).isEqualTo(keyCode);
        assertKeyEventEquals(session.mKeyUpEvent, event);

    }

    @Test
    public void verifyCommandDispatchTouchEvent() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final long now = SystemClock.uptimeMillis();
        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
        event.setSource(InputDevice.SOURCE_TOUCHSCREEN);

        onTvView(tvView -> tvView.dispatchTouchEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTouchEventCount > 0);

        assertThat(session.mTouchEventCount).isEqualTo(1);
        assertMotionEventEquals(session.mTouchEvent, event);
    }

    @Test
    public void verifyCommandDispatchTrackballEvent() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final long now = SystemClock.uptimeMillis();
        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
        event.setSource(InputDevice.SOURCE_TRACKBALL);
        onTvView(tvView -> tvView.dispatchTouchEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTrackballEventCount > 0);

        assertThat(session.mTrackballEventCount).isEqualTo(1);
        assertMotionEventEquals(session.mTrackballEvent, event);
    }

    @Test
    public void verifyCommandDispatchGenericMotionEvent() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final long now = SystemClock.uptimeMillis();
        final MotionEvent event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, 1.0f, 1.0f,
                1.0f, 1.0f, 0, 1.0f, 1.0f, 0, 0);
        event.setSource(InputDevice.SOURCE_UNKNOWN);
        onTvView(tvView -> tvView.dispatchGenericMotionEvent(event));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mGenricMotionEventCount > 0);

        assertThat(session.mGenricMotionEventCount).isEqualTo(1);
        assertMotionEventEquals(session.mGenricMotionEvent, event);
    }

    @Test
    public void verifyCommandTimeShiftPause() {
        final CountingSession session = tune(CHANNEL_0);
        onTvView(tvView -> tvView.timeShiftPause());
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTimeShiftPauseCount > 0);

        assertThat(session.mTimeShiftPauseCount).isEqualTo(1);
    }

    @Test
    public void verifyCommandTimeShiftResume() {
        final CountingSession session = tune(CHANNEL_0);

        onTvView(tvView -> {
            tvView.timeShiftResume();
        });
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTimeShiftResumeCount > 0);

        assertThat(session.mTimeShiftResumeCount).isEqualTo(1);
    }

    @Test
    public void verifyCommandTimeShiftSeekTo() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final long timeMs = 0;

        onTvView(tvView -> tvView.timeShiftSeekTo(timeMs));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTimeShiftSeekToCount > 0);

        assertThat(session.mTimeShiftSeekToCount).isEqualTo(1);
        assertThat(session.mTimeShiftSeekTo).isEqualTo(timeMs);
    }

    @Test
    public void verifyCommandTimeShiftSetPlaybackParams() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final PlaybackParams param = new PlaybackParams().setSpeed(2.0f)
                .setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT);
        onTvView(tvView -> tvView.timeShiftSetPlaybackParams(param));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT,
                () -> session != null && session.mTimeShiftSetPlaybackParamsCount > 0);

        assertThat(session.mTimeShiftSetPlaybackParamsCount).isEqualTo(1);
        assertPlaybackParamsEquals(session.mTimeShiftSetPlaybackParams, param);
    }

    @Test
    public void verifyCommandTimeShiftPlay() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final Uri fakeRecordedProgramUri = TvContract.buildRecordedProgramUri(0);

        onTvView(tvView -> tvView.timeShiftPlay(mStubInfo.getId(), fakeRecordedProgramUri));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> session.mTimeShiftPlayCount > 0);

        assertThat(session.mTimeShiftPlayCount).isEqualTo(1);
        assertThat(session.mRecordedProgramUri).isEqualTo(fakeRecordedProgramUri);
    }

    @Test
    public void verifyCommandSetTimeShiftPositionCallback() {
        tune(CHANNEL_0);

        onTvView(tvView -> tvView.setTimeShiftPositionCallback(mTimeShiftPositionCallback));
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT,
                () -> mTimeShiftPositionCallback.mTimeShiftCurrentPositionChanged > 0
                        && mTimeShiftPositionCallback.mTimeShiftStartPositionChanged > 0);

        assertThat(mTimeShiftPositionCallback.mTimeShiftCurrentPositionChanged).isEqualTo(1);
        assertThat(mTimeShiftPositionCallback.mTimeShiftStartPositionChanged).isEqualTo(1);
    }

    @Test
    public void verifyCommandOverlayViewSizeChanged() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int width = 10;
        final int height = 20;

        // There is a first OverlayViewSizeChange called on initial tune.
        assertThat(session.mOverlayViewSizeChangedCount).isEqualTo(1);

        onTvView(tvView -> tvView.setLayoutParams(new LinearLayout.LayoutParams(width, height)));

        PollingCheck.waitFor(TIME_OUT, () -> session.mOverlayViewSizeChangedCount > 1);

        assertThat(session.mOverlayViewSizeChangedCount).isEqualTo(2);
        assertThat(session.mOverlayViewSizeChangedWidth).isEqualTo(width);
        assertThat(session.mOverlayViewSizeChangedHeight).isEqualTo(height);
    }

    @Test
    public void verifyCommandSendAppPrivateCommand() {
        Bundle bundle = createTestBundle();
        tune(CHANNEL_0);
        final String action = "android.media.tv.cts.TvInputServiceTest.privateCommand";

        onTvView(tvView -> tvView.sendAppPrivateCommand(action, bundle));
        mInstrumentation.waitForIdleSync();
        final CountingSession session = waitForSessionCheck(s -> s.mAppPrivateCommandCount > 0);

        assertThat(session.mAppPrivateCommandCount).isEqualTo(1);
        assertBundlesAreEqual(session.mAppPrivateCommandData, bundle);
        assertThat(session.mAppPrivateCommandAction).isEqualTo(action);
    }

    @Test
    public void verifyCommandSetInteractiveAppNotificationEnabled() {
        tune(CHANNEL_0);
        final String action =
                "android.media.tv.cts.TvInputServiceTest.setInteractiveAppNotificationEnabled";

        onTvView(tvView -> tvView.setInteractiveAppNotificationEnabled(true));
        mInstrumentation.waitForIdleSync();
        final CountingSession session =
                waitForSessionCheck(s -> s.mSetInteractiveAppNotificationEnabledCount > 0);

        assertThat(session.mSetInteractiveAppNotificationEnabledCount).isEqualTo(1);
        assertThat(session.mInteractiveAppNotificationEnabled).isEqualTo(true);
    }

    @Test
    public void verifyCallbackChannelRetuned() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();

        session.notifyChannelRetuned(CHANNEL_0);
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mChannelRetunedCount > 0);

        assertThat(mCallback.mChannelRetunedCount).isEqualTo(1);
        assertThat(mCallback.mChannelRetunedUri).isEqualTo(CHANNEL_0);

    }

    @Test
    public void verifyCallbackVideoAvailable() {
        final CountingSession session = tune(CHANNEL_0);
        resetCounts();

        session.notifyVideoAvailable();
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mVideoAvailableCount > 0);

        assertThat(mCallback.mVideoAvailableCount).isEqualTo(1);
    }

    @Test
    public void verifyCallbackVideoUnavailable() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int reason = TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING;

        session.notifyVideoUnavailable(reason);
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mVideoUnavailableCount > 0);

        assertThat(mCallback.mVideoUnavailableCount).isEqualTo(1);
        assertThat(mCallback.mVideoUnavailableReason).isEqualTo(reason);
    }

    @Test
    public void verifyCallbackTracksChanged() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        ArrayList<TvTrackInfo> tracks = new ArrayList<>();
        tracks.add(TEST_TV_TRACK);

        session.notifyTracksChanged(tracks);
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mTrackChangedCount > 0
                && Objects.equals(mCallback.mTracksChangedTrackList, tracks));

        assertThat(mCallback.mTrackChangedCount).isEqualTo(1);
        assertThat(mCallback.mTracksChangedTrackList).isEqualTo(tracks);
    }

    @Test
    @Ignore("b/174076887")
    public void verifyCallbackVideoSizeChanged() {
        final CountingSession session = tune(CHANNEL_0);
        resetCounts();
        ArrayList<TvTrackInfo> tracks = new ArrayList<>();
        tracks.add(TEST_TV_TRACK);

        session.notifyTracksChanged(tracks);
        mInstrumentation.waitForIdleSync();
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mVideoSizeChanged > 0);

        assertThat(mCallback.mVideoSizeChanged).isEqualTo(1);
    }

    @Test
    public void verifyCallbackTrackSelected() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();

        session.notifyTrackSelected(TEST_TV_TRACK.getType(), TEST_TV_TRACK.getId());
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mTrackSelectedCount > 0);

        assertThat(mCallback.mTrackSelectedCount).isEqualTo(1);
        assertThat(mCallback.mTrackSelectedType).isEqualTo(TEST_TV_TRACK.getType());
        assertThat(mCallback.mTrackSelectedTrackId).isEqualTo(TEST_TV_TRACK.getId());
    }

    @Test
    public void verifyCallbackContentAllowed() {
        final CountingSession session = tune(CHANNEL_0);
        resetCounts();

        session.notifyContentAllowed();
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mContentAllowedCount > 0);

        assertThat(mCallback.mContentAllowedCount).isEqualTo(1);
    }

    @Test
    public void verifyCallbackContentBlocked() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final TvContentRating rating = TvContentRating.createRating("android.media.tv", "US_TVPG",
                "US_TVPG_TV_MA", "US_TVPG_S", "US_TVPG_V");

        session.notifyContentBlocked(rating);
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mContentBlockedCount > 0);

        assertThat(mCallback.mContentBlockedCount).isEqualTo(1);
        assertThat(mCallback.mContentBlockedRating).isEqualTo(rating);

    }

    @Test
    public void verifyCallbackTimeShiftStatusChanged() {
        final CountingSession session = tune(CHANNEL_0);
        resetPassedValues();
        final int status = TvInputManager.TIME_SHIFT_STATUS_AVAILABLE;

        session.notifyTimeShiftStatusChanged(status);
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mTimeShiftStatusChangedCount > 0);

        assertThat(mCallback.mTimeShiftStatusChangedCount).isEqualTo(1);
        assertThat(mCallback.mTimeShiftStatusChangedStatus).isEqualTo(status);
    }

    @Test
    public void verifyCallbackAitInfoUpdated() {
        final CountingSession session = tune(CHANNEL_0);
        resetCounts();
        resetPassedValues();

        session.notifyAitInfoUpdated(
                new AitInfo(TvInteractiveAppServiceInfo.INTERACTIVE_APP_TYPE_HBBTV, 2));
        PollingCheck.waitFor(TIME_OUT, () -> mCallback.mAitInfoUpdatedCount > 0);

        assertThat(mCallback.mAitInfoUpdatedCount).isEqualTo(1);
        assertThat(mCallback.mAitInfo.getType())
                .isEqualTo(TvInteractiveAppServiceInfo.INTERACTIVE_APP_TYPE_HBBTV);
        assertThat(mCallback.mAitInfo.getVersion()).isEqualTo(2);
    }

    @Test
    public void verifyCallbackLayoutSurface() {
        final CountingSession session = tune(CHANNEL_0);
        final int left = 10;
        final int top = 20;
        final int right = 30;
        final int bottom = 40;

        session.layoutSurface(left, top, right, bottom);
        PollingCheck.waitFor(TIME_OUT, () -> {
            final AtomicBoolean retValue = new AtomicBoolean();
            onTvView(tvView -> {
                int childCount = tvView.getChildCount();
                for (int i = 0; i < childCount; ++i) {
                    View v = tvView.getChildAt(i);
                    if (v instanceof SurfaceView) {
                        retValue.set(v.getLeft() == left && v.getTop() == top
                                && v.getRight() == right
                                && v.getBottom() == bottom
                        );
                        break;
                    }
                }
            });
            mInstrumentation.waitForIdleSync();
            return retValue.get();
        });
    }

    public static void assertKeyEventEquals(KeyEvent actual, KeyEvent expected) {
        if ((expected == null) != (actual == null)) {
            // Fail miss matched nulls early using the StandardSubject
            Truth.assertThat(actual).isEqualTo(expected);
        } else if (expected != null && actual != null) {
            assertThat(actual.getDownTime()).isEqualTo(expected.getDownTime());
            assertThat(actual.getEventTime()).isEqualTo(expected.getEventTime());
            assertThat(actual.getAction()).isEqualTo(expected.getAction());
            assertThat(actual.getKeyCode()).isEqualTo(expected.getKeyCode());
            assertThat(actual.getRepeatCount()).isEqualTo(expected.getRepeatCount());
            assertThat(actual.getMetaState()).isEqualTo(expected.getMetaState());
            assertThat(actual.getDeviceId()).isEqualTo(expected.getDeviceId());
            assertThat(actual.getScanCode()).isEqualTo(expected.getScanCode());
            assertThat(actual.getFlags()).isEqualTo(expected.getFlags());
            assertThat(actual.getSource()).isEqualTo(expected.getSource());
            assertThat(actual.getCharacters()).isEqualTo(expected.getCharacters());
        }// else both null so do nothing
    }

    public static void assertMotionEventEquals(MotionEvent actual, MotionEvent expected) {
        if ((expected == null) != (actual == null)) {
            // Fail miss matched nulls early using the StandardSubject
            Truth.assertThat(actual).isEqualTo(expected);
        } else if (expected != null && actual != null) {
            assertThat(actual).hasDownTime(expected.getDownTime());
            assertThat(actual).hasEventTime(expected.getEventTime());
            assertThat(actual).hasAction(expected.getAction());
            assertThat(actual).x().isEqualTo(expected.getX());
            assertThat(actual).y().isEqualTo(expected.getY());
            assertThat(actual).pressure().isEqualTo(expected.getPressure());
            assertThat(actual).size().isEqualTo(expected.getSize());
            assertThat(actual).hasMetaState(expected.getMetaState());
            assertThat(actual).xPrecision().isEqualTo(expected.getXPrecision());
            assertThat(actual).yPrecision().isEqualTo(expected.getYPrecision());
            assertThat(actual).hasDeviceId(expected.getDeviceId());
            assertThat(actual).hasEdgeFlags(expected.getEdgeFlags());
            assertThat(actual.getSource()).isEqualTo(expected.getSource());

        } // else both null so do nothing
    }

    public static void assertPlaybackParamsEquals(PlaybackParams actual, PlaybackParams expected) {
        if ((expected == null) != (actual == null)) {
            // Fail miss matched nulls early using the StandardSubject
            Truth.assertThat(actual).isEqualTo(expected);
        } else if (expected != null && actual != null) {
            assertThat(actual.getAudioFallbackMode()).isEqualTo(expected.getAudioFallbackMode());
            assertThat(actual.getSpeed()).isEqualTo(expected.getSpeed());
        } // else both null so do nothing
    }

    private static void assertBundlesAreEqual(Bundle actual, Bundle expected) {
        if ((expected == null) != (actual == null)) {
            // Fail miss matched nulls early using the StandardSubject
            Truth.assertThat(actual).isEqualTo(expected);
        } else if (expected != null && actual != null) {
            assertThat(actual.keySet()).isEqualTo(expected.keySet());
            for (String key : expected.keySet()) {
                assertThat(actual.get(key)).isEqualTo(expected.get(key));
            }
        }
    }

    private void notifyTuned(Uri uri) {
        final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
        session.notifyTuned(uri);
        PollingCheck.waitFor(TIME_OUT, () -> mRecordingCallback.mTunedCount > 0);
    }

    private void onTvView(Consumer<TvView> tvViewConsumer) {
        activityRule.getScenario().onActivity(viewAction(tvViewConsumer));

    }

    private void resetCounts() {
        if (CountingTvInputService.sSession != null) {
            CountingTvInputService.sSession.resetCounts();
        }
        if (CountingTvInputService.sRecordingSession != null) {
            CountingTvInputService.sRecordingSession.resetCounts();
        }
        mCallback.resetCounts();
        mTimeShiftPositionCallback.resetCounts();
        mRecordingCallback.resetCounts();
    }

    private void resetPassedValues() {
        if (CountingTvInputService.sSession != null) {
            CountingTvInputService.sSession.resetPassedValues();
        }
        if (CountingTvInputService.sRecordingSession != null) {
            CountingTvInputService.sRecordingSession.resetPassedValues();
        }
        mCallback.resetPassedValues();
        mRecordingCallback.resetPassedValues();
    }

    @NonNull
    private static PollingCheck.PollingCheckCondition recordingSessionCheck(
            ToBooleanFunction<CountingRecordingSession> toBooleanFunction) {
        return () -> {
            final CountingRecordingSession session = CountingTvInputService.sRecordingSession;
            return session != null && toBooleanFunction.apply(session);
        };
    }

    @NonNull
    private static PollingCheck.PollingCheckCondition sessionCheck(
            ToBooleanFunction<CountingSession> toBooleanFunction) {
        return () -> {
            final CountingSession session = CountingTvInputService.sSession;
            return session != null && toBooleanFunction.apply(session);
        };
    }

    @NonNull
    private CountingSession tune(Uri uri) {
        onTvView(tvView -> {
            tvView.setCallback(mCallback);
            tvView.overrideTvAppAttributionSource(mContext.getAttributionSource());
            tvView.tune(mStubInfo.getId(), CHANNEL_0);
        });
        return waitForSessionCheck(session -> session.mTuneCount > 0);
    }

    @NonNull
    private CountingRecordingSession tuneForRecording(Uri uri) {
        mTvRecordingClient.tune(mStubInfo.getId(), uri);
        return waitForRecordingSessionCheck(s -> s.mTuneCount > 0);
    }

    @NonNull
    private CountingRecordingSession tuneForRecording(Uri uri, Bundle bundle) {
        mTvRecordingClient.tune(mStubInfo.getId(), uri, bundle);
        return waitForRecordingSessionCheck(s -> s.mTuneCount > 0 && s.mTuneWithBundleCount > 0);
    }

    @NonNull
    private static ActivityScenario.ActivityAction<TvViewStubActivity> viewAction(
            Consumer<TvView> consumer) {
        return activity -> consumer.accept(activity.getTvView());
    }

    @NonNull
    private static CountingSession waitForSessionCheck(
            ToBooleanFunction<CountingSession> countingSessionToBooleanFunction) {
        PollingCheck.waitFor(TIME_OUT, sessionCheck(countingSessionToBooleanFunction));
        return CountingTvInputService.sSession;
    }

    @NonNull
    private static CountingRecordingSession waitForRecordingSessionCheck(
            ToBooleanFunction<CountingRecordingSession> toBool) {
        PollingCheck.waitFor(TIME_OUT, recordingSessionCheck(toBool));
        return CountingTvInputService.sRecordingSession;
    }

    public static class CountingTvInputService extends StubTvInputService {

        static CountingSession sSession;
        static CountingRecordingSession sRecordingSession;

        @Override
        public Session onCreateSession(String inputId) {
            return onCreateSession(inputId, null);
        }

        @Override
        public Session onCreateSession(String inputId, String tvInputSessionId) {
            if(sSession != null){
                Log.w(TAG,"onCreateSession called with sSession set to "+ sSession);
            }
            sSession = new CountingSession(this, tvInputSessionId);
            sSession.setOverlayViewEnabled(true);
            return sSession;
        }

        @Override
        public Session onCreateSession(
                String inputId, String tvInputSessionId, AttributionSource tvAppAttributionSource) {
            // todo: add AttributionSource equal check
            return onCreateSession(inputId, tvInputSessionId);
        }

        @Override
        public RecordingSession onCreateRecordingSession(String inputId) {
            return onCreateRecordingSession(inputId, null);
        }

        @Override
        public RecordingSession onCreateRecordingSession(String inputId, String tvInputSessionId) {
            if (sRecordingSession != null) {
                Log.w(TAG, "onCreateRecordingSession called with sRecordingSession set to "
                        + sRecordingSession);
            }
            sRecordingSession = new CountingRecordingSession(this, tvInputSessionId);
            return sRecordingSession;
        }

        @Override
        public IBinder createExtension() {
            super.createExtension();
            return null;
        }

        public static class CountingSession extends Session {
            public final String mSessionId;

            public volatile int mTuneCount;
            public volatile int mTuneWithBundleCount;
            public volatile int mSetStreamVolumeCount;
            public volatile int mSetCaptionEnabledCount;
            public volatile int mSelectTrackCount;
            public volatile int mCreateOverlayView;
            public volatile int mKeyDownCount;
            public volatile int mKeyLongPressCount;
            public volatile int mKeyMultipleCount;
            public volatile int mKeyUpCount;
            public volatile int mTouchEventCount;
            public volatile int mTrackballEventCount;
            public volatile int mGenricMotionEventCount;
            public volatile int mOverlayViewSizeChangedCount;
            public volatile int mTimeShiftPauseCount;
            public volatile int mTimeShiftResumeCount;
            public volatile int mTimeShiftSeekToCount;
            public volatile int mTimeShiftSetPlaybackParamsCount;
            public volatile int mTimeShiftPlayCount;
            public volatile long mTimeShiftGetCurrentPositionCount;
            public volatile long mTimeShiftGetStartPositionCount;
            public volatile int mAppPrivateCommandCount;
            public volatile int mSetInteractiveAppNotificationEnabledCount;

            public volatile String mAppPrivateCommandAction;
            public volatile Bundle mAppPrivateCommandData;
            public volatile Uri mTunedChannelUri;
            public volatile Bundle mTuneWithBundleData;
            public volatile Float mStreamVolume;
            public volatile Boolean mCaptionEnabled;
            public volatile Integer mSelectTrackType;
            public volatile String mSelectTrackId;
            public volatile Integer mKeyDownCode;
            public volatile KeyEvent mKeyDownEvent;
            public volatile Integer mKeyLongPressCode;
            public volatile KeyEvent mKeyLongPressEvent;
            public volatile Integer mKeyMultipleCode;
            public volatile Integer mKeyMultipleNumber;
            public volatile KeyEvent mKeyMultipleEvent;
            public volatile Integer mKeyUpCode;
            public volatile KeyEvent mKeyUpEvent;
            public volatile MotionEvent mTouchEvent;
            public volatile MotionEvent mTrackballEvent;
            public volatile MotionEvent mGenricMotionEvent;
            public volatile Long mTimeShiftSeekTo;
            public volatile PlaybackParams mTimeShiftSetPlaybackParams;
            public volatile Uri mRecordedProgramUri;
            public volatile Integer mOverlayViewSizeChangedWidth;
            public volatile Integer mOverlayViewSizeChangedHeight;
            public volatile Boolean mInteractiveAppNotificationEnabled;

            CountingSession(Context context, @Nullable String sessionId) {

                super(context);
                mSessionId = sessionId;

            }

            public void resetCounts() {
                mTuneCount = 0;
                mTuneWithBundleCount = 0;
                mSetStreamVolumeCount = 0;
                mSetCaptionEnabledCount = 0;
                mSelectTrackCount = 0;
                mCreateOverlayView = 0;
                mKeyDownCount = 0;
                mKeyLongPressCount = 0;
                mKeyMultipleCount = 0;
                mKeyUpCount = 0;
                mTouchEventCount = 0;
                mTrackballEventCount = 0;
                mGenricMotionEventCount = 0;
                mOverlayViewSizeChangedCount = 0;
                mTimeShiftPauseCount = 0;
                mTimeShiftResumeCount = 0;
                mTimeShiftSeekToCount = 0;
                mTimeShiftSetPlaybackParamsCount = 0;
                mTimeShiftPlayCount = 0;
                mTimeShiftGetCurrentPositionCount = 0;
                mTimeShiftGetStartPositionCount = 0;
                mAppPrivateCommandCount = 0;
                mSetInteractiveAppNotificationEnabledCount = 0;
            }

            public void resetPassedValues() {
                mAppPrivateCommandAction = null;
                mAppPrivateCommandData = null;
                mTunedChannelUri = null;
                mTuneWithBundleData = null;
                mStreamVolume = null;
                mCaptionEnabled = null;
                mSelectTrackType = null;
                mSelectTrackId = null;
                mKeyDownCode = null;
                mKeyDownEvent = null;
                mKeyLongPressCode = null;
                mKeyLongPressEvent = null;
                mKeyMultipleCode = null;
                mKeyMultipleNumber = null;
                mKeyMultipleEvent = null;
                mKeyUpCode = null;
                mKeyUpEvent = null;
                mTouchEvent = null;
                mTrackballEvent = null;
                mGenricMotionEvent = null;
                mTimeShiftSeekTo = null;
                mTimeShiftSetPlaybackParams = null;
                mRecordedProgramUri = null;
                mOverlayViewSizeChangedWidth = null;
                mOverlayViewSizeChangedHeight = null;
                mInteractiveAppNotificationEnabled = null;
            }

            @Override
            public void onAppPrivateCommand(String action, Bundle data) {
                mAppPrivateCommandCount++;
                mAppPrivateCommandAction = action;
                mAppPrivateCommandData = data;
            }

            @Override
            public void onRelease() {
            }

            @Override
            public boolean onSetSurface(Surface surface) {
                return false;
            }

            @Override
            public boolean onTune(Uri channelUri) {
                mTuneCount++;
                mTunedChannelUri = channelUri;
                return false;
            }

            @Override
            public boolean onTune(Uri channelUri, Bundle data) {
                mTuneWithBundleCount++;
                mTuneWithBundleData = data;
                // Also calls {@link #onTune(Uri)} since it will never be called if the
                // implementation overrides {@link #onTune(Uri, Bundle)}.
                onTune(channelUri);
                return false;
            }

            @Override
            public void onSetStreamVolume(float volume) {
                mSetStreamVolumeCount++;
                mStreamVolume = volume;
            }

            @Override
            public void onSetCaptionEnabled(boolean enabled) {
                mSetCaptionEnabledCount++;
                mCaptionEnabled = enabled;
            }

            @Override
            public boolean onSelectTrack(int type, String id) {
                mSelectTrackCount++;
                mSelectTrackType = type;
                mSelectTrackId = id;
                return false;
            }

            @Override
            public View onCreateOverlayView() {
                mCreateOverlayView++;
                return null;
            }

            @Override
            public boolean onKeyDown(int keyCode, KeyEvent event) {
                mKeyDownCount++;
                mKeyDownCode = keyCode;
                mKeyDownEvent = event;
                return false;
            }

            @Override
            public boolean onKeyLongPress(int keyCode, KeyEvent event) {
                mKeyLongPressCount++;
                mKeyLongPressCode = keyCode;
                mKeyLongPressEvent = event;
                return false;
            }

            @Override
            public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
                mKeyMultipleCount++;
                mKeyMultipleCode = keyCode;
                mKeyMultipleNumber = count;
                mKeyMultipleEvent = event;
                return false;
            }

            @Override
            public boolean onKeyUp(int keyCode, KeyEvent event) {
                mKeyUpCount++;
                mKeyUpCode = keyCode;
                mKeyUpEvent = event;
                return false;
            }

            @Override
            public boolean onTouchEvent(MotionEvent event) {
                mTouchEventCount++;
                mTouchEvent = event;
                return false;
            }

            @Override
            public boolean onTrackballEvent(MotionEvent event) {
                mTrackballEventCount++;
                mTrackballEvent = event;
                return false;
            }

            @Override
            public boolean onGenericMotionEvent(MotionEvent event) {
                mGenricMotionEventCount++;
                mGenricMotionEvent = event;
                return false;
            }

            @Override
            public void onTimeShiftPause() {
                mTimeShiftPauseCount++;
            }

            @Override
            public void onTimeShiftResume() {
                mTimeShiftResumeCount++;
            }

            @Override
            public void onTimeShiftSeekTo(long timeMs) {
                mTimeShiftSeekToCount++;
                mTimeShiftSeekTo = timeMs;
            }

            @Override
            public void onTimeShiftSetPlaybackParams(PlaybackParams param) {
                mTimeShiftSetPlaybackParamsCount++;
                mTimeShiftSetPlaybackParams = param;
            }

            @Override
            public void onTimeShiftPlay(Uri recordedProgramUri) {
                mTimeShiftPlayCount++;
                mRecordedProgramUri = recordedProgramUri;
            }

            @Override
            public long onTimeShiftGetCurrentPosition() {
                return ++mTimeShiftGetCurrentPositionCount;
            }

            @Override
            public long onTimeShiftGetStartPosition() {
                return ++mTimeShiftGetStartPositionCount;
            }

            @Override
            public void onOverlayViewSizeChanged(int width, int height) {
                mOverlayViewSizeChangedCount++;
                mOverlayViewSizeChangedWidth = width;
                mOverlayViewSizeChangedHeight = height;
            }

            @Override
            public void onSetInteractiveAppNotificationEnabled(boolean enabled) {
                mSetInteractiveAppNotificationEnabledCount++;
                mInteractiveAppNotificationEnabled = enabled;
            }
        }

        public static class CountingRecordingSession extends RecordingSession {
            public final String mSessionId;

            public volatile int mTuneCount;
            public volatile int mTuneWithBundleCount;
            public volatile int mReleaseCount;
            public volatile int mStartRecordingCount;
            public volatile int mStartRecordingWithBundleCount;
            public volatile int mPauseRecordingWithBundleCount;
            public volatile int mResumeRecordingWithBundleCount;
            public volatile int mStopRecordingCount;
            public volatile int mAppPrivateCommandCount;

            public volatile Uri mTunedChannelUri;
            public volatile Bundle mTuneWithBundleData;
            public volatile Uri mProgramHint;
            public volatile Bundle mStartRecordingWithBundleData;
            public volatile Bundle mPauseRecordingWithBundleData;
            public volatile Bundle mResumeRecordingWithBundleData;
            public volatile String mAppPrivateCommandAction;
            public volatile Bundle mAppPrivateCommandData;

            CountingRecordingSession(Context context, @Nullable String sessionId) {
                super(context);
                mSessionId = sessionId;
            }

            public void resetCounts() {
                mTuneCount = 0;
                mTuneWithBundleCount = 0;
                mReleaseCount = 0;
                mStartRecordingCount = 0;
                mStartRecordingWithBundleCount = 0;
                mPauseRecordingWithBundleCount = 0;
                mResumeRecordingWithBundleCount = 0;
                mStopRecordingCount = 0;
                mAppPrivateCommandCount = 0;
            }

            public void resetPassedValues() {
                mTunedChannelUri = null;
                mTuneWithBundleData = null;
                mProgramHint = null;
                mStartRecordingWithBundleData = null;
                mPauseRecordingWithBundleData = null;
                mResumeRecordingWithBundleData = null;
                mAppPrivateCommandAction = null;
                mAppPrivateCommandData = null;
            }

            @Override
            public void onTune(Uri channelUri) {
                mTuneCount++;
                mTunedChannelUri = channelUri;
            }

            @Override
            public void onTune(Uri channelUri, Bundle data) {
                mTuneWithBundleCount++;
                mTuneWithBundleData = data;
                // Also calls {@link #onTune(Uri)} since it will never be called if the
                // implementation overrides {@link #onTune(Uri, Bundle)}.
                onTune(channelUri);
            }

            @Override
            public void onRelease() {
                mReleaseCount++;
            }

            @Override
            public void onStartRecording(Uri programHint) {
                mStartRecordingCount++;
                mProgramHint = programHint;
            }

            @Override
            public void onStartRecording(Uri programHint, Bundle data) {
                mStartRecordingWithBundleCount++;
                mProgramHint = programHint;
                mStartRecordingWithBundleData = data;
                // Also calls {@link #onStartRecording(Uri)} since it will never be called if the
                // implementation overrides {@link #onStartRecording(Uri, Bundle)}.
                onStartRecording(programHint);
            }

            @Override
            public void onPauseRecording(Bundle data) {
                mPauseRecordingWithBundleCount++;
                mPauseRecordingWithBundleData = data;
            }

            @Override
            public void onResumeRecording(Bundle data) {
                mResumeRecordingWithBundleCount++;
                mResumeRecordingWithBundleData = data;

            }

            @Override
            public void onStopRecording() {
                mStopRecordingCount++;
            }

            @Override
            public void onAppPrivateCommand(String action, Bundle data) {
                mAppPrivateCommandCount++;
                mAppPrivateCommandAction = action;
                mAppPrivateCommandData = data;
            }
        }
    }

    private static class StubRecordingCallback extends TvRecordingClient.RecordingCallback {
        private int mTunedCount;
        private int mRecordingStoppedCount;
        private int mErrorCount;
        private int mConnectionFailedCount;
        private int mDisconnectedCount;

        private Uri mTunedChannelUri;
        private Uri mRecordedProgramUri;
        private Integer mError;

        @Override
        public void onTuned(Uri channelUri) {
            mTunedCount++;
            mTunedChannelUri = channelUri;
        }

        @Override
        public void onRecordingStopped(Uri recordedProgramUri) {
            mRecordingStoppedCount++;
            mRecordedProgramUri = recordedProgramUri;
        }

        @Override
        public void onError(int error) {
            mErrorCount++;
            mError = error;
        }

        @Override
        public void onConnectionFailed(String inputId) {
            mConnectionFailedCount++;
        }

        @Override
        public void onDisconnected(String inputId) {
            mDisconnectedCount++;
        }

        public void resetCounts() {
            mTunedCount = 0;
            mRecordingStoppedCount = 0;
            mErrorCount = 0;
            mConnectionFailedCount = 0;
            mDisconnectedCount = 0;
        }

        public void resetPassedValues() {
            mTunedChannelUri = null;
            mRecordedProgramUri = null;
            mError = null;
        }
    }


    // Copied from {@link com.android.internal.util.ToBooleanFunction}
    /**
     * Represents a function that produces an boolean-valued result.  This is the
     * {@code boolean}-producing primitive specialization for {@link Function}.
     *
     * <p>This is a <a href="package-summary.html">functional interface</a>
     * whose functional method is {@link #apply(Object)}.
     *
     * @param <T> the type of the input to the function
     *
     * @see Function
     */
    @FunctionalInterface
    private  interface ToBooleanFunction<T> {

        /**
         * Applies this function to the given argument.
         *
         * @param value the function argument
         * @return the function result
         */
        boolean apply(T value);
    }

}
