Merge tag 'android-15.0.0_r6' of https://android.googlesource.com/platform/packages/inputmethods/LatinIME into HEAD

Android 15.0.0 Release 6 (AP4A.241205.013)

Change-Id: I640527e5a6d68b9fc7e72c714c7eaec28693c73e

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCZ1IssgAKCRDorT+BmrEO
# eM80AKCQkF3gcDZYHY0rpm3J4cQnkdEl3ACePQg3fh/m6daGIsN3l7sAAmDQRQA=
# =qN3k
# -----END PGP SIGNATURE-----
# gpg: Signature faite le jeu 05 déc 2024 17:44:02 EST
# gpg:                avec la clef DSA 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Impossible de vérifier la signature : Pas de clef publique
diff --git a/java/res/values/custom_strings.xml b/java/res/values/custom_strings.xml
new file mode 100644
index 0000000..70445ec
--- /dev/null
+++ b/java/res/values/custom_strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The CyanogenMod 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.
+ -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="keyboard_theme_follow_system">Follow system settings</string>
+</resources>
diff --git a/java/res/values/keyboard-themes.xml b/java/res/values/keyboard-themes.xml
index 26b2582..2826f5f 100644
--- a/java/res/values/keyboard-themes.xml
+++ b/java/res/values/keyboard-themes.xml
@@ -22,6 +22,7 @@
     <string-array name="keyboard_theme_names" translatable="false">
         <item>@string/keyboard_theme_material_light</item>
         <item>@string/keyboard_theme_material_dark</item>
+        <item>@string/keyboard_theme_follow_system</item>
         <item>@string/keyboard_theme_holo_white</item>
         <item>@string/keyboard_theme_holo_blue</item>
     </string-array>
@@ -30,6 +31,7 @@
     <integer-array name="keyboard_theme_ids" translatable="false">
         <item>3</item>
         <item>4</item>
+        <item>5</item>
         <item>2</item>
         <item>0</item>
     </integer-array>
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
index 006d086..2796c2e 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardTheme.java
@@ -17,6 +17,7 @@
 package com.android.inputmethod.keyboard;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.SharedPreferences;
 import android.os.Build;
 import android.os.Build.VERSION_CODES;
@@ -41,7 +42,8 @@
     public static final int THEME_ID_KLP = 2;
     public static final int THEME_ID_LXX_LIGHT = 3;
     public static final int THEME_ID_LXX_DARK = 4;
-    public static final int DEFAULT_THEME_ID = THEME_ID_KLP;
+    public static final int THEME_ID_AUTO_DARK = 5;
+    public static final int DEFAULT_THEME_ID = THEME_ID_AUTO_DARK;
 
     private static KeyboardTheme[] AVAILABLE_KEYBOARD_THEMES;
 
@@ -59,6 +61,8 @@
         new KeyboardTheme(THEME_ID_LXX_DARK, "LXXDark", R.style.KeyboardTheme_LXX_Dark,
                 // This has never been selected as default theme.
                 VERSION_CODES.BASE),
+        new KeyboardTheme(THEME_ID_AUTO_DARK, "AutoDark", 0,
+                Build.VERSION_CODES.Q),
     };
 
     static {
@@ -167,9 +171,7 @@
     }
 
     public static KeyboardTheme getKeyboardTheme(final Context context) {
-        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
-        final KeyboardTheme[] availableThemeArray = getAvailableThemeArray(context);
-        return getKeyboardTheme(prefs, BuildCompatUtils.EFFECTIVE_SDK_INT, availableThemeArray);
+        return getKeyboardTheme(context, BuildCompatUtils.EFFECTIVE_SDK_INT);
     }
 
     /* package private for testing */
@@ -192,24 +194,43 @@
     }
 
     /* package private for testing */
