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

#ifndef KEYSTORE_CONFIRMATION_MANAGER_H_
#define KEYSTORE_CONFIRMATION_MANAGER_H_

#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
#include <android/hardware/confirmationui/1.0/types.h>
#include <binder/Binder.h>
#include <binder/IBinder.h>
#include <binder/Status.h>
#include <keystore/keymaster_types.h>
#include <map>
#include <mutex>
#include <utils/LruCache.h>
#include <utils/StrongPointer.h>
#include <vector>

#include "confirmationui_rate_limiting.h"

namespace keystore {

using android::binder::Status;
using android::hardware::confirmationui::V1_0::IConfirmationResultCallback;
using ConfirmationResponseCode = android::hardware::confirmationui::V1_0::ResponseCode;

class ConfirmationManager;

class ConfirmationManager : public android::hardware::hidl_death_recipient,
                            public IConfirmationResultCallback {
  public:
    explicit ConfirmationManager(android::IBinder::DeathRecipient* deathRecipient);

    // Calls into the confirmationui HAL to start a new prompt.
    //
    // Returns OperationPending if another application is already
    // showing a confirmation. Otherwise returns the return code from
    // the HAL.
    Status presentConfirmationPrompt(const android::sp<android::IBinder>& listener,
                                     const android::String16& promptText,
                                     const hidl_vec<uint8_t>& extraData,
                                     const android::String16& locale, int uiOptionsAsFlags,
                                     int32_t* aidl_return);

    // Calls into the confirmationui HAL to cancel displaying a
    // prompt.
    //
    // Returns OperatingPending if another application is showing a
    // confirmation. Otherwise returns the return code from the HAL.
    Status cancelConfirmationPrompt(const android::sp<android::IBinder>& listener,
                                    int32_t* aidl_return);

    // Checks if the confirmationUI HAL is available.
    Status isConfirmationPromptSupported(bool* aidl_return);

    // Gets the latest confirmation token received from the ConfirmationUI HAL.
    hidl_vec<uint8_t> getLatestConfirmationToken();

    // Called by KeyStoreService when a client binder has died.
    void binderDied(const android::wp<android::IBinder>& who);

    // hidl_death_recipient overrides:
    virtual void serviceDied(uint64_t cookie,
                             const android::wp<android::hidl::base::V1_0::IBase>& who) override;

    // IConfirmationResultCallback overrides:
    android::hardware::Return<void> result(ConfirmationResponseCode responseCode,
                                           const hidl_vec<uint8_t>& dataThatWasConfirmed,
                                           const hidl_vec<uint8_t>& confirmationToken) override;

  private:
    friend class ConfirmationResultCallback;

    // Set rate limiting to not decrement on next abort and aborts
    // confirmationui.
    void cancelPrompt();

    void finalizeTransaction(ConfirmationResponseCode responseCode,
                             hidl_vec<uint8_t> dataThatWasConfirmed);

    // This mutex protects all data below it.
    std::mutex mMutex;

    // The mCurrentListener and mCurrentConfirmationUI fields are set
    // if and only if a prompt is currently showing.
    android::sp<android::IBinder> mCurrentListener;
    android::sp<android::hardware::confirmationui::V1_0::IConfirmationUI> mCurrentConfirmationUI;
    android::IBinder::DeathRecipient* mDeathRecipient;
    hidl_vec<uint8_t> mLatestConfirmationToken;
    RateLimiting<> mRateLimiting;
};

}  // namespace keystore

#endif  // KEYSTORE_CONFIRMATION_MANAGER_H_
