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