package com.android.server.vr;

import static android.view.Display.INVALID_DISPLAY;

import android.app.ActivityManagerInternal;
import android.app.Vr2dDisplayProperties;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.ImageReader;
import android.os.Handler;
import android.os.RemoteException;
import android.service.vr.IPersistentVrStateCallbacks;
import android.service.vr.IVrManager;
import android.util.Log;
import android.view.Surface;

import com.android.server.LocalServices;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;

/**
 * Creates a 2D Virtual Display while VR Mode is enabled. This display will be used to run and
 * render 2D app within a VR experience. For example, bringing up the 2D calculator app in VR.
 */
class Vr2dDisplay {
    private final static String TAG = "Vr2dDisplay";
    private final static boolean DEBUG = false;

    private int mVirtualDisplayHeight;
    private int mVirtualDisplayWidth;
    private int mVirtualDisplayDpi;
    private final static int STOP_VIRTUAL_DISPLAY_DELAY_MILLIS = 2000;
    private final static String UNIQUE_DISPLAY_ID = "277f1a09-b88d-4d1e-8716-796f114d080b";
    private final static String DISPLAY_NAME = "VR 2D Display";

    private final static String DEBUG_ACTION_SET_MODE =
            "com.android.server.vr.Vr2dDisplay.SET_MODE";
    private final static String DEBUG_EXTRA_MODE_ON =
            "com.android.server.vr.Vr2dDisplay.EXTRA_MODE_ON";
    private final static String DEBUG_ACTION_SET_SURFACE =
            "com.android.server.vr.Vr2dDisplay.SET_SURFACE";
    private final static String DEBUG_EXTRA_SURFACE =
            "com.android.server.vr.Vr2dDisplay.EXTRA_SURFACE";

    /**
     * The default width of the VR virtual display
     */
    public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400;

    /**
     * The default height of the VR virtual display
     */
    public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1800;

    /**
     * The default height of the VR virtual dpi.
     */
    public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320;

    /**
     * The minimum height, width and dpi of VR virtual display.
     */
    public static final int MIN_VR_DISPLAY_WIDTH = 1;
    public static final int MIN_VR_DISPLAY_HEIGHT = 1;
    public static final int MIN_VR_DISPLAY_DPI = 1;

    private final ActivityManagerInternal mActivityManagerInternal;
    private final WindowManagerInternal mWindowManagerInternal;
    private final DisplayManager mDisplayManager;
    private final IVrManager mVrManager;
    private final Object mVdLock = new Object();
    private final Handler mHandler = new Handler();

    /**
     * Callback implementation to receive changes to VrMode.
     **/
    private final IPersistentVrStateCallbacks mVrStateCallbacks =
            new IPersistentVrStateCallbacks.Stub() {
        @Override
        public void onPersistentVrStateChanged(boolean enabled) {
            if (enabled != mIsPersistentVrModeEnabled) {
                mIsPersistentVrModeEnabled = enabled;
                updateVirtualDisplay();
            }
        }
    };

    private VirtualDisplay mVirtualDisplay;
    private Surface mSurface;
    private ImageReader mImageReader;
    private Runnable mStopVDRunnable;
    private boolean mIsVrModeOverrideEnabled;  // debug override to set vr mode.
    private boolean mIsVirtualDisplayAllowed = true;  // Virtual-display feature toggle
    private boolean mIsPersistentVrModeEnabled;  // indicates we are in vr persistent mode.
    private boolean mBootsToVr = false;  // The device boots into VR (standalone VR device)

    public Vr2dDisplay(DisplayManager displayManager,
           ActivityManagerInternal activityManagerInternal,
           WindowManagerInternal windowManagerInternal, IVrManager vrManager) {
        mDisplayManager = displayManager;
        mActivityManagerInternal = activityManagerInternal;
        mWindowManagerInternal = windowManagerInternal;
        mVrManager = vrManager;
        mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH;
        mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT;
        mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI;
    }

    /**
     * Initializes the compabilitiy display by listening to VR mode changes.
     */
    public void init(Context context, boolean bootsToVr) {
        startVrModeListener();
        startDebugOnlyBroadcastReceiver(context);
        mBootsToVr = bootsToVr;
        if (mBootsToVr) {
          // If we are booting into VR, we need to start the virtual display immediately. This
          // ensures that the virtual display is up by the time Setup Wizard is started.
          updateVirtualDisplay();
        }
    }

    /**
     * Creates and Destroys the virtual display depending on the current state of VrMode.
     */
    private void updateVirtualDisplay() {
        if (DEBUG) {
            Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: "
                    + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed
                    + ", bootsToVr: " + mBootsToVr);
        }

