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

#undef LOG_NDEBUG
#undef LOG_TAG
#define LOG_NDEBUG 0
#define LOG_TAG "ContextHubService"

#include <inttypes.h>
#include <jni.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/endian.h>

#include <chrono>
#include <mutex>
#include <queue>
#include <unordered_map>
#include <utility>

#include <android-base/macros.h>
#include <android/hardware/contexthub/1.0/IContexthub.h>
#include <cutils/log.h>

#include "core_jni_helpers.h"
#include <nativehelper/JNIHelp.h>

using android::hardware::contexthub::V1_0::AsyncEventType;
using android::hardware::contexthub::V1_0::ContextHub;
using android::hardware::contexthub::V1_0::ContextHubMsg;
using android::hardware::contexthub::V1_0::HubAppInfo;
using android::hardware::contexthub::V1_0::IContexthub;
using android::hardware::contexthub::V1_0::IContexthubCallback;
using android::hardware::contexthub::V1_0::NanoAppBinary;
using android::hardware::contexthub::V1_0::Result;
using android::hardware::contexthub::V1_0::TransactionResult;

using android::hardware::Return;

using std::chrono::steady_clock;

// If a transaction takes longer than this, we'll allow it to be
// canceled by a new transaction.  Note we do _not_ automatically
// cancel a transaction after this much time.  We can have a
// legal transaction which takes longer than this amount of time,
// as long as no other new transactions are attempted after this
// time has expired.
constexpr auto kMinTransactionCancelTime = std::chrono::seconds(29);

namespace android {

constexpr uint32_t kNanoAppBinaryHeaderVersion = 1;

// Important: this header is explicitly defined as little endian byte order, and
// therefore may not match host endianness
struct NanoAppBinaryHeader {
    uint32_t headerVersion;        // 0x1 for this version
    uint32_t magic;                // "NANO" (see NANOAPP_MAGIC in context_hub.h)
    uint64_t appId;                // App Id, contains vendor id
    uint32_t appVersion;           // Version of the app
    uint32_t flags;                // Signed, encrypted
    uint64_t hwHubType;            // Which hub type is this compiled for
    uint8_t targetChreApiMajorVersion; // Which CHRE API version this is compiled for
    uint8_t targetChreApiMinorVersion;
    uint8_t reserved[6];
} __attribute__((packed));

enum HubMessageType {
    CONTEXT_HUB_APPS_ENABLE  = 1, // Enables loaded nano-app(s)
    CONTEXT_HUB_APPS_DISABLE = 2, // Disables loaded nano-app(s)
    CONTEXT_HUB_LOAD_APP     = 3, // Load a supplied app
    CONTEXT_HUB_UNLOAD_APP   = 4, // Unload a specified app
    CONTEXT_HUB_QUERY_APPS   = 5, // Query for app(s) info on hub
    CONTEXT_HUB_QUERY_MEMORY = 6, // Query for memory info
    CONTEXT_HUB_OS_REBOOT    = 7, // Request to reboot context HUB OS
};

constexpr jint OS_APP_ID = -1;
constexpr jint INVALID_APP_ID = -2;

constexpr jint MIN_APP_ID = 1;
constexpr jint MAX_APP_ID = 128;

constexpr size_t MSG_HEADER_SIZE = 4;
constexpr size_t HEADER_FIELD_MSG_TYPE = 0;
constexpr size_t HEADER_FIELD_MSG_VERSION = 1;
constexpr size_t HEADER_FIELD_HUB_HANDLE = 2;
constexpr size_t HEADER_FIELD_APP_INSTANCE = 3;

constexpr size_t HEADER_FIELD_LOAD_APP_ID_LO = MSG_HEADER_SIZE;
constexpr size_t HEADER_FIELD_LOAD_APP_ID_HI = MSG_HEADER_SIZE + 1;
constexpr size_t MSG_HEADER_SIZE_LOAD_APP = MSG_HEADER_SIZE + 2;

jint getAppInstanceForAppId(uint64_t app_id);
int onMessageReceipt(const uint32_t *header,
                     size_t headerLen,
                     const char *msg,
                     size_t msgLen);
void onHubReset(uint32_t hubId);
void queryHubForApps(uint32_t hubId);
void passOnOsResponse(uint32_t hubHandle,
                      uint32_t msgType,
                      TransactionResult result,
                      const int8_t *additionalData,
                      size_t additionalDataLen);

bool closeLoadTxn(bool success, jint *appInstanceHandle);
void closeUnloadTxn(bool success);
int handleQueryAppsResponse(const std::vector<HubAppInfo> apps,
                               uint32_t hubHandle);

struct JniInfo {
    JavaVM *vm;
    jclass contextHubInfoClass;
    jclass contextHubServiceClass;
    jclass memoryRegionsClass;

    jobject jContextHubService;

    jmethodID msgReceiptCallBack;

