/*
 * Copyright (C) 2016 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.content.res;

import android.annotation.NonNull;
import android.app.ResourcesManager;
import android.os.Binder;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.DisplayMetrics;
import android.util.LocaleList;
import android.util.TypedValue;
import android.view.Display;
import junit.framework.TestCase;

public class ResourcesManagerTest extends TestCase {
    private static final String APP_ONE_RES_DIR = "app_one.apk";
    private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk";
    private static final String APP_TWO_RES_DIR = "app_two.apk";
    private static final String LIB_RES_DIR = "lib.apk";

    private ResourcesManager mResourcesManager;
    private DisplayMetrics mDisplayMetrics;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mDisplayMetrics = new DisplayMetrics();
        mDisplayMetrics.setToDefaults();

        // Override defaults (which take device specific properties).
        mDisplayMetrics.density = 1.0f;
        mDisplayMetrics.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
        mDisplayMetrics.xdpi = DisplayMetrics.DENSITY_DEFAULT;
        mDisplayMetrics.ydpi = DisplayMetrics.DENSITY_DEFAULT;
        mDisplayMetrics.noncompatDensity = mDisplayMetrics.density;
        mDisplayMetrics.noncompatDensityDpi = mDisplayMetrics.densityDpi;
        mDisplayMetrics.noncompatXdpi = DisplayMetrics.DENSITY_DEFAULT;
        mDisplayMetrics.noncompatYdpi = DisplayMetrics.DENSITY_DEFAULT;

        mResourcesManager = new ResourcesManager() {
            @Override
            protected AssetManager createAssetManager(@NonNull ResourcesKey key) {
                return new AssetManager();
            }

            @Override
            protected DisplayMetrics getDisplayMetricsLocked(int displayId) {
                return mDisplayMetrics;
            }
        };
    }

    @SmallTest
    public void testMultipleCallsWithIdenticalParametersCacheReference() {
        Resources resources = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources);

        Resources newResources = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(newResources);
        assertSame(resources, newResources);
    }

    @SmallTest
    public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() {
        Resources resources = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources);

        Configuration overrideConfig = new Configuration();
        overrideConfig.smallestScreenWidthDp = 200;
        Resources newResources = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, overrideConfig,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(newResources);
        assertNotSame(resources, newResources);
    }

    @SmallTest
    public void testAddingASplitCreatesANewImpl() {
        Resources resources1 = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources1);

        Resources resources2 = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null,
                Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources2);

        assertNotSame(resources1, resources2);
        assertNotSame(resources1.getImpl(), resources2.getImpl());
    }

    @SmallTest
    public void testUpdateConfigurationUpdatesAllAssetManagers() {
        Resources resources1 = mResourcesManager.getResources(
                null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources1);

        Resources resources2 = mResourcesManager.getResources(
                null, APP_TWO_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources2);

        Binder activity = new Binder();
        final Configuration overrideConfig = new Configuration();
        overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
        Resources resources3 = mResourcesManager.getResources(
                activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY,
                overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources3);

        // No Resources object should be the same.
        assertNotSame(resources1, resources2);
        assertNotSame(resources1, resources3);
        assertNotSame(resources2, resources3);

        // Each ResourcesImpl should be different.
        assertNotSame(resources1.getImpl(), resources2.getImpl());
        assertNotSame(resources1.getImpl(), resources3.getImpl());
        assertNotSame(resources2.getImpl(), resources3.getImpl());

        Configuration newConfig = new Configuration();
        newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
        mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null);

        final Configuration expectedConfig = new Configuration();
        expectedConfig.setLocales(LocaleList.getAdjustedDefault());
        expectedConfig.densityDpi = mDisplayMetrics.densityDpi;
        expectedConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;

        assertEquals(expectedConfig, resources1.getConfiguration());
        assertEquals(expectedConfig, resources2.getConfiguration());
        assertEquals(expectedConfig, resources3.getConfiguration());
    }

    @SmallTest
    public void testTwoActivitiesWithIdenticalParametersShareImpl() {
        Binder activity1 = new Binder();
        Resources resources1 = mResourcesManager.getResources(
                activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources1);

        Binder activity2 = new Binder();
        Resources resources2 = mResourcesManager.getResources(
                activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources1);

        // The references themselves should be unique.
        assertNotSame(resources1, resources2);

        // The implementations should be the same.
        assertSame(resources1.getImpl(), resources2.getImpl());

        final Configuration overrideConfig = new Configuration();
        overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
        Resources resources3 = mResourcesManager.getResources(
                activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY,
                overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);

        // Since we requested new resources for activity2, the resource should be the same
        // as the one returned before for activity2.
        assertSame(resources2, resources3);

        // But the implementation has changed.
        assertNotSame(resources1.getImpl(), resources2.getImpl());
    }

    @SmallTest
    public void testThemesGetUpdatedWithNewImpl() {
        Binder activity1 = new Binder();
        Resources resources1 = mResourcesManager.getResources(
                activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null,
                CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources1);

        Resources.Theme theme = resources1.newTheme();
        assertSame(resources1, theme.getResources());
        theme.applyStyle(android.R.style.Theme_NoTitleBar, false);

        TypedValue value = new TypedValue();
        assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true));
        assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type);
        assertTrue(value.data != 0);

        final Configuration overrideConfig = new Configuration();
        overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE;
        Resources resources2 = mResourcesManager.getResources(
                activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY,
                overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
        assertNotNull(resources2);
        assertSame(resources1, resources2);
        assertSame(resources2, theme.getResources());

        // Make sure we can still access the data.
        assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true));
        assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type);
        assertTrue(value.data != 0);
    }
}
