/*
 * Copyright (C) 2014 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 android.hardware.display;

import android.annotation.Nullable;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.PowerManager;
import android.util.IntArray;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl.Transaction;

/**
 * Display manager local system service interface.
 *
 * @hide Only for use within the system server.
 */
public abstract class DisplayManagerInternal {
    /**
     * Called by the power manager to initialize power management facilities.
     */
    public abstract void initPowerManagement(DisplayPowerCallbacks callbacks,
            Handler handler, SensorManager sensorManager);

    /**
     * Called by the power manager to request a new power state.
     * <p>
     * The display power controller makes a copy of the provided object and then
     * begins adjusting the power state to match what was requested.
     * </p>
     *
     * @param request The requested power state.
     * @param waitForNegativeProximity If true, issues a request to wait for
     * negative proximity before turning the screen back on, assuming the screen
     * was turned off by the proximity sensor.
     * @return True if display is ready, false if there are important changes that must
     * be made asynchronously (such as turning the screen on), in which case the caller
     * should grab a wake lock, watch for {@link DisplayPowerCallbacks#onStateChanged()}
     * then try the request again later until the state converges.
     */
    public abstract boolean requestPowerState(DisplayPowerRequest request,
            boolean waitForNegativeProximity);

    /**
     * Returns true if the proximity sensor screen-off function is available.
     */
    public abstract boolean isProximitySensorAvailable();

    /**
     * Take a screenshot of the specified display into the provided {@link Surface}.
     *
     * @param displayId The display id to take the screenshot of.
     * @param outSurface The {@link Surface} to take the screenshot into.
     * @return True if the screenshot is taken.
     */
    public abstract boolean screenshot(int displayId, Surface outSurface);

    /**
     * Returns information about the specified logical display.
     *
     * @param displayId The logical display id.
     * @return The logical display info, or null if the display does not exist.  The
     * returned object must be treated as immutable.
     */
    public abstract DisplayInfo getDisplayInfo(int displayId);

    /**
     * Registers a display transaction listener to provide the client a chance to
     * update its surfaces within the same transaction as any display layout updates.
     *
     * @param listener The listener to register.
     */
    public abstract void registerDisplayTransactionListener(DisplayTransactionListener listener);

    /**
     * Unregisters a display transaction listener to provide the client a chance to
     * update its surfaces within the same transaction as any display layout updates.
     *
     * @param listener The listener to unregister.
     */
    public abstract void unregisterDisplayTransactionListener(DisplayTransactionListener listener);

    /**
     * Overrides the display information of a particular logical display.
     * This is used by the window manager to control the size and characteristics
     * of the default display.  It is expected to apply the requested change
     * to the display information synchronously so that applications will immediately
     * observe the new state.
     *
     * NOTE: This method must be the only entry point by which the window manager
     * influences the logical configuration of displays.
     *
     * @param displayId The logical display id.
     * @param info The new data to be stored.
     */
    public abstract void setDisplayInfoOverrideFromWindowManager(
            int displayId, DisplayInfo info);