    jmethodID contextHubInfoCtor;
    jmethodID contextHubInfoSetId;
    jmethodID contextHubInfoSetName;
    jmethodID contextHubInfoSetVendor;
    jmethodID contextHubInfoSetToolchain;
    jmethodID contextHubInfoSetPlatformVersion;
    jmethodID contextHubInfoSetStaticSwVersion;
    jmethodID contextHubInfoSetToolchainVersion;
    jmethodID contextHubInfoSetPeakMips;
    jmethodID contextHubInfoSetStoppedPowerDrawMw;
    jmethodID contextHubInfoSetSleepPowerDrawMw;
    jmethodID contextHubInfoSetPeakPowerDrawMw;
    jmethodID contextHubInfoSetSupportedSensors;
    jmethodID contextHubInfoSetMemoryRegions;
    jmethodID contextHubInfoSetMaxPacketLenBytes;

    jmethodID contextHubServiceMsgReceiptCallback;
    jmethodID contextHubServiceAddAppInstance;
    jmethodID contextHubServiceDeleteAppInstance;
};



class TxnManager {
public:
    TxnManager() {
        mData = nullptr;
        mIsPending = false;
    }

    ~TxnManager() {
        closeTxn();
    }

    int addTxn(HubMessageType txnIdentifier, void *txnData) {
        std::lock_guard<std::mutex>lock(mLock);
        if (mIsPending) {
            ALOGW("Transaction already found pending when trying to add a new one.");
            return -1;
        }
        mIsPending = true;
        mFirstTimeTxnCanBeCanceled = steady_clock::now() + kMinTransactionCancelTime;
        mData = txnData;
        mIdentifier = txnIdentifier;

        return 0;
    }

    int closeTxn() {
        std::lock_guard<std::mutex>lock(mLock);
        closeTxnUnlocked();
        return 0;
    }

    bool isTxnPending() {
        std::lock_guard<std::mutex>lock(mLock);
        return mIsPending;
    }

    void closeAnyStaleTxns() {
        std::lock_guard<std::mutex>lock(mLock);
        if (mIsPending && steady_clock::now() >= mFirstTimeTxnCanBeCanceled) {
            ALOGW("Stale transaction canceled");
            closeTxnUnlocked();
        }
    }

    int fetchTxnData(HubMessageType *id, void **data) {
        if (id == nullptr || data == nullptr) {
            ALOGW("Null Params isNull{id, data} {%d, %d}",
                  id == nullptr ? 1 : 0,
                  data == nullptr ? 1 : 0);
            return -1;
        }

        std::lock_guard<std::mutex>lock(mLock);
        if (!mIsPending) {
            ALOGW("No Transactions pending");
            return -1;
        }

        *id = mIdentifier;
        *data = mData;
        return 0;
    }

 private:
    bool mIsPending;            // Is a transaction pending
    std::mutex mLock;           // mutex for manager
    HubMessageType mIdentifier; // What are we doing
    void *mData;                // Details
    steady_clock::time_point mFirstTimeTxnCanBeCanceled;

    // Only call this if you hold the lock.
    void closeTxnUnlocked() {
        mIsPending = false;
        free(mData);
        mData = nullptr;
    }
};


struct ContextHubServiceCallback : IContexthubCallback {
    uint32_t mContextHubId;

    ContextHubServiceCallback(uint32_t hubId) {
        mContextHubId = hubId;
    }

    virtual Return<void> handleClientMsg(const ContextHubMsg &msg) {
        jint appHandle = getAppInstanceForAppId(msg.appName);
        if (appHandle < 0) {
            ALOGE("Filtering out message due to invalid App Instance.");
        } else {
            uint32_t msgHeader[MSG_HEADER_SIZE] = {};
            msgHeader[HEADER_FIELD_MSG_TYPE] = msg.msgType;
            msgHeader[HEADER_FIELD_HUB_HANDLE] = mContextHubId;
            msgHeader[HEADER_FIELD_APP_INSTANCE] = appHandle;
            onMessageReceipt(msgHeader,
                             MSG_HEADER_SIZE,
                             reinterpret_cast<const char *>(msg.msg.data()),
                             msg.msg.size());
        }

        return android::hardware::Void();
    }

    virtual Return<void> handleHubEvent(AsyncEventType evt) {
        if (evt == AsyncEventType::RESTARTED) {
            ALOGW("Context Hub handle %d restarted", mContextHubId);
            onHubReset(mContextHubId);
        } else {
            ALOGW("Cannot handle event %u from hub %d", evt, mContextHubId);
        }

        return android::hardware::Void();
    }

