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

import static android.telephony.TelephonyManager.CALL_STATE_IDLE;
import static android.telephony.TelephonyManager.CALL_STATE_OFFHOOK;
import static android.telephony.TelephonyManager.CALL_STATE_RINGING;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.PowerManager;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.server.wifi.util.WifiHandler;
import com.android.wifi.resources.R;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.List;

/**
 * This class provides the Support for SAR to control WiFi TX power limits.
 * It deals with the following:
 * - Tracking the STA state through calls from  the ClientModeManager.
 * - Tracking the SAP state through calls from SoftApManager
 * - Tracking the Scan-Only state through ScanOnlyModeManager
 * - Tracking the state of the Cellular calls or data.
 * - It constructs the sar info and send it towards the HAL
 */
public class SarManager {
    // Period for checking on voice steam active (in ms)
    private static final int CHECK_VOICE_STREAM_INTERVAL_MS = 5000;

    /**
     * @hide constants copied over from {@link AudioManager}
     * TODO(b/144250387): Migrate to public API
     */
    private static final String STREAM_DEVICES_CHANGED_ACTION =
            "android.media.stream_devices_changed_action";
    private static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
    private static final String EXTRA_VOLUME_STREAM_DEVICES =
            "android.media.EXTRA_VOLUME_STREAM_DEVICES";
    private static final String EXTRA_PREV_VOLUME_STREAM_DEVICES =
            "android.media.EXTRA_PREV_VOLUME_STREAM_DEVICES";
    private static final int DEVICE_OUT_EARPIECE = 0x1;

    /* For Logging */
    private static final String TAG = "WifiSarManager";
    private boolean mVerboseLoggingEnabled = true;

    private SarInfo mSarInfo;

    /* Configuration for SAR support */
    private boolean mSupportSarTxPowerLimit;
    private boolean mSupportSarVoiceCall;
    private boolean mSupportSarSoftAp;

    // Device starts with screen on
    private boolean mScreenOn = false;
    private boolean mIsVoiceStreamCheckEnabled = false;

    /**
     * Other parameters passed in or created in the constructor.
     */
    private final Context mContext;
    private final TelephonyManager mTelephonyManager;
    private final AudioManager mAudioManager;
    private final WifiPhoneStateListener mPhoneStateListener;
    private final WifiNative mWifiNative;
    private final Handler mHandler;

    /**
     * Create new instance of SarManager.
     */
    SarManager(Context context,
               TelephonyManager telephonyManager,
               Looper looper,
               WifiNative wifiNative) {
        mContext = context;
        mTelephonyManager = telephonyManager;
        mWifiNative = wifiNative;
        mAudioManager = mContext.getSystemService(AudioManager.class);
        mHandler = new WifiHandler(TAG, looper);
        mPhoneStateListener = new WifiPhoneStateListener(looper);
    }

    /**
     * Handle boot completed, read config flags.
     */
    public void handleBootCompleted() {
        readSarConfigs();
        if (mSupportSarTxPowerLimit) {
            mSarInfo = new SarInfo();
            setSarConfigsInInfo();
            registerListeners();
        }
    }

    /**
     * Notify SarManager of screen status change
     */
    private void handleScreenStateChanged(boolean screenOn) {
        if (!mSupportSarVoiceCall) {
            return;
        }

        if (mScreenOn == screenOn) {
            return;
        }

        if (mVerboseLoggingEnabled) {
            Log.d(TAG, "handleScreenStateChanged: screenOn = " + screenOn);
        }

        mScreenOn = screenOn;

        // Only schedule a voice stream check if screen is turning on, and it is currently not
        // scheduled
        if (mScreenOn && !mIsVoiceStreamCheckEnabled) {
            mHandler.post(() -> {
                checkAudioDevice();
            });

            mIsVoiceStreamCheckEnabled = true;
        }
    }

    private boolean isVoiceCallOnEarpiece() {
        final AudioAttributes voiceCallAttr = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
                .build();
        List<AudioDeviceAttributes> devices = mAudioManager.getDevicesForAttributes(voiceCallAttr);
        for (AudioDeviceAttributes device : devices) {
            if (device.getRole() == AudioDeviceAttributes.ROLE_OUTPUT
                    && device.getType() == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
                return true;
            }
        }
        return false;
    }

    private boolean isVoiceCallStreamActive() {
        int mode = mAudioManager.getMode();
        return mode == AudioManager.MODE_IN_COMMUNICATION || mode == AudioManager.MODE_IN_CALL;
    }

