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

import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;

import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.os.Environment;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Slog;
import android.util.Xml;
import android.view.DisplayAddress;
import android.view.DisplayInfo;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.wm.DisplayWindowSettings.SettingsProvider;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * Implementation of {@link SettingsProvider} that reads the base settings provided in a display
 * settings file stored in /vendor/etc and then overlays those values with the settings provided in
 * /data/system.
 *
 * @see DisplayWindowSettings
 */
class DisplayWindowSettingsProvider implements SettingsProvider {
    private static final String TAG = TAG_WITH_CLASS_NAME
            ? "DisplayWindowSettingsProvider" : TAG_WM;

    private static final String DATA_DISPLAY_SETTINGS_FILE_PATH = "system/display_settings.xml";
    private static final String VENDOR_DISPLAY_SETTINGS_FILE_PATH = "etc/display_settings.xml";
    private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays";

    private static final int IDENTIFIER_UNIQUE_ID = 0;
    private static final int IDENTIFIER_PORT = 1;
    @IntDef(prefix = { "IDENTIFIER_" }, value = {
            IDENTIFIER_UNIQUE_ID,
            IDENTIFIER_PORT,
    })
    @interface DisplayIdentifierType {}

    /** Interface that allows reading the display window settings. */
    interface ReadableSettingsStorage {
        InputStream openRead() throws IOException;
    }

    /** Interface that allows reading and writing the display window settings. */
    interface WritableSettingsStorage extends ReadableSettingsStorage {
        OutputStream startWrite() throws IOException;
        void finishWrite(OutputStream os, boolean success);
    }

    @NonNull
    private ReadableSettings mBaseSettings;
    @NonNull
    private final WritableSettings mOverrideSettings;

    DisplayWindowSettingsProvider() {
        this(new AtomicFileStorage(getVendorSettingsFile()),
                new AtomicFileStorage(getOverrideSettingsFile()));
    }

    @VisibleForTesting
    DisplayWindowSettingsProvider(@NonNull ReadableSettingsStorage baseSettingsStorage,
            @NonNull WritableSettingsStorage overrideSettingsStorage) {
        mBaseSettings = new ReadableSettings(baseSettingsStorage);
        mOverrideSettings = new WritableSettings(overrideSettingsStorage);
    }

    /**
     * Overrides the path for the file that should be used to read base settings. If {@code null} is
     * passed the default base settings file path will be used.
     *
     * @see #VENDOR_DISPLAY_SETTINGS_FILE_PATH
     */
    void setBaseSettingsFilePath(@Nullable String path) {
        AtomicFile settingsFile;
        File file = path != null ? new File(path) : null;
        if (file != null && file.exists()) {
            settingsFile = new AtomicFile(file, WM_DISPLAY_COMMIT_TAG);
        } else {
            Slog.w(TAG, "display settings " + path + " does not exist, using vendor defaults");
            settingsFile = getVendorSettingsFile();
        }
        setBaseSettingsStorage(new AtomicFileStorage(settingsFile));
    }

    /**
     * Overrides the storage that should be used to read base settings.
     *
     * @see #setBaseSettingsFilePath(String)
     */
    @VisibleForTesting
    void setBaseSettingsStorage(@NonNull ReadableSettingsStorage baseSettingsStorage) {
        mBaseSettings = new ReadableSettings(baseSettingsStorage);
    }

    @Override
    @NonNull
    public SettingsEntry getSettings(@NonNull DisplayInfo info) {
        SettingsEntry baseSettings = mBaseSettings.getSettingsEntry(info);
        SettingsEntry overrideSettings = mOverrideSettings.getOrCreateSettingsEntry(info);
        if (baseSettings == null) {
            return new SettingsEntry(overrideSettings);
        } else {
            SettingsEntry mergedSettings = new SettingsEntry(baseSettings);
            mergedSettings.updateFrom(overrideSettings);
            return mergedSettings;
        }
    }

    @Override
    @NonNull
    public SettingsEntry getOverrideSettings(@NonNull DisplayInfo info) {
        return new SettingsEntry(mOverrideSettings.getOrCreateSettingsEntry(info));
    }

    @Override
    public void updateOverrideSettings(@NonNull DisplayInfo info,
            @NonNull SettingsEntry overrides) {
        mOverrideSettings.updateSettingsEntry(info, overrides);
    }

