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