    virtual Return<void> handleTxnResult(uint32_t txnId,
                                         TransactionResult result) {
        ALOGI("Handle transaction result , hubId %" PRIu32 ", txnId %" PRIu32 ", result %" PRIu32,
              mContextHubId,
              txnId,
              result);

        switch(txnId) {
            case CONTEXT_HUB_APPS_ENABLE:
            case CONTEXT_HUB_APPS_DISABLE:
                passOnOsResponse(mContextHubId, txnId, result, nullptr, 0);
                break;

            case CONTEXT_HUB_UNLOAD_APP:
                closeUnloadTxn(result == TransactionResult::SUCCESS);
                passOnOsResponse(mContextHubId, txnId, result, nullptr, 0);
                break;

            case CONTEXT_HUB_LOAD_APP:
                {
                    jint appInstanceHandle = INVALID_APP_ID;
                    bool appRunningOnHub = (result == TransactionResult::SUCCESS);
                    if (!(closeLoadTxn(appRunningOnHub, &appInstanceHandle))) {
                        if (appRunningOnHub) {
                            // Now we're in an odd situation.  Our nanoapp
                            // is up and running on the Context Hub.  However,
                            // something went wrong in our Service code so that
                            // we're not able to properly track this nanoapp
                            // in our Service code.  If we tell the Java layer
                            // things are good, it's a lie because the handle
                            // we give them will fail when used with the Service.
                            // If we tell the Java layer this failed, it's kind
                            // of a lie as well, since this nanoapp is running.
                            //
                            // We leave a more robust fix for later, and for
                            // now just tell the user things have failed.
                            //
                            // TODO(b/30835981): Make this situation better.
                            result = TransactionResult::FAILURE;
                        }
                    }

                    passOnOsResponse(mContextHubId,
                                     txnId,
                                     result,
                                     reinterpret_cast<int8_t *>(&appInstanceHandle),
                                     sizeof(appInstanceHandle));
                    break;
                }

            default:
                ALOGI("unrecognized transction id %" PRIu32, txnId);
                break;
        }
        return android::hardware::Void();
    }

    virtual Return<void> handleAppsInfo(
            const android::hardware::hidl_vec<HubAppInfo>& apps) {
        TransactionResult result = TransactionResult::SUCCESS;
        handleQueryAppsResponse(apps,mContextHubId);
        passOnOsResponse(mContextHubId, CONTEXT_HUB_QUERY_APPS, result, nullptr, 0);
        return android::hardware::Void();
    }

    virtual Return<void> handleAppAbort(uint64_t appId, uint32_t abortCode) {
        ALOGI("Handle app aport called from %" PRIx64 " with abort code %" PRIu32,
            appId,
            abortCode);

        // TODO: Plumb this to the clients interested in this app
        return android::hardware::Void();
    }

    void setContextHubId(uint32_t id) {
        mContextHubId = id;
    }

    uint32_t getContextHubId() {
        return(mContextHubId);
    }
};

struct AppInstanceInfo {
    HubAppInfo appInfo;          // returned from the HAL
    uint64_t truncName;          // Possibly truncated name for logging
    uint32_t hubHandle;          // Id of the hub this app is on
    jint instanceId;             // system wide unique instance id - assigned
};

struct ContextHubInfo {
    int numHubs;
    Vector<ContextHub> hubs;
    sp<IContexthub> contextHub;
};

struct ContextHubServiceDb {
    int initialized;
    ContextHubInfo hubInfo;
    JniInfo jniInfo;
    std::queue<jint> freeIds;
    std::unordered_map<jint, AppInstanceInfo> appInstances;
    TxnManager txnManager;
    std::vector<ContextHubServiceCallback *> regCallBacks;
};

ContextHubServiceDb db;

bool getHubIdForHubHandle(int hubHandle, uint32_t *hubId) {
    if (hubHandle < 0 || hubHandle >= db.hubInfo.numHubs || hubId == nullptr) {
        return false;
    } else {
        *hubId = db.hubInfo.hubs[hubHandle].hubId;
        return true;
    }
}

int getHubHandleForAppInstance(jint id) {
    if (!db.appInstances.count(id)) {
        ALOGD("%s: Cannot find app for app instance %" PRId32,
              __FUNCTION__,
              id);
        return -1;
    }

    return db.appInstances[id].hubHandle;
}

jint getAppInstanceForAppId(uint64_t app_id) {
    auto end = db.appInstances.end();
    for (auto current = db.appInstances.begin(); current != end; ++current) {
        if (current->second.appInfo.appId == app_id) {
            return current->first;
        }
    }
    ALOGD("Cannot find app for app id %" PRIu64 ".", app_id);
    return -1;
}

uint64_t getAppIdForAppInstance(jint id) {
    if (!db.appInstances.count(id)) {
        return INVALID_APP_ID;
    }
    return db.appInstances[id].appInfo.appId;
}

void queryHubForApps(uint32_t hubId) {
    Result r = db.hubInfo.contextHub->queryApps(hubId);
    ALOGD("Sent query for apps to hub %" PRIu32 " with result %" PRIu32, hubId, r);
}

void sendQueryForApps() {
    for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
        queryHubForApps(db.hubInfo.hubs[i].hubId);
    }
}

int returnId(jint id) {
    // Note : This method is not thread safe.
    // id returned is guaranteed to be in use
    if (id >= 0) {
        db.freeIds.push(id);
        return 0;
    }

    return -1;
}

jint generateId() {
    // Note : This method is not thread safe.
    jint retVal = -1;

    if (!db.freeIds.empty()) {
        retVal = db.freeIds.front();
        db.freeIds.pop();
    }

    return retVal;
}