    @Override
    public void onDisplayRemoved(@NonNull DisplayInfo info) {
        mOverrideSettings.onDisplayRemoved(info);
    }

    @Override
    public void clearDisplaySettings(@NonNull DisplayInfo info) {
        mOverrideSettings.clearDisplaySettings(info);
    }

    @VisibleForTesting
    int getOverrideSettingsSize() {
        return mOverrideSettings.mSettings.size();
    }

    /**
     * Class that allows reading {@link SettingsEntry entries} from a
     * {@link ReadableSettingsStorage}.
     */
    private static class ReadableSettings {
        /**
         * The preferred type of a display identifier to use when storing and retrieving entries
         * from the settings entries.
         *
         * @see #getIdentifier(DisplayInfo)
         */
        @DisplayIdentifierType
        protected int mIdentifierType;
        @NonNull
        protected final ArrayMap<String, SettingsEntry> mSettings = new ArrayMap<>();

        ReadableSettings(@NonNull ReadableSettingsStorage settingsStorage) {
            loadSettings(settingsStorage);
        }

        @Nullable
        final SettingsEntry getSettingsEntry(@NonNull DisplayInfo info) {
            final String identifier = getIdentifier(info);
            SettingsEntry settings;
            // Try to get corresponding settings using preferred identifier for the current config.
            if ((settings = mSettings.get(identifier)) != null) {
                return settings;
            }
            // Else, fall back to the display name.
            if ((settings = mSettings.get(info.name)) != null) {
                // Found an entry stored with old identifier.
                mSettings.remove(info.name);
                mSettings.put(identifier, settings);
                return settings;
            }
            return null;
        }

        /** Gets the identifier of choice for the current config. */
        @NonNull
        protected final String getIdentifier(@NonNull DisplayInfo displayInfo) {
            if (mIdentifierType == IDENTIFIER_PORT && displayInfo.address != null) {
                // Config suggests using port as identifier for physical displays.
                if (displayInfo.address instanceof DisplayAddress.Physical) {
                    return "port:" + ((DisplayAddress.Physical) displayInfo.address).getPort();
                }
            }
            return displayInfo.uniqueId;
        }

        private void loadSettings(@NonNull ReadableSettingsStorage settingsStorage) {
            FileData fileData = readSettings(settingsStorage);
            if (fileData != null) {
                mIdentifierType = fileData.mIdentifierType;
                mSettings.putAll(fileData.mSettings);
            }
        }
    }

    /**
     * Class that allows reading {@link SettingsEntry entries} from, and writing entries to, a
     * {@link WritableSettingsStorage}.
     */
    private static final class WritableSettings extends ReadableSettings {
        @NonNull
        private final WritableSettingsStorage mSettingsStorage;
        @NonNull
        private final ArraySet<String> mVirtualDisplayIdentifiers = new ArraySet<>();

        WritableSettings(@NonNull WritableSettingsStorage settingsStorage) {
            super(settingsStorage);
            mSettingsStorage = settingsStorage;
        }

        @NonNull
        SettingsEntry getOrCreateSettingsEntry(@NonNull DisplayInfo info) {
            final String identifier = getIdentifier(info);
            SettingsEntry settings;
            // Try to get corresponding settings using preferred identifier for the current config.
            if ((settings = mSettings.get(identifier)) != null) {
                return settings;
            }
            // Else, fall back to the display name.
            if ((settings = mSettings.get(info.name)) != null) {
                // Found an entry stored with old identifier.
                mSettings.remove(info.name);
                mSettings.put(identifier, settings);
                writeSettings();
                return settings;
            }

            settings = new SettingsEntry();
            mSettings.put(identifier, settings);
            if (info.type == TYPE_VIRTUAL) {
                // Keep track of virtual display. We don't want to write virtual display settings to
                // file.
                mVirtualDisplayIdentifiers.add(identifier);
            }
            return settings;
        }

        void updateSettingsEntry(@NonNull DisplayInfo info, @NonNull SettingsEntry settings) {
            final SettingsEntry overrideSettings = getOrCreateSettingsEntry(info);
            final boolean changed = overrideSettings.setTo(settings);
            if (changed && info.type != TYPE_VIRTUAL) {
                writeSettings();
            }
        }

