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

import static android.app.ActivityThread.DEBUG_CONFIGURATION;
import static android.window.ConfigurationHelper.freeTextLayoutCachesIfNeeded;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.HardwareRenderer;
import android.os.LocaleList;
import android.os.Trace;
import android.util.DisplayMetrics;
import android.util.Slog;
import android.view.ContextThemeWrapper;
import android.view.WindowManagerGlobal;

import com.android.internal.annotations.GuardedBy;

import java.util.ArrayList;
import java.util.Locale;

/**
 * A client side controller to handle process level configuration changes.
 * @hide
 */
class ConfigurationController {
    private static final String TAG = "ConfigurationController";

    private final ActivityThreadInternal mActivityThread;

    private final ResourcesManager mResourcesManager = ResourcesManager.getInstance();

    @GuardedBy("mResourcesManager")
    private @Nullable Configuration mPendingConfiguration;
    private @Nullable Configuration mCompatConfiguration;
    private @Nullable Configuration mConfiguration;

    ConfigurationController(@NonNull ActivityThreadInternal activityThread) {
        mActivityThread = activityThread;
    }

    /** Update the pending configuration. */
    Configuration updatePendingConfiguration(@NonNull Configuration config) {
        synchronized (mResourcesManager) {
            if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(config)) {
                mPendingConfiguration = config;
                return mPendingConfiguration;
            }
        }
        return null;
    }

    /** Get the pending configuration. */
    Configuration getPendingConfiguration(boolean clearPending) {
        Configuration outConfig = null;
        synchronized (mResourcesManager) {
            if (mPendingConfiguration != null) {
                outConfig = mPendingConfiguration;
                if (clearPending) {
                    mPendingConfiguration = null;
                }
            }
        }
        return outConfig;
    }

    /** Set the compatibility configuration. */
    void setCompatConfiguration(@NonNull Configuration config) {
        mCompatConfiguration = new Configuration(config);
    }

    /** Get the compatibility configuration. */
    Configuration getCompatConfiguration() {
        return mCompatConfiguration;
    }

    /** Apply the global compatibility configuration. */
    final Configuration applyCompatConfiguration() {
        Configuration config = mConfiguration;
        final int displayDensity = config.densityDpi;
        if (mCompatConfiguration == null) {
            mCompatConfiguration = new Configuration();
        }
        mCompatConfiguration.setTo(mConfiguration);
        if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) {
            config = mCompatConfiguration;
        }
        return config;
    }

    /** Set the configuration. */
    void setConfiguration(@NonNull Configuration config) {
        mConfiguration = new Configuration(config);
    }

    /** Get current configuration. */
    Configuration getConfiguration() {
        return mConfiguration;
    }

    /**
     * Update the configuration to latest.
     * @param config The new configuration.
     */
    void handleConfigurationChanged(@NonNull Configuration config) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
        handleConfigurationChanged(config, null /* compat */);
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }

    /**
     * Update the configuration to latest.
     * @param compat The new compatibility information.
     */
    void handleConfigurationChanged(@NonNull CompatibilityInfo compat) {
        handleConfigurationChanged(mConfiguration, compat);
        WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
    }

    /**
     * Update the configuration to latest.
     * @param config The new configuration.
     * @param compat The new compatibility information.
     */
    void handleConfigurationChanged(@Nullable Configuration config,
            @Nullable CompatibilityInfo compat) {
        int configDiff;
        boolean equivalent;

        // Get theme outside of synchronization to avoid nested lock.
        final Resources.Theme systemTheme = mActivityThread.getSystemContext().getTheme();
        final ContextImpl systemUiContext = mActivityThread.getSystemUiContextNoCreate();
        final Resources.Theme systemUiTheme =
                systemUiContext != null ? systemUiContext.getTheme() : null;
        synchronized (mResourcesManager) {
            if (mPendingConfiguration != null) {
                if (!mPendingConfiguration.isOtherSeqNewer(config)) {
                    config = mPendingConfiguration;
                    updateDefaultDensity(config.densityDpi);
                }
                mPendingConfiguration = null;
            }

            if (config == null) {
                return;
            }

            // This flag tracks whether the new configuration is fundamentally equivalent to the
            // existing configuration. This is necessary to determine whether non-activity callbacks
            // should receive notice when the only changes are related to non-public fields.
            // We do not gate calling {@link #performActivityConfigurationChanged} based on this
            // flag as that method uses the same check on the activity config override as well.
            equivalent = mConfiguration != null && (0 == mConfiguration.diffPublicOnly(config));

            if (DEBUG_CONFIGURATION) {
                Slog.v(TAG, "Handle configuration changed: " + config);
            }

            final Application app = mActivityThread.getApplication();
            final Resources appResources = app.getResources();
            mResourcesManager.applyConfigurationToResources(config, compat);
            updateLocaleListFromAppContext(app.getApplicationContext());

            if (mConfiguration == null) {
                mConfiguration = new Configuration();
            }
            if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
                return;
            }

            configDiff = mConfiguration.updateFrom(config);
            config = applyCompatConfiguration();
            HardwareRenderer.sendDeviceConfigurationForDebugging(config);

            if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
                systemTheme.rebase();
            }

            if (systemUiTheme != null
                    && (systemUiTheme.getChangingConfigurations() & configDiff) != 0) {
                systemUiTheme.rebase();
            }
        }

        final ArrayList<ComponentCallbacks2> callbacks =
                mActivityThread.collectComponentCallbacks(false /* includeUiContexts */);

        freeTextLayoutCachesIfNeeded(configDiff);

        if (callbacks != null) {
            final int size = callbacks.size();
            for (int i = 0; i < size; i++) {
                ComponentCallbacks2 cb = callbacks.get(i);
                if (!equivalent) {
                    performConfigurationChanged(cb, config);
                }
            }
        }
    }

    /**
     * Decides whether to update a component's configuration and whether to inform it.
     * @param cb The component callback to notify of configuration change.
     * @param newConfig The new configuration.
     */
    void performConfigurationChanged(@NonNull ComponentCallbacks2 cb,
            @NonNull Configuration newConfig) {
        // ContextThemeWrappers may override the configuration for that context. We must check and
        // apply any overrides defined.
        Configuration contextThemeWrapperOverrideConfig = null;
        if (cb instanceof ContextThemeWrapper) {
            final ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb;
            contextThemeWrapperOverrideConfig = contextThemeWrapper.getOverrideConfiguration();
        }

        // Apply the ContextThemeWrapper override if necessary.
        // NOTE: Make sure the configurations are not modified, as they are treated as immutable
        // in many places.
        final Configuration configToReport = createNewConfigAndUpdateIfNotNull(
                newConfig, contextThemeWrapperOverrideConfig);
        cb.onConfigurationChanged(configToReport);
    }

    /** Update default density. */
    void updateDefaultDensity(int densityDpi) {
        if (!mActivityThread.isInDensityCompatMode()
                && densityDpi != Configuration.DENSITY_DPI_UNDEFINED
                && densityDpi != DisplayMetrics.DENSITY_DEVICE) {
            DisplayMetrics.DENSITY_DEVICE = densityDpi;
            Bitmap.setDefaultDensity(densityDpi);
        }
    }

    /** Get current default display dpi. This is only done to maintain @UnsupportedAppUsage. */
    int getCurDefaultDisplayDpi() {
        return mConfiguration.densityDpi;
    }

    /**
     * The LocaleList set for the app's resources may have been shuffled so that the preferred
     * Locale is at position 0. We must find the index of this preferred Locale in the
     * original LocaleList.
     */
    void updateLocaleListFromAppContext(@NonNull Context context) {
        final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0);
        final LocaleList newLocaleList = mResourcesManager.getConfiguration().getLocales();
        final int newLocaleListSize = newLocaleList.size();
        for (int i = 0; i < newLocaleListSize; i++) {
            if (bestLocale.equals(newLocaleList.get(i))) {
                LocaleList.setDefault(newLocaleList, i);
                return;
            }
        }

        // The app may have overridden the LocaleList with its own Locale
        // (not present in the available list). Push the chosen Locale
        // to the front of the list.
        LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
    }

    /**
     * Creates a new Configuration only if override would modify base. Otherwise returns base.
     * @param base The base configuration.
     * @param override The update to apply to the base configuration. Can be null.
     * @return A Configuration representing base with override applied.
     */
    static Configuration createNewConfigAndUpdateIfNotNull(@NonNull Configuration base,
            @Nullable Configuration override) {
        if (override == null) {
            return base;
        }
        Configuration newConfig = new Configuration(base);
        newConfig.updateFrom(override);
        return newConfig;
    }

}