jint addAppInstance(const HubAppInfo *appInfo, uint32_t hubHandle,
        jint appInstanceHandle, JNIEnv *env) {
    // Not checking if the apps are indeed distinct
    AppInstanceInfo entry;
    assert(appInfo);


    entry.appInfo = *appInfo;

    entry.instanceId = appInstanceHandle;
    entry.truncName = appInfo->appId;
    entry.hubHandle = hubHandle;
    db.appInstances[appInstanceHandle] = entry;
    // Finally - let the service know of this app instance, to populate
    // the Java cache.
    env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceAddAppInstance,
                       hubHandle, entry.instanceId,
                       entry.truncName,
                       entry.appInfo.version);

    const char *action = (db.appInstances.count(appInstanceHandle) == 0) ? "Added" : "Updated";
    ALOGI("%s App 0x%" PRIx64 " on hub Handle %" PRId32
          " as appInstance %" PRId32, action, entry.truncName,
          entry.hubHandle, appInstanceHandle);

    return appInstanceHandle;
}

int deleteAppInstance(jint id, JNIEnv *env) {
    bool fullyDeleted = true;

    if (db.appInstances.count(id)) {
        db.appInstances.erase(id);
    } else {
        ALOGW("Cannot delete App id (%" PRId32 ") from the JNI C++ cache", id);
        fullyDeleted = false;
    }
    returnId(id);

    if ((env == nullptr) ||
        (env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceDeleteAppInstance,
                       id) != 0)) {
        ALOGW("Cannot delete App id (%" PRId32 ") from Java cache", id);
        fullyDeleted = false;
    }

    if (fullyDeleted) {
        ALOGI("Deleted App id : %" PRId32, id);
        return 0;
    }
    return -1;
}

int startLoadAppTxn(uint64_t appId, int hubHandle) {
    AppInstanceInfo *txnInfo = new AppInstanceInfo();
    jint instanceId = generateId();

    if (!txnInfo || instanceId < 0) {
        returnId(instanceId);
        delete txnInfo;
        return -1;
    }

    txnInfo->truncName = appId;
    txnInfo->hubHandle = hubHandle;
    txnInfo->instanceId = instanceId;

    txnInfo->appInfo.appId = appId;
    txnInfo->appInfo.version = -1; // Awaited

    if (db.txnManager.addTxn(CONTEXT_HUB_LOAD_APP, txnInfo) != 0) {
        returnId(instanceId);
        delete txnInfo;
        return -1;
    }

    return 0;
}

int startUnloadAppTxn(jint appInstanceHandle) {
    jint *txnData = new(jint);
    if (!txnData) {
        ALOGW("Cannot allocate memory to start unload transaction");
        return -1;
    }

    *txnData = appInstanceHandle;

    if (db.txnManager.addTxn(CONTEXT_HUB_UNLOAD_APP, txnData) != 0) {
        delete txnData;
        ALOGW("Cannot start transaction to unload app");
        return -1;
    }

    return 0;
}

void getHubsCb(const ::android::hardware::hidl_vec<ContextHub>& hubs)  {
    for (size_t i = 0; i < hubs.size(); i++) {
        db.hubInfo.hubs.push_back(hubs[i]);
    }
}

void initContextHubService() {
    db.hubInfo.numHubs = 0;

    db.hubInfo.contextHub = IContexthub::getService();

    if (db.hubInfo.contextHub == nullptr) {
        ALOGE("Could not load context hub hal");
    } else {
        ALOGI("Loaded context hub hal, isRemote %s", db.hubInfo.contextHub->isRemote() ? "TRUE" : "FALSE");
    }

    // Prep for storing app info
    for (jint i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
        db.freeIds.push(i);
    }

    if (db.hubInfo.contextHub != nullptr) {
        std::function<void(const ::android::hardware::hidl_vec<ContextHub>& hubs)> f = getHubsCb;
        if(!db.hubInfo.contextHub->getHubs(f).isOk()) {
            ALOGW("GetHubs Failed! transport error.");
            return;
        };

        int retNumHubs = db.hubInfo.hubs.size();
        ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
        db.hubInfo.numHubs = retNumHubs;

        for (int i = 0; i < db.hubInfo.numHubs; i++) {
            ALOGI("Subscribing to hubHandle %d", i);

            ContextHubServiceCallback *callBackPtr =
                new ContextHubServiceCallback(db.hubInfo.hubs[i].hubId);
            db.hubInfo.contextHub->registerCallback(db.hubInfo.hubs[i].hubId,
                                                    callBackPtr);
            db.regCallBacks.push_back(callBackPtr);
        }

        sendQueryForApps();

    } else {
        ALOGW("No Context Hub Module present");
    }
}

void onHubReset(uint32_t hubId) {
    TransactionResult result = TransactionResult::SUCCESS;
    db.txnManager.closeTxn();
    // TODO : Expose this through an api
    passOnOsResponse(hubId, CONTEXT_HUB_OS_REBOOT, result, nullptr, 0);
    queryHubForApps(hubId);
}

