1 /*
2  * Copyright (C) 2022 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.tv.settings.system.locale;
18 
19 
20 import static com.android.tv.settings.system.locale.LanguagePickerFragment.KEY_LOCALE_INFO;
21 
22 import android.app.ActivityManager;
23 import android.content.Context;
24 import android.os.Build;
25 import android.os.Bundle;
26 import android.os.Handler;
27 import android.os.LocaleList;
28 import android.os.Looper;
29 import android.util.Log;
30 
31 import androidx.annotation.Keep;
32 import androidx.lifecycle.ViewModelProvider;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceScreen;
35 
36 import com.android.internal.app.LocaleHelper;
37 import com.android.internal.app.LocaleStore;
38 import com.android.tv.settings.RadioPreference;
39 import com.android.tv.settings.SettingsPreferenceFragment;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.stream.Collectors;
45 
46 /** Country picker settings screen for locale selection. */
47 @Keep
48 public class CountryPickerFragment extends SettingsPreferenceFragment {
49     private static final String EXTRA_PARENT_LOCALE = "PARENT_LOCALE";
50     private static final String TAG = "CountryPickerFragment";
51     private static final String COUNTRY_PICKER_RADIO_GROUP = "country_picker_group";
52     private static final boolean DEBUG = Build.isDebuggable();
53     private LocaleDataViewModel mLocaleDataViewModel;
54     private Handler mHandler = new Handler(Looper.getMainLooper());
55 
prepareArgs(LocaleStore.LocaleInfo localeInfo)56     public static Bundle prepareArgs(LocaleStore.LocaleInfo localeInfo) {
57         Bundle b = new Bundle();
58         b.putSerializable(EXTRA_PARENT_LOCALE, localeInfo);
59         return b;
60     }
61 
62     @Override
onCreatePreferences(Bundle savedInstanceState, String s)63     public void onCreatePreferences(Bundle savedInstanceState, String s) {
64         mLocaleDataViewModel = new ViewModelProvider(getActivity()).get(LocaleDataViewModel.class);
65         final Context themedContext = getPreferenceManager().getContext();
66         LocaleStore.LocaleInfo parentLocale = (LocaleStore.LocaleInfo) getArguments()
67                 .getSerializable(EXTRA_PARENT_LOCALE);
68         final PreferenceScreen screen =
69                 getPreferenceManager().createPreferenceScreen(themedContext);
70         if (parentLocale != null) {
71             screen.setTitle(parentLocale.getFullNameNative());
72         }
73         Locale currentLocale = LocaleDataViewModel.getCurrentLocale();
74         List<LocaleStore.LocaleInfo> localeInfoCountryList = mLocaleDataViewModel
75                 .getLocaleInfoList(parentLocale);
76         Preference activePref = null;
77         if (localeInfoCountryList != null) {
78             Locale sortingLocale = Locale.getDefault();
79             LocaleHelper.LocaleInfoComparator comp =
80                     new LocaleHelper.LocaleInfoComparator(sortingLocale, true);
81 
82             for (LocaleStore.LocaleInfo localeInfo : localeInfoCountryList.stream()
83                     .sorted(comp).toList()) {
84                 RadioPreference preference = new RadioPreference(getContext());
85                 preference.setTitle(localeInfo.getFullCountryNameNative());
86                 if (localeInfo.getLocale().equals(currentLocale)) {
87                     activePref = preference;
88                     preference.setChecked(true);
89                 } else {
90                     preference.setChecked(false);
91                 }
92                 preference.setRadioGroup(COUNTRY_PICKER_RADIO_GROUP);
93                 preference.getExtras().putSerializable(KEY_LOCALE_INFO, localeInfo);
94                 screen.addPreference(preference);
95             }
96         }
97         if (activePref != null) {
98             final Preference pref = activePref;
99             mHandler.post(() -> scrollToPreference(pref));
100         }
101 
102         setPreferenceScreen(screen);
103     }
104 
105     @Override
onPreferenceTreeClick(Preference preference)106     public boolean onPreferenceTreeClick(Preference preference) {
107         if (DEBUG) {
108             Log.d(TAG, "Preference clicked: " + preference.getTitle());
109         }
110         if (preference instanceof RadioPreference) {
111             RadioPreference localePref = (RadioPreference) preference;
112             if (!localePref.isChecked()) {
113                 localePref.setChecked(true);
114                 return true;
115             }
116             LocaleStore.LocaleInfo localeInfo = localePref.getExtras().getSerializable(
117                     KEY_LOCALE_INFO, LocaleStore.LocaleInfo.class);
118             if (localeInfo != null) {
119                 getContext().getSystemService(ActivityManager.class).setDeviceLocales(
120                         new LocaleList(localeInfo.getLocale()));
121             }
122             localePref.clearOtherRadioPreferences(getPreferenceScreen());
123             return true;
124         }
125         return super.onPreferenceTreeClick(preference);
126     }
127 }
128