script-astra/Android/Sdk/sources/android-35/android/hardware/input/KeyboardLayout.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

324 lines
11 KiB
Java

/*
* Copyright (C) 2012 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 android.hardware.input;
import android.annotation.NonNull;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
/**
* Describes a keyboard layout.
*
* @hide
*/
public final class KeyboardLayout implements Parcelable, Comparable<KeyboardLayout> {
/** Undefined keyboard layout */
public static final String LAYOUT_TYPE_UNDEFINED = "undefined";
/** Qwerty-based keyboard layout */
public static final String LAYOUT_TYPE_QWERTY = "qwerty";
/** Qwertz-based keyboard layout */
public static final String LAYOUT_TYPE_QWERTZ = "qwertz";
/** Azerty-based keyboard layout */
public static final String LAYOUT_TYPE_AZERTY = "azerty";
/** Dvorak keyboard layout */
public static final String LAYOUT_TYPE_DVORAK = "dvorak";
/** Colemak keyboard layout */
public static final String LAYOUT_TYPE_COLEMAK = "colemak";
/** Workman keyboard layout */
public static final String LAYOUT_TYPE_WORKMAN = "workman";
/** Turkish-F keyboard layout */
public static final String LAYOUT_TYPE_TURKISH_F = "turkish_f";
/** Turkish-Q keyboard layout */
public static final String LAYOUT_TYPE_TURKISH_Q = "turkish_q";
/** Keyboard layout that has been enhanced with a large number of extra characters */
public static final String LAYOUT_TYPE_EXTENDED = "extended";
private final String mDescriptor;
private final String mLabel;
private final String mCollection;
private final int mPriority;
@NonNull
private final LocaleList mLocales;
private final LayoutType mLayoutType;
private final int mVendorId;
private final int mProductId;
/** Currently supported Layout types in the KCM files */
public enum LayoutType {
UNDEFINED(0, LAYOUT_TYPE_UNDEFINED),
QWERTY(1, LAYOUT_TYPE_QWERTY),
QWERTZ(2, LAYOUT_TYPE_QWERTZ),
AZERTY(3, LAYOUT_TYPE_AZERTY),
DVORAK(4, LAYOUT_TYPE_DVORAK),
COLEMAK(5, LAYOUT_TYPE_COLEMAK),
WORKMAN(6, LAYOUT_TYPE_WORKMAN),
TURKISH_Q(7, LAYOUT_TYPE_TURKISH_Q),
TURKISH_F(8, LAYOUT_TYPE_TURKISH_F),
EXTENDED(9, LAYOUT_TYPE_EXTENDED);
private final int mValue;
private final String mName;
private static final Map<Integer, LayoutType> VALUE_TO_ENUM_MAP = new HashMap<>();
private static final Map<String, LayoutType> NAME_TO_ENUM_MAP = new HashMap<>();
static {
for (LayoutType type : LayoutType.values()) {
VALUE_TO_ENUM_MAP.put(type.mValue, type);
NAME_TO_ENUM_MAP.put(type.mName, type);
}
}
private static LayoutType of(int value) {
return VALUE_TO_ENUM_MAP.getOrDefault(value, UNDEFINED);
}
LayoutType(int value, String name) {
this.mValue = value;
this.mName = name;
}
private int getValue() {
return mValue;
}
private String getName() {
return mName;
}
/**
* Returns enum value for provided layout type
* @param layoutName name of the layout type
* @return int value corresponding to the LayoutType enum that matches the layout name.
* (LayoutType.UNDEFINED if no match found)
*/
public static int getLayoutTypeEnumValue(String layoutName) {
return NAME_TO_ENUM_MAP.getOrDefault(layoutName, UNDEFINED).getValue();
}
/**
* Returns name for provided layout type enum value
* @param enumValue value representation for LayoutType enum
* @return Layout name corresponding to the enum value (LAYOUT_TYPE_UNDEFINED if not found)
*/
public static String getLayoutNameFromValue(int enumValue) {
return VALUE_TO_ENUM_MAP.getOrDefault(enumValue, UNDEFINED).getName();
}
}
@NonNull
public static final Parcelable.Creator<KeyboardLayout> CREATOR = new Parcelable.Creator<>() {
public KeyboardLayout createFromParcel(Parcel source) {
return new KeyboardLayout(source);
}
public KeyboardLayout[] newArray(int size) {
return new KeyboardLayout[size];
}
};
public KeyboardLayout(String descriptor, String label, String collection, int priority,
LocaleList locales, int layoutValue, int vid, int pid) {
mDescriptor = descriptor;
mLabel = label;
mCollection = collection;
mPriority = priority;
mLocales = locales;
mLayoutType = LayoutType.of(layoutValue);
mVendorId = vid;
mProductId = pid;
}
private KeyboardLayout(Parcel source) {
mDescriptor = source.readString();
mLabel = source.readString();
mCollection = source.readString();
mPriority = source.readInt();
mLocales = LocaleList.CREATOR.createFromParcel(source);
mLayoutType = LayoutType.of(source.readInt());
mVendorId = source.readInt();
mProductId = source.readInt();
}
/**
* Gets the keyboard layout descriptor, which can be used to retrieve
* the keyboard layout again later using
* {@link InputManager#getKeyboardLayout(String)}.
*
* @return The keyboard layout descriptor.
*/
public String getDescriptor() {
return mDescriptor;
}
/**
* Gets the keyboard layout descriptive label to show in the user interface.
* @return The keyboard layout descriptive label.
*/
public String getLabel() {
return mLabel;
}
/**
* Gets the name of the collection to which the keyboard layout belongs. This is
* the label of the broadcast receiver or application that provided the keyboard layout.
* @return The keyboard layout collection name.
*/
public String getCollection() {
return mCollection;
}
/**
* Gets the locales that this keyboard layout is intended for.
* This may be empty if a locale has not been assigned to this keyboard layout.
* @return The keyboard layout's intended locale.
*/
public LocaleList getLocales() {
return mLocales;
}
/**
* Gets the layout type that this keyboard layout is intended for.
* This may be "undefined" if a layoutType has not been assigned to this keyboard layout.
* @return The keyboard layout's intended layout type.
*/
public String getLayoutType() {
return mLayoutType.getName();
}
/**
* Gets the vendor ID of the hardware device this keyboard layout is intended for.
* Returns -1 if this is not specific to any piece of hardware.
* @return The hardware vendor ID of the keyboard layout's intended device.
*/
public int getVendorId() {
return mVendorId;
}
/**
* Gets the product ID of the hardware device this keyboard layout is intended for.
* Returns -1 if this is not specific to any piece of hardware.
* @return The hardware product ID of the keyboard layout's intended device.
*/
public int getProductId() {
return mProductId;
}
/**
* Returns if the Keyboard layout follows the ANSI Physical key layout.
*/
public boolean isAnsiLayout() {
for (int i = 0; i < mLocales.size(); i++) {
Locale locale = mLocales.get(i);
if (locale != null && locale.getCountry().equalsIgnoreCase("us")
&& mLayoutType != LayoutType.EXTENDED) {
return true;
}
}
return false;
}
/**
* Returns if the Keyboard layout follows the JIS Physical key layout.
*/
public boolean isJisLayout() {
for (int i = 0; i < mLocales.size(); i++) {
Locale locale = mLocales.get(i);
if (locale != null && locale.getCountry().equalsIgnoreCase("jp")) {
return true;
}
}
return false;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mDescriptor);
dest.writeString(mLabel);
dest.writeString(mCollection);
dest.writeInt(mPriority);
mLocales.writeToParcel(dest, 0);
dest.writeInt(mLayoutType.getValue());
dest.writeInt(mVendorId);
dest.writeInt(mProductId);
}
@Override
public int compareTo(KeyboardLayout another) {
// Note that these arguments are intentionally flipped since you want higher priority
// keyboards to be listed before lower priority keyboards.
int result = Integer.compare(another.mPriority, mPriority);
if (result == 0) {
result = Integer.compare(mLayoutType.mValue, another.mLayoutType.mValue);
}
if (result == 0) {
result = mLabel.compareToIgnoreCase(another.mLabel);
}
if (result == 0) {
result = mCollection.compareToIgnoreCase(another.mCollection);
}
return result;
}
@Override
public String toString() {
String collectionString = mCollection.isEmpty() ? "" : " - " + mCollection;
return "KeyboardLayout " + mLabel + collectionString
+ ", descriptor: " + mDescriptor
+ ", priority: " + mPriority
+ ", locales: " + mLocales.toString()
+ ", layout type: " + mLayoutType.getName()
+ ", vendorId: " + mVendorId
+ ", productId: " + mProductId;
}
/**
* Check if the provided layout type is supported/valid.
*
* @param layoutName name of layout type
* @return {@code true} if the provided layout type is supported/valid.
*/
public static boolean isLayoutTypeValid(@NonNull String layoutName) {
Objects.requireNonNull(layoutName, "Provided layout name should not be null");
for (LayoutType layoutType : LayoutType.values()) {
if (layoutName.equals(layoutType.getName())) {
return true;
}
}
// Layout doesn't match any supported layout types
return false;
}
}