int onMessageReceipt(const uint32_t *header,
                     size_t headerLen,
                     const char *msg,
                     size_t msgLen) {
    JNIEnv *env;

    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
      return -1;
    }

    jbyteArray jmsg = env->NewByteArray(msgLen);
    if (jmsg == nullptr) {
        ALOGW("Can't allocate %zu byte array", msgLen);
        return -1;
    }
    jintArray jheader = env->NewIntArray(headerLen);
    if (jheader == nullptr) {
        env->DeleteLocalRef(jmsg);
        ALOGW("Can't allocate %zu int array", headerLen);
        return -1;
    }

    env->SetByteArrayRegion(jmsg, 0, msgLen, reinterpret_cast<const jbyte *>(msg));
    env->SetIntArrayRegion(jheader, 0, headerLen, reinterpret_cast<const jint *>(header));

    int ret = (env->CallIntMethod(db.jniInfo.jContextHubService,
                                  db.jniInfo.contextHubServiceMsgReceiptCallback,
                                  jheader,
                                  jmsg) != 0);
    env->DeleteLocalRef(jmsg);
    env->DeleteLocalRef(jheader);

    return ret;
}

int handleQueryAppsResponse(const std::vector<HubAppInfo> apps,
                               uint32_t hubHandle) {
    JNIEnv *env;
    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
            return -1;
    }

    int numApps = apps.size();

    // We use this information to sync our JNI and Java caches of nanoapp info.
    // We want to accomplish two things here:
    // 1) Remove entries from our caches which are stale, and pertained to
    //    apps no longer running on Context Hub.
    // 2) Populate our caches with the latest information of all these apps.

    // We make a couple of assumptions here:
    // A) The JNI and Java caches are in sync with each other (this isn't
    //    necessarily true; any failure of a single call into Java land to
    //    update its cache will leave that cache in a bad state.  For NYC,
    //    we're willing to tolerate this for now).
    // B) The total number of apps is relatively small, so horribly inefficent
    //    algorithms aren't too painful.
    // C) We're going to call this relatively infrequently, so its inefficency
    //    isn't a big impact.


    // (1).  Looking for stale cache entries.  Yes, this is O(N^2).  See
    // assumption (B).  Per assumption (A), it is sufficient to iterate
    // over just the JNI cache.
    auto end = db.appInstances.end();
    for (auto current = db.appInstances.begin(); current != end; ) {
        AppInstanceInfo cacheEntry = current->second;
        // We perform our iteration here because if we call
        // delete_app_instance() below, it will erase() this entry.
        current++;
        bool entryIsStale = true;
        for (int i = 0; i < numApps; i++) {
            if (apps[i].appId == cacheEntry.appInfo.appId) {
                // We found a match; this entry is current.
                entryIsStale = false;
                break;
            }
        }

        if (entryIsStale) {
            deleteAppInstance(cacheEntry.instanceId, env);
        }
    }

    // (2).  Update our caches with the latest.
    for (int i = 0; i < numApps; i++) {
        // We will only have one instance of the app
        // TODO : Change this logic once we support multiple instances of the same app
        jint appInstance = getAppInstanceForAppId(apps[i].appId);
        if (appInstance == -1) {
            // This is a previously unknown app, let's allocate an "id" for it.
            appInstance = generateId();
        }
        addAppInstance(&apps[i], hubHandle, appInstance, env);
    }
    return 0;
}

// TODO(b/30807327): Do not use raw bytes for additional data.  Use the
//     JNI interfaces for the appropriate types.
void passOnOsResponse(uint32_t hubHandle,
                      uint32_t msgType,
                      TransactionResult result,
                      const int8_t *additionalData,
                      size_t additionalDataLen) {
    JNIEnv *env;

    if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
        ALOGW("Cannot latch to JNI env, dropping OS response %" PRIu32,
              msgType);
        return;
    }

    uint32_t header[MSG_HEADER_SIZE];
    memset(header, 0, sizeof(header));

    if (!additionalData) {
        additionalDataLen = 0; // clamp
    }
    int msgLen = 1 + additionalDataLen;

    int8_t *msg = new int8_t[msgLen];

    if (!msg) {
        ALOGW("Unexpected : Ran out of memory, cannot send response");
        return;
    }

    header[HEADER_FIELD_MSG_TYPE] = msgType;
    header[HEADER_FIELD_MSG_VERSION] = 0;
    header[HEADER_FIELD_HUB_HANDLE] = hubHandle;
    header[HEADER_FIELD_APP_INSTANCE] = OS_APP_ID;

    // Due to API constraints, at the moment we can't change the fact that
    // we're changing our 4-byte response to a 1-byte value.  But we can prevent
    // the possible change in sign (and thus meaning) that would happen from
    // a naive cast.  Further, we can log when we're losing part of the value.
    // TODO(b/30918279): Don't truncate this result.
    int8_t truncatedResult;
    truncatedResult = static_cast<int8_t>(result);
    msg[0] = truncatedResult;

    if (additionalData) {
        memcpy(&msg[1], additionalData, additionalDataLen);
    }

    jbyteArray jmsg = env->NewByteArray(msgLen);
    jintArray jheader = env->NewIntArray(arraysize(header));

    env->SetByteArrayRegion(jmsg, 0, msgLen, reinterpret_cast<jbyte *>(msg));
    env->SetIntArrayRegion(jheader, 0, arraysize(header), reinterpret_cast<jint *>(header));

    ALOGI("Passing msg type %" PRIu32 " from app %" PRIu32 " from hub %" PRIu32,
          header[HEADER_FIELD_MSG_TYPE],
          header[HEADER_FIELD_APP_INSTANCE],
          header[HEADER_FIELD_HUB_HANDLE]);

    env->CallIntMethod(db.jniInfo.jContextHubService,
                       db.jniInfo.contextHubServiceMsgReceiptCallback,
                       jheader,
                       jmsg);

    env->DeleteLocalRef(jmsg);
    env->DeleteLocalRef(jheader);

    delete[] msg;
}

