/*
 * 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.view;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * This class contains window content frame statistics. For example, a window content
 * is rendred in frames when a view is scrolled. The frame statistics are a snapshot
 * for the time interval from {@link #getStartTimeNano()} to {@link #getEndTimeNano()}.
 * <p>
 * The key idea is that in order to provide a smooth user experience an application
 * has to draw a frame at a specific time interval obtained by calling {@link
 * #getRefreshPeriodNano()}. If the application does not render a frame every refresh
 * period the user will see irregular UI transitions.
 * </p>
 * <p>
 * An application posts a frame for presentation by synchronously rendering its contents
 * in a buffer which is then posted or posting a buffer to which the application is
 * asychronously rendering the content via GL. After the frame is posted and rendered
 * (potentially asynchronosly) it is presented to the user. The time a frame was posted
 * can be obtained via {@link #getFramePostedTimeNano(int)}, the time a frame content
 * was rendered and ready for dsiplay (GL case) via {@link #getFrameReadyTimeNano(int)},
 * and the time a frame was presented on the screen via {@link #getFramePresentedTimeNano(int)}.
 * </p>
 */
public final class WindowContentFrameStats extends FrameStats implements Parcelable {
    private long[] mFramesPostedTimeNano;
    private long[] mFramesReadyTimeNano;

    /**
     * @hide
     */
    public WindowContentFrameStats() {
        /* do nothing */
    }

    /**
     * Initializes this isntance.
     *
     * @param refreshPeriodNano The display refresh period.
     * @param framesPostedTimeNano The times in milliseconds for when the frame contents were posted.
     * @param framesPresentedTimeNano The times in milliseconds for when the frame contents were presented.
     * @param framesReadyTimeNano The times in milliseconds for when the frame contents were ready to be presented.
     *
     * @hide
     */
    public void init(long refreshPeriodNano, long[] framesPostedTimeNano,
            long[] framesPresentedTimeNano, long[] framesReadyTimeNano) {
        mRefreshPeriodNano = refreshPeriodNano;
        mFramesPostedTimeNano = framesPostedTimeNano;
        mFramesPresentedTimeNano = framesPresentedTimeNano;
        mFramesReadyTimeNano = framesReadyTimeNano;
    }

    private WindowContentFrameStats(Parcel parcel) {
        mRefreshPeriodNano = parcel.readLong();
        mFramesPostedTimeNano = parcel.createLongArray();
        mFramesPresentedTimeNano = parcel.createLongArray();
        mFramesReadyTimeNano = parcel.createLongArray();
    }

    /**
     * Get the time a frame at a given index was posted by the producer (e.g. the application).
     * It is either explicitly set or defaulted to the time when the render buffer was posted.
     * <p>
     * <strong>Note:</strong> A frame can be posted and still it contents being rendered
     * asynchronously in GL. To get the time the frame content was completely rendered and
     * ready to display call {@link #getFrameReadyTimeNano(int)}.
     * </p>
     *
     * @param index The frame index.
     * @return The posted time in nanoseconds.
     */
    public long getFramePostedTimeNano(int index) {
        if (mFramesPostedTimeNano == null) {
            throw new IndexOutOfBoundsException();
        }
        return mFramesPostedTimeNano[index];
    }

    /**
     * Get the time a frame at a given index was ready for presentation.
     * <p>
     * <strong>Note:</strong> A frame can be posted and still it contents being rendered
     * asynchronously in GL. In such a case this is the time when the frame contents were
     * completely rendered.
     * </p>
     *
     * @param index The frame index.
     * @return The ready time in nanoseconds or {@link #UNDEFINED_TIME_NANO}
     *         if the frame is not ready yet.
     */
    public long getFrameReadyTimeNano(int index) {
        if (mFramesReadyTimeNano == null) {
            throw new IndexOutOfBoundsException();
        }
        return mFramesReadyTimeNano[index];
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeLong(mRefreshPeriodNano);
        parcel.writeLongArray(mFramesPostedTimeNano);
        parcel.writeLongArray(mFramesPresentedTimeNano);
        parcel.writeLongArray(mFramesReadyTimeNano);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("WindowContentFrameStats[");
        builder.append("frameCount:" + getFrameCount());
        builder.append(", fromTimeNano:" + getStartTimeNano());
        builder.append(", toTimeNano:" + getEndTimeNano());
        builder.append(']');
        return builder.toString();
    }

    public static final Parcelable.Creator<WindowContentFrameStats> CREATOR =
            new Creator<WindowContentFrameStats>() {
                @Override
                public WindowContentFrameStats createFromParcel(Parcel parcel) {
                    return new WindowContentFrameStats(parcel);
                }

                @Override
                public WindowContentFrameStats[] newArray(int size) {
                    return new WindowContentFrameStats[size];
                }
            };
}
