/*
 * Copyright (C) 2015 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.systemui.keyboard;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
import android.widget.Toast;

import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.Utils;
import com.android.systemui.R;
import com.android.systemui.SystemUI;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;

public class KeyboardUI extends SystemUI implements InputManager.OnTabletModeChangedListener {
    private static final String TAG = "KeyboardUI";
    private static final boolean DEBUG = false;

    // Give BT some time to start after SyUI comes up. This avoids flashing a dialog in the user's
    // face because BT starts a little bit later in the boot process than SysUI and it takes some
    // time for us to receive the signal that it's starting.
    private static final long BLUETOOTH_START_DELAY_MILLIS = 10 * 1000;

    // We will be scanning up to 30 seconds, after which we'll stop.
    private static final long BLUETOOTH_SCAN_TIMEOUT_MILLIS = 30 * 1000;

    private static final int STATE_NOT_ENABLED = -1;
    private static final int STATE_UNKNOWN = 0;
    private static final int STATE_WAITING_FOR_BOOT_COMPLETED = 1;
    private static final int STATE_WAITING_FOR_TABLET_MODE_EXIT = 2;
    private static final int STATE_WAITING_FOR_DEVICE_DISCOVERY = 3;
    private static final int STATE_WAITING_FOR_BLUETOOTH = 4;
    private static final int STATE_PAIRING = 5;
    private static final int STATE_PAIRED = 6;
    private static final int STATE_PAIRING_FAILED = 7;
    private static final int STATE_USER_CANCELLED = 8;
    private static final int STATE_DEVICE_NOT_FOUND = 9;

    private static final int MSG_INIT = 0;
    private static final int MSG_ON_BOOT_COMPLETED = 1;
    private static final int MSG_PROCESS_KEYBOARD_STATE = 2;
    private static final int MSG_ENABLE_BLUETOOTH = 3;
    private static final int MSG_ON_BLUETOOTH_STATE_CHANGED = 4;
    private static final int MSG_ON_DEVICE_BOND_STATE_CHANGED = 5;
    private static final int MSG_ON_BLUETOOTH_DEVICE_ADDED = 6;
    private static final int MSG_ON_BLE_SCAN_FAILED = 7;
    private static final int MSG_SHOW_BLUETOOTH_DIALOG = 8;
    private static final int MSG_DISMISS_BLUETOOTH_DIALOG = 9;
    private static final int MSG_BLE_ABORT_SCAN = 10;
    private static final int MSG_SHOW_ERROR = 11;

    private volatile KeyboardHandler mHandler;
    private volatile KeyboardUIHandler mUIHandler;

    protected volatile Context mContext;

    private boolean mEnabled;
    private String mKeyboardName;
    private CachedBluetoothDeviceManager mCachedDeviceManager;
    private LocalBluetoothAdapter mLocalBluetoothAdapter;
    private LocalBluetoothProfileManager mProfileManager;
    private boolean mBootCompleted;
    private long mBootCompletedTime;

    private int mInTabletMode = InputManager.SWITCH_STATE_UNKNOWN;
    private int mScanAttempt = 0;
    private ScanCallback mScanCallback;
    private BluetoothDialog mDialog;

    private int mState;

    @Override
    public void start() {
        mContext = super.mContext;
        HandlerThread thread = new HandlerThread("Keyboard", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mHandler = new KeyboardHandler(thread.getLooper());
        mHandler.sendEmptyMessage(MSG_INIT);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("KeyboardUI:");
        pw.println("  mEnabled=" + mEnabled);
        pw.println("  mBootCompleted=" + mEnabled);
        pw.println("  mBootCompletedTime=" + mBootCompletedTime);
        pw.println("  mKeyboardName=" + mKeyboardName);
        pw.println("  mInTabletMode=" + mInTabletMode);
        pw.println("  mState=" + stateToString(mState));
    }

    @Override
    protected void onBootCompleted() {
        mHandler.sendEmptyMessage(MSG_ON_BOOT_COMPLETED);
    }

    @Override
    public void onTabletModeChanged(long whenNanos, boolean inTabletMode) {
        if (DEBUG) {
            Slog.d(TAG, "onTabletModeChanged(" + whenNanos + ", " + inTabletMode + ")");
        }

        if (inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_ON
                || !inTabletMode && mInTabletMode != InputManager.SWITCH_STATE_OFF) {
            mInTabletMode = inTabletMode ?
                    InputManager.SWITCH_STATE_ON : InputManager.SWITCH_STATE_OFF;
            processKeyboardState();
        }
    }

    // Shoud only be called on the handler thread
    private void init() {
        Context context = mContext;
        mKeyboardName =
                context.getString(com.android.internal.R.string.config_packagedKeyboardName);
        if (TextUtils.isEmpty(mKeyboardName)) {
            if (DEBUG) {
                Slog.d(TAG, "No packaged keyboard name given.");
            }
            return;
        }

        LocalBluetoothManager bluetoothManager = LocalBluetoothManager.getInstance(context, null);
        if (bluetoothManager == null)  {
            if (DEBUG) {
                Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance");
            }
            return;
        }
        mEnabled = true;
        mCachedDeviceManager = bluetoothManager.getCachedDeviceManager();
        mLocalBluetoothAdapter = bluetoothManager.getBluetoothAdapter();
        mProfileManager = bluetoothManager.getProfileManager();
        bluetoothManager.getEventManager().registerCallback(new BluetoothCallbackHandler());
        Utils.setErrorListener(new BluetoothErrorListener());

        InputManager im = context.getSystemService(InputManager.class);
        im.registerOnTabletModeChangedListener(this, mHandler);
        mInTabletMode = im.isInTabletMode();

        processKeyboardState();
        mUIHandler = new KeyboardUIHandler();
    }

    // Should only be called on the handler thread
    private void processKeyboardState() {
        mHandler.removeMessages(MSG_PROCESS_KEYBOARD_STATE);

        if (!mEnabled) {
            mState = STATE_NOT_ENABLED;
            return;
        }

        if (!mBootCompleted) {
            mState = STATE_WAITING_FOR_BOOT_COMPLETED;
            return;
        }

        if (mInTabletMode != InputManager.SWITCH_STATE_OFF) {
            if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) {
                stopScanning();
            } else if (mState == STATE_WAITING_FOR_BLUETOOTH) {
                mUIHandler.sendEmptyMessage(MSG_DISMISS_BLUETOOTH_DIALOG);
            }
            mState = STATE_WAITING_FOR_TABLET_MODE_EXIT;
            return;
        }

        final int btState = mLocalBluetoothAdapter.getState();
        if ((btState == BluetoothAdapter.STATE_TURNING_ON || btState == BluetoothAdapter.STATE_ON)
                && mState == STATE_WAITING_FOR_BLUETOOTH) {
            // If we're waiting for bluetooth but it has come on in the meantime, or is coming
            // on, just dismiss the dialog. This frequently happens during device startup.
            mUIHandler.sendEmptyMessage(MSG_DISMISS_BLUETOOTH_DIALOG);
        }

        if (btState == BluetoothAdapter.STATE_TURNING_ON) {
            mState = STATE_WAITING_FOR_BLUETOOTH;
            // Wait for bluetooth to fully come on.
            return;
        }

        if (btState != BluetoothAdapter.STATE_ON) {
            mState = STATE_WAITING_FOR_BLUETOOTH;
            showBluetoothDialog();
            return;
        }

        CachedBluetoothDevice device = getPairedKeyboard();
        if (mState == STATE_WAITING_FOR_TABLET_MODE_EXIT || mState == STATE_WAITING_FOR_BLUETOOTH) {
            if (device != null) {
                // If we're just coming out of tablet mode or BT just turned on,
                // then we want to go ahead and automatically connect to the
                // keyboard. We want to avoid this in other cases because we might
                // be spuriously called after the user has manually disconnected
                // the keyboard, meaning we shouldn't try to automtically connect
                // it again.
                mState = STATE_PAIRED;
                device.connect(false);
                return;
            }
            mCachedDeviceManager.clearNonBondedDevices();
        }

        device = getDiscoveredKeyboard();
        if (device != null) {
            mState = STATE_PAIRING;
            device.startPairing();
        } else {
            mState = STATE_WAITING_FOR_DEVICE_DISCOVERY;
            startScanning();
        }
    }

    // Should only be called on the handler thread
    public void onBootCompletedInternal() {
        mBootCompleted = true;
        mBootCompletedTime = SystemClock.uptimeMillis();
        if (mState == STATE_WAITING_FOR_BOOT_COMPLETED) {
            processKeyboardState();
        }
    }

    // Should only be called on the handler thread
    private void showBluetoothDialog() {
        if (isUserSetupComplete()) {
            long now = SystemClock.uptimeMillis();
            long earliestDialogTime = mBootCompletedTime + BLUETOOTH_START_DELAY_MILLIS;
            if (earliestDialogTime < now) {
                mUIHandler.sendEmptyMessage(MSG_SHOW_BLUETOOTH_DIALOG);
            } else {
                mHandler.sendEmptyMessageAtTime(MSG_PROCESS_KEYBOARD_STATE, earliestDialogTime);
            }
        } else {
            // If we're in setup wizard and the keyboard is docked, just automatically enable BT.
            mLocalBluetoothAdapter.enable();
        }
    }

    private boolean isUserSetupComplete() {
        ContentResolver resolver = mContext.getContentResolver();
        return Secure.getIntForUser(
                resolver, Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
    }

    private CachedBluetoothDevice getPairedKeyboard() {
        Set<BluetoothDevice> devices = mLocalBluetoothAdapter.getBondedDevices();
        for (BluetoothDevice d : devices) {
            if (mKeyboardName.equals(d.getName())) {
                return getCachedBluetoothDevice(d);
            }
        }
        return null;
    }

    private CachedBluetoothDevice getDiscoveredKeyboard() {
        Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
        for (CachedBluetoothDevice d : devices) {
            if (d.getName().equals(mKeyboardName)) {
                return d;
            }
        }
        return null;
    }


    private CachedBluetoothDevice getCachedBluetoothDevice(BluetoothDevice d) {
        CachedBluetoothDevice cachedDevice = mCachedDeviceManager.findDevice(d);
        if (cachedDevice == null) {
            cachedDevice = mCachedDeviceManager.addDevice(
                    mLocalBluetoothAdapter, mProfileManager, d);
        }
        return cachedDevice;
    }

    private void startScanning() {
        BluetoothLeScanner scanner = mLocalBluetoothAdapter.getBluetoothLeScanner();
        ScanFilter filter = (new ScanFilter.Builder()).setDeviceName(mKeyboardName).build();
        ScanSettings settings = (new ScanSettings.Builder())
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setReportDelay(0)
            .build();
        mScanCallback = new KeyboardScanCallback();
        scanner.startScan(Arrays.asList(filter), settings, mScanCallback);

        Message abortMsg = mHandler.obtainMessage(MSG_BLE_ABORT_SCAN, ++mScanAttempt, 0);
        mHandler.sendMessageDelayed(abortMsg, BLUETOOTH_SCAN_TIMEOUT_MILLIS);
    }

    private void stopScanning() {
        if (mScanCallback != null) {
            BluetoothLeScanner scanner = mLocalBluetoothAdapter.getBluetoothLeScanner();
            if (scanner != null) {
                scanner.stopScan(mScanCallback);
            }
            mScanCallback = null;
        }
    }

    // Should only be called on the handler thread
    private void bleAbortScanInternal(int scanAttempt) {
        if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY && scanAttempt == mScanAttempt) {
            if (DEBUG) {
                Slog.d(TAG, "Bluetooth scan timed out");
            }
            stopScanning();
            // FIXME: should we also try shutting off bluetooth if we enabled
            // it in the first place?
            mState = STATE_DEVICE_NOT_FOUND;
        }
    }

    // Should only be called on the handler thread
    private void onDeviceAddedInternal(CachedBluetoothDevice d) {
        if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY && d.getName().equals(mKeyboardName)) {
            stopScanning();
            d.startPairing();
            mState = STATE_PAIRING;
        }
    }

    // Should only be called on the handler thread
    private void onBluetoothStateChangedInternal(int bluetoothState) {
        if (bluetoothState == BluetoothAdapter.STATE_ON && mState == STATE_WAITING_FOR_BLUETOOTH) {
            processKeyboardState();
        }
    }

    // Should only be called on the handler thread
    private void onDeviceBondStateChangedInternal(CachedBluetoothDevice d, int bondState) {
        if (mState == STATE_PAIRING && d.getName().equals(mKeyboardName)) {
            if (bondState == BluetoothDevice.BOND_BONDED) {
                // We don't need to manually connect to the device here because it will
                // automatically try to connect after it has been paired.
                mState = STATE_PAIRED;
            } else if (bondState == BluetoothDevice.BOND_NONE) {
                mState = STATE_PAIRING_FAILED;
            }
        }
    }

    // Should only be called on the handler thread
    private void onBleScanFailedInternal() {
        mScanCallback = null;
        if (mState == STATE_WAITING_FOR_DEVICE_DISCOVERY) {
            mState = STATE_DEVICE_NOT_FOUND;
        }
    }

    // Should only be called on the handler thread. We want to be careful not to show errors for
    // pairings not initiated by this UI, so we only pop up the toast when we're at an appropriate
    // point in our pairing flow and it's the expected device.
    private void onShowErrorInternal(Context context, String name, int messageResId) {
        if ((mState == STATE_PAIRING || mState == STATE_PAIRING_FAILED)
                && mKeyboardName.equals(name)) {
            String message = context.getString(messageResId, name);
            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
        }
    }

    private final class KeyboardUIHandler extends Handler {
        public KeyboardUIHandler() {
            super(Looper.getMainLooper(), null, true /*async*/);
        }
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_SHOW_BLUETOOTH_DIALOG: {
                    if (mDialog != null) {
                        // Don't show another dialog if one is already present
                        break;
                    }
                    DialogInterface.OnClickListener clickListener =
                            new BluetoothDialogClickListener();
                    DialogInterface.OnDismissListener dismissListener =
                            new BluetoothDialogDismissListener();
                    mDialog = new BluetoothDialog(mContext);
                    mDialog.setTitle(R.string.enable_bluetooth_title);
                    mDialog.setMessage(R.string.enable_bluetooth_message);
                    mDialog.setPositiveButton(
                            R.string.enable_bluetooth_confirmation_ok, clickListener);
                    mDialog.setNegativeButton(android.R.string.cancel, clickListener);
                    mDialog.setOnDismissListener(dismissListener);
                    mDialog.show();
                    break;
                }
                case MSG_DISMISS_BLUETOOTH_DIALOG: {
                    if (mDialog != null) {
                        mDialog.dismiss();
                    }
                    break;
                }
            }
        }
    }

    private final class KeyboardHandler extends Handler {
        public KeyboardHandler(Looper looper) {
            super(looper, null, true /*async*/);
        }

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_INIT: {
                    init();
                    break;
                }
                case MSG_ON_BOOT_COMPLETED: {
                    onBootCompletedInternal();
                    break;
                }
                case MSG_PROCESS_KEYBOARD_STATE: {
                    processKeyboardState();
                    break;
                }
                case MSG_ENABLE_BLUETOOTH: {
                    boolean enable = msg.arg1 == 1;
                    if (enable) {
                        mLocalBluetoothAdapter.enable();
                    } else {
                        mState = STATE_USER_CANCELLED;
                    }
                    break;
                }
                case MSG_BLE_ABORT_SCAN: {
                    int scanAttempt = msg.arg1;
                    bleAbortScanInternal(scanAttempt);
                    break;
                }
                case MSG_ON_BLUETOOTH_STATE_CHANGED: {
                    int bluetoothState = msg.arg1;
                    onBluetoothStateChangedInternal(bluetoothState);
                    break;
                }
                case MSG_ON_DEVICE_BOND_STATE_CHANGED: {
                    CachedBluetoothDevice d = (CachedBluetoothDevice)msg.obj;
                    int bondState = msg.arg1;
                    onDeviceBondStateChangedInternal(d, bondState);
                    break;
                }
                case MSG_ON_BLUETOOTH_DEVICE_ADDED: {
                    BluetoothDevice d = (BluetoothDevice)msg.obj;
                    CachedBluetoothDevice cachedDevice = getCachedBluetoothDevice(d);
                    onDeviceAddedInternal(cachedDevice);
                    break;

                }
                case MSG_ON_BLE_SCAN_FAILED: {
                    onBleScanFailedInternal();
                    break;
                }
                case MSG_SHOW_ERROR: {
                    Pair<Context, String> p = (Pair<Context, String>) msg.obj;
                    onShowErrorInternal(p.first, p.second, msg.arg1);
                }
            }
        }
    }

    private final class BluetoothDialogClickListener implements DialogInterface.OnClickListener {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            int enable = DialogInterface.BUTTON_POSITIVE == which ? 1 : 0;
            mHandler.obtainMessage(MSG_ENABLE_BLUETOOTH, enable, 0).sendToTarget();
            mDialog = null;
        }
    }

    private final class BluetoothDialogDismissListener
            implements DialogInterface.OnDismissListener {
        @Override
        public void onDismiss(DialogInterface dialog) {
            mDialog = null;
        }
    }

    private final class KeyboardScanCallback extends ScanCallback {

        private boolean isDeviceDiscoverable(ScanResult result) {
            final ScanRecord scanRecord = result.getScanRecord();
            final int flags = scanRecord.getAdvertiseFlags();
            final int BT_DISCOVERABLE_MASK = 0x03;

            return (flags & BT_DISCOVERABLE_MASK) != 0;
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            if (DEBUG) {
                Slog.d(TAG, "onBatchScanResults(" + results.size() + ")");
            }

            BluetoothDevice bestDevice = null;
            int bestRssi = Integer.MIN_VALUE;

            for (ScanResult result : results) {
                if (DEBUG) {
                    Slog.d(TAG, "onBatchScanResults: considering " + result);
                }

                if (isDeviceDiscoverable(result) && result.getRssi() > bestRssi) {
                    bestDevice = result.getDevice();
                    bestRssi = result.getRssi();
                }
            }

            if (bestDevice != null) {
                mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED, bestDevice).sendToTarget();
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            if (DEBUG) {
                Slog.d(TAG, "onScanFailed(" + errorCode + ")");
            }
            mHandler.obtainMessage(MSG_ON_BLE_SCAN_FAILED).sendToTarget();
        }

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            if (DEBUG) {
                Slog.d(TAG, "onScanResult(" + callbackType + ", " + result + ")");
            }

            if (isDeviceDiscoverable(result)) {
                mHandler.obtainMessage(MSG_ON_BLUETOOTH_DEVICE_ADDED,
                        result.getDevice()).sendToTarget();
            } else if (DEBUG) {
                Slog.d(TAG, "onScanResult: device " + result.getDevice() +
                       " is not discoverable, ignoring");
            }
        }
    }

    private final class BluetoothCallbackHandler implements BluetoothCallback {
        @Override
        public void onBluetoothStateChanged(int bluetoothState) {
            mHandler.obtainMessage(MSG_ON_BLUETOOTH_STATE_CHANGED,
                    bluetoothState, 0).sendToTarget();
        }

        @Override
        public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
            mHandler.obtainMessage(MSG_ON_DEVICE_BOND_STATE_CHANGED,
                    bondState, 0, cachedDevice).sendToTarget();
        }

        @Override
        public void onDeviceAdded(CachedBluetoothDevice cachedDevice) { }
        @Override
        public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) { }
        @Override
        public void onScanningStateChanged(boolean started) { }
        @Override
        public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) { }
        @Override
        public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice,
                                          int bluetoothProfile) { }

        @Override
        public void onAudioModeChanged() { }
    }

    private final class BluetoothErrorListener implements Utils.ErrorListener {
        public void onShowError(Context context, String name, int messageResId) {
            mHandler.obtainMessage(MSG_SHOW_ERROR, messageResId, 0 /*unused*/,
                    new Pair<>(context, name)).sendToTarget();
        }
    }

    private static String stateToString(int state) {
        switch (state) {
            case STATE_NOT_ENABLED:
                return "STATE_NOT_ENABLED";
            case STATE_WAITING_FOR_BOOT_COMPLETED:
                return "STATE_WAITING_FOR_BOOT_COMPLETED";
            case STATE_WAITING_FOR_TABLET_MODE_EXIT:
                return "STATE_WAITING_FOR_TABLET_MODE_EXIT";
            case STATE_WAITING_FOR_DEVICE_DISCOVERY:
                return "STATE_WAITING_FOR_DEVICE_DISCOVERY";
            case STATE_WAITING_FOR_BLUETOOTH:
                return "STATE_WAITING_FOR_BLUETOOTH";
            case STATE_PAIRING:
                return "STATE_PAIRING";
            case STATE_PAIRED:
                return "STATE_PAIRED";
            case STATE_PAIRING_FAILED:
                return "STATE_PAIRING_FAILED";
            case STATE_USER_CANCELLED:
                return "STATE_USER_CANCELLED";
            case STATE_DEVICE_NOT_FOUND:
                return "STATE_DEVICE_NOT_FOUND";
            case STATE_UNKNOWN:
            default:
                return "STATE_UNKNOWN (" + state + ")";
        }
    }
}
