diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index b510773d822cfc..8bf08fdd17a6d8 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -487,8 +487,6 @@ export type Props = $ReadOnly<{| * * - `visible-password` * - * On Android devices manufactured by Xiaomi with Android Q, 'email-address' - * type will be replaced in native by 'default' to prevent a system related crash. */ keyboardType?: ?KeyboardType, @@ -685,7 +683,12 @@ export type Props = $ReadOnly<{| /** * If `true`, caret is hidden. The default value is `false`. - * This property is supported only for single-line TextInput component on iOS. + * + * On Android devices manufactured by Xiaomi with Android Q, + * when keyboardType equals 'email-address'this will be set + * in native to 'true' to prevent a system related crash. This + * will cause cursor to be diabled as a side-effect. + * */ caretHidden?: ?boolean, diff --git a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h index ea6aaa0bcb7edd..93f4a41177323f 100644 --- a/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h +++ b/Libraries/FBReactNativeSpec/FBReactNativeSpec/FBReactNativeSpec.h @@ -1915,6 +1915,8 @@ namespace JS { RCTRequired Model; NSString *ServerHost; RCTRequired uiMode; + RCTRequired Brand; + RCTRequired Manufacturer; }; /** Initialize with a set of values */ @@ -3391,6 +3393,10 @@ inline JS::NativePlatformConstantsAndroid::Constants::Builder::Builder(const Inp d[@"ServerHost"] = ServerHost; auto uiMode = i.uiMode.get(); d[@"uiMode"] = uiMode; + auto Brand = i.Brand.get(); + d[@"Brand"] = Brand; + auto Manufacturer = i.Manufacturer.get(); + d[@"Manufacturer"] = Manufacturer; return d; }) {} inline JS::NativePlatformConstantsAndroid::Constants::Builder::Builder(Constants i) : _factory(^{ diff --git a/Libraries/Utilities/NativePlatformConstantsAndroid.js b/Libraries/Utilities/NativePlatformConstantsAndroid.js index c12339267e5081..993b8091ddb487 100644 --- a/Libraries/Utilities/NativePlatformConstantsAndroid.js +++ b/Libraries/Utilities/NativePlatformConstantsAndroid.js @@ -29,6 +29,8 @@ export interface Spec extends TurboModule { Model: string, ServerHost?: string, uiMode: string, + Brand: string, + Manufacturer: string, |}; +getAndroidID: () => string; } diff --git a/Libraries/Utilities/Platform.android.js b/Libraries/Utilities/Platform.android.js index ece5fe511ad288..ab3bc9b345c5b2 100644 --- a/Libraries/Utilities/Platform.android.js +++ b/Libraries/Utilities/Platform.android.js @@ -42,6 +42,8 @@ const Platform = { Model: string, ServerHost?: string, uiMode: string, + Brand: string, + Manufacturer: string, |} { if (this.__constants == null) { this.__constants = NativePlatformConstantsAndroid.getConstants(); diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec.java b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec.java index c8340538348f63..00d2039ade6a21 100644 --- a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec.java +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/NativePlatformConstantsAndroidSpec.java @@ -41,12 +41,14 @@ public NativePlatformConstantsAndroidSpec(ReactApplicationContext reactContext) Map constants = getTypedExportedConstants(); if (ReactBuildConfig.DEBUG || ReactBuildConfig.IS_INTERNAL_BUILD) { Set obligatoryFlowConstants = new HashSet<>(Arrays.asList( + "Brand", "Serial", "Fingerprint", "uiMode", "Version", "reactNativeVersion", "Model", + "Manufacturer", "isTesting", "Release" )); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java index 3c4be024f518c5..b2355c7ecbf62e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java @@ -70,6 +70,8 @@ public String getName() { constants.put("Serial", Build.SERIAL); constants.put("Fingerprint", Build.FINGERPRINT); constants.put("Model", Build.MODEL); + constants.put("Manufacturer", Build.MANUFACTURER); + constants.put("Brand", Build.BRAND); if (ReactBuildConfig.DEBUG) { constants.put( "ServerHost", diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index c0cb0df07b8fa2..8995949bb76dcb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -392,21 +392,8 @@ public void setInputType(int type) { // Input type password defaults to monospace font, so we need to re-apply the font super.setTypeface(tf); - int inputType = type; - - // Set InputType to TYPE_CLASS_TEXT (the default one for Android) to fix a crash on Xiaomi - // devices with Android Q. This crash happens when focusing on a email EditText within a - // ScrollView, a prompt will be triggered but the system fail to locate it properly. - // Here is an example post discussing about this issue: - // https://github.com/facebook/react-native/issues/27204 - if (inputType == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS - && Build.VERSION.SDK_INT == Build.VERSION_CODES.Q - && Build.MANUFACTURER.startsWith("Xiaomi")) { - inputType = InputType.TYPE_CLASS_TEXT; - } - - super.setInputType(inputType); - mStagedInputType = inputType; + super.setInputType(type); + mStagedInputType = type; /** * If set forces multiline on input, because of a restriction on Android source that enables @@ -421,7 +408,7 @@ public void setInputType(int type) { // We override the KeyListener so that all keys on the soft input keyboard as well as hardware // keyboards work. Some KeyListeners like DigitsKeyListener will display the keyboard but not // accept all input from it - mKeyListener.setInputType(inputType); + mKeyListener.setInputType(type); setKeyListener(mKeyListener); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 5e044b283cfa54..774ceb25e46ea6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -479,6 +479,19 @@ public void setCursorColor(ReactEditText view, @Nullable Integer color) { @ReactProp(name = "caretHidden", defaultBoolean = false) public void setCaretHidden(ReactEditText view, boolean caretHidden) { + // Set cursor's visibility to False to fix a crash on some Xiaomi devices with Android Q. This + // crash happens when focusing on a email EditText, during which a prompt will be triggered but + // the system fail to locate it properly. Here is an example post discussing about this + // issue: https://github.com/facebook/react-native/issues/27204 + String manufacturer = Build.MANUFACTURER.toLowerCase(); + if ((view.getInputType() == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS + || view.getInputType() == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS) + && Build.VERSION.SDK_INT == Build.VERSION_CODES.Q + && manufacturer.contains("xiaomi")) { + view.setCursorVisible(false); + return; + } + view.setCursorVisible(!caretHidden); }