Home | History | Annotate | Download | only in common
      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  *     &#64;Override
     40  *     public void setUp() throws Exception {
     41  *         super.setUp();
     42  *         mLocaleTestUtils = new LocaleTestUtils(getContext());
     43  *         mLocaleTestUtils.setLocale(Locale.CANADA_FRENCH);
     44  *     }
     45  *
     46  *     &#64;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      */
     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      */
     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      */
     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      */
    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 }