-    static KeyboardTheme getKeyboardTheme(final SharedPreferences prefs, final int sdkVersion,
-            final KeyboardTheme[] availableThemeArray) {
-        final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null);
-        if (lxxThemeIdString == null) {
-            return getDefaultKeyboardTheme(prefs, sdkVersion, availableThemeArray);
-        }
-        try {
-            final int themeId = Integer.parseInt(lxxThemeIdString);
-            final KeyboardTheme theme = searchKeyboardThemeById(themeId, availableThemeArray);
-            if (theme != null) {
-                return theme;
+    static KeyboardTheme getKeyboardTheme(final Context context, final int sdkVersion) {
+        int themeId = getSelectedKeyboardThemeId(context);
+        if (THEME_ID_AUTO_DARK == themeId) {
+            Configuration cfg = context.getResources().getConfiguration();
+            int nightMode = cfg.uiMode & Configuration.UI_MODE_NIGHT_MASK;
+            if (nightMode == Configuration.UI_MODE_NIGHT_YES) {
+                themeId = THEME_ID_LXX_DARK;
+            } else {
+                themeId = THEME_ID_LXX_LIGHT;
             }
-            Log.w(TAG, "Unknown keyboard theme in LXX preference: " + lxxThemeIdString);
-        } catch (final NumberFormatException e) {
-            Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e);
+        }
+        final KeyboardTheme[] availableThemeArray = getAvailableThemeArray(context);
+        final KeyboardTheme theme = searchKeyboardThemeById(themeId, availableThemeArray);
+        if (theme != null) {
+            return theme;
+        }
+        Log.w(TAG, "Unknown keyboard theme in LXX preference: " + themeId);
+        // Remove preference that contains unknown or illegal theme id.
+        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply();
+        return getDefaultKeyboardTheme(prefs, sdkVersion, availableThemeArray);
+    }
+
+    public static int getSelectedKeyboardThemeId(final Context context) {
+        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+        final KeyboardTheme[] availableThemeArray = getAvailableThemeArray(context);
+        final String lxxThemeIdString = prefs.getString(LXX_KEYBOARD_THEME_KEY, null);
+        if (lxxThemeIdString != null) {
+            try {
+                return Integer.parseInt(lxxThemeIdString);
+            } catch (final NumberFormatException e) {
+                Log.w(TAG, "Illegal keyboard theme in LXX preference: " + lxxThemeIdString, e);
+            }
         }
         // Remove preference that contains unknown or illegal theme id.
         prefs.edit().remove(LXX_KEYBOARD_THEME_KEY).apply();
-        return getDefaultKeyboardTheme(prefs, sdkVersion, availableThemeArray);
+        return getDefaultKeyboardTheme(prefs, BuildCompatUtils.EFFECTIVE_SDK_INT,
+                availableThemeArray).mThemeId;
     }
 }
diff --git a/java/src/com/android/inputmethod/latin/define/JniLibName.java b/java/src/com/android/inputmethod/latin/define/JniLibName.java
index abfc36d..83ed5eb 100644
--- a/java/src/com/android/inputmethod/latin/define/JniLibName.java
+++ b/java/src/com/android/inputmethod/latin/define/JniLibName.java
@@ -22,4 +22,5 @@
     }
 
     public static final String JNI_LIB_NAME = "jni_latinime";
+    public static final String JNI_LIB_NAME2 = "jni_latinimegoogle";
 }
diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java
index 940f1bd..803b3bd 100644
--- a/java/src/com/android/inputmethod/latin/settings/Settings.java
+++ b/java/src/com/android/inputmethod/latin/settings/Settings.java
@@ -31,6 +31,7 @@
 import com.android.inputmethod.latin.R;
 import com.android.inputmethod.latin.common.StringUtils;
 import com.android.inputmethod.latin.utils.AdditionalSubtypeUtils;
+import com.android.inputmethod.latin.utils.JniUtils;
 import com.android.inputmethod.latin.utils.ResourceUtils;
 import com.android.inputmethod.latin.utils.RunInLocale;
 import com.android.inputmethod.latin.utils.StatsUtils;
@@ -48,6 +49,7 @@
     public static final String SCREEN_ACCOUNTS = "screen_accounts";
     public static final String SCREEN_THEME = "screen_theme";
     public static final String SCREEN_DEBUG = "screen_debug";
