1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 package android.content.res; 17 18 import android.annotation.NonNull; 19 import android.app.ResourcesManager; 20 import android.os.Binder; 21 import android.os.LocaleList; 22 import android.support.test.filters.SmallTest; 23 import android.util.DisplayMetrics; 24 import android.util.TypedValue; 25 import android.view.Display; 26 import android.view.DisplayAdjustments; 27 28 import junit.framework.TestCase; 29 30 public class ResourcesManagerTest extends TestCase { 31 private static final String APP_ONE_RES_DIR = "app_one.apk"; 32 private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk"; 33 private static final String APP_TWO_RES_DIR = "app_two.apk"; 34 private static final String LIB_RES_DIR = "lib.apk"; 35 36 private ResourcesManager mResourcesManager; 37 private DisplayMetrics mDisplayMetrics; 38 39 @Override 40 protected void setUp() throws Exception { 41 super.setUp(); 42 43 mDisplayMetrics = new DisplayMetrics(); 44 mDisplayMetrics.setToDefaults(); 45 46 // Override defaults (which take device specific properties). 47 mDisplayMetrics.density = 1.0f; 48 mDisplayMetrics.densityDpi = DisplayMetrics.DENSITY_DEFAULT; 49 mDisplayMetrics.xdpi = DisplayMetrics.DENSITY_DEFAULT; 50 mDisplayMetrics.ydpi = DisplayMetrics.DENSITY_DEFAULT; 51 mDisplayMetrics.noncompatDensity = mDisplayMetrics.density; 52 mDisplayMetrics.noncompatDensityDpi = mDisplayMetrics.densityDpi; 53 mDisplayMetrics.noncompatXdpi = DisplayMetrics.DENSITY_DEFAULT; 54 mDisplayMetrics.noncompatYdpi = DisplayMetrics.DENSITY_DEFAULT; 55 56 mResourcesManager = new ResourcesManager() { 57 @Override 58 protected AssetManager createAssetManager(@NonNull ResourcesKey key) { 59 return new AssetManager(); 60 } 61 62 @Override 63 protected DisplayMetrics getDisplayMetrics(int displayId, DisplayAdjustments daj) { 64 return mDisplayMetrics; 65 } 66 }; 67 } 68 69 @SmallTest 70 public void testMultipleCallsWithIdenticalParametersCacheReference() { 71 Resources resources = mResourcesManager.getResources( 72 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 73 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 74 assertNotNull(resources); 75 76 Resources newResources = mResourcesManager.getResources( 77 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 78 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 79 assertNotNull(newResources); 80 assertSame(resources, newResources); 81 } 82 83 @SmallTest 84 public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() { 85 Resources resources = mResourcesManager.getResources( 86 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 87 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 88 assertNotNull(resources); 89 90 Configuration overrideConfig = new Configuration(); 91 overrideConfig.smallestScreenWidthDp = 200; 92 Resources newResources = mResourcesManager.getResources( 93 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, overrideConfig, 94 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 95 assertNotNull(newResources); 96 assertNotSame(resources, newResources); 97 } 98 99 @SmallTest 100 public void testAddingASplitCreatesANewImpl() { 101 Resources resources1 = mResourcesManager.getResources( 102 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 103 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 104 assertNotNull(resources1); 105 106 Resources resources2 = mResourcesManager.getResources( 107 null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null, 108 Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 109 assertNotNull(resources2); 110 111 assertNotSame(resources1, resources2); 112 assertNotSame(resources1.getImpl(), resources2.getImpl()); 113 } 114 115 @SmallTest 116 public void testUpdateConfigurationUpdatesAllAssetManagers() { 117 Resources resources1 = mResourcesManager.getResources( 118 null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 119 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 120 assertNotNull(resources1); 121 122 Resources resources2 = mResourcesManager.getResources( 123 null, APP_TWO_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 124 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 125 assertNotNull(resources2); 126 127 Binder activity = new Binder(); 128 final Configuration overrideConfig = new Configuration(); 129 overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 130 Resources resources3 = mResourcesManager.getResources( 131 activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, 132 overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 133 assertNotNull(resources3); 134 135 // No Resources object should be the same. 136 assertNotSame(resources1, resources2); 137 assertNotSame(resources1, resources3); 138 assertNotSame(resources2, resources3); 139 140 // Each ResourcesImpl should be different. 141 assertNotSame(resources1.getImpl(), resources2.getImpl()); 142 assertNotSame(resources1.getImpl(), resources3.getImpl()); 143 assertNotSame(resources2.getImpl(), resources3.getImpl()); 144 145 Configuration newConfig = new Configuration(); 146 newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 147 mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null); 148 149 final Configuration expectedConfig = new Configuration(); 150 expectedConfig.setToDefaults(); 151 expectedConfig.setLocales(LocaleList.getAdjustedDefault()); 152 expectedConfig.densityDpi = mDisplayMetrics.densityDpi; 153 expectedConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 154 155 assertEquals(expectedConfig, resources1.getConfiguration()); 156 assertEquals(expectedConfig, resources2.getConfiguration()); 157 assertEquals(expectedConfig, resources3.getConfiguration()); 158 } 159 160 @SmallTest 161 public void testTwoActivitiesWithIdenticalParametersShareImpl() { 162 Binder activity1 = new Binder(); 163 Resources resources1 = mResourcesManager.getResources( 164 activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 165 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 166 assertNotNull(resources1); 167 168 Binder activity2 = new Binder(); 169 Resources resources2 = mResourcesManager.getResources( 170 activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 171 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 172 assertNotNull(resources1); 173 174 // The references themselves should be unique. 175 assertNotSame(resources1, resources2); 176 177 // The implementations should be the same. 178 assertSame(resources1.getImpl(), resources2.getImpl()); 179 } 180 181 @SmallTest 182 public void testThemesGetUpdatedWithNewImpl() { 183 Binder activity1 = new Binder(); 184 Resources resources1 = mResourcesManager.createBaseActivityResources( 185 activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, 186 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 187 assertNotNull(resources1); 188 189 Resources.Theme theme = resources1.newTheme(); 190 assertSame(resources1, theme.getResources()); 191 theme.applyStyle(android.R.style.Theme_NoTitleBar, false); 192 193 TypedValue value = new TypedValue(); 194 assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true)); 195 assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type); 196 assertTrue(value.data != 0); 197 198 final Configuration overrideConfig = new Configuration(); 199 overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; 200 mResourcesManager.updateResourcesForActivity(activity1, overrideConfig, 201 Display.DEFAULT_DISPLAY, false /* movedToDifferentDisplay */); 202 assertSame(resources1, theme.getResources()); 203 204 // Make sure we can still access the data. 205 assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true)); 206 assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type); 207 assertTrue(value.data != 0); 208 } 209 210 @SmallTest 211 public void testMultipleResourcesForOneActivityGetUpdatedWhenActivityBaseUpdates() { 212 Binder activity1 = new Binder(); 213 214 // Create a Resources for the Activity. 215 Configuration config1 = new Configuration(); 216 config1.densityDpi = 280; 217 Resources resources1 = mResourcesManager.createBaseActivityResources( 218 activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config1, 219 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 220 assertNotNull(resources1); 221 222 // Create a Resources based on the Activity. 223 Configuration config2 = new Configuration(); 224 config2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES; 225 Resources resources2 = mResourcesManager.getResources( 226 activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, config2, 227 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 228 assertNotNull(resources2); 229 230 assertNotSame(resources1, resources2); 231 assertNotSame(resources1.getImpl(), resources2.getImpl()); 232 233 final Configuration expectedConfig1 = new Configuration(); 234 expectedConfig1.setToDefaults(); 235 expectedConfig1.setLocales(LocaleList.getAdjustedDefault()); 236 expectedConfig1.densityDpi = 280; 237 assertEquals(expectedConfig1, resources1.getConfiguration()); 238 239 // resources2 should be based on the Activity's override config, so the density should 240 // be the same as resources1. 241 final Configuration expectedConfig2 = new Configuration(); 242 expectedConfig2.setToDefaults(); 243 expectedConfig2.setLocales(LocaleList.getAdjustedDefault()); 244 expectedConfig2.densityDpi = 280; 245 expectedConfig2.screenLayout |= Configuration.SCREENLAYOUT_ROUND_YES; 246 assertEquals(expectedConfig2, resources2.getConfiguration()); 247 248 // Now update the Activity base override, and both resources should update. 249 config1.orientation = Configuration.ORIENTATION_LANDSCAPE; 250 mResourcesManager.updateResourcesForActivity(activity1, config1, Display.DEFAULT_DISPLAY, 251 false /* movedToDifferentDisplay */); 252 253 expectedConfig1.orientation = Configuration.ORIENTATION_LANDSCAPE; 254 assertEquals(expectedConfig1, resources1.getConfiguration()); 255 256 expectedConfig2.orientation = Configuration.ORIENTATION_LANDSCAPE; 257 assertEquals(expectedConfig2, resources2.getConfiguration()); 258 } 259 } 260