/*
 * Copyright 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.
 */

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <android/looper.h>
#include <android/sensor.h>
#include <cutils/log.h>

// Hall-effect sensor type
#define SENSOR_TYPE 33171016

#define RETRY_LIMIT     120
#define RETRY_PERIOD    30          // 30 seconds
#define WARN_PERIOD     (time_t)300 // 5 minutes

/*
 * This simple daemon listens for events from the Hall-effect sensor and writes
 * the appropriate SW_LID event to a uinput node. This allows the screen to be
 * locked with a magnetic folio case.
 */
int main(void) {
    int uinputFd;
    int err;
    struct uinput_user_dev uidev;
    ASensorManager *sensorManager = nullptr;
    ASensorRef hallSensor;
    ALooper *looper;
    ASensorEventQueue *eventQueue = nullptr;
    int32_t hallMinDelay = 0;
    time_t lastWarn = 0;
    int attemptCount = 0;

    ALOGI("Started");

    uinputFd = TEMP_FAILURE_RETRY(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
    if (uinputFd < 0) {
        ALOGE("Unable to open uinput node: %s", strerror(errno));
        goto out;
    }

    err = TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_EVBIT, EV_SW))
        | TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_EVBIT, EV_SYN))
        | TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_SET_SWBIT, SW_LID));
    if (err != 0) {
        ALOGE("Unable to enable SW_LID events: %s", strerror(errno));
        goto out;
    }

    memset(&uidev, 0, sizeof (uidev));
    snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "uinput-folio");
    uidev.id.bustype = BUS_VIRTUAL;
    uidev.id.vendor = 0;
    uidev.id.product = 0;
    uidev.id.version = 0;

    err = TEMP_FAILURE_RETRY(write(uinputFd, &uidev, sizeof (uidev)));
    if (err < 0) {
        ALOGE("Write user device to uinput node failed: %s", strerror(errno));
        goto out;
    }

    err = TEMP_FAILURE_RETRY(ioctl(uinputFd, UI_DEV_CREATE));
    if (err < 0) {
        ALOGE("Unable to create uinput device: %s", strerror(errno));
        goto out;
    }

    ALOGI("Successfully registered uinput-folio for SW_LID events");

    // Get Hall-effect sensor events from the NDK
    sensorManager = ASensorManager_getInstanceForPackage(nullptr);
    looper = ALooper_forThread();
    if (looper == nullptr) {
        looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    }

    eventQueue = ASensorManager_createEventQueue(sensorManager, looper, 0, NULL,
                                                 NULL);

    /*
     * As long as we are unable to get the sensor handle, periodically retry
     * and emit an error message at a low frequency to prevent high CPU usage
     * and log spam. If we simply exited with an error here, we would be
     * immediately restarted and fail in the same way indefinitely.
     */
    while (true) {
        time_t now = time(NULL);
        hallSensor = ASensorManager_getDefaultSensor(sensorManager,
                                                     SENSOR_TYPE);
        if (hallSensor != nullptr) {
            hallMinDelay = ASensor_getMinDelay(hallSensor);
            break;
        }

        if (++attemptCount >= RETRY_LIMIT) {
            ALOGE("Retries exhausted; exiting");
            goto out;
        } else if (now > lastWarn + WARN_PERIOD) {
            ALOGE("Unable to get Hall-effect sensor");
            lastWarn = now;
        }

        sleep(RETRY_PERIOD);
    }

    err = ASensorEventQueue_registerSensor(eventQueue, hallSensor,
                                           hallMinDelay, 10000);
    if (err < 0) {
        ALOGE("Unable to register for Hall-effect sensor events");
        goto out;
    }

    ALOGI("Starting polling loop");

    // Polling loop
    while (ALooper_pollAll(-1, NULL, NULL, NULL) == 0) {
        int eventCount = 0;
        ASensorEvent sensorEvent;
        while (ASensorEventQueue_getEvents(eventQueue, &sensorEvent, 1) > 0) {
            // 1 means closed; 0 means open
            int isClosed = sensorEvent.data[0] > 0.0f ? 1 : 0;
            struct input_event event;
            event.type = EV_SW;
            event.code = SW_LID;
            event.value = isClosed;
            err = TEMP_FAILURE_RETRY(write(uinputFd, &event, sizeof (event)));
            if (err < 0) {
                ALOGE("Write EV_SW to uinput node failed: %s", strerror(errno));
                goto out;
            }

            // Force a flush with an EV_SYN
            event.type = EV_SYN;
            event.code = SYN_REPORT;
            event.value = 0;
            err = TEMP_FAILURE_RETRY(write(uinputFd, &event, sizeof (event)));
            if (err < 0) {
                ALOGE("Write EV_SYN to uinput node failed: %s",
                      strerror(errno));
                goto out;
            }

            ALOGI("Sent lid %s event", isClosed ? "closed" : "open");
            eventCount++;
        }

        if (eventCount == 0) {
            ALOGE("Poll returned with zero events: %s", strerror(errno));
            break;
        }
    }

out:
    // Clean up
    if (sensorManager != nullptr && eventQueue != nullptr) {
        ASensorManager_destroyEventQueue(sensorManager, eventQueue);
    }

    if (uinputFd >= 0) {
        close(uinputFd);
    }

    // The loop can only be exited via failure or signal
    return 1;
}
