1b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak/* 2b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Copyright (C) 2017 The Android Open Source Project 3b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 4b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Licensed under the Apache License, Version 2.0 (the "License"); 5b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * you may not use this file except in compliance with the License. 6b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * You may obtain a copy of the License at 7b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 8b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * http://www.apache.org/licenses/LICENSE-2.0 9b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 10b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Unless required by applicable law or agreed to in writing, software 11b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * distributed under the License is distributed on an "AS IS" BASIS, 12b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * See the License for the specific language governing permissions and 14b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * limitations under the License. 15b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 16b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 17b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakpackage com.android.managedprovisioning.common; 18b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 19b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakimport android.content.Context; 20b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakimport android.content.res.Configuration; 21b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakimport android.content.res.Resources; 22b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 23b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakimport java.util.Locale; 24b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 25b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak/** 26b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Utility class to save and restore the locale of the system. 27b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * <p> 28b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Taken from <a href="https://android.googlesource.com/platform/packages/apps/Dialer/+/94b10b530c0fc297e2974e57e094c500d3ee6003/tests/src/com/android/dialer/util/LocaleTestUtils.java">com.android.dialer.util.LocaleTestUtils</a> 29b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * <p> 30b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * This can be used for tests that assume to be run in a certain locale, e.g., because they 31b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * check against strings in a particular language or require an assumption on how the system 32b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * will behave in a specific locale. 33b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * <p> 34b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * In your test, you can change the locale with the following code: 35b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * <pre> 36b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * public class CanadaFrenchTest extends AndroidTestCase { 37b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * private LocaleTestUtils mLocaleTestUtils; 38b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 39b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @Override 40b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * public void setUp() throws Exception { 41b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * super.setUp(); 42b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * mLocaleTestUtils = new LocaleTestUtils(getContext()); 43b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * mLocaleTestUtils.setLocale(Locale.CANADA_FRENCH); 44b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * } 45b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 46b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @Override 47b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * public void tearDown() throws Exception { 48b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * mLocaleTestUtils.restoreLocale(); 49b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * mLocaleTestUtils = null; 50b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * super.tearDown(); 51b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * } 52b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 53b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * ... 54b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * } 55b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * </pre> 56b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Note that one should not call {@link #setLocale(Locale)} more than once without calling 57b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * {@link #restoreLocale()} first. 58b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * <p> 59b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * This class is not thread-safe. Usually its methods should be invoked only from the test thread. 60b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 61b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzakpublic class LocaleTestUtils { 62b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak private final Context mContext; 63b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak private boolean mSaved; 64b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak private Locale mSavedContextLocale; 65b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak private Locale mSavedSystemLocale; 66b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 67b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak /** 68b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Create a new instance that can be used to set and reset the locale for the given context. 69b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 70b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @param context the context on which to alter the locale 71b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 72b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak public LocaleTestUtils(Context context) { 73b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mContext = context; 74b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mSaved = false; 75b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 76b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 77b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak /** 78b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Set the locale to the given value and saves the previous value. 79b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 80b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @param locale the value to which the locale should be set 81b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @throws IllegalStateException if the locale was already set 82b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 83b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak public void setLocale(Locale locale) { 84b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak if (mSaved) { 85b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak throw new IllegalStateException( 86b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak "call restoreLocale() before calling setLocale() again"); 87b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 88b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mSavedContextLocale = setResourcesLocale(mContext.getResources(), locale); 89b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mSavedSystemLocale = setResourcesLocale(Resources.getSystem(), locale); 90b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mSaved = true; 91b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 92b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 93b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak /** 94b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Restores the previously set locale. 95b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 96b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @throws IllegalStateException if the locale was not set using {@link #setLocale(Locale)} 97b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 98b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak public void restoreLocale() { 99b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak if (!mSaved) { 100b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak throw new IllegalStateException("call setLocale() before calling restoreLocale()"); 101b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 102b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak setResourcesLocale(mContext.getResources(), mSavedContextLocale); 103b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak setResourcesLocale(Resources.getSystem(), mSavedSystemLocale); 104b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak mSaved = false; 105b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 106b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak 107b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak /** 108b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * Sets the locale for the given resources and returns the previous locale. 109b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * 110b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @param resources the resources on which to set the locale 111b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @param locale the value to which to set the locale 112b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak * @return the previous value of the locale for the resources 113b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak */ 114b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak private Locale setResourcesLocale(Resources resources, Locale locale) { 115b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak Configuration contextConfiguration = new Configuration(resources.getConfiguration()); 116b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak Locale savedLocale = contextConfiguration.locale; 117b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak contextConfiguration.locale = locale; 118b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak resources.updateConfiguration(contextConfiguration, null); 119b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak return savedLocale; 120b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak } 121b9a9b872b7bd51a738dfef1b55fe1990d3ecb309Jakub Gielzak}