/* * 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.os.LocaleList; import android.support.test.filters.SmallTest; import android.util.DisplayMetrics; import android.util.TypedValue; import android.view.Display; import android.view.DisplayAdjustments; 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 getDisplayMetrics(int displayId, DisplayAdjustments daj) { 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()); } @SmallTest public void testThemesGetUpdatedWithNewImpl() { Binder activity1 = new Binder(); Resources resources1 = mResourcesManager.createBaseActivityResources( 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; mResourcesManager.updateResourcesForActivity(activity1, overrideConfig); assertSame(resources1, 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); } @SmallTest public void testMultipleResourcesForOneActivityGetUpdatedWhenActivityBaseUpdates() { Binder activity1 = new Binder(); // Create a Resources for the Activity. Configuration config1 = new Configuration(); config1.densityDpi = 280; Resources resources1 = mResourcesManager.createBaseActivityResources( activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config1, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); assertNotNull(resources1); // Create a Resources based on the Activity. Configuration config2 = new Configuration(); config2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES; Resources resources2 = mResourcesManager.getResources( activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config2, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); assertNotNull(resources2); assertNotSame(resources1, resources2); assertNotSame(resources1.getImpl(), resources2.getImpl()); final Configuration expectedConfig1 = new Configuration(); expectedConfig1.setLocales(LocaleList.getAdjustedDefault()); expectedConfig1.densityDpi = 280; assertEquals(expectedConfig1, resources1.getConfiguration()); // resources2 should be based on the Activity's override config, so the density should // be the same as resources1. final Configuration expectedConfig2 = new Configuration(); expectedConfig2.setLocales(LocaleList.getAdjustedDefault()); expectedConfig2.densityDpi = 280; expectedConfig2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES; assertEquals(expectedConfig2, resources2.getConfiguration()); // Now update the Activity base override, and both resources should update. config1.orientation = Configuration.ORIENTATION_LANDSCAPE; mResourcesManager.updateResourcesForActivity(activity1, config1); expectedConfig1.orientation = Configuration.ORIENTATION_LANDSCAPE; assertEquals(expectedConfig1, resources1.getConfiguration()); expectedConfig2.orientation = Configuration.ORIENTATION_LANDSCAPE; assertEquals(expectedConfig2, resources2.getConfiguration()); } }