    private void checkAudioDevice() {
        // First Check if audio stream is on
        boolean voiceStreamActive = isVoiceCallStreamActive();
        boolean earPieceActive;

        if (voiceStreamActive) {
            // Check on the audio route
            earPieceActive = isVoiceCallOnEarpiece();

            if (mVerboseLoggingEnabled) {
                Log.d(TAG, "EarPiece active = " + earPieceActive);
            }
        } else {
            earPieceActive = false;
        }

        // If audio route has changed, update SAR
        if (earPieceActive != mSarInfo.isEarPieceActive) {
            mSarInfo.isEarPieceActive = earPieceActive;
            updateSarScenario();
        }

        // Now should we proceed with the checks
        if (!mScreenOn && !voiceStreamActive) {
            // No need to continue checking
            mIsVoiceStreamCheckEnabled = false;
        } else {
            // Schedule another check
            mHandler.postDelayed(() -> {
                checkAudioDevice();
            }, CHECK_VOICE_STREAM_INTERVAL_MS);
        }
    }

    private void readSarConfigs() {
        mSupportSarTxPowerLimit = mContext.getResources().getBoolean(
                R.bool.config_wifi_framework_enable_sar_tx_power_limit);
        /* In case SAR is disabled,
           then all SAR inputs are automatically disabled as well (irrespective of the config) */
        if (!mSupportSarTxPowerLimit) {
            mSupportSarVoiceCall = false;
            mSupportSarSoftAp = false;
            return;
        }

        /* Voice calls are supported when SAR is supported */
        mSupportSarVoiceCall = true;

        mSupportSarSoftAp = mContext.getResources().getBoolean(
                R.bool.config_wifi_framework_enable_soft_ap_sar_tx_power_limit);
    }

    private void setSarConfigsInInfo() {
        mSarInfo.sarVoiceCallSupported = mSupportSarVoiceCall;
        mSarInfo.sarSapSupported = mSupportSarSoftAp;
    }

    private void registerListeners() {
        if (mSupportSarVoiceCall) {
            /* Listen for Phone State changes */
            registerPhoneStateListener();
            registerVoiceStreamListener();
            registerScreenListener();
        }
    }

