| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 1 | /* |
| Michael Bestas | ec05005 | 2024-02-14 20:35:43 +0200 | [diff] [blame] | 2 | * SPDX-FileCopyrightText: 2016 The CyanogenMod Project |
| 3 | * SPDX-FileCopyrightText: 2017-2024 The LineageOS Project |
| 4 | * SPDX-License-Identifier: Apache-2.0 |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 5 | */ |
| 6 | |
| Michael Bestas | c83309e | 2018-02-03 17:42:13 +0200 | [diff] [blame] | 7 | package org.lineageos.setupwizard; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 8 | |
| 9 | import android.app.Activity; |
| 10 | import android.content.BroadcastReceiver; |
| 11 | import android.content.Context; |
| 12 | import android.content.Intent; |
| 13 | import android.content.IntentFilter; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 14 | import android.os.Bundle; |
| 15 | import android.os.Handler; |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 16 | import android.os.Looper; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 17 | import android.telephony.SubscriptionInfo; |
| 18 | import android.telephony.SubscriptionManager; |
| 19 | import android.telephony.TelephonyManager; |
| Tommy Webb | ac47a02 | 2024-04-15 18:34:09 +0000 | [diff] [blame] | 20 | import android.util.Log; |
| Timi Rautamäki | c893e61 | 2022-01-27 15:41:46 +0000 | [diff] [blame] | 21 | import android.view.View; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 22 | import android.widget.ArrayAdapter; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 23 | import android.widget.NumberPicker; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 24 | import android.widget.Toast; |
| 25 | |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 26 | import com.android.internal.telephony.TelephonyIntents; |
| Renlord | 4027def | 2020-09-21 22:48:41 +1000 | [diff] [blame] | 27 | import com.android.internal.telephony.util.LocaleUtils; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 28 | |
| Timi Rautamäki | ab4f123 | 2021-08-23 16:56:13 +0000 | [diff] [blame] | 29 | import com.google.android.setupcompat.util.SystemBarHelper; |
| 30 | |
| Michael Bestas | c83309e | 2018-02-03 17:42:13 +0200 | [diff] [blame] | 31 | import org.lineageos.setupwizard.widget.LocalePicker; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 32 | |
| 33 | import java.util.List; |
| 34 | import java.util.Locale; |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 35 | import java.util.concurrent.ExecutorService; |
| 36 | import java.util.concurrent.Executors; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 37 | |
| 38 | public class LocaleActivity extends BaseSetupWizardActivity { |
| 39 | |
| Tommy Webb | ac47a02 | 2024-04-15 18:34:09 +0000 | [diff] [blame] | 40 | private static final String TAG = LocaleActivity.class.getSimpleName(); |
| 41 | |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 42 | private ArrayAdapter<com.android.internal.app.LocalePicker.LocaleInfo> mLocaleAdapter; |
| 43 | private Locale mCurrentLocale; |
| 44 | private int[] mAdapterIndices; |
| 45 | private LocalePicker mLanguagePicker; |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 46 | private ExecutorService mFetchUpdateSimLocaleTask; |
| 47 | private final Handler mHandler = new Handler(Looper.getMainLooper()); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 48 | private boolean mPendingLocaleUpdate; |
| 49 | private boolean mPaused = true; |
| 50 | |
| 51 | private final Runnable mUpdateLocale = new Runnable() { |
| 52 | public void run() { |
| 53 | if (mCurrentLocale != null) { |
| 54 | mLanguagePicker.setEnabled(false); |
| Oliver Scott | d9d2859 | 2024-04-09 11:43:05 -0400 | [diff] [blame] | 55 | com.android.internal.app.LocalePicker.updateLocale(mCurrentLocale); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 56 | } |
| 57 | } |
| 58 | }; |
| 59 | |
| 60 | private final BroadcastReceiver mSimChangedReceiver = new BroadcastReceiver() { |
| 61 | @Override |
| 62 | public void onReceive(Context context, Intent intent) { |
| 63 | if (intent.getAction().equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { |
| 64 | fetchAndUpdateSimLocale(); |
| 65 | } |
| 66 | } |
| 67 | }; |
| 68 | |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 69 | @Override |
| 70 | protected void onCreate(Bundle savedInstanceState) { |
| 71 | super.onCreate(savedInstanceState); |
| Timi Rautamäki | ab4f123 | 2021-08-23 16:56:13 +0000 | [diff] [blame] | 72 | SystemBarHelper.setBackButtonVisible(getWindow(), true); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 73 | setNextText(R.string.next); |
| Oliver Scott | 51fde0a | 2024-01-06 22:15:26 -0500 | [diff] [blame] | 74 | mLanguagePicker = findViewById(R.id.locale_list); |
| Timi Rautamäki | daef80e | 2022-01-15 09:25:02 +0000 | [diff] [blame] | 75 | mLanguagePicker.setNextRight(getNextButton().getId()); |
| 76 | mLanguagePicker.requestFocus(); |
| Timi Rautamäki | c893e61 | 2022-01-27 15:41:46 +0000 | [diff] [blame] | 77 | if (getResources().getBoolean(R.bool.config_isLargeNoTouch)) { |
| Oliver Scott | fd0fdb8 | 2024-01-10 18:39:27 -0500 | [diff] [blame] | 78 | mLanguagePicker.setOnClickListener((View v) -> getNextButton().performClick()); |
| Timi Rautamäki | c893e61 | 2022-01-27 15:41:46 +0000 | [diff] [blame] | 79 | } |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 80 | loadLanguages(); |
| 81 | } |
| 82 | |
| 83 | @Override |
| 84 | public void onPause() { |
| 85 | super.onPause(); |
| 86 | mPaused = true; |
| 87 | unregisterReceiver(mSimChangedReceiver); |
| 88 | } |
| 89 | |
| 90 | @Override |
| 91 | public void onResume() { |
| 92 | super.onResume(); |
| 93 | mPaused = false; |
| 94 | registerReceiver(mSimChangedReceiver, |
| 95 | new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED)); |
| 96 | if (mLanguagePicker != null) { |
| 97 | mLanguagePicker.setEnabled(true); |
| 98 | } |
| 99 | if (mPendingLocaleUpdate) { |
| 100 | mPendingLocaleUpdate = false; |
| 101 | fetchAndUpdateSimLocale(); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | @Override |
| cretin45 | d4cea55 | 2016-04-25 11:00:04 -0700 | [diff] [blame] | 106 | protected int getLayoutResId() { |
| 107 | return R.layout.setup_locale; |
| 108 | } |
| 109 | |
| 110 | @Override |
| 111 | protected int getTitleResId() { |
| 112 | return R.string.setup_locale; |
| 113 | } |
| 114 | |
| 115 | @Override |
| 116 | protected int getIconResId() { |
| 117 | return R.drawable.ic_locale; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | private void loadLanguages() { |
| 121 | mLocaleAdapter = com.android.internal.app.LocalePicker.constructAdapter(this, |
| 122 | R.layout.locale_picker_item, R.id.locale); |
| 123 | mCurrentLocale = Locale.getDefault(); |
| 124 | fetchAndUpdateSimLocale(); |
| 125 | mAdapterIndices = new int[mLocaleAdapter.getCount()]; |
| 126 | int currentLocaleIndex = 0; |
| Michael Bestas | b7b34b9 | 2021-08-25 19:13:30 +0300 | [diff] [blame] | 127 | String[] labels = new String[mLocaleAdapter.getCount()]; |
| 128 | for (int i = 0; i < mAdapterIndices.length; i++) { |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 129 | com.android.internal.app.LocalePicker.LocaleInfo localLocaleInfo = |
| 130 | mLocaleAdapter.getItem(i); |
| 131 | Locale localLocale = localLocaleInfo.getLocale(); |
| 132 | if (localLocale.equals(mCurrentLocale)) { |
| 133 | currentLocaleIndex = i; |
| 134 | } |
| 135 | mAdapterIndices[i] = i; |
| 136 | labels[i] = localLocaleInfo.getLabel(); |
| 137 | } |
| 138 | mLanguagePicker.setDisplayedValues(labels); |
| 139 | mLanguagePicker.setMaxValue(labels.length - 1); |
| 140 | mLanguagePicker.setValue(currentLocaleIndex); |
| 141 | mLanguagePicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); |
| Michael W | 2236d29 | 2018-07-15 15:09:20 +0200 | [diff] [blame] | 142 | mLanguagePicker.setOnValueChangedListener((pkr, oldVal, newVal) -> setLocaleFromPicker()); |
| 143 | |
| 144 | mLanguagePicker.setOnScrollListener((view, scrollState) -> { |
| 145 | if (scrollState == NumberPicker.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) { |
| Michael Bestas | b7b34b9 | 2021-08-25 19:13:30 +0300 | [diff] [blame] | 146 | ((SetupWizardApp) getApplication()).setIgnoreSimLocale(true); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 147 | } |
| 148 | }); |
| 149 | } |
| 150 | |
| 151 | private void setLocaleFromPicker() { |
| Michael Bestas | b7b34b9 | 2021-08-25 19:13:30 +0300 | [diff] [blame] | 152 | ((SetupWizardApp) getApplication()).setIgnoreSimLocale(true); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 153 | int i = mAdapterIndices[mLanguagePicker.getValue()]; |
| Michael W | 2236d29 | 2018-07-15 15:09:20 +0200 | [diff] [blame] | 154 | final com.android.internal.app.LocalePicker.LocaleInfo localLocaleInfo = |
| 155 | mLocaleAdapter.getItem(i); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 156 | onLocaleChanged(localLocaleInfo.getLocale()); |
| 157 | } |
| 158 | |
| 159 | private void onLocaleChanged(Locale paramLocale) { |
| 160 | mLanguagePicker.setEnabled(true); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 161 | mHandler.removeCallbacks(mUpdateLocale); |
| 162 | mCurrentLocale = paramLocale; |
| 163 | mHandler.postDelayed(mUpdateLocale, 1000); |
| 164 | } |
| 165 | |
| 166 | private void fetchAndUpdateSimLocale() { |
| Michael Bestas | b7b34b9 | 2021-08-25 19:13:30 +0300 | [diff] [blame] | 167 | if (((SetupWizardApp) getApplication()).ignoreSimLocale() || isDestroyed()) { |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 168 | return; |
| 169 | } |
| 170 | if (mPaused) { |
| 171 | mPendingLocaleUpdate = true; |
| 172 | return; |
| 173 | } |
| 174 | if (mFetchUpdateSimLocaleTask != null) { |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 175 | mFetchUpdateSimLocaleTask.shutdown(); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 176 | } |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 177 | mFetchUpdateSimLocaleTask = Executors.newSingleThreadExecutor(); |
| 178 | mFetchUpdateSimLocaleTask.execute(() -> { |
| Tommy Webb | ac47a02 | 2024-04-15 18:34:09 +0000 | [diff] [blame] | 179 | Locale locale = null; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 180 | Activity activity = LocaleActivity.this; |
| 181 | if (!activity.isFinishing() || !activity.isDestroyed()) { |
| 182 | // If the sim is currently pin locked, return |
| 183 | TelephonyManager telephonyManager = (TelephonyManager) |
| 184 | activity.getSystemService(Context.TELEPHONY_SERVICE); |
| 185 | int state = telephonyManager.getSimState(); |
| Michael Bestas | b7b34b9 | 2021-08-25 19:13:30 +0300 | [diff] [blame] | 186 | if (state == TelephonyManager.SIM_STATE_PIN_REQUIRED || |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 187 | state == TelephonyManager.SIM_STATE_PUK_REQUIRED) { |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 188 | return; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 189 | } |
| 190 | |
| 191 | final SubscriptionManager subscriptionManager = |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 192 | activity.getSystemService(SubscriptionManager.class); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 193 | List<SubscriptionInfo> activeSubs = |
| 194 | subscriptionManager.getActiveSubscriptionInfoList(); |
| 195 | if (activeSubs == null || activeSubs.isEmpty()) { |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 196 | return; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 197 | } |
| 198 | |
| 199 | // Fetch locale for active sim's MCC |
| Tommy Webb | ac47a02 | 2024-04-15 18:34:09 +0000 | [diff] [blame] | 200 | final String mccString = activeSubs.get(0).getMccString(); |
| 201 | try { |
| 202 | if (mccString != null && !mccString.isEmpty()) { |
| 203 | int mcc = Integer.parseInt(mccString); |
| 204 | locale = LocaleUtils.getLocaleFromMcc(activity, mcc, null); |
| 205 | } else { |
| 206 | Log.w(TAG, "Unexpected mccString: '" + mccString + "'"); |
| 207 | } |
| 208 | } catch (NumberFormatException e) { |
| 209 | Log.w(TAG, "mccString not a number: '" + mccString + "'", e); |
| 210 | } |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 211 | |
| 212 | // If that fails, fall back to preferred languages reported |
| 213 | // by the sim |
| 214 | if (locale == null) { |
| Michael Bestas | 79e9f1c | 2024-03-05 23:17:41 +0200 | [diff] [blame] | 215 | Locale simLocale = telephonyManager.getSimLocale(); |
| 216 | if (simLocale != null) { |
| 217 | locale = simLocale; |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 218 | } |
| 219 | } |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 220 | Locale finalLocale = locale; |
| 221 | mHandler.post(() -> { |
| 222 | if (finalLocale != null && !finalLocale.equals(mCurrentLocale)) { |
| 223 | if (!((SetupWizardApp) getApplication()).ignoreSimLocale() |
| 224 | && !isDestroyed()) { |
| 225 | String label = getString(R.string.sim_locale_changed, |
| 226 | finalLocale.getDisplayName()); |
| 227 | Toast.makeText(LocaleActivity.this, label, Toast.LENGTH_SHORT).show(); |
| 228 | onLocaleChanged(finalLocale); |
| 229 | ((SetupWizardApp) getApplication()).setIgnoreSimLocale(true); |
| 230 | } |
| 231 | } |
| 232 | }); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 233 | } |
| Oliver Scott | f58c0f4 | 2024-01-08 14:52:12 -0500 | [diff] [blame] | 234 | }); |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 235 | } |
| cretin45 | 3593f03 | 2016-04-20 16:21:05 -0700 | [diff] [blame] | 236 | } |