void closeUnloadTxn(bool success) {
    void *txnData = nullptr;
    HubMessageType txnId;

    if (success && db.txnManager.fetchTxnData(&txnId, &txnData) == 0 &&
        txnId == CONTEXT_HUB_UNLOAD_APP) {
        JNIEnv *env;
        if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
            ALOGW("Could not attach to JVM !");
            env = nullptr;
        }
        jint handle = *reinterpret_cast<jint *>(txnData);
        deleteAppInstance(handle, env);
    } else {
        ALOGW("Could not unload the app successfully ! success %d, txnData %p",
              success,
              txnData);
    }

    db.txnManager.closeTxn();
}

bool closeLoadTxn(bool success, jint *appInstanceHandle) {
    void *txnData;
    HubMessageType txnId;

    if (success && db.txnManager.fetchTxnData(&txnId, &txnData) == 0 &&
        txnId == CONTEXT_HUB_LOAD_APP) {
        AppInstanceInfo *info = static_cast<AppInstanceInfo *>(txnData);
        *appInstanceHandle = info->instanceId;

        JNIEnv *env;
        if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) == JNI_OK) {
            addAppInstance(&info->appInfo, info->hubHandle, info->instanceId, env);
        } else {
            ALOGW("Could not attach to JVM !");
            success = false;
        }
        // While we just called addAppInstance above, our info->appInfo was
        // incomplete (for example, the 'version' is hardcoded to -1).  So we
        // trigger an additional query to the CHRE, so we'll be able to get
        // all the app "info", and have our JNI and Java caches with the
        // full information.
        sendQueryForApps();
    } else {
        ALOGW("Could not load the app successfully ! Unexpected failure");
        *appInstanceHandle = INVALID_APP_ID;
        success = false;
    }

    db.txnManager.closeTxn();
    return success;
}

int initJni(JNIEnv *env, jobject instance) {
    if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
        return -1;
    }

    db.jniInfo.jContextHubService = env->NewGlobalRef(instance);

    db.jniInfo.contextHubInfoClass =
            env->FindClass("android/hardware/location/ContextHubInfo");
    db.jniInfo.contextHubServiceClass =
            env->FindClass("com/android/server/location/ContextHubService");

    db.jniInfo.memoryRegionsClass =
            env->FindClass("android/hardware/location/MemoryRegion");

    db.jniInfo.contextHubInfoCtor =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
    db.jniInfo.contextHubInfoSetId =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "setId", "(I)V");
    db.jniInfo.contextHubInfoSetName =
            env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName", "(Ljava/lang/String;)V");
    db.jniInfo.contextHubInfoSetVendor =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setVendor",
                             "(Ljava/lang/String;)V");
    db.jniInfo.contextHubInfoSetToolchain =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setToolchain",
                             "(Ljava/lang/String;)V");
    db.jniInfo.contextHubInfoSetPlatformVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setPlatformVersion",
                             "(I)V");
    db.jniInfo.contextHubInfoSetStaticSwVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setStaticSwVersion",
                             "(I)V");
    db.jniInfo.contextHubInfoSetToolchainVersion =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setToolchainVersion",
                             "(I)V");
    db.jniInfo.contextHubInfoSetPeakMips =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setPeakMips",
                             "(F)V");
    db.jniInfo.contextHubInfoSetStoppedPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setStoppedPowerDrawMw",
                             "(F)V");
    db.jniInfo.contextHubInfoSetSleepPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setSleepPowerDrawMw",
                             "(F)V");
    db.jniInfo.contextHubInfoSetPeakPowerDrawMw =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setPeakPowerDrawMw",
                             "(F)V");
    db.jniInfo.contextHubInfoSetSupportedSensors =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setSupportedSensors",
                             "([I)V");
    db.jniInfo.contextHubInfoSetMemoryRegions =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setMemoryRegions",
                             "([Landroid/hardware/location/MemoryRegion;)V");
    db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
             env->GetMethodID(db.jniInfo.contextHubInfoClass,
                              "setMaxPacketLenBytes",
                              "(I)V");
    db.jniInfo.contextHubServiceMsgReceiptCallback =
            env->GetMethodID(db.jniInfo.contextHubServiceClass,
                             "onMessageReceipt",
                             "([I[B)I");
    db.jniInfo.contextHubInfoSetName =
            env->GetMethodID(db.jniInfo.contextHubInfoClass,
                             "setName",
                             "(Ljava/lang/String;)V");
    db.jniInfo.contextHubServiceAddAppInstance =
                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
                                  "addAppInstance",
                                  "(IIJI)I");
    db.jniInfo.contextHubServiceDeleteAppInstance =
                 env->GetMethodID(db.jniInfo.contextHubServiceClass,
                                  "deleteAppInstance",
                                  "(I)I");

    return 0;
}