+    public static final String SCREEN_GESTURE = "screen_gesture";
     // In the same order as xml/prefs.xml
     public static final String PREF_AUTO_CAP = "auto_cap";
     public static final String PREF_VIBRATE_ON = "vibrate_on";
@@ -230,6 +232,9 @@
     }
 
     public static boolean readFromBuildConfigIfGestureInputEnabled(final Resources res) {
+        if (!JniUtils.sHaveGestureLib) {
+            return false;
+        }
         return res.getBoolean(R.bool.config_gesture_input_enabled_by_build_config);
     }
 
diff --git a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
index 874f221..ca7bd3a 100644
--- a/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/SettingsFragment.java
@@ -31,6 +31,7 @@
 import com.android.inputmethod.latin.define.ProductionFlags;
 import com.android.inputmethod.latin.utils.ApplicationUtils;
 import com.android.inputmethod.latin.utils.FeedbackUtils;
+import com.android.inputmethod.latin.utils.JniUtils;
 import com.android.inputmethodcommon.InputMethodSettingsFragment;
 
 public final class SettingsFragment extends InputMethodSettingsFragment {
@@ -55,6 +56,10 @@
             final Preference accountsPreference = findPreference(Settings.SCREEN_ACCOUNTS);
             preferenceScreen.removePreference(accountsPreference);
         }
+        if (!JniUtils.sHaveGestureLib) {
+            final Preference gesturePreference = findPreference(Settings.SCREEN_GESTURE);
+            preferenceScreen.removePreference(gesturePreference);
+        }
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
index 29289ae..437209b 100644
--- a/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/settings/ThemeSettingsFragment.java
@@ -46,11 +46,11 @@
     static void updateKeyboardThemeSummary(final Preference pref) {
         final Context context = pref.getContext();
         final Resources res = context.getResources();
-        final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(context);
+        final int keyboardThemeId = KeyboardTheme.getSelectedKeyboardThemeId(context);
         final String[] keyboardThemeNames = res.getStringArray(R.array.keyboard_theme_names);
         final int[] keyboardThemeIds = res.getIntArray(R.array.keyboard_theme_ids);
         for (int index = 0; index < keyboardThemeNames.length; index++) {
-            if (keyboardTheme.mThemeId == keyboardThemeIds[index]) {
+            if (keyboardThemeId == keyboardThemeIds[index]) {
                 pref.setSummary(keyboardThemeNames[index]);
                 return;
             }
@@ -72,8 +72,7 @@
             screen.addPreference(pref);
             pref.setOnRadioButtonClickedListener(this);
         }
-        final KeyboardTheme keyboardTheme = KeyboardTheme.getKeyboardTheme(context);
-        mSelectedThemeId = keyboardTheme.mThemeId;
+        mSelectedThemeId = KeyboardTheme.getSelectedKeyboardThemeId(context);
     }
 
     @Override
diff --git a/java/src/com/android/inputmethod/latin/utils/JniUtils.java b/java/src/com/android/inputmethod/latin/utils/JniUtils.java
index e7fdafa..458c169 100644
--- a/java/src/com/android/inputmethod/latin/utils/JniUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/JniUtils.java
@@ -23,11 +23,18 @@
 public final class JniUtils {
     private static final String TAG = JniUtils.class.getSimpleName();
 
+    public static boolean sHaveGestureLib = false;
     static {
         try {
-            System.loadLibrary(JniLibName.JNI_LIB_NAME);
-        } catch (UnsatisfiedLinkError ule) {
-            Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME, ule);
+            System.loadLibrary(JniLibName.JNI_LIB_NAME2);
+            sHaveGestureLib = true;
+        } catch (UnsatisfiedLinkError ue) {
+            Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME2, ue);
+            try {
+                System.loadLibrary(JniLibName.JNI_LIB_NAME);
+            } catch (UnsatisfiedLinkError ule) {
+                Log.e(TAG, "Could not load native library " + JniLibName.JNI_LIB_NAME, ule);
+            }
         }
     }