1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.input; 18 19 import android.annotation.NonNull; 20 import android.annotation.SystemApi; 21 import android.icu.util.ULocale; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import java.util.Objects; 26 27 28 /** 29 * Configurations to create virtual keyboard. 30 * 31 * @hide 32 */ 33 @SystemApi 34 public final class VirtualKeyboardConfig extends VirtualInputDeviceConfig implements Parcelable { 35 /** 36 * Default language tag when creating virtual keyboard. Used when the language tag is not set. 37 */ 38 public static final String DEFAULT_LANGUAGE_TAG = "en-Latn-US"; 39 /** Default layout type when creating virtual keyboard. Used when the layout type is not set. */ 40 public static final String DEFAULT_LAYOUT_TYPE = "qwerty"; 41 42 @NonNull 43 private final String mLanguageTag; 44 45 @NonNull 46 private final String mLayoutType; 47 48 @NonNull 49 public static final Creator<VirtualKeyboardConfig> CREATOR = 50 new Creator<VirtualKeyboardConfig>() { 51 @Override 52 public VirtualKeyboardConfig createFromParcel(Parcel in) { 53 return new VirtualKeyboardConfig(in); 54 } 55 56 @Override 57 public VirtualKeyboardConfig[] newArray(int size) { 58 return new VirtualKeyboardConfig[size]; 59 } 60 }; 61 VirtualKeyboardConfig(@onNull Builder builder)62 private VirtualKeyboardConfig(@NonNull Builder builder) { 63 super(builder); 64 mLanguageTag = builder.mLanguageTag; 65 mLayoutType = builder.mLayoutType; 66 } 67 VirtualKeyboardConfig(@onNull Parcel in)68 private VirtualKeyboardConfig(@NonNull Parcel in) { 69 super(in); 70 mLanguageTag = in.readString8(); 71 mLayoutType = in.readString8(); 72 } 73 74 /** 75 * @see Builder#setLanguageTag(). 76 */ 77 @NonNull getLanguageTag()78 public String getLanguageTag() { 79 return mLanguageTag; 80 } 81 82 /** 83 * @see Builder#setLayoutType(). 84 */ 85 @NonNull getLayoutType()86 public String getLayoutType() { 87 return mLayoutType; 88 } 89 90 @Override describeContents()91 public int describeContents() { 92 return 0; 93 } 94 95 @Override writeToParcel(@onNull Parcel dest, int flags)96 public void writeToParcel(@NonNull Parcel dest, int flags) { 97 super.writeToParcel(dest, flags); 98 dest.writeString8(mLanguageTag); 99 dest.writeString8(mLayoutType); 100 } 101 102 /** 103 * Builder for creating a {@link VirtualKeyboardConfig}. 104 */ 105 public static final class Builder extends VirtualInputDeviceConfig.Builder<Builder> { 106 @NonNull 107 private String mLanguageTag = DEFAULT_LANGUAGE_TAG; 108 @NonNull 109 private String mLayoutType = DEFAULT_LAYOUT_TYPE; 110 111 /** 112 * Sets the preferred input language of the virtual keyboard using an IETF 113 * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a> conformant tag. 114 * 115 * The passed in {@code languageTag} will be canonized using {@link 116 * ULocale} and used by the system as a hint to configure the keyboard layout. 117 * 118 * If {@code languageTag} is not specified, the virtual keyboard will be created with {@link 119 * #DEFAULT_LANGUAGE_TAG}. 120 * 121 * Note that the preferred layout is not guaranteed. If the specified language is 122 * well-formed but not supported, the keyboard will be using English US QWERTY layout. 123 * 124 * In case where the owning Virtual Device has created multiple virtual keyboards, only the 125 * {@code languageTag} of the most recent virtual keyboard will be kept to hint the locale 126 * of the Virtual Device. 127 * 128 * @throws IllegalArgumentException if either of the language or country is not present in 129 * the language tag. 130 */ 131 @NonNull setLanguageTag(@onNull String languageTag)132 public Builder setLanguageTag(@NonNull String languageTag) { 133 Objects.requireNonNull(languageTag, "languageTag cannot be null"); 134 ULocale locale = ULocale.forLanguageTag(languageTag); 135 if (locale.getLanguage().isEmpty()) { 136 throw new IllegalArgumentException("The language tag is not valid."); 137 } 138 mLanguageTag = ULocale.createCanonical(locale).toLanguageTag(); 139 return this; 140 } 141 142 /** 143 * Sets the preferred layout type of the virtual keyboard. See {@code keyboardLayoutType} 144 * attribute in frameworks/base/core/res/res/values/attrs.xml for a list of supported 145 * layout types. 146 * 147 * Note that the preferred layout is not guaranteed. If the specified layout type is 148 * well-formed but not supported, the keyboard will be using English US QWERTY layout. 149 * 150 * If not specified, the virtual keyboard will be created with {@link #DEFAULT_LAYOUT_TYPE}. 151 */ 152 @NonNull setLayoutType(@onNull String layoutType)153 public Builder setLayoutType(@NonNull String layoutType) { 154 Objects.requireNonNull(layoutType, "layoutType cannot be null"); 155 mLayoutType = layoutType; 156 return this; 157 } 158 159 /** 160 * Builds the {@link VirtualKeyboardConfig} instance. 161 */ 162 @NonNull build()163 public VirtualKeyboardConfig build() { 164 return new VirtualKeyboardConfig(this); 165 } 166 } 167 } 168