/*
 * Copyright (C) 2013 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.hardware.camera2;

import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraOfflineSession;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.utils.SubmitInfo;
import android.view.Surface;

/** @hide */
interface ICameraDeviceUser
{
    void disconnect();

    const int NO_IN_FLIGHT_REPEATING_FRAMES = -1;

    SubmitInfo submitRequest(in CaptureRequest request, boolean streaming);
    SubmitInfo submitRequestList(in CaptureRequest[] requestList, boolean streaming);

    /**
     * Cancel the repeating request specified by requestId
     * Returns the frame number of the last frame that will be produced from this
     * repeating request, or NO_IN_FLIGHT_REPEATING_FRAMES if no frames were produced
     * by this repeating request.
     *
     * Repeating request may be stopped by camera device due to an error. Canceling a stopped
     * repeating request will trigger ERROR_ILLEGAL_ARGUMENT.
     */
    long cancelRequest(int requestId);

    /**
     * Begin the device configuration.
     *
     * <p>
     * beginConfigure must be called before any call to deleteStream, createStream,
     * or endConfigure.  It is not valid to call this when the device is not idle.
     * <p>
     */
    void beginConfigure();

    /**
     * The standard operating mode for a camera device; all API guarantees are in force
     */
    const int NORMAL_MODE = 0;

    /**
     * High-speed recording mode; only two outputs targeting preview and video recording may be
     * used, and requests must be batched.
     */
    const int CONSTRAINED_HIGH_SPEED_MODE = 1;

    /**
     * Start of custom vendor modes
     */
    const int VENDOR_MODE_START = 0x8000;

    /**
     * End the device configuration.
     *
     * <p>
     * endConfigure must be called after stream configuration is complete (i.e. after
     * a call to beginConfigure and subsequent createStream/deleteStream calls).  This
     * must be called before any requests can be submitted.
     * <p>
     * @param operatingMode The kind of session to create; either NORMAL_MODE or
     *     CONSTRAINED_HIGH_SPEED_MODE. Must be a non-negative value.
     * @param sessionParams Session wide camera parameters
     * @param startTimeMs The timestamp of session creation start, measured by
     *                    SystemClock.uptimeMillis.
     * @return a list of stream ids that can be used in offline mode via "switchToOffline"
     */
    int[] endConfigure(int operatingMode, in CameraMetadataNative sessionParams, long startTimeMs);

    /**
      * Check whether a particular session configuration has camera device
      * support.
      *
      * @param sessionConfiguration Specific session configuration to be verified.
      * @return true  - in case the stream combination is supported.
      *         false - in case there is no device support.
      */
    boolean isSessionConfigurationSupported(in SessionConfiguration sessionConfiguration);

    /**
     * Get the camera characteristics for a particular session configuration
     *
     * @param sessionConfiguration Specific session configuration for which the characteristics
     * are fetched.
     * @return - characteristics associated with the given session.
     */
    CameraMetadataNative getSessionCharacteristics(in SessionConfiguration sessionConfiguration);

    void deleteStream(int streamId);

    /**
     * Create an output stream
     *
     * <p>Create an output stream based on the given output configuration</p>
     *
     * @param outputConfiguration size, format, and other parameters for the stream
     * @return new stream ID
     */
    int createStream(in OutputConfiguration outputConfiguration);

    /**
     * Create an input stream
     *
     * <p>Create an input stream of width, height, and format</p>
     *
     * @param width Width of the input buffers
     * @param height Height of the input buffers
     * @param format Format of the input buffers. One of HAL_PIXEL_FORMAT_*.
     * @param isMultiResolution Whether the input stream supports variable resolution image.
     *
     * @return new stream ID
     */
    int createInputStream(int width, int height, int format, boolean isMultiResolution);

    /**
     * Get the surface of the input stream.
     *
     * <p>It's valid to call this method only after a stream configuration is completed
     * successfully and the stream configuration includes a input stream.</p>
     *
     * @param surface An output argument for the surface of the input stream buffer queue.
     */
    Surface getInputSurface();

    // Keep in sync with public API in
    // frameworks/base/core/java/android/hardware/camera2/CameraDevice.java
    const int TEMPLATE_PREVIEW = 1;
    const int TEMPLATE_STILL_CAPTURE = 2;
    const int TEMPLATE_RECORD = 3;
    const int TEMPLATE_VIDEO_SNAPSHOT = 4;
    const int TEMPLATE_ZERO_SHUTTER_LAG = 5;
    const int TEMPLATE_MANUAL = 6;

    CameraMetadataNative createDefaultRequest(int templateId);

    CameraMetadataNative getCameraInfo();

    void waitUntilIdle();

    long flush();

    void prepare(int streamId);

    void tearDown(int streamId);

    void prepare2(int maxCount, int streamId);

    void updateOutputConfiguration(int streamId, in OutputConfiguration outputConfiguration);

    void finalizeOutputConfigurations(int streamId, in OutputConfiguration outputConfiguration);


    // Keep in sync with public API in
    // frameworks/base/core/java/android/hardware/camera2/CameraDevice.java
    const int AUDIO_RESTRICTION_NONE = 0;
    const int AUDIO_RESTRICTION_VIBRATION = 1;
    const int AUDIO_RESTRICTION_VIBRATION_SOUND = 3;

    /**
      * Set audio restriction mode for this camera device.
      *
      * @param mode the audio restriction mode ID as above
      *
      */
    void setCameraAudioRestriction(int mode);

    /**
      * Get global audio restriction mode for all camera clients.
      *
      * @return the currently applied system-wide audio restriction mode
      */
    int getGlobalAudioRestriction();

    /**
     * Offline processing main entry point
     *
     * @param callbacks Object that will receive callbacks from offline session
     * @param offlineOutputIds The ID of streams that needs to be preserved in offline session
     *
     * @return Offline session object.
     */
    ICameraOfflineSession switchToOffline(in ICameraDeviceCallbacks callbacks,
            in int[] offlineOutputIds);
}
