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 *     &#64;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 *     &#64;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}