    /**
     * Get current display info without override from WindowManager.
     * Current implementation of LogicalDisplay#getDisplayInfoLocked() always returns display info
     * with overrides from WM if set. This method can be used for getting real display size without
     * overrides to determine if real changes to display metrics happened.
     * @param displayId Id of the target display.
     * @param outInfo {@link DisplayInfo} to fill.
     */
    public abstract void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo);

    /**
     * Called by the window manager to perform traversals while holding a
     * surface flinger transaction.
     */
    public abstract void performTraversal(Transaction t);

    /**
     * Tells the display manager about properties of the display that depend on the windows on it.
     * This includes whether there is interesting unique content on the specified logical display,
     * and whether the one of the windows has a preferred refresh rate.
     * <p>
     * If the display has unique content, then the display manager arranges for it
     * to be presented on a physical display if appropriate.  Otherwise, the display manager
     * may choose to make the physical display mirror some other logical display.
     * </p>
     *
     * <p>
     * If one of the windows on the display has a preferred refresh rate that's supported by the
     * display, then the display manager will request its use.
     * </p>
     *
     * @param displayId The logical display id to update.
     * @param hasContent True if the logical display has content. This is used to control automatic
     * mirroring.
     * @param requestedRefreshRate The preferred refresh rate for the top-most visible window that
     * has a preference.
     * @param requestedModeId The preferred mode id for the top-most visible window that has a
     * preference.
     * @param inTraversal True if called from WindowManagerService during a window traversal
     * prior to call to performTraversalInTransactionFromWindowManager.
     */
    public abstract void setDisplayProperties(int displayId, boolean hasContent,
            float requestedRefreshRate, int requestedModeId, boolean inTraversal);

    /**
     * Applies an offset to the contents of a display, for example to avoid burn-in.
     * <p>
     * TODO: Technically this should be associated with a physical rather than logical
     * display but this is good enough for now.
     * </p>
     *
     * @param displayId The logical display id to update.
     * @param x The X offset by which to shift the contents of the display.
     * @param y The Y offset by which to shift the contents of the display.
     */
    public abstract void setDisplayOffsets(int displayId, int x, int y);

    /**
     * Disables scaling for a display.
     *
     * @param displayId The logical display id to disable scaling for.
     * @param disableScaling {@code true} to disable scaling,
     * {@code false} to use the default scaling behavior of the logical display.
     */
    public abstract void setDisplayScalingDisabled(int displayId, boolean disableScaling);

    /**
     * Provide a list of UIDs that are present on the display and are allowed to access it.
     *
     * @param displayAccessUIDs Mapping displayId -> int array of UIDs.
     */
    public abstract void setDisplayAccessUIDs(SparseArray<IntArray> displayAccessUIDs);

    /**
     * Check if specified UID's content is present on display and should be granted access to it.
     *
     * @param uid UID to be checked.
     * @param displayId id of the display where presence of the content is checked.
     * */
    public abstract boolean isUidPresentOnDisplay(int uid, int displayId);

    /**
     * Persist brightness slider events and ambient brightness stats.
     */
    public abstract void persistBrightnessTrackerState();

    /**
     * Notifies the display manager that resource overlays have changed.
     */
    public abstract void onOverlayChanged();

    /**
     * Get the attributes available for display color sampling.
     * @param displayId id of the display to collect the sample from.
     *
     * @return The attributes the display supports, or null if sampling is not supported.
     */
    @Nullable
    public abstract DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes(
            int displayId);

    /**
     * Enable or disable the collection of color samples.
     *
     * @param displayId id of the display to collect the sample from.
     * @param componentMask a bitmask of the color channels to collect samples for, or zero for all
     *                      available.
     * @param maxFrames maintain a ringbuffer of the last maxFrames.
     * @param enable True to enable, False to disable.
     *
     * @return True if sampling was enabled, false if failure.
     */
    public abstract boolean setDisplayedContentSamplingEnabled(
            int displayId, boolean enable, int componentMask, int maxFrames);

    /**
     * Accesses the color histogram statistics of displayed frames on devices that support sampling.
     *
     * @param displayId id of the display to collect the sample from
     * @param maxFrames limit the statistics to the last maxFrames number of frames.
     * @param timestamp discard statistics that were collected prior to timestamp, where timestamp
     *                  is given as CLOCK_MONOTONIC.
     * @return The statistics representing a histogram of the color distribution of the frames
     *         displayed on-screen, or null if sampling is not supported.
    */
    @Nullable
    public abstract DisplayedContentSample getDisplayedContentSample(
            int displayId, long maxFrames, long timestamp);

    /**
     * Describes the requested power state of the display.
     *
     * This object is intended to describe the general characteristics of the
     * power state, such as whether the screen should be on or off and the current
     * brightness controls leaving the DisplayPowerController to manage the
     * details of how the transitions between states should occur.  The goal is for
     * the PowerManagerService to focus on the global power state and not
     * have to micro-manage screen off animations, auto-brightness and other effects.
     */
    public static final class DisplayPowerRequest {
        // Policy: Turn screen off as if the user pressed the power button
        // including playing a screen off animation if applicable.
        public static final int POLICY_OFF = 0;
        // Policy: Enable dozing and always-on display functionality.
        public static final int POLICY_DOZE = 1;
        // Policy: Make the screen dim when the user activity timeout is
        // about to expire.
        public static final int POLICY_DIM = 2;
        // Policy: Make the screen bright as usual.
        public static final int POLICY_BRIGHT = 3;
        // Policy: Keep the screen and display optimized for VR mode.
        public static final int POLICY_VR = 4;

        // The basic overall policy to apply: off, doze, dim or bright.
        public int policy;

        // If true, the proximity sensor overrides the screen state when an object is
        // nearby, turning it off temporarily until the object is moved away.
        public boolean useProximitySensor;

        // An override of the screen brightness. Set to -1 is used if there's no override.
        public int screenBrightnessOverride;

        // An override of the screen auto-brightness adjustment factor in the range -1 (dimmer) to
        // 1 (brighter). Set to Float.NaN if there's no override.
        public float screenAutoBrightnessAdjustmentOverride;

        // If true, enables automatic brightness control.
        public boolean useAutoBrightness;

        // If true, scales the brightness to a fraction of desired (as defined by
        // screenLowPowerBrightnessFactor).
        public boolean lowPowerMode;

        // The factor to adjust the screen brightness in low power mode in the range
        // 0 (screen off) to 1 (no change)
        public float screenLowPowerBrightnessFactor;

        // If true, applies a brightness boost.
        public boolean boostScreenBrightness;

        // If true, prevents the screen from completely turning on if it is currently off.
        // The display does not enter a "ready" state if this flag is true and screen on is
        // blocked.  The window manager policy blocks screen on while it prepares the keyguard to
        // prevent the user from seeing intermediate updates.
        //
        // Technically, we may not block the screen itself from turning on (because that introduces
        // extra unnecessary latency) but we do prevent content on screen from becoming
        // visible to the user.
        public boolean blockScreenOn;

        // Overrides the policy for adjusting screen brightness and state while dozing.
        public int dozeScreenBrightness;
        public int dozeScreenState;

        public DisplayPowerRequest() {
            policy = POLICY_BRIGHT;
            useProximitySensor = false;
            screenBrightnessOverride = -1;
            useAutoBrightness = false;
            screenAutoBrightnessAdjustmentOverride = Float.NaN;
            screenLowPowerBrightnessFactor = 0.5f;
            blockScreenOn = false;
            dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
            dozeScreenState = Display.STATE_UNKNOWN;
        }

        public DisplayPowerRequest(DisplayPowerRequest other) {
            copyFrom(other);
        }

        public boolean isBrightOrDim() {
            return policy == POLICY_BRIGHT || policy == POLICY_DIM;
        }

        public boolean isVr() {
            return policy == POLICY_VR;
        }

        public void copyFrom(DisplayPowerRequest other) {
            policy = other.policy;
            useProximitySensor = other.useProximitySensor;
            screenBrightnessOverride = other.screenBrightnessOverride;
            useAutoBrightness = other.useAutoBrightness;
            screenAutoBrightnessAdjustmentOverride = other.screenAutoBrightnessAdjustmentOverride;
            screenLowPowerBrightnessFactor = other.screenLowPowerBrightnessFactor;
            blockScreenOn = other.blockScreenOn;
            lowPowerMode = other.lowPowerMode;
            boostScreenBrightness = other.boostScreenBrightness;
            dozeScreenBrightness = other.dozeScreenBrightness;
            dozeScreenState = other.dozeScreenState;
        }

        @Override
        public boolean equals(Object o) {
            return o instanceof DisplayPowerRequest
                    && equals((DisplayPowerRequest)o);
        }

        public boolean equals(DisplayPowerRequest other) {
            return other != null
                    && policy == other.policy
                    && useProximitySensor == other.useProximitySensor
                    && screenBrightnessOverride == other.screenBrightnessOverride
                    && useAutoBrightness == other.useAutoBrightness
                    && floatEquals(screenAutoBrightnessAdjustmentOverride,
                            other.screenAutoBrightnessAdjustmentOverride)
                    && screenLowPowerBrightnessFactor
                    == other.screenLowPowerBrightnessFactor
                    && blockScreenOn == other.blockScreenOn
                    && lowPowerMode == other.lowPowerMode
                    && boostScreenBrightness == other.boostScreenBrightness
                    && dozeScreenBrightness == other.dozeScreenBrightness
                    && dozeScreenState == other.dozeScreenState;
        }

        private boolean floatEquals(float f1, float f2) {
            return f1 == f2 || Float.isNaN(f1) && Float.isNaN(f2);
        }

        @Override
        public int hashCode() {
            return 0; // don't care
        }

        @Override
        public String toString() {
            return "policy=" + policyToString(policy)
                    + ", useProximitySensor=" + useProximitySensor
                    + ", screenBrightnessOverride=" + screenBrightnessOverride
                    + ", useAutoBrightness=" + useAutoBrightness
                    + ", screenAutoBrightnessAdjustmentOverride="
                    + screenAutoBrightnessAdjustmentOverride
                    + ", screenLowPowerBrightnessFactor=" + screenLowPowerBrightnessFactor
                    + ", blockScreenOn=" + blockScreenOn
                    + ", lowPowerMode=" + lowPowerMode
                    + ", boostScreenBrightness=" + boostScreenBrightness
                    + ", dozeScreenBrightness=" + dozeScreenBrightness
                    + ", dozeScreenState=" + Display.stateToString(dozeScreenState);
        }

        public static String policyToString(int policy) {
            switch (policy) {
                case POLICY_OFF:
                    return "OFF";
                case POLICY_DOZE:
                    return "DOZE";
                case POLICY_DIM:
                    return "DIM";
                case POLICY_BRIGHT:
                    return "BRIGHT";
                case POLICY_VR:
                    return "VR";
                default:
                    return Integer.toString(policy);
            }
        }
    }

    /**
     * Asynchronous callbacks from the power controller to the power manager service.
     */
    public interface DisplayPowerCallbacks {
        void onStateChanged();
        void onProximityPositive();
        void onProximityNegative();
        void onDisplayStateChange(int state); // one of the Display state constants

        void acquireSuspendBlocker();
        void releaseSuspendBlocker();
    }

    /**
     * Called within a Surface transaction whenever the size or orientation of a
     * display may have changed.  Provides an opportunity for the client to
     * update the position of its surfaces as part of the same transaction.
     */
    public interface DisplayTransactionListener {
        void onDisplayTransaction(Transaction t);
    }
}
