use of android.os.LocaleList in project android_frameworks_base by DirtyUnicorns.
the class ActivityManagerService method updateConfigurationLocked.
/**
* Do either or both things: (1) change the current configuration, and (2)
* make sure the given activity is running with the (now) current
* configuration. Returns true if the activity has been left running, or
* false if <var>starting</var> is being destroyed to match the new
* configuration.
*
* @param userId is only used when persistent parameter is set to true to persist configuration
* for that particular user
*/
private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale, boolean persistent, int userId, boolean deferResume) {
int changes = 0;
if (mWindowManager != null) {
mWindowManager.deferSurfaceLayout();
}
if (values != null) {
Configuration newConfig = new Configuration(mConfiguration);
changes = newConfig.updateFrom(values);
if (changes != 0) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION)
Slog.i(TAG_CONFIGURATION, "Updating configuration to: " + values);
EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
final LocaleList locales = values.getLocales();
int bestLocaleIndex = 0;
if (locales.size() > 1) {
if (mSupportedSystemLocales == null) {
mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
}
bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
}
SystemProperties.set("persist.sys.locale", locales.get(bestLocaleIndex).toLanguageTag());
LocaleList.setDefault(locales, bestLocaleIndex);
mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, locales.get(bestLocaleIndex)));
}
mConfigurationSeq++;
if (mConfigurationSeq <= 0) {
mConfigurationSeq = 1;
}
newConfig.seq = mConfigurationSeq;
mConfiguration = newConfig;
Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
mUsageStatsService.reportConfigurationChange(newConfig, mUserController.getCurrentUserIdLocked());
//mUsageStatsService.noteStartConfig(newConfig);
final Configuration configCopy = new Configuration(mConfiguration);
// TODO: If our config changes, should we auto dismiss any currently
// showing dialogs?
mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
AttributeCache ac = AttributeCache.instance();
if (ac != null) {
ac.updateConfiguration(configCopy);
}
// Make sure all resources in our process are updated
// right now, so that anyone who is going to retrieve
// resource values after we return will be sure to get
// the new ones. This is especially important during
// boot, where the first config change needs to guarantee
// all resources have that config before following boot
// code is executed.
mSystemThread.applyConfigurationToResources(configCopy);
if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
msg.obj = new Configuration(configCopy);
msg.arg1 = userId;
mHandler.sendMessage(msg);
}
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange) {
// Reset the unsupported display size dialog.
mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
killAllBackgroundProcessesExcept(Build.VERSION_CODES.N, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
}
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
ProcessRecord app = mLruProcesses.get(i);
try {
if (app.thread != null) {
if (DEBUG_CONFIGURATION)
Slog.v(TAG_CONFIGURATION, "Sending to proc " + app.processName + " new config " + mConfiguration);
app.thread.scheduleConfigurationChanged(configCopy);
}
} catch (Exception e) {
}
}
Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_FOREGROUND);
broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
if (initLocale || !mProcessesReady) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
}
// ensureActivityConfigurationLocked().
if (mWindowManager != null) {
final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
if (resizedStacks != null) {
for (int stackId : resizedStacks) {
final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
mStackSupervisor.resizeStackLocked(stackId, newBounds, null, null, false, false, deferResume);
}
}
}
}
boolean kept = true;
final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
// mainStack is null during startup.
if (mainStack != null) {
if (changes != 0 && starting == null) {
// If the configuration changed, and the caller is not already
// in the process of starting an activity, then find the top
// activity to check if its configuration needs to change.
starting = mainStack.topRunningActivityLocked();
}
if (starting != null) {
kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, !PRESERVE_WINDOWS);
}
}
if (mWindowManager != null) {
mWindowManager.continueSurfaceLayout();
}
return kept;
}
use of android.os.LocaleList in project android_frameworks_base by AOSPA.
the class ActivityThread method updateLocaleListFromAppContext.
/**
* The LocaleList set for the app's resources may have been shuffled so that the preferred
* Locale is at position 0. We must find the index of this preferred Locale in the
* original LocaleList.
*/
private void updateLocaleListFromAppContext(Context context, LocaleList newLocaleList) {
final Locale bestLocale = context.getResources().getConfiguration().getLocales().get(0);
final int newLocaleListSize = newLocaleList.size();
for (int i = 0; i < newLocaleListSize; i++) {
if (bestLocale.equals(newLocaleList.get(i))) {
LocaleList.setDefault(newLocaleList, i);
return;
}
}
// The app may have overridden the LocaleList with its own Locale
// (not present in the available list). Push the chosen Locale
// to the front of the list.
LocaleList.setDefault(new LocaleList(bestLocale, newLocaleList));
}
use of android.os.LocaleList in project android_frameworks_base by AOSPA.
the class InputMethodUtils method getImplicitlyApplicableSubtypesLockedImpl.
private static ArrayList<InputMethodSubtype> getImplicitlyApplicableSubtypesLockedImpl(Resources res, InputMethodInfo imi) {
final List<InputMethodSubtype> subtypes = InputMethodUtils.getSubtypes(imi);
final LocaleList systemLocales = res.getConfiguration().getLocales();
final String systemLocale = systemLocales.get(0).toString();
if (TextUtils.isEmpty(systemLocale))
return new ArrayList<>();
final int numSubtypes = subtypes.size();
// Handle overridesImplicitlyEnabledSubtype mechanism.
final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = new HashMap<>();
for (int i = 0; i < numSubtypes; ++i) {
// scan overriding implicitly enabled subtypes.
final InputMethodSubtype subtype = subtypes.get(i);
if (subtype.overridesImplicitlyEnabledSubtype()) {
final String mode = subtype.getMode();
if (!applicableModeAndSubtypesMap.containsKey(mode)) {
applicableModeAndSubtypesMap.put(mode, subtype);
}
}
}
if (applicableModeAndSubtypesMap.size() > 0) {
return new ArrayList<>(applicableModeAndSubtypesMap.values());
}
final HashMap<String, ArrayList<InputMethodSubtype>> nonKeyboardSubtypesMap = new HashMap<>();
final ArrayList<InputMethodSubtype> keyboardSubtypes = new ArrayList<>();
for (int i = 0; i < numSubtypes; ++i) {
final InputMethodSubtype subtype = subtypes.get(i);
final String mode = subtype.getMode();
if (SUBTYPE_MODE_KEYBOARD.equals(mode)) {
keyboardSubtypes.add(subtype);
} else {
if (!nonKeyboardSubtypesMap.containsKey(mode)) {
nonKeyboardSubtypesMap.put(mode, new ArrayList<>());
}
nonKeyboardSubtypesMap.get(mode).add(subtype);
}
}
final ArrayList<InputMethodSubtype> applicableSubtypes = new ArrayList<>();
LocaleUtils.filterByLanguage(keyboardSubtypes, sSubtypeToLocale, systemLocales, applicableSubtypes);
if (!applicableSubtypes.isEmpty()) {
boolean hasAsciiCapableKeyboard = false;
final int numApplicationSubtypes = applicableSubtypes.size();
for (int i = 0; i < numApplicationSubtypes; ++i) {
final InputMethodSubtype subtype = applicableSubtypes.get(i);
if (subtype.containsExtraValueKey(TAG_ASCII_CAPABLE)) {
hasAsciiCapableKeyboard = true;
break;
}
}
if (!hasAsciiCapableKeyboard) {
final int numKeyboardSubtypes = keyboardSubtypes.size();
for (int i = 0; i < numKeyboardSubtypes; ++i) {
final InputMethodSubtype subtype = keyboardSubtypes.get(i);
final String mode = subtype.getMode();
if (SUBTYPE_MODE_KEYBOARD.equals(mode) && subtype.containsExtraValueKey(TAG_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE)) {
applicableSubtypes.add(subtype);
}
}
}
}
if (applicableSubtypes.isEmpty()) {
InputMethodSubtype lastResortKeyboardSubtype = findLastResortApplicableSubtypeLocked(res, subtypes, SUBTYPE_MODE_KEYBOARD, systemLocale, true);
if (lastResortKeyboardSubtype != null) {
applicableSubtypes.add(lastResortKeyboardSubtype);
}
}
// For each non-keyboard mode, extract subtypes with system locales.
for (final ArrayList<InputMethodSubtype> subtypeList : nonKeyboardSubtypesMap.values()) {
LocaleUtils.filterByLanguage(subtypeList, sSubtypeToLocale, systemLocales, applicableSubtypes);
}
return applicableSubtypes;
}
use of android.os.LocaleList in project android_frameworks_base by AOSPA.
the class ResourcesImpl method updateConfiguration.
public void updateConfiguration(Configuration config, DisplayMetrics metrics, CompatibilityInfo compat) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ResourcesImpl#updateConfiguration");
try {
synchronized (mAccessLock) {
if (false) {
Slog.i(TAG, "**** Updating config of " + this + ": old config is " + mConfiguration + " old compat is " + mDisplayAdjustments.getCompatibilityInfo());
Slog.i(TAG, "**** Updating config of " + this + ": new config is " + config + " new compat is " + compat);
}
if (compat != null) {
mDisplayAdjustments.setCompatibilityInfo(compat);
}
if (metrics != null) {
mMetrics.setTo(metrics);
}
// NOTE: We should re-arrange this code to create a Display
// with the CompatibilityInfo that is used everywhere we deal
// with the display in relation to this app, rather than
// doing the conversion here. This impl should be okay because
// we make sure to return a compatible display in the places
// where there are public APIs to retrieve the display... but
// it would be cleaner and more maintainable to just be
// consistently dealing with a compatible display everywhere in
// the framework.
mDisplayAdjustments.getCompatibilityInfo().applyToDisplayMetrics(mMetrics);
@Config final int configChanges = calcConfigChanges(config);
// If even after the update there are no Locales set, grab the default locales.
LocaleList locales = mConfiguration.getLocales();
if (locales.isEmpty()) {
locales = LocaleList.getDefault();
mConfiguration.setLocales(locales);
}
if ((configChanges & ActivityInfo.CONFIG_LOCALE) != 0) {
if (locales.size() > 1) {
// The LocaleList has changed. We must query the AssetManager's available
// Locales and figure out the best matching Locale in the new LocaleList.
String[] availableLocales = mAssets.getNonSystemLocales();
if (LocaleList.isPseudoLocalesOnly(availableLocales)) {
// No app defined locales, so grab the system locales.
availableLocales = mAssets.getLocales();
if (LocaleList.isPseudoLocalesOnly(availableLocales)) {
availableLocales = null;
}
}
if (availableLocales != null) {
final Locale bestLocale = locales.getFirstMatchWithEnglishSupported(availableLocales);
if (bestLocale != null && bestLocale != locales.get(0)) {
mConfiguration.setLocales(new LocaleList(bestLocale, locales));
}
}
}
}
if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
mMetrics.densityDpi = mConfiguration.densityDpi;
mMetrics.density = mConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
final int width, height;
if (mMetrics.widthPixels >= mMetrics.heightPixels) {
width = mMetrics.widthPixels;
height = mMetrics.heightPixels;
} else {
//noinspection SuspiciousNameCombination
width = mMetrics.heightPixels;
//noinspection SuspiciousNameCombination
height = mMetrics.widthPixels;
}
final int keyboardHidden;
if (mConfiguration.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO && mConfiguration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT;
} else {
keyboardHidden = mConfiguration.keyboardHidden;
}
mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc, adjustLanguageTag(mConfiguration.getLocales().get(0).toLanguageTag()), mConfiguration.orientation, mConfiguration.touchscreen, mConfiguration.densityDpi, mConfiguration.keyboard, keyboardHidden, mConfiguration.navigation, width, height, mConfiguration.smallestScreenWidthDp, mConfiguration.screenWidthDp, mConfiguration.screenHeightDp, mConfiguration.screenLayout, mConfiguration.uiMode, Build.VERSION.RESOURCES_SDK_INT);
if (DEBUG_CONFIG) {
Slog.i(TAG, "**** Updating config of " + this + ": final config is " + mConfiguration + " final compat is " + mDisplayAdjustments.getCompatibilityInfo());
}
mDrawableCache.onConfigurationChange(configChanges);
mColorDrawableCache.onConfigurationChange(configChanges);
mComplexColorCache.onConfigurationChange(configChanges);
mAnimatorCache.onConfigurationChange(configChanges);
mStateListAnimatorCache.onConfigurationChange(configChanges);
flushLayoutCache();
}
synchronized (sSync) {
if (mPluralRule != null) {
mPluralRule = PluralRules.forLocale(mConfiguration.getLocales().get(0));
}
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
}
use of android.os.LocaleList in project android_frameworks_base by AOSPA.
the class LocalePickerWithRegion method setListener.
/**
* Sets the listener and initializes the locale list.
*
* <p>Returns true if we need to show the list, false if not.</p>
*
* <p>Can return false because of an error, trying to show a list of countries,
* but no parent locale was provided.</p>
*
* <p>It can also return false if the caller tries to show the list in country mode and
* there is only one country available (i.e. Japanese => Japan).
* In this case we don't even show the list, we call the listener with that locale,
* "pretending" it was selected, and return false.</p>
*/
private boolean setListener(Context context, LocaleSelectedListener listener, LocaleStore.LocaleInfo parent, boolean translatedOnly) {
this.mParentLocale = parent;
this.mListener = listener;
this.mTranslatedOnly = translatedOnly;
setRetainInstance(true);
final HashSet<String> langTagsToIgnore = new HashSet<>();
if (!translatedOnly) {
final LocaleList userLocales = LocalePicker.getLocales();
final String[] langTags = userLocales.toLanguageTags().split(",");
Collections.addAll(langTagsToIgnore, langTags);
}
if (parent != null) {
mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore, parent, translatedOnly);
if (mLocaleList.size() <= 1) {
if (listener != null && (mLocaleList.size() == 1)) {
listener.onLocaleSelected(mLocaleList.iterator().next());
}
return false;
}
} else {
mLocaleList = LocaleStore.getLevelLocales(context, langTagsToIgnore, null, /* no parent */
translatedOnly);
}
return true;
}
Aggregations