        void onDisplayRemoved(@NonNull DisplayInfo info) {
            final String identifier = getIdentifier(info);
            if (!mSettings.containsKey(identifier)) {
                return;
            }
            if (mVirtualDisplayIdentifiers.remove(identifier)
                    || mSettings.get(identifier).isEmpty()) {
                // Don't keep track of virtual display or empty settings to avoid growing the cached
                // map.
                mSettings.remove(identifier);
            }
        }

        void clearDisplaySettings(@NonNull DisplayInfo info) {
            final String identifier = getIdentifier(info);
            mSettings.remove(identifier);
            mVirtualDisplayIdentifiers.remove(identifier);
        }

        private void writeSettings() {
            final FileData fileData = new FileData();
            fileData.mIdentifierType = mIdentifierType;
            final int size = mSettings.size();
            for (int i = 0; i < size; i++) {
                final String identifier = mSettings.keyAt(i);
                if (mVirtualDisplayIdentifiers.contains(identifier)) {
                    // Do not write virtual display settings to file.
                    continue;
                }
                fileData.mSettings.put(identifier, mSettings.get(identifier));
            }
            DisplayWindowSettingsProvider.writeSettings(mSettingsStorage, fileData);
        }
    }

    @NonNull
    private static AtomicFile getVendorSettingsFile() {
        // First look under product path for treblized builds.
        File vendorFile = new File(Environment.getProductDirectory(),
                VENDOR_DISPLAY_SETTINGS_FILE_PATH);
        if (!vendorFile.exists()) {
            // Try and look in vendor path.
            vendorFile = new File(Environment.getVendorDirectory(),
                VENDOR_DISPLAY_SETTINGS_FILE_PATH);
        }
        return new AtomicFile(vendorFile, WM_DISPLAY_COMMIT_TAG);
    }

    @NonNull
    private static AtomicFile getOverrideSettingsFile() {
        final File overrideSettingsFile = new File(Environment.getDataDirectory(),
                DATA_DISPLAY_SETTINGS_FILE_PATH);
        return new AtomicFile(overrideSettingsFile, WM_DISPLAY_COMMIT_TAG);
    }

