summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/notification/SystemNotificationChannels.java6
-rw-r--r--core/res/res/values/strings.xml21
-rw-r--r--core/res/res/values/symbols.xml12
-rw-r--r--services/core/java/com/android/server/input/KeyboardLayoutManager.java257
-rw-r--r--services/core/java/com/android/server/input/PersistentDataStore.java40
5 files changed, 271 insertions, 65 deletions
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
index 0489dc812ab6..fef5e83cecca 100644
--- a/core/java/com/android/internal/notification/SystemNotificationChannels.java
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -17,7 +17,6 @@ package com.android.internal.notification;
import static android.app.admin.DevicePolicyResources.Strings.Core.NOTIFICATION_CHANNEL_DEVICE_ADMIN;
import android.app.INotificationManager;
-import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
@@ -25,7 +24,6 @@ import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.os.RemoteException;
-import android.provider.Settings;
import com.android.internal.R;
@@ -78,9 +76,7 @@ public class SystemNotificationChannels {
final NotificationChannel physicalKeyboardChannel = new NotificationChannel(
PHYSICAL_KEYBOARD,
context.getString(R.string.notification_channel_physical_keyboard),
- NotificationManager.IMPORTANCE_DEFAULT);
- physicalKeyboardChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
- Notification.AUDIO_ATTRIBUTES_DEFAULT);
+ NotificationManager.IMPORTANCE_LOW);
physicalKeyboardChannel.setBlockable(true);
channelsList.add(physicalKeyboardChannel);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 07f353025f87..307490665080 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3787,8 +3787,10 @@
<!-- Title of the physical keyboard category in the input method selector [CHAR LIMIT=30] -->
<string name="hardware">Show virtual keyboard</string>
- <!-- Title of the notification to prompt the user to configure physical keyboard settings. -->
- <string name="select_keyboard_layout_notification_title">Configure physical keyboard</string>
+ <!-- Title of the notification to prompt the user to configure physical keyboard settings. [CHAR LIMIT=NOTIF_TITLE] -->
+ <string name="select_keyboard_layout_notification_title">Configure <xliff:g id="device_name" example="Foobar USB Keyboard">%s</xliff:g></string>
+ <!-- Title of the notification to prompt the user to configure physical keyboard settings when multiple keyboards connected. [CHAR LIMIT=NOTIF_TITLE] -->
+ <string name="select_multiple_keyboards_layout_notification_title">Configure physical keyboards</string>
<!-- Message of the notification to prompt the user to configure physical keyboard settings
where the user can associate language with physical keyboard layout. -->
<string name="select_keyboard_layout_notification_message">Tap to select language and layout</string>
@@ -6264,4 +6266,19 @@ ul.</string>
<string name="concurrent_display_notification_thermal_content">Dual Screen is unavailable because your phone is getting too warm</string>
<!-- Text of device state notification turn off button. [CHAR LIMIT=NONE] -->
<string name="device_state_notification_turn_off_button">Turn off</string>
+
+ <!-- Notification title when a keyboard has been configured [CHAR LIMIT=NOTIF_TITLE] -->
+ <string name="keyboard_layout_notification_selected_title"><xliff:g id="device_name" example="Foobar USB Keyboard">%s</xliff:g> configured</string>
+ <!-- Notification message shown when one layout was configured for a physical keyboard [CHAR LIMIT=NOTIF_BODY] -->
+ <string name="keyboard_layout_notification_one_selected_message">Keyboard layout set to <xliff:g id="layout_1" example="English (US)">%s</xliff:g>. Tap to change.</string>
+ <!-- Notification message shown when two layout were configured for a physical keyboard [CHAR LIMIT=NOTIF_BODY] -->
+ <string name="keyboard_layout_notification_two_selected_message">Keyboard layout set to <xliff:g id="layout_1" example="English (US)">%1$s</xliff:g>, <xliff:g id="layout_2" example="German">%2$s</xliff:g>. Tap to change.</string>
+ <!-- Notification message shown when three layout were configured for a physical keyboard [CHAR LIMIT=NOTIF_BODY] -->
+ <string name="keyboard_layout_notification_three_selected_message">Keyboard layout set to <xliff:g id="layout_1" example="English (US)">%1$s</xliff:g>, <xliff:g id="layout_2" example="German">%2$s</xliff:g>, <xliff:g id="layout_3" example="French">%3$s</xliff:g>. Tap to change.</string>
+ <!-- Notification message shown when more than three layout were configured for a physical keyboard [CHAR LIMIT=NOTIF_BODY] -->
+ <string name="keyboard_layout_notification_more_than_three_selected_message">Keyboard layout set to <xliff:g id="layout_1" example="English (US)">%1$s</xliff:g>, <xliff:g id="layout_2" example="English (US)">%2$s</xliff:g>, <xliff:g id="layout_3" example="French">%3$s</xliff:g>\u2026 Tap to change.</string>
+ <!-- Notification title when multiple keyboards with selected layouts have been connected the first time simultaneously [CHAR LIMIT=NOTIF_TITLE] -->
+ <string name="keyboard_layout_notification_multiple_selected_title">Physical keyboards configured</string>
+ <!-- Notification message when multiple keyboards with selected layouts have been connected the first time simultaneously [CHAR LIMIT=NOTIF_BODY] -->
+ <string name="keyboard_layout_notification_multiple_selected_message">Tap to view keyboards</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92dc5694ff2c..4c03e6a33fda 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2138,6 +2138,7 @@
<java-symbol type="string" name="report" />
<java-symbol type="string" name="select_input_method" />
<java-symbol type="string" name="select_keyboard_layout_notification_title" />
+ <java-symbol type="string" name="select_multiple_keyboards_layout_notification_title" />
<java-symbol type="string" name="select_keyboard_layout_notification_message" />
<java-symbol type="string" name="smv_application" />
<java-symbol type="string" name="smv_process" />
@@ -4964,10 +4965,19 @@
<!-- Whether to show weather on the lockscreen by default. -->
<java-symbol type="bool" name="config_lockscreenWeatherEnabledByDefault" />
+ <!-- For keyboard notification -->
+ <java-symbol type="string" name="keyboard_layout_notification_selected_title"/>
+ <java-symbol type="string" name="keyboard_layout_notification_one_selected_message"/>
+ <java-symbol type="string" name="keyboard_layout_notification_two_selected_message"/>
+ <java-symbol type="string" name="keyboard_layout_notification_three_selected_message"/>
+ <java-symbol type="string" name="keyboard_layout_notification_more_than_three_selected_message"/>
+ <java-symbol type="string" name="keyboard_layout_notification_multiple_selected_title"/>
+ <java-symbol type="string" name="keyboard_layout_notification_multiple_selected_message"/>
+
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
<java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
-
+
<java-symbol name="materialColorOnSecondaryFixedVariant" type="attr"/>
<java-symbol name="materialColorOnTertiaryFixedVariant" type="attr"/>
<java-symbol name="materialColorSurfaceContainerLowest" type="attr"/>
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 289079c809c3..f873a1b867d2 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -45,14 +45,17 @@ import android.os.LocaleList;
import android.os.Looper;
import android.os.Message;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.view.InputDevice;
import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.Toast;
@@ -75,6 +78,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.stream.Stream;
/**
@@ -102,8 +106,10 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
private final PersistentDataStore mDataStore;
private final Handler mHandler;
- private final List<InputDevice> mKeyboardsWithMissingLayouts = new ArrayList<>();
- private boolean mKeyboardLayoutNotificationShown = false;
+ // Connected keyboards with associated keyboard layouts (either auto-detected or manually
+ // selected layout). If the mapped value is null/empty, it means that no layout has been
+ // configured for the keyboard and user might need to manually configure it from the Settings.
+ private final SparseArray<Set<String>> mConfiguredKeyboards = new SparseArray<>();
private Toast mSwitchedKeyboardLayoutToast;
// This cache stores "best-matched" layouts so that we don't need to run the matching
@@ -158,10 +164,8 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
@Override
public void onInputDeviceRemoved(int deviceId) {
- if (!useNewSettingsUi()) {
- mKeyboardsWithMissingLayouts.removeIf(device -> device.getId() == deviceId);
- maybeUpdateNotification();
- }
+ mConfiguredKeyboards.remove(deviceId);
+ maybeUpdateNotification();
}
@Override
@@ -178,13 +182,53 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
if (layout != null) {
setCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier(), layout);
} else {
- mKeyboardsWithMissingLayouts.add(inputDevice);
+ mConfiguredKeyboards.put(inputDevice.getId(), new HashSet<>());
}
}
- maybeUpdateNotification();
+ }
+ } else {
+ final InputDeviceIdentifier identifier = inputDevice.getIdentifier();
+ final String key = getLayoutDescriptor(identifier);
+ Set<String> selectedLayouts = new HashSet<>();
+ boolean needToShowMissingLayoutNotification = false;
+ for (ImeInfo imeInfo : getImeInfoListForLayoutMapping()) {
+ // Check if the layout has been previously configured
+ String layout = getKeyboardLayoutForInputDeviceInternal(identifier,
+ new ImeInfo(imeInfo.mUserId, imeInfo.mImeSubtypeHandle,
+ imeInfo.mImeSubtype));
+ if (layout == null) {
+ needToShowMissingLayoutNotification = true;
+ continue;
+ }
+ selectedLayouts.add(layout);
+ }
+
+ if (needToShowMissingLayoutNotification) {
+ // If even one layout not configured properly we will show configuration
+ // notification allowing user to set the keyboard layout.
+ selectedLayouts.clear();
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG,
+ "Layouts selected for input device: " + identifier + " -> selectedLayouts: "
+ + selectedLayouts);
+ }
+ mConfiguredKeyboards.set(inputDevice.getId(), selectedLayouts);
+
+ synchronized (mDataStore) {
+ try {
+ if (!mDataStore.setSelectedKeyboardLayouts(key, selectedLayouts)) {
+ // No need to show the notification only if layout selection didn't change
+ // from the previous configuration
+ return;
+ }
+ } finally {
+ mDataStore.saveIfNeeded();
+ }
}
}
- // TODO(b/259530132): Show notification for new Settings UI
+ maybeUpdateNotification();
}
private String getDefaultKeyboardLayout(final InputDevice inputDevice) {
@@ -999,66 +1043,140 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
}
private void maybeUpdateNotification() {
- NotificationManager notificationManager = mContext.getSystemService(
- NotificationManager.class);
- if (notificationManager == null) {
+ if (mConfiguredKeyboards.size() == 0) {
+ hideKeyboardLayoutNotification();
return;
}
- if (!mKeyboardsWithMissingLayouts.isEmpty()) {
- if (mKeyboardsWithMissingLayouts.size() > 1) {
- // We have more than one keyboard missing a layout, so drop the
- // user at the generic input methods page, so they can pick which
- // one to set.
- showMissingKeyboardLayoutNotification(notificationManager, null);
- } else {
- showMissingKeyboardLayoutNotification(notificationManager,
- mKeyboardsWithMissingLayouts.get(0));
+ for (int i = 0; i < mConfiguredKeyboards.size(); i++) {
+ // If we have a keyboard with no selected layouts, we should always show missing
+ // layout notification even if there are other keyboards that are configured properly.
+ if (mConfiguredKeyboards.valueAt(i).isEmpty()) {
+ showMissingKeyboardLayoutNotification();
+ return;
}
- } else if (mKeyboardLayoutNotificationShown) {
- hideMissingKeyboardLayoutNotification(notificationManager);
}
+ showConfiguredKeyboardLayoutNotification();
}
// Must be called on handler.
- private void showMissingKeyboardLayoutNotification(NotificationManager notificationManager,
- InputDevice device) {
- if (!mKeyboardLayoutNotificationShown) {
- final Intent intent = new Intent(Settings.ACTION_HARD_KEYBOARD_SETTINGS);
- if (device != null) {
- intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier());
+ private void showMissingKeyboardLayoutNotification() {
+ final Resources r = mContext.getResources();
+ final String missingKeyboardLayoutNotificationContent = r.getString(
+ R.string.select_keyboard_layout_notification_message);
+
+ if (mConfiguredKeyboards.size() == 1) {
+ final InputDevice device = getInputDevice(mConfiguredKeyboards.keyAt(0));
+ if (device == null) {
+ return;
}
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
- intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
-
- Resources r = mContext.getResources();
- Notification notification =
- new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD)
- .setContentTitle(r.getString(
- R.string.select_keyboard_layout_notification_title))
- .setContentText(r.getString(
- R.string.select_keyboard_layout_notification_message))
- .setContentIntent(keyboardLayoutIntent)
- .setSmallIcon(R.drawable.ic_settings_language)
- .setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .build();
- notificationManager.notifyAsUser(null,
- SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT,
- notification, UserHandle.ALL);
- mKeyboardLayoutNotificationShown = true;
+ showKeyboardLayoutNotification(
+ r.getString(
+ R.string.select_keyboard_layout_notification_title,
+ device.getName()),
+ missingKeyboardLayoutNotificationContent,
+ device);
+ } else {
+ showKeyboardLayoutNotification(
+ r.getString(R.string.select_multiple_keyboards_layout_notification_title),
+ missingKeyboardLayoutNotificationContent,
+ null);
+ }
+ }
+
+ private void showKeyboardLayoutNotification(@NonNull String intentTitle,
+ @NonNull String intentContent, @Nullable InputDevice targetDevice) {
+ final NotificationManager notificationManager = mContext.getSystemService(
+ NotificationManager.class);
+ if (notificationManager == null) {
+ return;
+ }
+
+ final Intent intent = new Intent(Settings.ACTION_HARD_KEYBOARD_SETTINGS);
+
+ if (targetDevice != null) {
+ intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, targetDevice.getIdentifier());
}
+
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
+ intent, PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
+
+ Notification notification =
+ new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD)
+ .setContentTitle(intentTitle)
+ .setContentText(intentContent)
+ .setContentIntent(keyboardLayoutIntent)
+ .setSmallIcon(R.drawable.ic_settings_language)
+ .setColor(mContext.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setAutoCancel(true)
+ .build();
+ notificationManager.notifyAsUser(null,
+ SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT,
+ notification, UserHandle.ALL);
}
// Must be called on handler.
- private void hideMissingKeyboardLayoutNotification(NotificationManager notificationManager) {
- if (mKeyboardLayoutNotificationShown) {
- mKeyboardLayoutNotificationShown = false;
- notificationManager.cancelAsUser(null,
- SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT,
- UserHandle.ALL);
+ private void hideKeyboardLayoutNotification() {
+ NotificationManager notificationManager = mContext.getSystemService(
+ NotificationManager.class);
+ if (notificationManager == null) {
+ return;
+ }
+
+ notificationManager.cancelAsUser(null,
+ SystemMessageProto.SystemMessage.NOTE_SELECT_KEYBOARD_LAYOUT,
+ UserHandle.ALL);
+ }
+
+ private void showConfiguredKeyboardLayoutNotification() {
+ final Resources r = mContext.getResources();
+
+ if (mConfiguredKeyboards.size() != 1) {
+ showKeyboardLayoutNotification(
+ r.getString(R.string.keyboard_layout_notification_multiple_selected_title),
+ r.getString(R.string.keyboard_layout_notification_multiple_selected_message),
+ null);
+ return;
+ }
+
+ final InputDevice inputDevice = getInputDevice(mConfiguredKeyboards.keyAt(0));
+ final Set<String> selectedLayouts = mConfiguredKeyboards.valueAt(0);
+ if (inputDevice == null || selectedLayouts == null || selectedLayouts.isEmpty()) {
+ return;
+ }
+
+ showKeyboardLayoutNotification(
+ r.getString(
+ R.string.keyboard_layout_notification_selected_title,
+ inputDevice.getName()),
+ createConfiguredNotificationText(mContext, selectedLayouts),
+ inputDevice);
+ }
+
+ private String createConfiguredNotificationText(@NonNull Context context,
+ @NonNull Set<String> selectedLayouts) {
+ final Resources r = context.getResources();
+ List<String> layoutNames = new ArrayList<>();
+ selectedLayouts.forEach(
+ (layoutDesc) -> layoutNames.add(getKeyboardLayout(layoutDesc).getLabel()));
+ Collections.sort(layoutNames);
+ switch (layoutNames.size()) {
+ case 1:
+ return r.getString(R.string.keyboard_layout_notification_one_selected_message,
+ layoutNames.get(0));
+ case 2:
+ return r.getString(R.string.keyboard_layout_notification_two_selected_message,
+ layoutNames.get(0), layoutNames.get(1));
+ case 3:
+ return r.getString(R.string.keyboard_layout_notification_three_selected_message,
+ layoutNames.get(0), layoutNames.get(1), layoutNames.get(2));
+ default:
+ return r.getString(
+ R.string.keyboard_layout_notification_more_than_three_selected_message,
+ layoutNames.get(0), layoutNames.get(1), layoutNames.get(2));
}
}
@@ -1102,6 +1220,31 @@ final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
identifier.getDescriptor()) : null;
}
+ private List<ImeInfo> getImeInfoListForLayoutMapping() {
+ List<ImeInfo> imeInfoList = new ArrayList<>();
+ UserManager userManager = Objects.requireNonNull(
+ mContext.getSystemService(UserManager.class));
+ InputMethodManager inputMethodManager = Objects.requireNonNull(
+ mContext.getSystemService(InputMethodManager.class));
+ for (UserHandle userHandle : userManager.getUserHandles(true /* excludeDying */)) {
+ int userId = userHandle.getIdentifier();
+ for (InputMethodInfo imeInfo : inputMethodManager.getEnabledInputMethodListAsUser(
+ userId)) {
+ for (InputMethodSubtype imeSubtype :
+ inputMethodManager.getEnabledInputMethodSubtypeList(
+ imeInfo, true /* allowsImplicitlyEnabledSubtypes */)) {
+ if (!imeSubtype.isSuitableForPhysicalKeyboardLayoutMapping()) {
+ continue;
+ }
+ imeInfoList.add(
+ new ImeInfo(userId, InputMethodSubtypeHandle.of(imeInfo, imeSubtype),
+ imeSubtype));
+ }
+ }
+ }
+ return imeInfoList;
+ }
+
private String createLayoutKey(InputDeviceIdentifier identifier, int userId,
@NonNull InputMethodSubtypeHandle subtypeHandle) {
Objects.requireNonNull(subtypeHandle, "subtypeHandle must not be null");
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index a2b183628686..bce210d0a4a4 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -16,6 +16,7 @@
package com.android.server.input;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.input.TouchCalibration;
import android.util.ArrayMap;
@@ -43,6 +44,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -155,6 +157,16 @@ final class PersistentDataStore {
return false;
}
+ public boolean setSelectedKeyboardLayouts(String inputDeviceDescriptor,
+ @NonNull Set<String> selectedLayouts) {
+ InputDeviceState state = getOrCreateInputDeviceState(inputDeviceDescriptor);
+ if (state.setSelectedKeyboardLayouts(selectedLayouts)) {
+ setDirty();
+ return true;
+ }
+ return false;
+ }
+
public String[] getKeyboardLayouts(String inputDeviceDescriptor) {
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor);
if (state == null) {
@@ -408,6 +420,8 @@ final class PersistentDataStore {
private final Map<String, String> mKeyboardLayoutMap = new ArrayMap<>();
+ private Set<String> mSelectedKeyboardLayouts;
+
public TouchCalibration getTouchCalibration(int surfaceRotation) {
try {
return mTouchCalibration[surfaceRotation];
@@ -439,6 +453,14 @@ final class PersistentDataStore {
return !Objects.equals(mKeyboardLayoutMap.put(key, keyboardLayout), keyboardLayout);
}
+ public boolean setSelectedKeyboardLayouts(@NonNull Set<String> selectedLayouts) {
+ if (Objects.equals(mSelectedKeyboardLayouts, selectedLayouts)) {
+ return false;
+ }
+ mSelectedKeyboardLayouts = new HashSet<>(selectedLayouts);
+ return true;
+ }
+
@Nullable
public String getCurrentKeyboardLayout() {
return mCurrentKeyboardLayout;
@@ -588,6 +610,16 @@ final class PersistentDataStore {
"Missing layout attribute on keyed-keyboard-layout.");
}
mKeyboardLayoutMap.put(key, layout);
+ } else if (parser.getName().equals("selected-keyboard-layout")) {
+ String layout = parser.getAttributeValue(null, "layout");
+ if (layout == null) {
+ throw new XmlPullParserException(
+ "Missing layout attribute on selected-keyboard-layout.");
+ }
+ if (mSelectedKeyboardLayouts == null) {
+ mSelectedKeyboardLayouts = new HashSet<>();
+ }
+ mSelectedKeyboardLayouts.add(layout);
} else if (parser.getName().equals("light-info")) {
int lightId = parser.getAttributeInt(null, "light-id");
int lightBrightness = parser.getAttributeInt(null, "light-brightness");
@@ -668,6 +700,14 @@ final class PersistentDataStore {
serializer.endTag(null, "keyed-keyboard-layout");
}
+ if (mSelectedKeyboardLayouts != null) {
+ for (String layout : mSelectedKeyboardLayouts) {
+ serializer.startTag(null, "selected-keyboard-layout");
+ serializer.attribute(null, "layout", layout);
+ serializer.endTag(null, "selected-keyboard-layout");
+ }
+ }
+
for (int i = 0; i < mKeyboardBacklightBrightnessMap.size(); i++) {
serializer.startTag(null, "light-info");
serializer.attributeInt(null, "light-id", mKeyboardBacklightBrightnessMap.keyAt(i));