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

//#define LOG_NDEBUG 0
#define LOG_TAG "CameraBase"
#include <utils/Log.h>
#include <utils/threads.h>
#include <utils/Mutex.h>
#include <cutils/properties.h>

#include <android/hardware/ICameraService.h>
#include <com/android/internal/compat/IPlatformCompatNative.h>

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>

#include <camera/CameraBase.h>
#include <camera/CameraUtils.h>
#include <camera/StringUtils.h>

// needed to instantiate
#include <camera/Camera.h>

#include <system/camera_metadata.h>

namespace android {

namespace hardware {

status_t CameraInfo::writeToParcel(android::Parcel* parcel) const {
    status_t res;
    res = parcel->writeInt32(facing);
    if (res != OK) return res;
    res = parcel->writeInt32(orientation);
    return res;
}

status_t CameraInfo::readFromParcel(const android::Parcel* parcel) {
    status_t res;
    res = parcel->readInt32(&facing);
    if (res != OK) return res;
    res = parcel->readInt32(&orientation);
    return res;
}

status_t CameraStatus::writeToParcel(android::Parcel* parcel) const {
    auto res = parcel->writeString16(toString16(cameraId));
    if (res != OK) return res;

    res = parcel->writeInt32(status);
    if (res != OK) return res;

    std::vector<String16> unavailablePhysicalIds16;
    for (auto& id8 : unavailablePhysicalIds) {
        unavailablePhysicalIds16.push_back(toString16(id8));
    }
    res = parcel->writeString16Vector(unavailablePhysicalIds16);
    if (res != OK) return res;

    res = parcel->writeString16(toString16(clientPackage));
    return res;
}

status_t CameraStatus::readFromParcel(const android::Parcel* parcel) {
    String16 tempCameraId;
    auto res = parcel->readString16(&tempCameraId);
    if (res != OK) return res;
    cameraId = toString8(tempCameraId);

    res = parcel->readInt32(&status);
    if (res != OK) return res;

    std::vector<String16> unavailablePhysicalIds16;
    res = parcel->readString16Vector(&unavailablePhysicalIds16);
    if (res != OK) return res;
    for (auto& id16 : unavailablePhysicalIds16) {
        unavailablePhysicalIds.push_back(toStdString(id16));
    }

    String16 tempClientPackage;
    res = parcel->readString16(&tempClientPackage);
    if (res != OK) return res;
    clientPackage = toStdString(tempClientPackage);

    return res;
}

} // namespace hardware

namespace {
    sp<::android::hardware::ICameraService> gCameraService;
    const int                 kCameraServicePollDelay = 500000; // 0.5s
    const char*               kCameraServiceName      = "media.camera";

    Mutex                     gLock;

    class DeathNotifier : public IBinder::DeathRecipient
    {
    public:
        DeathNotifier() {
        }

        virtual void binderDied(const wp<IBinder>& /*who*/) {
            ALOGV("binderDied");
            Mutex::Autolock _l(gLock);
            gCameraService.clear();
            ALOGW("Camera service died!");
        }
    };

    sp<DeathNotifier>         gDeathNotifier;
}; // namespace anonymous

///////////////////////////////////////////////////////////
// CameraBase definition
///////////////////////////////////////////////////////////

// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<::android::hardware::ICameraService> CameraBase<TCam, TCamTraits>::getCameraService()
{
    Mutex::Autolock _l(gLock);
    if (gCameraService.get() == 0) {
        if (CameraUtils::isCameraServiceDisabled()) {
            return gCameraService;
        }

        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(toString16(kCameraServiceName));
            if (binder != 0) {
                break;
            }
            ALOGW("CameraService not published, waiting...");
            usleep(kCameraServicePollDelay);
        } while(true);
        if (gDeathNotifier == NULL) {
            gDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(gDeathNotifier);
        gCameraService = interface_cast<::android::hardware::ICameraService>(binder);
    }
    ALOGE_IF(gCameraService == 0, "no CameraService!?");
    return gCameraService;
}

template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
                                               const std::string& clientPackageName,
                                               int clientUid, int clientPid, int targetSdkVersion,
                                               bool overrideToPortrait, bool forceSlowJpegMode)
{
    ALOGV("%s: connect", __FUNCTION__);
    sp<TCam> c = new TCam(cameraId);
    sp<TCamCallbacks> cl = c;
    const sp<::android::hardware::ICameraService> cs = getCameraService();

    binder::Status ret;
    if (cs != nullptr) {
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        ALOGI("Connect camera (legacy API) - overrideToPortrait %d, forceSlowJpegMode %d",
                overrideToPortrait, forceSlowJpegMode);
        ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                clientPid, targetSdkVersion, overrideToPortrait, forceSlowJpegMode,
                 /*out*/ &c->mCamera);
    }
    if (ret.isOk() && c->mCamera != nullptr) {
        IInterface::asBinder(c->mCamera)->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
                (cs == nullptr) ? "Service not available" : ret.toString8().c_str());
        c.clear();
    }
    return c;
}

