/*
 * Copyright (C) 2019 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.wm;

import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE;
import static android.provider.AndroidDeviceConfig.KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP;

import android.provider.AndroidDeviceConfig;
import android.provider.DeviceConfig;
import android.provider.DeviceConfigInterface;

import com.android.internal.annotations.VisibleForTesting;

import java.io.PrintWriter;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
 * Settings constants that can modify the window manager's behavior.
 */
final class WindowManagerConstants {

    /**
     * The minimum duration between gesture exclusion logging for a given window in
     * milliseconds.
     *
     * Events that happen in-between will be silently dropped.
     *
     * A non-positive value disables logging.
     *
     * <p>Note: On Devices running Q, this key is in the "android:window_manager" namespace.
     *
     * @see android.provider.DeviceConfig#NAMESPACE_WINDOW_MANAGER
     */
    static final String KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS =
            "system_gesture_exclusion_log_debounce_millis";

    private static final int MIN_GESTURE_EXCLUSION_LIMIT_DP = 200;

    /** @see #KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS */
    long mSystemGestureExclusionLogDebounceTimeoutMillis;
    /** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP */
    int mSystemGestureExclusionLimitDp;
    /** @see AndroidDeviceConfig#KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE */
    boolean mSystemGestureExcludedByPreQStickyImmersive;

    private final WindowManagerGlobalLock mGlobalLock;
    private final Runnable mUpdateSystemGestureExclusionCallback;
    private final DeviceConfigInterface mDeviceConfig;
    private final DeviceConfig.OnPropertiesChangedListener mListenerAndroid;
    private final DeviceConfig.OnPropertiesChangedListener mListenerWindowManager;

    WindowManagerConstants(WindowManagerService service, DeviceConfigInterface deviceConfig) {
        this(service.mGlobalLock, () -> service.mRoot.forAllDisplays(
                DisplayContent::updateSystemGestureExclusionLimit), deviceConfig);
    }

    @VisibleForTesting
    WindowManagerConstants(WindowManagerGlobalLock globalLock,
            Runnable updateSystemGestureExclusionCallback,
            DeviceConfigInterface deviceConfig) {
        mGlobalLock = Objects.requireNonNull(globalLock);
        mUpdateSystemGestureExclusionCallback = Objects.requireNonNull(updateSystemGestureExclusionCallback);
        mDeviceConfig = deviceConfig;
        mListenerAndroid = this::onAndroidPropertiesChanged;
        mListenerWindowManager = this::onWindowPropertiesChanged;
    }

    void start(Executor executor) {
        mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ANDROID, executor,
                mListenerAndroid);
        mDeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                executor, mListenerWindowManager);

        updateSystemGestureExclusionLogDebounceMillis();
        updateSystemGestureExclusionLimitDp();
        updateSystemGestureExcludedByPreQStickyImmersive();
    }

    private void onAndroidPropertiesChanged(DeviceConfig.Properties properties) {
        synchronized (mGlobalLock) {
            boolean updateSystemGestureExclusionLimit = false;
            for (String name : properties.getKeyset()) {
                if (name == null) {
                    return;
                }
                switch (name) {
                    case KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP:
                        updateSystemGestureExclusionLimitDp();
                        updateSystemGestureExclusionLimit = true;
                        break;
                    case KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE:
                        updateSystemGestureExcludedByPreQStickyImmersive();
                        updateSystemGestureExclusionLimit = true;
                        break;
                    default:
                        break;
                }
            }
            if (updateSystemGestureExclusionLimit) {
                mUpdateSystemGestureExclusionCallback.run();
            }
        }
    }

    private void onWindowPropertiesChanged(DeviceConfig.Properties properties) {
        synchronized (mGlobalLock) {
            for (String name : properties.getKeyset()) {
                if (name == null) {
                    return;
                }
                switch (name) {
                    case KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS:
                        updateSystemGestureExclusionLogDebounceMillis();
                        break;
                    default:
                        break;
                }
            }
        }
    }

    private void updateSystemGestureExclusionLogDebounceMillis() {
        mSystemGestureExclusionLogDebounceTimeoutMillis =
                mDeviceConfig.getLong(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
                        KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS, 0);
    }

    private void updateSystemGestureExclusionLimitDp() {
        mSystemGestureExclusionLimitDp = Math.max(MIN_GESTURE_EXCLUSION_LIMIT_DP,
                mDeviceConfig.getInt(DeviceConfig.NAMESPACE_ANDROID,
                        KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP, 0));
    }

    private void updateSystemGestureExcludedByPreQStickyImmersive() {
        mSystemGestureExcludedByPreQStickyImmersive = mDeviceConfig.getBoolean(
                DeviceConfig.NAMESPACE_ANDROID,
                KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE, false);
    }

    void dump(PrintWriter pw) {
        pw.println("WINDOW MANAGER CONSTANTS (dumpsys window constants):");

        pw.print("  "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LOG_DEBOUNCE_MILLIS);
        pw.print("="); pw.println(mSystemGestureExclusionLogDebounceTimeoutMillis);
        pw.print("  "); pw.print(KEY_SYSTEM_GESTURE_EXCLUSION_LIMIT_DP);
        pw.print("="); pw.println(mSystemGestureExclusionLimitDp);
        pw.print("  "); pw.print(KEY_SYSTEM_GESTURES_EXCLUDED_BY_PRE_Q_STICKY_IMMERSIVE);
        pw.print("="); pw.println(mSystemGestureExcludedByPreQStickyImmersive);
        pw.println();
    }
}
