/*
 * Copyright (C) 2018 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.app;

import android.content.Context;
import android.content.Intent;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.perftests.utils.StubActivity;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;

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

// Due to b/71353150, you might get "java.lang.AssertionError: Binder ProxyMap has too many
// entries", but it's flaky. Adding "Runtime.getRuntime().gc()" between each iteration solves
// the problem, but it doesn't seem like it's currently needed.
@RunWith(AndroidJUnit4.class)
@LargeTest
public class PendingIntentPerfTest {

    private Context mContext;

    @Rule
    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();

    private Intent mIntent;

    @Before
    public void setUp() {
        mContext = InstrumentationRegistry.getTargetContext();
        mIntent = StubActivity.createLaunchIntent(mContext);
    }

    /**
     * Benchmark time to create a PendingIntent.
     */
    @Test
    public void create() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            state.pauseTiming();
            state.resumeTiming();

            final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
                    0);

            state.pauseTiming();
            pendingIntent.cancel();
            state.resumeTiming();
        }
    }

    /**
     * Benchmark time to create a PendingIntent with FLAG_CANCEL_CURRENT, already having an active
     * PendingIntent.
     */
    @Test
    public void createWithCancelFlag() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            state.pauseTiming();
            final PendingIntent previousPendingIntent = PendingIntent.getActivity(mContext, 0,
                    mIntent, 0);
            state.resumeTiming();

            final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
                    PendingIntent.FLAG_CANCEL_CURRENT);

            state.pauseTiming();
            pendingIntent.cancel();
            state.resumeTiming();
        }
    }

    /**
     * Benchmark time to create a PendingIntent with FLAG_UPDATE_CURRENT, already having an active
     * PendingIntent.
     */
    @Test
    public void createWithUpdateFlag() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            state.pauseTiming();
            final PendingIntent previousPendingIntent = PendingIntent.getActivity(mContext, 0,
                    mIntent, 0);
            state.resumeTiming();

            final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, mIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            state.pauseTiming();
            previousPendingIntent.cancel();
            pendingIntent.cancel();
            state.resumeTiming();
        }
    }

    /**
     * Benchmark time to cancel a PendingIntent.
     */
    @Test
    public void cancel() {
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        while (state.keepRunning()) {
            state.pauseTiming();
            final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
                    mIntent, 0);
            state.resumeTiming();

            pendingIntent.cancel();
        }
    }
}

