• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.car.settings.system;
18 
19 import android.arch.lifecycle.LiveData;
20 import android.arch.lifecycle.MutableLiveData;
21 import android.arch.lifecycle.ViewModel;
22 import android.arch.lifecycle.ViewModelProviders;
23 import android.content.Context;
24 import android.content.res.Configuration;
25 import android.content.res.Resources;
26 import android.os.AsyncTask;
27 import android.os.Build;
28 import android.os.Bundle;
29 
30 import androidx.car.widget.ListItemProvider;
31 
32 import com.android.car.settings.R;
33 import com.android.car.settings.common.ListItemSettingsFragment;
34 import com.android.car.settingslib.language.LanguagePickerUtils;
35 import com.android.car.settingslib.language.LocaleListItemProvider;
36 import com.android.car.settingslib.language.LocaleSelectionListener;
37 import com.android.internal.app.LocalePicker;
38 import com.android.internal.app.LocaleStore;
39 
40 import java.util.HashSet;
41 import java.util.Locale;
42 import java.util.Set;
43 
44 /**
45  * Fragment for showing the list of languages.
46  */
47 public class LanguagePickerFragment extends ListItemSettingsFragment implements
48         LocaleSelectionListener {
49 
50     private LocaleListItemProvider mLocaleListItemProvider;
51     private final HashSet<String> mLangTagsToIgnore = new HashSet<>();
52 
53     /**
54      * Factory method for creating LanguagePickerFragment.
55      */
newInstance()56     public static LanguagePickerFragment newInstance() {
57         LanguagePickerFragment LanguagePickerFragment = new LanguagePickerFragment();
58         Bundle bundle = ListItemSettingsFragment.getBundle();
59         bundle.putInt(EXTRA_TITLE_ID, R.string.language_settings);
60         bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar);
61         LanguagePickerFragment.setArguments(bundle);
62         return LanguagePickerFragment;
63     }
64 
65     @Override
onActivityCreated(Bundle savedInstanceState)66     public void onActivityCreated(Bundle savedInstanceState) {
67         super.onActivityCreated(savedInstanceState);
68 
69         LocaleViewModel viewModel = getLocaleViewModel();
70         viewModel.getLocaleInfos(getContext(), mLangTagsToIgnore).observe(this,
71                 localeInfos -> resetLocaleList(localeInfos));
72     }
73 
74     @Override
getItemProvider()75     public ListItemProvider getItemProvider() {
76         if (mLocaleListItemProvider == null) {
77             mLocaleListItemProvider = new LocaleListItemProvider(
78                     getContext(),
79                     new HashSet<LocaleStore.LocaleInfo>(),
80                     /* localeSelectionListener= */ this,
81                     mLangTagsToIgnore);
82         }
83         return mLocaleListItemProvider;
84     }
85 
86     @Override
onLocaleSelected(LocaleStore.LocaleInfo localeInfo)87     public void onLocaleSelected(LocaleStore.LocaleInfo localeInfo) {
88         if (localeInfo == null || localeInfo.getLocale() == null) {
89             return;
90         }
91 
92         Locale locale = localeInfo.getLocale();
93 
94         Resources res = getResources();
95         Configuration baseConfig = res.getConfiguration();
96         Configuration config = new Configuration(baseConfig);
97         config.setLocale(locale);
98         res.updateConfiguration(config, null);
99 
100         // Apply locale to system.
101         LocalePicker.updateLocale(locale);
102         getFragmentController().goBack();
103     }
104 
105     @Override
onParentWithChildrenLocaleSelected(LocaleStore.LocaleInfo localeInfo)106     public void onParentWithChildrenLocaleSelected(LocaleStore.LocaleInfo localeInfo) {
107         if (localeInfo != null) {
108             setTitle(localeInfo.getFullNameNative());
109             refreshList();
110         }
111     }
112 
113     @Override
onBackPressed()114     protected void onBackPressed() {
115         if (isChildLocaleDisplayed()) {
116             setTitle(getString(R.string.language_settings));
117             getLocaleViewModel().reloadLocales(getContext(), mLangTagsToIgnore);
118         } else {
119             super.onBackPressed();
120         }
121     }
122 
getLocaleViewModel()123     private LocaleViewModel getLocaleViewModel() {
124         return ViewModelProviders.of(this).get(LocaleViewModel.class);
125     }
126 
isChildLocaleDisplayed()127     private boolean isChildLocaleDisplayed() {
128         return mLocaleListItemProvider != null && mLocaleListItemProvider.isChildLocale();
129     }
130 
131     /**
132      * Add a pseudo locale in debug build for testing RTL.
133      *
134      * @param localeInfos the set of {@link LocaleStore.LocaleInfo} to which the locale is added.
135      */
maybeAddPseudoLocale(Set<LocaleStore.LocaleInfo> localeInfos)136     private void maybeAddPseudoLocale(Set<LocaleStore.LocaleInfo> localeInfos) {
137         if (Build.IS_USERDEBUG) {
138             // The ar-XB pseudo-locale is RTL.
139             localeInfos.add(LocaleStore.getLocaleInfo(new Locale("ar", "XB")));
140         }
141     }
142 
resetLocaleList(Set<LocaleStore.LocaleInfo> localeInfos)143     private void resetLocaleList(Set<LocaleStore.LocaleInfo> localeInfos) {
144         if (mLocaleListItemProvider != null) {
145             maybeAddPseudoLocale(localeInfos);
146             mLocaleListItemProvider.updateSuggestedLocaleAdapter(
147                     LanguagePickerUtils.createSuggestedLocaleAdapter(
148                             getContext(), localeInfos, /* parent= */ null),
149                     /* isChildLocale= */ false);
150             refreshList();
151         }
152     }
153 
154     /**
155      * ViewModel for holding the LocaleInfos.
156      */
157     public static class LocaleViewModel extends ViewModel {
158 
159         private MutableLiveData<Set<LocaleStore.LocaleInfo>> mLocaleInfos;
160 
161         /**
162          * Returns LiveData holding a set of LocaleInfo.
163          */
getLocaleInfos(Context context, Set<String> ignorables)164         public LiveData<Set<LocaleStore.LocaleInfo>> getLocaleInfos(Context context,
165                 Set<String> ignorables) {
166 
167             if (mLocaleInfos == null) {
168                 mLocaleInfos = new MutableLiveData<Set<LocaleStore.LocaleInfo>>();
169                 reloadLocales(context, ignorables);
170             }
171             return mLocaleInfos;
172         }
173 
174         /**
175          * Reload the locales based on the current context.
176          */
reloadLocales(Context context, Set<String> ignorables)177         public void reloadLocales(Context context, Set<String> ignorables) {
178             new AsyncTask<Context, Void, Set<LocaleStore.LocaleInfo>>() {
179                 @Override
180                 protected Set<LocaleStore.LocaleInfo> doInBackground(Context... contexts) {
181                     return LocaleStore.getLevelLocales(
182                             contexts[0],
183                             ignorables,
184                             /* parent= */ null,
185                             /* translatedOnly= */ true);
186                 }
187 
188                 @Override
189                 protected void onPostExecute(Set<LocaleStore.LocaleInfo> localeInfos) {
190                     LocaleViewModel.this.mLocaleInfos.setValue(localeInfos);
191                 }
192             }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, context);
193         }
194     }
195 }
196