1 /* 2 * Copyright (C) 2011 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.dialer.util; 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 * This can be used for tests that assume to be run in a certain locale, e.g., because they 29 * check against strings in a particular language or require an assumption on how the system 30 * will behave in a specific locale. 31 * <p> 32 * In your test, you can change the locale with the following code: 33 * <pre> 34 * public class CanadaFrenchTest extends AndroidTestCase { 35 * private LocaleTestUtils mLocaleTestUtils; 36 * 37 * @Override 38 * public void setUp() throws Exception { 39 * super.setUp(); 40 * mLocaleTestUtils = new LocaleTestUtils(getContext()); 41 * mLocaleTestUtils.setLocale(Locale.CANADA_FRENCH); 42 * } 43 * 44 * @Override 45 * public void tearDown() throws Exception { 46 * mLocaleTestUtils.restoreLocale(); 47 * mLocaleTestUtils = null; 48 * super.tearDown(); 49 * } 50 * 51 * ... 52 * } 53 * </pre> 54 * Note that one should not call {@link #setLocale(Locale)} more than once without calling 55 * {@link #restoreLocale()} first. 56 * <p> 57 * This class is not thread-safe. Usually its methods should be invoked only from the test thread. 58 */ 59 public class LocaleTestUtils { 60 private final Context mContext; 61 private boolean mSaved; 62 private Locale mSavedContextLocale; 63 private Locale mSavedSystemLocale; 64 65 /** 66 * Create a new instance that can be used to set and reset the locale for the given context. 67 * 68 * @param context the context on which to alter the locale 69 */ LocaleTestUtils(Context context)70 public LocaleTestUtils(Context context) { 71 mContext = context; 72 mSaved = false; 73 } 74 75 /** 76 * Set the locale to the given value and saves the previous value. 77 * 78 * @param locale the value to which the locale should be set 79 * @throws IllegalStateException if the locale was already set 80 */ setLocale(Locale locale)81 public void setLocale(Locale locale) { 82 if (mSaved) { 83 throw new IllegalStateException( 84 "call restoreLocale() before calling setLocale() again"); 85 } 86 mSavedContextLocale = setResourcesLocale(mContext.getResources(), locale); 87 mSavedSystemLocale = setResourcesLocale(Resources.getSystem(), locale); 88 mSaved = true; 89 } 90 91 /** 92 * Restores the previously set locale. 93 * 94 * @throws IllegalStateException if the locale was not set using {@link #setLocale(Locale)} 95 */ restoreLocale()96 public void restoreLocale() { 97 if (!mSaved) { 98 throw new IllegalStateException("call setLocale() before calling restoreLocale()"); 99 } 100 setResourcesLocale(mContext.getResources(), mSavedContextLocale); 101 setResourcesLocale(Resources.getSystem(), mSavedSystemLocale); 102 mSaved = false; 103 } 104 105 /** 106 * Sets the locale for the given resources and returns the previous locale. 107 * 108 * @param resources the resources on which to set the locale 109 * @param locale the value to which to set the locale 110 * @return the previous value of the locale for the resources 111 */ setResourcesLocale(Resources resources, Locale locale)112 private Locale setResourcesLocale(Resources resources, Locale locale) { 113 Configuration contextConfiguration = new Configuration(resources.getConfiguration()); 114 Locale savedLocale = contextConfiguration.locale; 115 contextConfiguration.locale = locale; 116 resources.updateConfiguration(contextConfiguration, null); 117 return savedLocale; 118 } 119 } 120