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

import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.Nullable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A callback class for use when the application is in a group call. The middleware
 * will provide updates on the status of the call via this callback.
 */
public interface GroupCallCallback {
    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(value = {
            MbmsErrors.ERROR_NO_UNIQUE_MIDDLEWARE,
            MbmsErrors.ERROR_MIDDLEWARE_LOST,
            MbmsErrors.ERROR_MIDDLEWARE_NOT_BOUND,
            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_NOT_YET_READY,
            MbmsErrors.GeneralErrors.ERROR_OUT_OF_MEMORY,
            MbmsErrors.GeneralErrors.ERROR_MIDDLEWARE_TEMPORARILY_UNAVAILABLE,
            MbmsErrors.GeneralErrors.ERROR_IN_E911,
            MbmsErrors.GeneralErrors.ERROR_NOT_CONNECTED_TO_HOME_CARRIER_LTE,
            MbmsErrors.GeneralErrors.ERROR_UNABLE_TO_READ_SIM,
            MbmsErrors.GeneralErrors.ERROR_CARRIER_CHANGE_NOT_ALLOWED}, prefix = { "ERROR_" })
    @interface GroupCallError{}

    /**
     * Indicates broadcast signal strength is not available for this call.
     *
     * This may be due to the call no longer being available due to geography
     * or timing (end of service)
     */
    int SIGNAL_STRENGTH_UNAVAILABLE = -1;

    /**
     * Called by the middleware when it has detected an error condition in this group call. The
     * possible error codes are listed in {@link MbmsErrors}.
     * @param errorCode The error code.
     * @param message A human-readable message generated by the middleware for debugging purposes.
     */
    default void onError(@GroupCallError int errorCode, @Nullable String message) {}

    /**
     * Called to indicate this call has changed state.
     *
     * See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED}
     * and {@link GroupCall#STATE_STALLED}.
     */
    default void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
            @GroupCall.GroupCallStateChangeReason int reason) {}

    /**
     * Broadcast Signal Strength updated.
     *
     * This signal strength is the BROADCAST signal strength which,
     * depending on technology in play and it's deployment, may be
     * stronger or weaker than the traditional UNICAST signal
     * strength.  It a simple int from 0-4 for valid levels or
     * {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
     * for this call due to timing, geography or popularity.
     */
    default void onBroadcastSignalStrengthUpdated(
            @IntRange(from = -1, to = 4) int signalStrength) {}
}
