/*
 * 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 com.android.server.oemlock;

import android.annotation.Nullable;
import android.content.Context;
import android.hardware.oemlock.V1_0.IOemLock;
import android.hardware.oemlock.V1_0.OemLockSecureStatus;
import android.hardware.oemlock.V1_0.OemLockStatus;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;

import java.util.ArrayList;
import java.util.NoSuchElementException;

/**
 * Uses the OEM lock HAL.
 */
class VendorLock extends OemLock {
    private static final String TAG = "OemLock";

    private Context mContext;
    private IOemLock mOemLock;

    static IOemLock getOemLockHalService() {
        try {
            return IOemLock.getService();
        } catch (NoSuchElementException e) {
            Slog.i(TAG, "OemLock HAL not present on device");
            return null;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    VendorLock(Context context, IOemLock oemLock) {
        mContext = context;
        mOemLock = oemLock;
    }

    @Override
    void setOemUnlockAllowedByCarrier(boolean allowed, @Nullable byte[] signature) {
        try {
            switch (mOemLock.setOemUnlockAllowedByCarrier(allowed, toByteArrayList(signature))) {
                case OemLockSecureStatus.OK:
                    Slog.i(TAG, "Updated carrier allows OEM lock state to: " + allowed);
                    return;

                case OemLockSecureStatus.INVALID_SIGNATURE:
                    throw new SecurityException(
                            "Invalid signature used in attempt to carrier unlock");

                default:
                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
                    // Fallthrough
                case OemLockSecureStatus.FAILED:
                    throw new RuntimeException("Failed to set carrier OEM unlock state");
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to set carrier state with HAL", e);
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    boolean isOemUnlockAllowedByCarrier() {
        final Integer[] requestStatus = new Integer[1];
        final Boolean[] allowedByCarrier = new Boolean[1];

        try {
            mOemLock.isOemUnlockAllowedByCarrier((status, allowed) -> {
                requestStatus[0] = status;
                allowedByCarrier[0] = allowed;
            });
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to get carrier state from HAL");
            throw e.rethrowFromSystemServer();
        }

        switch (requestStatus[0]) {
            case OemLockStatus.OK:
                // Success
                return allowedByCarrier[0];

            default:
                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
                // Fallthrough
            case OemLockStatus.FAILED:
                throw new RuntimeException("Failed to get carrier OEM unlock state");
        }
    }

    @Override
    void setOemUnlockAllowedByDevice(boolean allowedByDevice) {
        try {
            switch (mOemLock.setOemUnlockAllowedByDevice(allowedByDevice)) {
                case OemLockSecureStatus.OK:
                    Slog.i(TAG, "Updated device allows OEM lock state to: " + allowedByDevice);
                    return;

                default:
                    Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
                    // Fallthrough
                case OemLockSecureStatus.FAILED:
                    throw new RuntimeException("Failed to set device OEM unlock state");
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to set device state with HAL", e);
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    boolean isOemUnlockAllowedByDevice() {
        final Integer[] requestStatus = new Integer[1];
        final Boolean[] allowedByDevice = new Boolean[1];

        try {
            mOemLock.isOemUnlockAllowedByDevice((status, allowed) -> {
                requestStatus[0] = status;
                allowedByDevice[0] = allowed;
            });
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to get devie state from HAL");
            throw e.rethrowFromSystemServer();
        }

        switch (requestStatus[0]) {
            case OemLockStatus.OK:
                // Success
                return allowedByDevice[0];

            default:
                Slog.e(TAG, "Unknown return value indicates code is out of sync with HAL");
                // Fallthrough
            case OemLockStatus.FAILED:
                throw new RuntimeException("Failed to get device OEM unlock state");
        }
    }

    private ArrayList toByteArrayList(byte[] data) {
        if (data == null) {
            return null;
        }
        ArrayList<Byte> result = new ArrayList<Byte>(data.length);
        for (final byte b : data) {
            result.add(b);
        }
        return result;
    }
}
