// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.media;

import static android.content.Context.UI_MODE_SERVICE;

import android.annotation.SuppressLint;
import android.app.UiModeManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Build;
import android.text.TextUtils;
import android.view.Display;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * A class for retrieving the physical display size from a device. This is necessary because
 * Display.Mode.getPhysicalDisplaySize might not report the real physical display size
 * because most ATV devices don't report all available modes correctly. In this case there is no
 * way to find out whether a device is capable to display 4k content. This class offers a
 * workaround for this problem.
 * Note: This code is copied from androidx.core.view.DisplayCompat.
 */
public final class DisplayCompat {
    private static final int DISPLAY_SIZE_4K_WIDTH = 3840;
    private static final int DISPLAY_SIZE_4K_HEIGHT = 2160;

    private DisplayCompat() {
        // This class is non-instantiable.
    }

    /**
     * Gets the supported modes of the given display where at least one of the modes is flagged
     * as isNative(). Note that a native mode might not wrap any Display.Mode object in case
     * the display returns no mode with the physical display size.
     *
     * @return an array of supported modes where at least one of the modes is native which
     * contains the physical display size
     */
    @NonNull
    @SuppressLint("ArrayReturn")
    public static ModeCompat[] getSupportedModes(
            @NonNull Context context, @NonNull Display display) {
        Point physicalDisplaySize = getPhysicalDisplaySize(context, display);
        // Display.Mode class and display.getSupportedModes() exist
        Display.Mode[] supportedModes = display.getSupportedModes();
        ArrayList<ModeCompat> supportedModesCompat = new ArrayList<>(supportedModes.length);
        boolean nativeModeExists = false;
        for (int i = 0; i < supportedModes.length; i++) {
            if (physicalSizeEquals(supportedModes[i], physicalDisplaySize)) {
                // Current mode has native resolution, flag it accordingly
                supportedModesCompat.add(i, new ModeCompat(supportedModes[i], true));
                nativeModeExists = true;
            } else {
                supportedModesCompat.add(i, new ModeCompat(supportedModes[i], false));
            }
        }
        if (!nativeModeExists) {
            // If no mode with physicalDisplaySize dimension exists, add the mode with the
            // native display resolution
            supportedModesCompat.add(new ModeCompat(physicalDisplaySize));
        }
        return supportedModesCompat.toArray(new ModeCompat[0]);
    }

    /**
     * Returns whether the app is running on a TV device
     *
     * @return true iff the app is running on a TV device
     */
    public static boolean isTv(@NonNull Context context) {
        // See https://developer.android.com/training/tv/start/hardware.html#runtime-check.
        UiModeManager uiModeManager = (UiModeManager) context.getSystemService(UI_MODE_SERVICE);
        return uiModeManager != null
                && uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
    }

    /**
     * Parses a string which represents the display-size which contains 'x' as a delimiter
     * between two integers representing the display's width and height and returns the
     * display size as a Point object.
     *
     * @param displaySize a string
     * @return a Point object containing the size in x and y direction in pixels
     * @throws NumberFormatException in case the integers cannot be parsed
     */
    private static Point parseDisplaySize(@NonNull String displaySize)
            throws NumberFormatException {
        String[] displaySizeParts = displaySize.trim().split("x", -1);
        if (displaySizeParts.length == 2) {
            int width = Integer.parseInt(displaySizeParts[0]);
            int height = Integer.parseInt(displaySizeParts[1]);
            if (width > 0 && height > 0) {
                return new Point(width, height);
            }
        }
        throw new NumberFormatException();
    }