jobject constructJContextHubInfo(JNIEnv *env, const ContextHub &hub) {
    jstring jstrBuf;
    jintArray jintBuf;
    jobjectArray jmemBuf;

    jobject jHub = env->NewObject(db.jniInfo.contextHubInfoClass,
                                  db.jniInfo.contextHubInfoCtor);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetId, hub.hubId);

    jstrBuf = env->NewStringUTF(hub.name.c_str());
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetName, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    jstrBuf = env->NewStringUTF(hub.vendor.c_str());
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetVendor, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    jstrBuf = env->NewStringUTF(hub.toolchain.c_str());
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchain, jstrBuf);
    env->DeleteLocalRef(jstrBuf);

    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub.platformVersion);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub.toolchainVersion);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub.peakMips);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw,
                        hub.stoppedPowerDrawMw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw,
                        hub.sleepPowerDrawMw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw,
                        hub.peakPowerDrawMw);
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
                        hub.maxSupportedMsgLen);


    jintBuf = env->NewIntArray(hub.connectedSensors.size());
    int *connectedSensors = new int[hub.connectedSensors.size()];

    if (!connectedSensors) {
      ALOGW("Cannot allocate memory! Unexpected");
      assert(false);
    } else {
      for (unsigned int i = 0; i < hub.connectedSensors.size(); i++) {
        // TODO :: Populate connected sensors.
        //connectedSensors[i] = hub.connectedSensors[i].sensorType;
        connectedSensors[i] = 0;
      }
    }

    env->SetIntArrayRegion(jintBuf, 0, hub.connectedSensors.size(),
                           connectedSensors);

    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSupportedSensors, jintBuf);
    env->DeleteLocalRef(jintBuf);

    // We are not getting the memory regions from the CH Hal - change this when it is available
    jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
    // Note the zero size above. We do not need to set any elements
    env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
    env->DeleteLocalRef(jmemBuf);


    delete[] connectedSensors;
    return jHub;
}

jobjectArray nativeInitialize(JNIEnv *env, jobject instance) {
    jobject hub;
    jobjectArray retArray;

    if (initJni(env, instance) < 0) {
        return nullptr;
    }

    initContextHubService();

    if (db.hubInfo.numHubs > 1) {
        ALOGW("Clamping the number of hubs to 1");
        db.hubInfo.numHubs = 1;
    }

    retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);

    for(int i = 0; i < db.hubInfo.numHubs; i++) {
        hub = constructJContextHubInfo(env, db.hubInfo.hubs[i]);
        env->SetObjectArrayElement(retArray, i, hub);
    }

    return retArray;
}

Result sendLoadNanoAppRequest(uint32_t hubId,
                              jbyte *data,
                              size_t dataBufferLength) {
    auto header = reinterpret_cast<const NanoAppBinaryHeader *>(data);
    Result result;

    if (dataBufferLength < sizeof(NanoAppBinaryHeader)) {
        ALOGE("Got short NanoApp, length %zu", dataBufferLength);
        result = Result::BAD_PARAMS;
    } else if (header->headerVersion != htole32(kNanoAppBinaryHeaderVersion)) {
        ALOGE("Got unexpected NanoApp header version %" PRIu32,
              letoh32(header->headerVersion));
        result = Result::BAD_PARAMS;
    } else {
        NanoAppBinary nanoapp;

        // Data from the common nanoapp header goes into explicit fields
        nanoapp.appId      = letoh64(header->appId);
        nanoapp.appVersion = letoh32(header->appVersion);
        nanoapp.flags      = letoh32(header->flags);
        nanoapp.targetChreApiMajorVersion = header->targetChreApiMajorVersion;
        nanoapp.targetChreApiMinorVersion = header->targetChreApiMinorVersion;

        // Everything past the header goes in customBinary
        auto dataBytes = reinterpret_cast<const uint8_t *>(data);
        std::vector<uint8_t> customBinary(
            dataBytes + sizeof(NanoAppBinaryHeader),
            dataBytes + dataBufferLength);
        nanoapp.customBinary = std::move(customBinary);

        ALOGW("Calling Load NanoApp on hub %d", hubId);
        result = db.hubInfo.contextHub->loadNanoApp(hubId,
                                                    nanoapp,
                                                    CONTEXT_HUB_LOAD_APP);
    }

    return result;
}

