/*
 * Copyright (C) 2021 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 android.view.displayhash;


import static android.content.Context.DISPLAY_HASH_SERVICE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Log;
import android.view.WindowManagerGlobal;

import com.android.internal.annotations.GuardedBy;

import java.util.Collections;
import java.util.Set;

/**
 * Manages DisplayHash requests. The manager object can be retrieved by calling
 * {@code Context.getSystemService(Context.DISPLAY_HASH_SERVICE)}
 */
@SystemService(DISPLAY_HASH_SERVICE)
public final class DisplayHashManager {
    private static final String TAG = "DisplayHashManager";

    private final Object mSupportedHashingAlgorithmLock = new Object();

    @GuardedBy("mSupportedAlgorithmLock")
    private static Set<String> sSupportedHashAlgorithms;

    /**
     * @hide
     */
    public DisplayHashManager() {
    }

    /**
     * Get a Set of DisplayHash algorithms that the device supports.
     *
     * @return a String Set of supported hashing algorithms. The String value of one
     * algorithm should be used when requesting to generate the DisplayHash.
     */
    @NonNull
    public Set<String> getSupportedHashAlgorithms() {
        synchronized (mSupportedHashingAlgorithmLock) {
            if (sSupportedHashAlgorithms != null) {
                return sSupportedHashAlgorithms;
            }

            try {
                String[] supportedAlgorithms = WindowManagerGlobal.getWindowManagerService()
                        .getSupportedDisplayHashAlgorithms();
                if (supportedAlgorithms == null) {
                    return Collections.emptySet();
                }
                sSupportedHashAlgorithms = new ArraySet<>(supportedAlgorithms);
                return sSupportedHashAlgorithms;
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to send request getSupportedHashingAlgorithms", e);
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Call to verify that the DisplayHash passed in was generated by the system.
     *
     * @param displayHash The hash to verify that it was generated by the system.
     * @return a {@link VerifiedDisplayHash} if the hash was generated by the system or null
     * if the hash cannot be verified.
     */
    @Nullable
    public VerifiedDisplayHash verifyDisplayHash(@NonNull DisplayHash displayHash) {
        try {
            return WindowManagerGlobal.getWindowManagerService().verifyDisplayHash(displayHash);
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to send request verifyImpressionToken", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Call to enable or disable the throttling when generating a display hash. This should only be
     * used for testing. Throttling is enabled by default.
     *
     * @hide
     */
    @TestApi
    @RequiresPermission(android.Manifest.permission.READ_FRAME_BUFFER)
    public void setDisplayHashThrottlingEnabled(boolean enable) {
        try {
            WindowManagerGlobal.getWindowManagerService().setDisplayHashThrottlingEnabled(enable);
        } catch (RemoteException e) {
        }
    }
}