template <typename TCam, typename TCamTraits>
void CameraBase<TCam, TCamTraits>::disconnect()
{
    ALOGV("%s: disconnect", __FUNCTION__);
    if (mCamera != 0) {
        mCamera->disconnect();
        IInterface::asBinder(mCamera)->unlinkToDeath(this);
        mCamera = 0;
    }
    ALOGV("%s: disconnect (done)", __FUNCTION__);
}

template <typename TCam, typename TCamTraits>
CameraBase<TCam, TCamTraits>::CameraBase(int cameraId) :
    mStatus(UNKNOWN_ERROR),
    mCameraId(cameraId)
{
}

template <typename TCam, typename TCamTraits>
CameraBase<TCam, TCamTraits>::~CameraBase()
{
}

template <typename TCam, typename TCamTraits>
sp<typename TCamTraits::TCamUser> CameraBase<TCam, TCamTraits>::remote()
{
    return mCamera;
}

template <typename TCam, typename TCamTraits>
status_t CameraBase<TCam, TCamTraits>::getStatus()
{
    return mStatus;
}

template <typename TCam, typename TCamTraits>
void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& /*who*/) {
    ALOGW("mediaserver's remote binder Camera object died");
    notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0);
}

template <typename TCam, typename TCamTraits>
void CameraBase<TCam, TCamTraits>::setListener(const sp<TCamListener>& listener)
{
    Mutex::Autolock _l(mLock);
    mListener = listener;
}

// callback from camera service
template <typename TCam, typename TCamTraits>
void CameraBase<TCam, TCamTraits>::notifyCallback(int32_t msgType,
                                                  int32_t ext1,
                                                  int32_t ext2)
{
    sp<TCamListener> listener;
    {
        Mutex::Autolock _l(mLock);
        listener = mListener;
    }
    if (listener != NULL) {
        listener->notify(msgType, ext1, ext2);
    }
}

template <typename TCam, typename TCamTraits>
int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {
    const sp<::android::hardware::ICameraService> cs = getCameraService();

    if (!cs.get()) {
        // as required by the public Java APIs
        return 0;
    }
    int32_t count;
    binder::Status res = cs->getNumberOfCameras(
            ::android::hardware::ICameraService::CAMERA_TYPE_BACKWARD_COMPATIBLE,
            &count);
    if (!res.isOk()) {
        ALOGE("Error reading number of cameras: %s",
                res.toString8().c_str());
        count = 0;
    }
    return count;
}

// this can be in BaseCamera but it should be an instance method
template <typename TCam, typename TCamTraits>
status_t CameraBase<TCam, TCamTraits>::getCameraInfo(int cameraId,
        bool overrideToPortrait,
        struct hardware::CameraInfo* cameraInfo) {
    const sp<::android::hardware::ICameraService> cs = getCameraService();
    if (cs == 0) return UNKNOWN_ERROR;
    binder::Status res = cs->getCameraInfo(cameraId, overrideToPortrait, cameraInfo);
    return res.isOk() ? OK : res.serviceSpecificErrorCode();
}

template class CameraBase<Camera>;

} // namespace android
