blob: 9bb87fadf3ee3e1e2d985060f5cac3b3e914a4fb [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.car.settings.language;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceGroup;
import com.android.car.settings.common.Logger;
import com.android.car.settings.common.PreferenceUtil;
import com.android.car.settingslib.R;
import com.android.car.settingslib.language.LanguagePickerUtils;
import com.android.car.ui.preference.CarUiPreference;
import com.android.internal.app.LocaleStore;
import com.android.internal.app.SuggestedLocaleAdapter;
import java.util.Set;
/**
* Provides a wrapper around the {@link SuggestedLocaleAdapter} to create Preferences to populate
* the Language Settings screen.
*/
public class LocalePreferenceProvider {
private static final Logger LOG = new Logger(LanguagePickerPreferenceController.class);
/** Creates a new instance of the preference provider. */
public static LocalePreferenceProvider newInstance(Context context,
Set<LocaleStore.LocaleInfo> localeInfoSet,
@Nullable LocaleStore.LocaleInfo parentLocale) {
SuggestedLocaleAdapter adapter = LanguagePickerUtils.createSuggestedLocaleAdapter(context,
localeInfoSet, parentLocale);
return new LocalePreferenceProvider(context, adapter);
}
/**
* Header types are copied from {@link SuggestedLocaleAdapter} in order to be able to
* determine the header rows.
*/
@VisibleForTesting
static final int TYPE_HEADER_SUGGESTED = 0;
@VisibleForTesting
static final int TYPE_HEADER_ALL_OTHERS = 1;
@VisibleForTesting
static final int TYPE_LOCALE = 2;
private final Context mContext;
private SuggestedLocaleAdapter mSuggestedLocaleAdapter;
@VisibleForTesting
LocalePreferenceProvider(Context context, SuggestedLocaleAdapter localeAdapter) {
mContext = context;
mSuggestedLocaleAdapter = localeAdapter;
}
/**
* Populates the base preference group based on the hierarchy provided by this provider.
*
* @param base the preference container which will hold the language preferences created by
* this provider
* @param listener the click listener registered to the language/locale preferences contained in
* the base preference group
*/
public void populateBasePreference(PreferenceGroup base, Set<String> ignorables,
Preference.OnPreferenceClickListener listener) {
/*
* LocalePreferenceProvider can give elements to be represented in 2 ways. In the first
* way, it simply provides the LocalePreferences which lists the available options. In the
* second way, this provider may also provide PreferenceCategories to break up the
* options into "Suggested" and "All others". The screen is constructed by taking a look
* at the type of Preference that is provided through LocalePreferenceProvider.
*
* In the first case (no subcategories), preferences are added directly to the base
* container. Otherwise, elements are added to the last category that was provided
* (stored in "category").
*/
PreferenceCategory category = null;
for (int position = 0; position < mSuggestedLocaleAdapter.getCount(); position++) {
Preference preference = getPreference(position, ignorables);
if (PreferenceUtil.checkPreferenceType(preference, PreferenceCategory.class)) {
category = (PreferenceCategory) preference;
base.addPreference(category);
} else {
preference.setOnPreferenceClickListener(listener);
if (category == null) {
base.addPreference(preference);
} else {
category.addPreference(preference);
}
}
}
}
/**
* Constructs a PreferenceCategory or Preference with locale arguments based on the type of item
* provided.
*/
private Preference getPreference(int position, Set<String> ignorables) {
int type = mSuggestedLocaleAdapter.getItemViewType(position);
switch (type) {
case TYPE_HEADER_SUGGESTED:
case TYPE_HEADER_ALL_OTHERS:
PreferenceCategory category = new PreferenceCategory(mContext);
category.setTitle(type == TYPE_HEADER_SUGGESTED
? R.string.language_picker_list_suggested_header
: R.string.language_picker_list_all_header);
return category;
case TYPE_LOCALE:
LocaleStore.LocaleInfo info =
(LocaleStore.LocaleInfo) mSuggestedLocaleAdapter.getItem(position);
CarUiPreference preference = new CarUiPreference(mContext);
preference.setTitle(info.getFullNameNative());
// Only locales with multiple sublocales needs to show the chevron, since in those
// cases, the user needs to navigate to the child fragment to select the sublocale.
Set<LocaleStore.LocaleInfo> subLocales = LocaleStore.getLevelLocales(
mContext,
ignorables,
info,
/* translatedOnly */ true);
preference.setShowChevron(subLocales.size() > 1);
LocaleUtil.setLocaleArgument(preference, info);
return preference;
default:
LOG.d("Attempting to get unknown type: " + type);
throw new IllegalStateException("Unknown locale list item type");
}
}
}