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.language;
18 
19 import android.car.drivingstate.CarUxRestrictions;
20 import android.content.Context;
21 
22 import androidx.preference.Preference;
23 import androidx.preference.PreferenceGroup;
24 
25 import com.android.car.settings.common.FragmentController;
26 import com.android.car.settings.common.PreferenceController;
27 import com.android.internal.app.LocalePicker;
28 import com.android.internal.app.LocaleStore;
29 
30 import java.util.HashSet;
31 import java.util.Set;
32 
33 /**
34  * Common business logic shared between the primary and secondary screens for language selection.
35  */
36 public abstract class LanguageBasePreferenceController extends
37         PreferenceController<PreferenceGroup> implements Preference.OnPreferenceClickListener {
38 
39     /** Actions that should be taken on selection of the preference. */
40     public interface LocaleSelectedListener {
41         /** Handle selection of locale. */
onLocaleSelected(LocaleStore.LocaleInfo localeInfo)42         void onLocaleSelected(LocaleStore.LocaleInfo localeInfo);
43     }
44 
45     private Set<String> mExclusionSet = new HashSet<>();
46     private LocaleSelectedListener mLocaleSelectedListener;
47 
LanguageBasePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)48     public LanguageBasePreferenceController(Context context, String preferenceKey,
49             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
50         super(context, preferenceKey, fragmentController, uxRestrictions);
51     }
52 
53     @Override
getPreferenceType()54     protected Class<PreferenceGroup> getPreferenceType() {
55         return PreferenceGroup.class;
56     }
57 
58     /** Register a listener for when a locale is selected. */
setLocaleSelectedListener(LocaleSelectedListener listener)59     public void setLocaleSelectedListener(LocaleSelectedListener listener) {
60         mLocaleSelectedListener = listener;
61     }
62 
63     /** Gets the exclusion set. */
getExclusionSet()64     public Set<String> getExclusionSet() {
65         return mExclusionSet;
66     }
67 
68     /** Defines the locale provider that should be used by the given preference controller. */
defineLocaleProvider()69     protected abstract LocalePreferenceProvider defineLocaleProvider();
70 
71     @Override
updateState(PreferenceGroup preferenceGroup)72     protected void updateState(PreferenceGroup preferenceGroup) {
73         // Only populate if the preference group is empty.
74         if (preferenceGroup.getPreferenceCount() == 0) {
75             defineLocaleProvider().populateBasePreference(preferenceGroup, getExclusionSet(), this);
76         }
77     }
78 
79     /**
80      * Defines the action that should be taken when a locale with children is clicked. By default,
81      * does nothing.
82      */
handleLocaleWithChildren(LocaleStore.LocaleInfo parentLocaleInfo)83     protected void handleLocaleWithChildren(LocaleStore.LocaleInfo parentLocaleInfo) {
84     }
85 
86     @Override
onPreferenceClick(Preference preference)87     public boolean onPreferenceClick(Preference preference) {
88         LocaleStore.LocaleInfo localeInfo = LocaleUtil.getLocaleArgument(preference);
89 
90         // Preferences without a associated locale should not be acted on.
91         if (localeInfo == null) {
92             return false;
93         }
94 
95         if (localeInfo.getParent() == null) {
96             // The locale only has the language info. Need to look up the sub-level
97             // locale to get the country/region info as well.
98             Set<LocaleStore.LocaleInfo> subLocales = LocaleStore.getLevelLocales(
99                     getContext(),
100                     getExclusionSet(),
101                     /* parent= */ localeInfo,
102                     /* translatedOnly= */ true);
103 
104             if (subLocales.size() > 1) {
105                 handleLocaleWithChildren(localeInfo);
106                 return true;
107             }
108 
109             if (subLocales.size() < 1) {
110                 return false;
111             }
112 
113             // If only 1 sublocale, just operate as if there are no sublocales.
114             localeInfo = subLocales.iterator().next();
115         }
116 
117         LocalePicker.updateLocale(localeInfo.getLocale());
118         if (mLocaleSelectedListener != null) {
119             mLocaleSelectedListener.onLocaleSelected(localeInfo);
120         }
121         getFragmentController().goBack();
122         return true;
123     }
124 }
125