        if (shouldRunVirtualDisplay()) {
            Log.i(TAG, "Attempting to start virtual display");
            // TODO: Consider not creating the display until ActivityManager needs one on
            // which to display a 2D application.
            startVirtualDisplay();
        } else {
            // Stop virtual display to test exit condition
            stopVirtualDisplay();
        }
    }

    /**
     * Creates a DEBUG-only BroadcastReceiver through which a test app can simulate VrMode and
     * set a custom Surface for the virtual display.  This allows testing of the virtual display
     * without going into full 3D.
     *
     * @param context The context.
     */
    private void startDebugOnlyBroadcastReceiver(Context context) {
        if (DEBUG) {
            IntentFilter intentFilter = new IntentFilter(DEBUG_ACTION_SET_MODE);
            intentFilter.addAction(DEBUG_ACTION_SET_SURFACE);

            context.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    final String action = intent.getAction();
                    if (DEBUG_ACTION_SET_MODE.equals(action)) {
                        mIsVrModeOverrideEnabled =
                                intent.getBooleanExtra(DEBUG_EXTRA_MODE_ON, false);
                        updateVirtualDisplay();
                    } else if (DEBUG_ACTION_SET_SURFACE.equals(action)) {
                        if (mVirtualDisplay != null) {
                            if (intent.hasExtra(DEBUG_EXTRA_SURFACE)) {
                                setSurfaceLocked(intent.getParcelableExtra(DEBUG_EXTRA_SURFACE));
                            }
                        } else {
                            Log.w(TAG, "Cannot set the surface because the VD is null.");
                        }
                    }
                }
            }, intentFilter);
        }
    }

    /**
     * Starts listening to VrMode changes.
     */
    private void startVrModeListener() {
        if (mVrManager != null) {
            try {
                mVrManager.registerPersistentVrStateListener(mVrStateCallbacks);
            } catch (RemoteException e) {
                Log.e(TAG, "Could not register VR State listener.", e);
            }
        }
    }

    /**
     * Sets the resolution and DPI of the Vr2d virtual display used to display
     * 2D applications in VR mode.
     *
     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
     *
     * @param displayProperties Properties of the virtual display for 2D applications
     * in VR mode.
     */
    public void setVirtualDisplayProperties(Vr2dDisplayProperties displayProperties) {
        synchronized(mVdLock) {
            if (DEBUG) {
                Log.i(TAG, "VD setVirtualDisplayProperties: " +
                        displayProperties.toString());
            }

            int width = displayProperties.getWidth();
            int height = displayProperties.getHeight();
            int dpi = displayProperties.getDpi();
            boolean resized = false;

            if (width < MIN_VR_DISPLAY_WIDTH || height < MIN_VR_DISPLAY_HEIGHT ||
                    dpi < MIN_VR_DISPLAY_DPI) {
                Log.i(TAG, "Ignoring Width/Height/Dpi values of " + width + "," + height + ","
                        + dpi);
            } else {
                Log.i(TAG, "Setting width/height/dpi to " + width + "," + height + "," + dpi);
                mVirtualDisplayWidth = width;
                mVirtualDisplayHeight = height;
                mVirtualDisplayDpi = dpi;
                resized = true;
            }

            if ((displayProperties.getAddedFlags() &
                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
                mIsVirtualDisplayAllowed = true;
            } else if ((displayProperties.getRemovedFlags() &
                    Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED)
                    == Vr2dDisplayProperties.FLAG_VIRTUAL_DISPLAY_ENABLED) {
                mIsVirtualDisplayAllowed = false;
            }

            if (mVirtualDisplay != null && resized && mIsVirtualDisplayAllowed) {
                mVirtualDisplay.resize(mVirtualDisplayWidth, mVirtualDisplayHeight,
                    mVirtualDisplayDpi);
                ImageReader oldImageReader = mImageReader;
                mImageReader = null;
                startImageReader();
                oldImageReader.close();
            }

            // Start/Stop the virtual display in case the updates indicated that we should.
            updateVirtualDisplay();
        }
    }

    /**
     * Returns the virtual display ID if one currently exists, otherwise returns
     * {@link INVALID_DISPLAY_ID}.
     *
     * @return The virtual display ID.
     */
    public int getVirtualDisplayId() {
        synchronized(mVdLock) {
            if (mVirtualDisplay != null) {
                int virtualDisplayId = mVirtualDisplay.getDisplay().getDisplayId();
                if (DEBUG) {
                    Log.i(TAG, "VD id: " + virtualDisplayId);
                }
                return virtualDisplayId;
            }
        }
        return INVALID_DISPLAY;
    }

    /**
     * Starts the virtual display if one does not already exist.
     */
    private void startVirtualDisplay() {
        if (DEBUG) {
            Log.d(TAG, "Request to start VD, DM:" + mDisplayManager);
        }

        if (mDisplayManager == null) {
            Log.w(TAG, "Cannot create virtual display because mDisplayManager == null");
            return;
        }

        synchronized (mVdLock) {
            if (mVirtualDisplay != null) {
                Log.i(TAG, "VD already exists, ignoring request");
                return;
            }

            int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;

            mVirtualDisplay = mDisplayManager.createVirtualDisplay(null /* projection */,
                    DISPLAY_NAME, mVirtualDisplayWidth, mVirtualDisplayHeight, mVirtualDisplayDpi,
                    null /* surface */, flags, null /* callback */, null /* handler */,
                    UNIQUE_DISPLAY_ID);

            if (mVirtualDisplay != null) {
                updateDisplayId(mVirtualDisplay.getDisplay().getDisplayId());
                // Now create the ImageReader to supply a Surface to the new virtual display.
                startImageReader();
            } else {
                Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
                updateDisplayId(INVALID_DISPLAY);
                return;
            }
        }

        Log.i(TAG, "VD created: " + mVirtualDisplay);
    }

    private void updateDisplayId(int displayId) {
        LocalServices.getService(ActivityTaskManagerInternal.class).setVr2dDisplayId(displayId);
        mWindowManagerInternal.setVr2dDisplayId(displayId);
    }

    /**
     * Stops the virtual display with a {@link #STOP_VIRTUAL_DISPLAY_DELAY_MILLIS} timeout.
     * The timeout prevents the virtual display from bouncing in cases where VrMode goes in and out
     * of being enabled. This can happen sometimes with our 2D test app.
     */
    private void stopVirtualDisplay() {
        if (mStopVDRunnable == null) {
           mStopVDRunnable = new Runnable() {
               @Override
               public void run() {
                    if (shouldRunVirtualDisplay()) {
                        Log.i(TAG, "Virtual Display destruction stopped: VrMode is back on.");
                    } else {
                        Log.i(TAG, "Stopping Virtual Display");
                        synchronized (mVdLock) {
                            updateDisplayId(INVALID_DISPLAY);
                            setSurfaceLocked(null); // clean up and release the surface first.
                            if (mVirtualDisplay != null) {
                                mVirtualDisplay.release();
                                mVirtualDisplay = null;
                            }
                            stopImageReader();
                        }
                    }
               }
           };
        }

        mHandler.removeCallbacks(mStopVDRunnable);
        mHandler.postDelayed(mStopVDRunnable, STOP_VIRTUAL_DISPLAY_DELAY_MILLIS);
    }

    /**
     * Set the surface to use with the virtual display.
     *
     * Code should be locked by {@link #mVdLock} before invoked.
     *
     * @param surface The Surface to set.
     */
    private void setSurfaceLocked(Surface surface) {
        // Change the surface to either a valid surface or a null value.
        if (mSurface != surface && (surface == null || surface.isValid())) {
            Log.i(TAG, "Setting the new surface from " + mSurface + " to " + surface);
            if (mVirtualDisplay != null) {
                mVirtualDisplay.setSurface(surface);
            }
            if (mSurface != null) {
                mSurface.release();
            }
            mSurface = surface;
        }
    }

    /**
     * Starts an ImageReader as a do-nothing Surface.  The virtual display will not get fully
     * initialized within surface flinger unless it has a valid Surface associated with it. We use
     * the ImageReader as the default valid Surface.
     */
    private void startImageReader() {
        if (mImageReader == null) {
            mImageReader = ImageReader.newInstance(mVirtualDisplayWidth, mVirtualDisplayHeight,
                PixelFormat.RGBA_8888, 2 /* maxImages */);
            Log.i(TAG, "VD startImageReader: res = " + mVirtualDisplayWidth + "X" +
                    mVirtualDisplayHeight + ", dpi = " + mVirtualDisplayDpi);
        }
        synchronized (mVdLock) {
            setSurfaceLocked(mImageReader.getSurface());
        }
    }

    /**
     * Cleans up the ImageReader.
     */
    private void stopImageReader() {
        if (mImageReader != null) {
            mImageReader.close();
            mImageReader = null;
        }
    }

    private boolean shouldRunVirtualDisplay() {
        // Virtual Display should run whenever:
        // * Virtual Display is allowed/enabled AND
        // (1) BootsToVr is set indicating the device never leaves VR
        // (2) VR (persistent) mode is enabled
        // (3) VR mode is overridden to be enabled.
        return mIsVirtualDisplayAllowed &&
                (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled);
    }
}