    /**
     * Reads a system property and returns its string value.
     *
     * @param name the name of the system property
     * @return the result string or null if an exception occurred
     */
    @Nullable
    private static String getSystemProperty(String name) {
        try {
            @SuppressLint("PrivateApi")
            Class<?> systemProperties = Class.forName("android.os.SystemProperties");
            Method getMethod = systemProperties.getMethod("get", String.class);
            return (String) getMethod.invoke(systemProperties, name);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Returns true if mode.getPhysicalWidth and mode.getPhysicalHeight are equal to the given size
     *
     * @param mode a Display.Mode object
     * @param size a Point object representing the size in horizontal and vertical direction
     */
    private static boolean physicalSizeEquals(Display.Mode mode, Point size) {
        return (mode.getPhysicalWidth() == size.x && mode.getPhysicalHeight() == size.y)
                || (mode.getPhysicalWidth() == size.y && mode.getPhysicalHeight() == size.x);
    }

    /**
     * Helper function to determine the physical display size from the system properties only. On
     * Android TVs it is common for the UI to be configured for a lower resolution than SurfaceViews
     * can output. Before API 26 the Display object does not provide a way to identify this case,
     * and up to and including API 28 many devices still do not correctly set their hardware
     * composer output size.
     *
     * @return the physical display size, in pixels or null if the information is not available
     */
    @Nullable
    private static Point parsePhysicalDisplaySizeFromSystemProperties(
            @NonNull String property, @NonNull Display display) {
        if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
            // Check the system property for display size. From API 28 treble may prevent the
            // system from writing sys.display-size so we check vendor.display-size instead.
            String displaySize = getSystemProperty(property);
            // If we managed to read the display size, attempt to parse it.
            if (!TextUtils.isEmpty(displaySize)) {
                try {
                    return parseDisplaySize(displaySize);
                } catch (NumberFormatException e) {
                    // Do nothing for now, null is returned in the end
                }
            }
        }
        // Unable to determine display size from system properties
        return null;
    }

    /**
     * Gets the physical size of the given display in pixels. The size is collected in the
     * following order:
     * 1) sys.display-size if API < 28 (P) and the system-property is set
     * 2) vendor.display-size if API >= 28 (P) and the system-property is set
     * 3) physical width and height from display.getMode() for API >= 23
     * 4) display.getRealSize() for API >= 17
     * 5) display.getSize()
     *
     * @return the physical display size, in pixels
     */
    private static Point getPhysicalDisplaySize(
            @NonNull Context context, @NonNull Display display) {
        Point displaySize = Build.VERSION.SDK_INT < Build.VERSION_CODES.P
                ? parsePhysicalDisplaySizeFromSystemProperties("sys.display-size", display)
                : parsePhysicalDisplaySizeFromSystemProperties("vendor.display-size", display);
        if (displaySize != null) {
            return displaySize;
        } else if (isSonyBravia4kTv(context)) {
            // Sony Android TVs advertise support for 4k output via a system feature.
            return new Point(DISPLAY_SIZE_4K_WIDTH, DISPLAY_SIZE_4K_HEIGHT);
        } else {
            // Unable to retrieve the physical display size from system properties, get display
            // size from the framework API. Note that this might not be the actual physical
            // display size but the, possibly down-scaled, UI size.
            displaySize = new Point();
            Display.Mode mode = display.getMode();
            displaySize.x = mode.getPhysicalWidth();
            displaySize.y = mode.getPhysicalHeight();
        }
        return displaySize;
    }

    /**
     * Determines whether the connected display is a 4k capable Sony TV.
     *
     * @return true if the display is a Sony BRAVIA TV that supports 4k
     */
    private static boolean isSonyBravia4kTv(@NonNull Context context) {
        return isTv(context) && "Sony".equals(Build.MANUFACTURER)
                && Build.MODEL.startsWith("BRAVIA")
                && context.getPackageManager().hasSystemFeature("com.sony.dtv.hardware.panel.qfhd");
    }

    /**
     * Compat class which provides an additional isNative() field. This field indicates whether a
     * mode is native, which is important when searching for the highest possible native
     * resolution of a display.
     */
    public static final class ModeCompat {
        private final Display.Mode mMode;
        private final Point mPhysicalDisplaySize;
        private final boolean mIsNative;

        /**
         * Package private constructor which creates a native ModeCompat object that does not
         * wrap any Display.Mode object but only contains the given display size
         *
         * @param physicalDisplaySize a Point object representing the display size in pixels
         *                            (Point.x horizontal and Point.y vertical size)
         */
        ModeCompat(@NonNull Point physicalDisplaySize) {
            if (physicalDisplaySize == null) {
                throw new NullPointerException("physicalDisplaySize == null");
            }

            mIsNative = true;
            mPhysicalDisplaySize = physicalDisplaySize;
            mMode = null;
        }

        /**
         * Package private constructor which creates a non-native ModeCompat and wraps the given
         * Mode object
         *
         * @param mode a Display.Mode object
         */
        ModeCompat(@NonNull Display.Mode mode, boolean isNative) {
            if (mode == null) {
                throw new NullPointerException("Display.Mode == null, can't wrap a null reference");
            }

            mIsNative = isNative;
            // This simplifies the getPhysicalWidth() / getPhysicalHeight functions below
            mPhysicalDisplaySize = new Point(mode.getPhysicalWidth(), mode.getPhysicalHeight());
            mMode = mode;
        }

        /**
         * Returns the physical width of the given display when configured in this mode
         *
         * @return the physical screen width in pixels
         */
        public int getPhysicalWidth() {
            return mPhysicalDisplaySize.x;
        }

        /**
         * Returns the physical height of the given display when configured in this mode
         *
         * @return the physical screen height in pixels
         */
        public int getPhysicalHeight() {
            return mPhysicalDisplaySize.y;
        }

        /**
         * Function to get the wrapped object
         *
         * @return the wrapped Display.Mode object or null if there was no matching mode for the
         * native resolution.
         */
        @Nullable
        public Display.Mode toMode() {
            return mMode;
        }

        /**
         * This field indicates whether a mode is native, which is important when searching for
         * the highest possible native resolution of a display.
         *
         * @return true if this is a native mode of the wrapped display
         */
        public boolean isNative() {
            return mIsNative;
        }
    }
}
