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

import android.annotation.UiThread;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AtomicFile;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.util.Xml;

import com.android.internal.util.FastXmlSerializer;

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

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * Manages warning dialogs shown during application lifecycle.
 */
class AppWarnings {
    private static final String TAG = "AppWarnings";
    private static final String CONFIG_FILE_NAME = "packages-warnings.xml";

    public static final int FLAG_HIDE_DISPLAY_SIZE = 0x01;
    public static final int FLAG_HIDE_COMPILE_SDK = 0x02;

    private final HashMap<String, Integer> mPackageFlags = new HashMap<>();

    private final ActivityManagerService mAms;
    private final Context mUiContext;
    private final ConfigHandler mAmsHandler;
    private final UiHandler mUiHandler;
    private final AtomicFile mConfigFile;

    private UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
    private UnsupportedCompileSdkDialog mUnsupportedCompileSdkDialog;

    /**
     * Creates a new warning dialog manager.
     * <p>
     * <strong>Note:</strong> Must be called from the ActivityManagerService thread.
     *
     * @param ams
     * @param uiContext
     * @param amsHandler
     * @param uiHandler
     * @param systemDir
     */
    public AppWarnings(ActivityManagerService ams, Context uiContext, Handler amsHandler,
            Handler uiHandler, File systemDir) {
        mAms = ams;
        mUiContext = uiContext;
        mAmsHandler = new ConfigHandler(amsHandler.getLooper());
        mUiHandler = new UiHandler(uiHandler.getLooper());
        mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME));

        readConfigFromFileAmsThread();
    }

    /**
     * Shows the "unsupported display size" warning, if necessary.
     *
     * @param r activity record for which the warning may be displayed
     */
    public void showUnsupportedDisplaySizeDialogIfNeeded(ActivityRecord r) {
        final Configuration globalConfig = mAms.getGlobalConfiguration();
        if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
                && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
            mUiHandler.showUnsupportedDisplaySizeDialog(r);
        }
    }

    /**
     * Shows the "unsupported compile SDK" warning, if necessary.
     *
     * @param r activity record for which the warning may be displayed
     */
    public void showUnsupportedCompileSdkDialogIfNeeded(ActivityRecord r) {
        if (r.appInfo.compileSdkVersion == 0 || r.appInfo.compileSdkVersionCodename == null) {
            // We don't know enough about this package. Abort!
            return;
        }

        // If the application was built against an pre-release SDK that's older than the current
        // platform OR if the current platform is pre-release and older than the SDK against which
        // the application was built OR both are pre-release with the same SDK_INT but different
        // codenames (e.g. simultaneous pre-release development), then we're likely to run into
        // compatibility issues. Warn the user and offer to check for an update.
        final int compileSdk = r.appInfo.compileSdkVersion;
        final int platformSdk = Build.VERSION.SDK_INT;
        final boolean isCompileSdkPreview = !"REL".equals(r.appInfo.compileSdkVersionCodename);
        final boolean isPlatformSdkPreview = !"REL".equals(Build.VERSION.CODENAME);
        if ((isCompileSdkPreview && compileSdk < platformSdk)
                || (isPlatformSdkPreview && platformSdk < compileSdk)
                || (isCompileSdkPreview && isPlatformSdkPreview && platformSdk == compileSdk
                    && !Build.VERSION.CODENAME.equals(r.appInfo.compileSdkVersionCodename))) {
            mUiHandler.showUnsupportedCompileSdkDialog(r);
        }
    }

    /**
     * Called when an activity is being started.
     *
     * @param r record for the activity being started
     */
    public void onStartActivity(ActivityRecord r) {
        showUnsupportedCompileSdkDialogIfNeeded(r);
        showUnsupportedDisplaySizeDialogIfNeeded(r);
    }

    /**
     * Called when an activity was previously started and is being resumed.
     *
     * @param r record for the activity being resumed
     */
    public void onResumeActivity(ActivityRecord r) {
        showUnsupportedDisplaySizeDialogIfNeeded(r);
    }

    /**
     * Called by ActivityManagerService when package data has been cleared.
     *
     * @param name the package whose data has been cleared
     */
    public void onPackageDataCleared(String name) {
        removePackageAndHideDialogs(name);
    }

    /**
     * Called by ActivityManagerService when a package has been uninstalled.
     *
     * @param name the package that has been uninstalled
     */
    public void onPackageUninstalled(String name) {
        removePackageAndHideDialogs(name);
    }

    /**
     * Called by ActivityManagerService when the default display density has changed.
     */
    public void onDensityChanged() {
        mUiHandler.hideUnsupportedDisplaySizeDialog();
    }

    /**
     * Does what it says on the tin.
     */
    private void removePackageAndHideDialogs(String name) {
        mUiHandler.hideDialogsForPackage(name);

        synchronized (mPackageFlags) {
            mPackageFlags.remove(name);
            mAmsHandler.scheduleWrite();
        }
    }

    /**
     * Hides the "unsupported display size" warning.
     * <p>
     * <strong>Note:</strong> Must be called on the UI thread.
     */
    @UiThread
    private void hideUnsupportedDisplaySizeDialogUiThread() {
        if (mUnsupportedDisplaySizeDialog != null) {
            mUnsupportedDisplaySizeDialog.dismiss();
            mUnsupportedDisplaySizeDialog = null;
        }
    }

    /**
     * Shows the "unsupported display size" warning for the given application.
     * <p>
     * <strong>Note:</strong> Must be called on the UI thread.
     *
     * @param ar record for the activity that triggered the warning
     */
    @UiThread
    private void showUnsupportedDisplaySizeDialogUiThread(ActivityRecord ar) {
        if (mUnsupportedDisplaySizeDialog != null) {
            mUnsupportedDisplaySizeDialog.dismiss();
            mUnsupportedDisplaySizeDialog = null;
        }
        if (ar != null && !hasPackageFlag(
                ar.packageName, FLAG_HIDE_DISPLAY_SIZE)) {
            mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
                    AppWarnings.this, mUiContext, ar.info.applicationInfo);
            mUnsupportedDisplaySizeDialog.show();
        }
    }

    /**
     * Shows the "unsupported compile SDK" warning for the given application.
     * <p>
     * <strong>Note:</strong> Must be called on the UI thread.
     *
     * @param ar record for the activity that triggered the warning
     */
    @UiThread
    private void showUnsupportedCompileSdkDialogUiThread(ActivityRecord ar) {
        if (mUnsupportedCompileSdkDialog != null) {
            mUnsupportedCompileSdkDialog.dismiss();
            mUnsupportedCompileSdkDialog = null;
        }
        if (ar != null && !hasPackageFlag(
                ar.packageName, FLAG_HIDE_COMPILE_SDK)) {
            mUnsupportedCompileSdkDialog = new UnsupportedCompileSdkDialog(
                    AppWarnings.this, mUiContext, ar.info.applicationInfo);
            mUnsupportedCompileSdkDialog.show();
        }
    }

    /**
     * Dismisses all warnings for the given package.
     * <p>
     * <strong>Note:</strong> Must be called on the UI thread.
     *
     * @param name the package for which warnings should be dismissed, or {@code null} to dismiss
     *             all warnings
     */
    @UiThread
    private void hideDialogsForPackageUiThread(String name) {
        // Hides the "unsupported display" dialog if necessary.
        if (mUnsupportedDisplaySizeDialog != null && (name == null || name.equals(
                mUnsupportedDisplaySizeDialog.getPackageName()))) {
            mUnsupportedDisplaySizeDialog.dismiss();
            mUnsupportedDisplaySizeDialog = null;
        }

        // Hides the "unsupported compile SDK" dialog if necessary.
        if (mUnsupportedCompileSdkDialog != null && (name == null || name.equals(
                mUnsupportedCompileSdkDialog.getPackageName()))) {
            mUnsupportedCompileSdkDialog.dismiss();
            mUnsupportedCompileSdkDialog = null;
        }
    }

    /**
     * Returns the value of the flag for the given package.
     *
     * @param name the package from which to retrieve the flag
     * @param flag the bitmask for the flag to retrieve
     * @return {@code true} if the flag is enabled, {@code false} otherwise
     */
    boolean hasPackageFlag(String name, int flag) {
        return (getPackageFlags(name) & flag) == flag;
    }

    /**
     * Sets the flag for the given package to the specified value.
     *
     * @param name the package on which to set the flag
     * @param flag the bitmask for flag to set
     * @param enabled the value to set for the flag
     */
    void setPackageFlag(String name, int flag, boolean enabled) {
        synchronized (mPackageFlags) {
            final int curFlags = getPackageFlags(name);
            final int newFlags = enabled ? (curFlags & ~flag) : (curFlags | flag);
            if (curFlags != newFlags) {
                if (newFlags != 0) {
                    mPackageFlags.put(name, newFlags);
                } else {
                    mPackageFlags.remove(name);
                }
                mAmsHandler.scheduleWrite();
            }
        }
    }

    /**
     * Returns the bitmask of flags set for the specified package.
     */
    private int getPackageFlags(String name) {
        synchronized (mPackageFlags) {
            return mPackageFlags.getOrDefault(name, 0);
        }
    }

    /**
     * Handles messages on the system process UI thread.
     */
    private final class UiHandler extends Handler {
        private static final int MSG_SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG = 1;
        private static final int MSG_HIDE_UNSUPPORTED_DISPLAY_SIZE_DIALOG = 2;
        private static final int MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG = 3;
        private static final int MSG_HIDE_DIALOGS_FOR_PACKAGE = 4;

        public UiHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG: {
                    final ActivityRecord ar = (ActivityRecord) msg.obj;
                    showUnsupportedDisplaySizeDialogUiThread(ar);
                } break;
                case MSG_HIDE_UNSUPPORTED_DISPLAY_SIZE_DIALOG: {
                    hideUnsupportedDisplaySizeDialogUiThread();
                } break;
                case MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG: {
                    final ActivityRecord ar = (ActivityRecord) msg.obj;
                    showUnsupportedCompileSdkDialogUiThread(ar);
                } break;
                case MSG_HIDE_DIALOGS_FOR_PACKAGE: {
                    final String name = (String) msg.obj;
                    hideDialogsForPackageUiThread(name);
                } break;
            }
        }

        public void showUnsupportedDisplaySizeDialog(ActivityRecord r) {
            removeMessages(MSG_SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG);
            obtainMessage(MSG_SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG, r).sendToTarget();
        }

        public void hideUnsupportedDisplaySizeDialog() {
            removeMessages(MSG_HIDE_UNSUPPORTED_DISPLAY_SIZE_DIALOG);
            sendEmptyMessage(MSG_HIDE_UNSUPPORTED_DISPLAY_SIZE_DIALOG);
        }

        public void showUnsupportedCompileSdkDialog(ActivityRecord r) {
            removeMessages(MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG);
            obtainMessage(MSG_SHOW_UNSUPPORTED_COMPILE_SDK_DIALOG, r).sendToTarget();
        }

        public void hideDialogsForPackage(String name) {
            obtainMessage(MSG_HIDE_DIALOGS_FOR_PACKAGE, name).sendToTarget();
        }
    }

    /**
     * Handles messages on the ActivityManagerService thread.
     */
    private final class ConfigHandler extends Handler {
        private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;

        private static final int DELAY_MSG_WRITE = 10000;

        public ConfigHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_WRITE:
                    writeConfigToFileAmsThread();
                    break;
            }
        }

        public void scheduleWrite() {
            removeMessages(MSG_WRITE);
            sendEmptyMessageDelayed(MSG_WRITE, DELAY_MSG_WRITE);
        }
    }

    /**
     * Writes the configuration file.
     * <p>
     * <strong>Note:</strong> Should be called from the ActivityManagerService thread unless you
     * don't care where you're doing I/O operations. But you <i>do</i> care, don't you?
     */
    private void writeConfigToFileAmsThread() {
        // Create a shallow copy so that we don't have to synchronize on config.
        final HashMap<String, Integer> packageFlags;
        synchronized (mPackageFlags) {
            packageFlags = new HashMap<>(mPackageFlags);
        }

        FileOutputStream fos = null;
        try {
            fos = mConfigFile.startWrite();

            final XmlSerializer out = new FastXmlSerializer();
            out.setOutput(fos, StandardCharsets.UTF_8.name());
            out.startDocument(null, true);
            out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
            out.startTag(null, "packages");

            for (Map.Entry<String, Integer> entry : packageFlags.entrySet()) {
                String pkg = entry.getKey();
                int mode = entry.getValue();
                if (mode == 0) {
                    continue;
                }
                out.startTag(null, "package");
                out.attribute(null, "name", pkg);
                out.attribute(null, "flags", Integer.toString(mode));
                out.endTag(null, "package");
            }

            out.endTag(null, "packages");
            out.endDocument();

            mConfigFile.finishWrite(fos);
        } catch (java.io.IOException e1) {
            Slog.w(TAG, "Error writing package metadata", e1);
            if (fos != null) {
                mConfigFile.failWrite(fos);
            }
        }
    }

    /**
     * Reads the configuration file and populates the package flags.
     * <p>
     * <strong>Note:</strong> Must be called from the constructor (and thus on the
     * ActivityManagerService thread) since we don't synchronize on config.
     */
    private void readConfigFromFileAmsThread() {
        FileInputStream fis = null;

        try {
            fis = mConfigFile.openRead();

            final XmlPullParser parser = Xml.newPullParser();
            parser.setInput(fis, StandardCharsets.UTF_8.name());

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.START_TAG &&
                    eventType != XmlPullParser.END_DOCUMENT) {
                eventType = parser.next();
            }
            if (eventType == XmlPullParser.END_DOCUMENT) {
                return;
            }

            String tagName = parser.getName();
            if ("packages".equals(tagName)) {
                eventType = parser.next();
                do {
                    if (eventType == XmlPullParser.START_TAG) {
                        tagName = parser.getName();
                        if (parser.getDepth() == 2) {
                            if ("package".equals(tagName)) {
                                final String name = parser.getAttributeValue(null, "name");
                                if (name != null) {
                                    final String flags = parser.getAttributeValue(
                                            null, "flags");
                                    int flagsInt = 0;
                                    if (flags != null) {
                                        try {
                                            flagsInt = Integer.parseInt(flags);
                                        } catch (NumberFormatException e) {
                                        }
                                    }
                                    mPackageFlags.put(name, flagsInt);
                                }
                            }
                        }
                    }
                    eventType = parser.next();
                } while (eventType != XmlPullParser.END_DOCUMENT);
            }
        } catch (XmlPullParserException e) {
            Slog.w(TAG, "Error reading package metadata", e);
        } catch (java.io.IOException e) {
            if (fis != null) Slog.w(TAG, "Error reading package metadata", e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (java.io.IOException e1) {
                }
            }
        }
    }
}