jint nativeSendMessage(JNIEnv *env,
                       jobject instance,
                       jintArray header_,
                       jbyteArray data_) {
    // With the new binderized HAL definition, this function can be made much simpler.
    // All the magic can be removed. This is not however needed for the default implementation
    // TODO :: Change the JNI interface to conform to the new HAL interface and clean up this
    // function
    jint retVal = -1; // Default to failure

    jint *header = env->GetIntArrayElements(header_, 0);
    size_t numHeaderElements = env->GetArrayLength(header_);
    jbyte *data = env->GetByteArrayElements(data_, 0);
    size_t dataBufferLength = env->GetArrayLength(data_);

    if (numHeaderElements < MSG_HEADER_SIZE) {
        ALOGW("Malformed header len");
        return -1;
    }

    jint appInstanceHandle = header[HEADER_FIELD_APP_INSTANCE];
    uint32_t msgType = header[HEADER_FIELD_MSG_TYPE];
    int hubHandle = -1;
    uint64_t appId;

    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
        hubHandle = getHubHandleForAppInstance(appInstanceHandle);
    } else if (msgType == CONTEXT_HUB_LOAD_APP) {
        if (numHeaderElements < MSG_HEADER_SIZE_LOAD_APP) {
            return -1;
        }
        uint64_t appIdLo = header[HEADER_FIELD_LOAD_APP_ID_LO];
        uint64_t appIdHi = header[HEADER_FIELD_LOAD_APP_ID_HI];
        appId = appIdHi << 32 | appIdLo;

        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
    } else {
        hubHandle = header[HEADER_FIELD_HUB_HANDLE];
    }

    uint32_t hubId = -1;
    if (!getHubIdForHubHandle(hubHandle, &hubId)) {
        ALOGD("Invalid hub Handle %d", hubHandle);
        return -1;
    }

    if (msgType == CONTEXT_HUB_LOAD_APP ||
        msgType == CONTEXT_HUB_UNLOAD_APP) {

        db.txnManager.closeAnyStaleTxns();

        if (db.txnManager.isTxnPending()) {
            // TODO : There is a race conditio
            ALOGW("Cannot load or unload app while a transaction is pending !");
            return -1;
        } else if (msgType == CONTEXT_HUB_LOAD_APP) {
            if (startLoadAppTxn(appId, hubHandle) != 0) {
                ALOGW("Cannot Start Load Transaction");
                return -1;
            }
        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
            if (startUnloadAppTxn(appInstanceHandle) != 0) {
                ALOGW("Cannot Start UnLoad Transaction");
                return -1;
            }
        }
    }

    Result result;

    if (msgType == CONTEXT_HUB_UNLOAD_APP) {
        ALOGW("Calling UnLoad NanoApp for app %" PRIx64 " on hub %" PRIu32,
              db.appInstances[appInstanceHandle].appInfo.appId,
              hubId);
        result = db.hubInfo.contextHub->unloadNanoApp(
                hubId, db.appInstances[appInstanceHandle].appInfo.appId, CONTEXT_HUB_UNLOAD_APP);
    } else {
        if (appInstanceHandle == OS_APP_ID) {
            if (msgType == CONTEXT_HUB_LOAD_APP) {
                result = sendLoadNanoAppRequest(hubId, data, dataBufferLength);
            } else if (msgType == CONTEXT_HUB_QUERY_APPS) {
                result = db.hubInfo.contextHub->queryApps(hubId);
            } else {
                ALOGD("Dropping OS addresses message of type - %" PRIu32, msgType);
                result = Result::BAD_PARAMS;
            }
        } else {
            appId = getAppIdForAppInstance(appInstanceHandle);
            if (appId == static_cast<uint64_t>(INVALID_APP_ID)) {
                ALOGD("Cannot find application instance %d", appInstanceHandle);
                result = Result::BAD_PARAMS;
            } else if (hubHandle != getHubHandleForAppInstance(appInstanceHandle)) {
                ALOGE("Given hubHandle (%d) doesn't match expected for app instance (%d)",
                      hubHandle,
                      getHubHandleForAppInstance(appInstanceHandle));
                result = Result::BAD_PARAMS;
            } else {
                ContextHubMsg msg;
                msg.appName = appId;
                msg.msgType = msgType;
                msg.msg.setToExternal((unsigned char *)data, dataBufferLength);

                ALOGW("Sending msg of type %" PRIu32 " len %zu to app %" PRIx64 " on hub %" PRIu32,
                       msgType,
                       dataBufferLength,
                       appId,
                       hubId);
                result = db.hubInfo.contextHub->sendMessageToHub(hubId, msg);
            }
        }
    }

    if (result != Result::OK) {
        ALOGD("Send Message failure - %d", retVal);
        if (msgType == CONTEXT_HUB_LOAD_APP) {
            jint ignored;
            closeLoadTxn(false, &ignored);
        } else if (msgType == CONTEXT_HUB_UNLOAD_APP) {
            closeUnloadTxn(false);
        }
    } else {
        retVal = 0;
    }

    env->ReleaseIntArrayElements(header_, header, 0);
    env->ReleaseByteArrayElements(data_, data, 0);

    return retVal;
}

//--------------------------------------------------------------------------------------------------
//
const JNINativeMethod gContextHubServiceMethods[] = {
    {"nativeInitialize",
            "()[Landroid/hardware/location/ContextHubInfo;",
            reinterpret_cast<void*>(nativeInitialize)},
    {"nativeSendMessage",
            "([I[B)I",
            reinterpret_cast<void*>(nativeSendMessage)}
};

int register_android_server_location_ContextHubService(JNIEnv *env)
{
    RegisterMethodsOrDie(env, "com/android/server/location/ContextHubService",
            gContextHubServiceMethods, NELEM(gContextHubServiceMethods));

    return 0;
}

}//namespace android