    @Nullable
    private static FileData readSettings(@NonNull ReadableSettingsStorage storage) {
        InputStream stream;
        try {
            stream = storage.openRead();
        } catch (IOException e) {
            Slog.i(TAG, "No existing display settings, starting empty");
            return null;
        }
        FileData fileData = new FileData();
        boolean success = false;
        try {
            TypedXmlPullParser parser = Xml.resolvePullParser(stream);
            int type;
            while ((type = parser.next()) != XmlPullParser.START_TAG
                    && type != XmlPullParser.END_DOCUMENT) {
                // Do nothing.
            }

            if (type != XmlPullParser.START_TAG) {
                throw new IllegalStateException("no start tag found");
            }

            int outerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }

                String tagName = parser.getName();
                if (tagName.equals("display")) {
                    readDisplay(parser, fileData);
                } else if (tagName.equals("config")) {
                    readConfig(parser, fileData);
                } else {
                    Slog.w(TAG, "Unknown element under <display-settings>: "
                            + parser.getName());
                    XmlUtils.skipCurrentTag(parser);
                }
            }
            success = true;
        } catch (IllegalStateException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } catch (NullPointerException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } catch (NumberFormatException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } catch (XmlPullParserException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } catch (IOException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } catch (IndexOutOfBoundsException e) {
            Slog.w(TAG, "Failed parsing " + e);
        } finally {
            try {
                stream.close();
            } catch (IOException ignored) {
            }
        }
        if (!success) {
            fileData.mSettings.clear();
        }
        return fileData;
    }

    private static int getIntAttribute(@NonNull TypedXmlPullParser parser, @NonNull String name,
            int defaultValue) {
        return parser.getAttributeInt(null, name, defaultValue);
    }

    @Nullable
    private static Integer getIntegerAttribute(@NonNull TypedXmlPullParser parser,
            @NonNull String name, @Nullable Integer defaultValue) {
        try {
            return parser.getAttributeInt(null, name);
        } catch (Exception ignored) {
            return defaultValue;
        }
    }

    @Nullable
    private static Boolean getBooleanAttribute(@NonNull TypedXmlPullParser parser,
            @NonNull String name, @Nullable Boolean defaultValue) {
        try {
            return parser.getAttributeBoolean(null, name);
        } catch (Exception ignored) {
            return defaultValue;
        }
    }

    private static void readDisplay(@NonNull TypedXmlPullParser parser, @NonNull FileData fileData)
            throws NumberFormatException, XmlPullParserException, IOException {
        String name = parser.getAttributeValue(null, "name");
        if (name != null) {
            SettingsEntry settingsEntry = new SettingsEntry();
            settingsEntry.mWindowingMode = getIntAttribute(parser, "windowingMode",
                    WindowConfiguration.WINDOWING_MODE_UNDEFINED /* defaultValue */);
            settingsEntry.mUserRotationMode = getIntegerAttribute(parser, "userRotationMode",
                    null /* defaultValue */);
            settingsEntry.mUserRotation = getIntegerAttribute(parser, "userRotation",
                    null /* defaultValue */);
            settingsEntry.mForcedWidth = getIntAttribute(parser, "forcedWidth",
                    0 /* defaultValue */);
            settingsEntry.mForcedHeight = getIntAttribute(parser, "forcedHeight",
                    0 /* defaultValue */);
            settingsEntry.mForcedDensity = getIntAttribute(parser, "forcedDensity",
                    0 /* defaultValue */);
            settingsEntry.mForcedScalingMode = getIntegerAttribute(parser, "forcedScalingMode",
                    null /* defaultValue */);
            settingsEntry.mRemoveContentMode = getIntAttribute(parser, "removeContentMode",
                    REMOVE_CONTENT_MODE_UNDEFINED /* defaultValue */);
            settingsEntry.mShouldShowWithInsecureKeyguard = getBooleanAttribute(parser,
                    "shouldShowWithInsecureKeyguard", null /* defaultValue */);
            settingsEntry.mShouldShowSystemDecors = getBooleanAttribute(parser,
                    "shouldShowSystemDecors", null /* defaultValue */);
            final Boolean shouldShowIme = getBooleanAttribute(parser, "shouldShowIme",
                    null /* defaultValue */);
            if (shouldShowIme != null) {
                settingsEntry.mImePolicy = shouldShowIme ? DISPLAY_IME_POLICY_LOCAL
                        : DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
            } else {
                settingsEntry.mImePolicy = getIntegerAttribute(parser, "imePolicy",
                        null /* defaultValue */);
            }
            settingsEntry.mFixedToUserRotation = getIntegerAttribute(parser, "fixedToUserRotation",
                    null /* defaultValue */);
            settingsEntry.mIgnoreOrientationRequest = getBooleanAttribute(parser,
                    "ignoreOrientationRequest", null /* defaultValue */);
            settingsEntry.mIgnoreDisplayCutout = getBooleanAttribute(parser,
                    "ignoreDisplayCutout", null /* defaultValue */);
            settingsEntry.mDontMoveToTop = getBooleanAttribute(parser,
                    "dontMoveToTop", null /* defaultValue */);

            fileData.mSettings.put(name, settingsEntry);
        }
        XmlUtils.skipCurrentTag(parser);
    }

    private static void readConfig(@NonNull TypedXmlPullParser parser, @NonNull FileData fileData)
            throws NumberFormatException,
            XmlPullParserException, IOException {
        fileData.mIdentifierType = getIntAttribute(parser, "identifier",
                IDENTIFIER_UNIQUE_ID);
        XmlUtils.skipCurrentTag(parser);
    }

    private static void writeSettings(@NonNull WritableSettingsStorage storage,
            @NonNull FileData data) {
        OutputStream stream;
        try {
            stream = storage.startWrite();
        } catch (IOException e) {
            Slog.w(TAG, "Failed to write display settings: " + e);
            return;
        }

        boolean success = false;
        try {
            TypedXmlSerializer out = Xml.resolveSerializer(stream);
            out.startDocument(null, true);

            out.startTag(null, "display-settings");

            out.startTag(null, "config");
            out.attributeInt(null, "identifier", data.mIdentifierType);
            out.endTag(null, "config");

            for (Map.Entry<String, SettingsEntry> entry
                    : data.mSettings.entrySet()) {
                String displayIdentifier = entry.getKey();
                SettingsEntry settingsEntry = entry.getValue();
                if (settingsEntry.isEmpty()) {
                    continue;
                }

                out.startTag(null, "display");
                out.attribute(null, "name", displayIdentifier);
                if (settingsEntry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
                    out.attributeInt(null, "windowingMode", settingsEntry.mWindowingMode);
                }
                if (settingsEntry.mUserRotationMode != null) {
                    out.attributeInt(null, "userRotationMode",
                            settingsEntry.mUserRotationMode);
                }
                if (settingsEntry.mUserRotation != null) {
                    out.attributeInt(null, "userRotation",
                            settingsEntry.mUserRotation);
                }
                if (settingsEntry.mForcedWidth != 0 && settingsEntry.mForcedHeight != 0) {
                    out.attributeInt(null, "forcedWidth", settingsEntry.mForcedWidth);
                    out.attributeInt(null, "forcedHeight", settingsEntry.mForcedHeight);
                }
                if (settingsEntry.mForcedDensity != 0) {
                    out.attributeInt(null, "forcedDensity", settingsEntry.mForcedDensity);
                }
                if (settingsEntry.mForcedScalingMode != null) {
                    out.attributeInt(null, "forcedScalingMode",
                            settingsEntry.mForcedScalingMode);
                }
                if (settingsEntry.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED) {
                    out.attributeInt(null, "removeContentMode", settingsEntry.mRemoveContentMode);
                }
                if (settingsEntry.mShouldShowWithInsecureKeyguard != null) {
                    out.attributeBoolean(null, "shouldShowWithInsecureKeyguard",
                            settingsEntry.mShouldShowWithInsecureKeyguard);
                }
                if (settingsEntry.mShouldShowSystemDecors != null) {
                    out.attributeBoolean(null, "shouldShowSystemDecors",
                            settingsEntry.mShouldShowSystemDecors);
                }
                if (settingsEntry.mImePolicy != null) {
                    out.attributeInt(null, "imePolicy", settingsEntry.mImePolicy);
                }
                if (settingsEntry.mFixedToUserRotation != null) {
                    out.attributeInt(null, "fixedToUserRotation",
                            settingsEntry.mFixedToUserRotation);
                }
                if (settingsEntry.mIgnoreOrientationRequest != null) {
                    out.attributeBoolean(null, "ignoreOrientationRequest",
                            settingsEntry.mIgnoreOrientationRequest);
                }
                if (settingsEntry.mIgnoreDisplayCutout != null) {
                    out.attributeBoolean(null, "ignoreDisplayCutout",
                            settingsEntry.mIgnoreDisplayCutout);
                }
                if (settingsEntry.mDontMoveToTop != null) {
                    out.attributeBoolean(null, "dontMoveToTop",
                            settingsEntry.mDontMoveToTop);
                }
                out.endTag(null, "display");
            }

            out.endTag(null, "display-settings");
            out.endDocument();
            success = true;
        } catch (IOException e) {
            Slog.w(TAG, "Failed to write display window settings.", e);
        } finally {
            storage.finishWrite(stream, success);
        }
    }

    private static final class FileData {
        int mIdentifierType;
        @NonNull
        final Map<String, SettingsEntry> mSettings = new ArrayMap<>();

        @Override
        public String toString() {
            return "FileData{"
                    + "mIdentifierType=" + mIdentifierType
                    + ", mSettings=" + mSettings
                    + '}';
        }
    }

    private static final class AtomicFileStorage implements WritableSettingsStorage {
        @NonNull
        private final AtomicFile mAtomicFile;

        AtomicFileStorage(@NonNull AtomicFile atomicFile) {
            mAtomicFile = atomicFile;
        }

        @Override
        public InputStream openRead() throws FileNotFoundException {
            return mAtomicFile.openRead();
        }

        @Override
        public OutputStream startWrite() throws IOException {
            return mAtomicFile.startWrite();
        }

        @Override
        public void finishWrite(OutputStream os, boolean success) {
            if (!(os instanceof FileOutputStream)) {
                throw new IllegalArgumentException("Unexpected OutputStream as argument: " + os);
            }
            FileOutputStream fos = (FileOutputStream) os;
            if (success) {
                mAtomicFile.finishWrite(fos);
            } else {
                mAtomicFile.failWrite(fos);
            }
        }
    }
}
