/*
 * Copyright (C) 2017 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;

import android.annotation.IntDef;
import android.os.MemoryFile;

import dalvik.system.CloseGuard;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.channels.Channel;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Class representing a sensor direct channel. Use
 * {@link SensorManager#createDirectChannel(android.os.MemoryFile)} or
 * {@link SensorManager#createDirectChannel(android.hardware.HardwareBuffer)}
 * to obtain an object. The channel object can be then configured
 * (see {@link #configure(Sensor, int)})
 * to start delivery of sensor events into shared memory buffer.
 */
public final class SensorDirectChannel implements Channel {

    // shared memory types

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
            TYPE_MEMORY_FILE,
            TYPE_HARDWARE_BUFFER
    })
    public @interface MemoryType {}

    /**
     * Shared memory type ashmem, wrapped in MemoryFile object.
     *
     * @see SensorManager#createDirectChannel(MemoryFile)
     */
    public static final int TYPE_MEMORY_FILE = 1;

    /**
     * Shared memory type wrapped by HardwareBuffer object.
     *
     * @see SensorManager#createDirectChannel(HardwareBuffer)
     */
    public static final int TYPE_HARDWARE_BUFFER = 2;

    // sensor rate levels

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "RATE_" }, value = {
            RATE_STOP,
            RATE_NORMAL,
            RATE_FAST,
            RATE_VERY_FAST
    })
    public @interface RateLevel {}

    /**
     * Sensor stopped (no event output).
     *
     * @see #configure(Sensor, int)
     */
    public static final int RATE_STOP = 0;
    /**
     * Sensor operates at nominal rate of 50Hz.
     *
     * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 27.5Hz to
     * 110Hz.
     *
     * @see #configure(Sensor, int)
     */
    public static final int RATE_NORMAL = 1; //50Hz
    /**
     * Sensor operates at nominal rate of 200Hz.
     *
     * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 110Hz to
     * 440Hz.
     *
     * @see #configure(Sensor, int)
     */
    public static final int RATE_FAST = 2; // ~200Hz
    /**
     * Sensor operates at nominal rate of 800Hz.
     *
     * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 440Hz to
     * 1760Hz.
     *
     * @see #configure(Sensor, int)
     */
    public static final int RATE_VERY_FAST = 3; // ~800Hz

    /**
     * Determine if a channel is still valid. A channel is invalidated after {@link #close()} is
     * called.
     *
     * @return <code>true</code> if channel is valid.
     */
    @Override
    public boolean isOpen() {
        return !mClosed.get();
    }

    /** @removed */
    @Deprecated
    public boolean isValid() {
        return isOpen();
    }

    /**
     * Close sensor direct channel.
     *
     * Stop all active sensor in the channel and free sensor system resource related to channel.
     * Shared memory used for creating the direct channel need to be closed or freed separately.
     *
     * @see SensorManager#createDirectChannel(MemoryFile)
     * @see SensorManager#createDirectChannel(HardwareBuffer)
     */
    @Override
    public void close() {
        if (mClosed.compareAndSet(false, true)) {
            mCloseGuard.close();
            // actual close action
            mManager.destroyDirectChannel(this);
        }
    }

    /**
     * Configure sensor rate or stop sensor report.
     *
     * To start event report of a sensor, or change rate of existing report, call this function with
     * rateLevel other than {@link android.hardware.SensorDirectChannel#RATE_STOP}. Sensor events
     * will be added into a queue formed by the shared memory used in creation of direction channel.
     * Each element of the queue has size of 104 bytes and represents a sensor event. Data
     * structure of an element (all fields in little-endian):
     *
     * <pre>
     *   offset   type                    name
     * ------------------------------------------------------------------------
     *   0x0000   int32_t                 size (always 104)
     *   0x0004   int32_t                 sensor report token
     *   0x0008   int32_t                 type (see SensorType)
     *   0x000C   uint32_t                atomic counter
     *   0x0010   int64_t                 timestamp (see Event)
     *   0x0018   float[16]/int64_t[8]    data (data type depends on sensor type)
     *   0x0058   int32_t[4]              reserved (set to zero)
     * </pre>
     *
     * There are no head or tail pointers. The sequence and frontier of new sensor events is
     * determined by the atomic counter, which counts from 1 after creation of direct channel and
     * increments 1 for each new event. Atomic counter will wrap back to 1 after it reaches
     * UINT32_MAX, skipping value 0 to avoid confusion with uninitialized memory. The writer in
     * sensor system will wrap around from the start of shared memory region when it reaches the
     * end. If size of memory region is not a multiple of size of element (104 bytes), the residual
     * is not used at the end.  Function returns a positive sensor report token on success. This
     * token can be used to differentiate sensor events from multiple sensor of the same type. For
     * example, if there are two accelerometers in the system A and B, it is guaranteed different
     * report tokens will be returned when starting sensor A and B.
     *
     * To stop a sensor, call this function with rateLevel equal {@link
     * android.hardware.SensorDirectChannel#RATE_STOP}. If the sensor parameter is left to be null,
     * this will stop all active sensor report associated with the direct channel specified.
     * Function return 1 on success or 0 on failure.
     *
     * @param sensor A {@link android.hardware.Sensor} object to denote sensor to be operated.
     * @param rateLevel rate level defined in {@link android.hardware.SensorDirectChannel}.
     * @return * starting report or changing rate: positive sensor report token on success,
     *                                             0 on failure;
     *         * stopping report: 1 on success, 0 on failure.
     * @throws NullPointerException when channel is null.
     */
    public int configure(Sensor sensor, @RateLevel int rateLevel) {
        return mManager.configureDirectChannelImpl(this, sensor, rateLevel);
    }

    /** @hide */
    SensorDirectChannel(SensorManager manager, int id, int type, long size) {
        mManager = manager;
        mNativeHandle = id;
        mType = type;
        mSize = size;
        mCloseGuard.open("SensorDirectChannel");
    }

    /** @hide */
    int getNativeHandle() {
        return mNativeHandle;
    }

    /**
     * This function encode handle information in {@link android.os.MemoryFile} into a long array to
     * be passed down to native methods.
     *
     * @hide */
    static long[] encodeData(MemoryFile ashmem) {
        int fd;
        try {
            fd = ashmem.getFileDescriptor().getInt$();
        } catch (IOException e) {
            fd = -1;
        }
        return new long[] { 1 /*numFds*/, 0 /*numInts*/, fd };
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (mCloseGuard != null) {
                mCloseGuard.warnIfOpen();
            }

            close();
        } finally {
            super.finalize();
        }
    }

    private final AtomicBoolean mClosed = new AtomicBoolean();
    private final CloseGuard mCloseGuard = CloseGuard.get();
    private final SensorManager mManager;
    private final int mNativeHandle;
    private final long mSize;
    private final int mType;
}