    private void registerScreenListener() {
        // Listen to screen changes
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);

        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();
                        if (action.equals(Intent.ACTION_SCREEN_ON)) {
                            handleScreenStateChanged(true);
                        } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                            handleScreenStateChanged(false);
                        }
                    }
                }, filter, null, mHandler);
        PowerManager powerManager = mContext.getSystemService(PowerManager.class);
        handleScreenStateChanged(powerManager.isInteractive());
    }

    private void registerVoiceStreamListener() {
        Log.i(TAG, "Registering for voice stream status");

        // Register for listening to transitions of change of voice stream devices
        IntentFilter filter = new IntentFilter();
        filter.addAction(STREAM_DEVICES_CHANGED_ACTION);

        mContext.registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        boolean voiceStreamActive = isVoiceCallStreamActive();
                        if (!voiceStreamActive) {
                            // No need to proceed, there is no voice call ongoing
                            return;
                        }

                        String action = intent.getAction();
                        int streamType =
                                intent.getIntExtra(EXTRA_VOLUME_STREAM_TYPE, -1);
                        int device = intent.getIntExtra(EXTRA_VOLUME_STREAM_DEVICES, -1);
                        int oldDevice = intent.getIntExtra(EXTRA_PREV_VOLUME_STREAM_DEVICES, -1);

                        if (streamType == AudioManager.STREAM_VOICE_CALL) {
                            boolean earPieceActive = mSarInfo.isEarPieceActive;
                            if (device == DEVICE_OUT_EARPIECE) {
                                if (mVerboseLoggingEnabled) {
                                    Log.d(TAG, "Switching to earpiece : HEAD ON");
                                    Log.d(TAG, "Old device = " + oldDevice);
                                }
                                earPieceActive = true;
                            } else if (oldDevice == DEVICE_OUT_EARPIECE) {
                                if (mVerboseLoggingEnabled) {
                                    Log.d(TAG, "Switching from earpiece : HEAD OFF");
                                    Log.d(TAG, "New device = " + device);
                                }
                                earPieceActive = false;
                            }

                            if (earPieceActive != mSarInfo.isEarPieceActive) {
                                mSarInfo.isEarPieceActive = earPieceActive;
                                updateSarScenario();
                            }
                        }
                    }
                }, filter, null, mHandler);
    }

    /**
     * Register the phone state listener.
     */
    private void registerPhoneStateListener() {
        Log.i(TAG, "Registering for telephony call state changes");
        mTelephonyManager.listen(
                mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    /**
     * Update Wifi Client State
     */
    public void setClientWifiState(int state) {
        boolean newIsEnabled;
        /* No action is taken if SAR is not supported */
        if (!mSupportSarTxPowerLimit) {
            return;
        }

        if (state == WifiManager.WIFI_STATE_DISABLED) {
            newIsEnabled = false;
        } else if (state == WifiManager.WIFI_STATE_ENABLED) {
            newIsEnabled = true;
        } else {
            /* No change so exiting with no action */
            return;
        }

        /* Report change to HAL if needed */
        if (mSarInfo.isWifiClientEnabled != newIsEnabled) {
            mSarInfo.isWifiClientEnabled = newIsEnabled;
            updateSarScenario();
        }
    }

    /**
     * Update Wifi SoftAP State
     */
    public void setSapWifiState(int state) {
        boolean newIsEnabled;
        /* No action is taken if SAR is not supported */
        if (!mSupportSarTxPowerLimit) {
            return;
        }

        if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
            newIsEnabled = false;
        } else if (state == WifiManager.WIFI_AP_STATE_ENABLED) {
            newIsEnabled = true;
        } else {
            /* No change so exiting with no action */
            return;
        }

        /* Report change to HAL if needed */
        if (mSarInfo.isWifiSapEnabled != newIsEnabled) {
            mSarInfo.isWifiSapEnabled = newIsEnabled;
            updateSarScenario();
        }
    }

    /**
     * Update Wifi ScanOnly State
     */
    public void setScanOnlyWifiState(int state) {
        boolean newIsEnabled;
        /* No action is taken if SAR is not supported */
        if (!mSupportSarTxPowerLimit) {
            return;
        }

        if (state == WifiManager.WIFI_STATE_DISABLED) {
            newIsEnabled = false;
        } else if (state == WifiManager.WIFI_STATE_ENABLED) {
            newIsEnabled = true;
        } else {
            /* No change so exiting with no action */
            return;
        }

        /* Report change to HAL if needed */
        if (mSarInfo.isWifiScanOnlyEnabled != newIsEnabled) {
            mSarInfo.isWifiScanOnlyEnabled = newIsEnabled;
            updateSarScenario();
        }
    }

    /**
     * Report Cell state event
     */
    private void onCellStateChangeEvent(int state) {
        boolean newIsVoiceCall;
        switch (state) {
            case CALL_STATE_OFFHOOK:
            case CALL_STATE_RINGING:
                newIsVoiceCall = true;
                break;

            case CALL_STATE_IDLE:
                newIsVoiceCall = false;
                break;

            default:
                Log.e(TAG, "Invalid Cell State: " + state);
                return;
        }

        /* Report change to HAL if needed */
        if (mSarInfo.isVoiceCall != newIsVoiceCall) {
            mSarInfo.isVoiceCall = newIsVoiceCall;

            if (mVerboseLoggingEnabled) {
                Log.d(TAG, "Voice Call = " + newIsVoiceCall);
            }
            updateSarScenario();
        }
    }

    /**
     * Enable/disable verbose logging.
     */
    public void enableVerboseLogging(int verbose) {
        if (verbose > 0) {
            mVerboseLoggingEnabled = true;
        } else {
            mVerboseLoggingEnabled = false;
        }
    }

    /**
     * dump()
     * Dumps SarManager state (as well as its SarInfo member variable state)
     */
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("Dump of SarManager");
        pw.println("isSarSupported: " + mSupportSarTxPowerLimit);
        pw.println("isSarVoiceCallSupported: " + mSupportSarVoiceCall);
        pw.println("isSarSoftApSupported: " + mSupportSarSoftAp);
        pw.println("");
        if (mSarInfo != null) {
            mSarInfo.dump(fd, pw, args);
        }
    }

    /**
     * Listen for phone call state events to set/reset TX power limits for SAR requirements.
     */
    private class WifiPhoneStateListener extends PhoneStateListener {
        WifiPhoneStateListener(Looper looper) {
            super(new HandlerExecutor(new Handler(looper)));
        }

        /**
         * onCallStateChanged()
         * This callback is called when a call state event is received
         * Note that this runs in the WifiCoreHandlerThread
         * since the corresponding Looper was passed to the WifiPhoneStateListener constructor.
         */
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            Log.d(TAG, "Received Phone State Change: " + state);

            /* In case of an unsolicited event */
            if (!mSupportSarTxPowerLimit || !mSupportSarVoiceCall) {
                return;
            }
            onCellStateChangeEvent(state);
        }
    }

    /**
     * updateSarScenario()
     * Update HAL with the new SAR scenario if needed.
     */
    private void updateSarScenario() {
        if (!mSarInfo.shouldReport()) {
            return;
        }

        /* Report info to HAL*/
        if (mWifiNative.selectTxPowerScenario(mSarInfo)) {
            mSarInfo.reportingSuccessful();
        } else {
            Log.e(TAG, "Failed in WifiNative.selectTxPowerScenario()");
        }

        return;
    }
}
