Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d34e9b6 authored by Mike LeBeau's avatar Mike LeBeau
Browse files

Add new setting for the ComponentName of the service to be used

for voice recognition on the device. Right now this just queries
the package manager at boot and finds the (hopefully) single
available recognizer.

TODO: Add an attribute to let recognition services expose a settings
activity, and expose the settings activity of the chosen recognition
service in the system settings for voice input & output.
parent 575c6710
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import org.apache.commons.codec.binary.Base64;

import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -2956,6 +2957,14 @@ public final class Settings {
         */
        public static final String ANR_SHOW_BACKGROUND = "anr_show_background";
        
        /**
         * The {@link ComponentName} string of the service to be used as the voice recognition
         * service.
         * 
         * @hide
         */
        public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";

        /**
         * @hide
         */
+16 −2
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import java.util.LinkedList;
@@ -218,8 +220,20 @@ public class RecognitionManager {
        checkIsCalledFromMainThread();
        if (mConnection == null) { // first time connection
            mConnection = new Connection();
            if (!mContext.bindService(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH),
                    mConnection, Context.BIND_AUTO_CREATE)) {
            
            Intent serviceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
            String serviceComponent = Settings.Secure.getString(mContext.getContentResolver(),
                    Settings.Secure.VOICE_RECOGNITION_SERVICE);
            
            if (TextUtils.isEmpty(serviceComponent)) {
                Log.e(TAG, "no selected voice recognition service");
                mListener.onError(ERROR_CLIENT);
                return;
            }
            
            serviceIntent.setComponent(ComponentName.unflattenFromString(serviceComponent));
            
            if (!mContext.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE)) {
                Log.e(TAG, "bind to recognition service failed");
                mConnection = null;
                mService = null;
+49 −1
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
@@ -36,6 +38,7 @@ import android.net.ConnectivityManager;
import android.os.Environment;
import android.os.SystemProperties;
import android.provider.Settings;
import android.speech.RecognizerIntent;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
@@ -72,7 +75,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
    // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
    // is properly propagated through your change.  Not doing so will result in a loss of user
    // settings.
    private static final int DATABASE_VERSION = 48;
    private static final int DATABASE_VERSION = 49;

    private Context mContext;

@@ -612,6 +615,23 @@ public class DatabaseHelper extends SQLiteOpenHelper {
           upgradeVersion = 48;
       }
        
       if (upgradeVersion == 48) {
           /*
            * Adding a new setting for which voice recognition service to use.
            */
           db.beginTransaction();
           try {
               SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                       + " VALUES(?,?);");
               loadVoiceRecognitionServiceSetting(stmt);
               stmt.close();
               db.setTransactionSuccessful();
           } finally {
               db.endTransaction();
           }
           upgradeVersion = 49;
       }

       if (upgradeVersion != currentVersion) {
            Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
                    + ", must wipe the settings provider");
@@ -956,6 +976,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
        loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
                R.bool.def_mount_ums_notify_enabled);
        
        loadVoiceRecognitionServiceSetting(stmt);

        stmt.close();
    }

@@ -967,6 +989,32 @@ public class DatabaseHelper extends SQLiteOpenHelper {
                R.string.def_backup_transport);
    }
    
    /**
     * Introduced in database version 49.
     */
    private void loadVoiceRecognitionServiceSetting(SQLiteStatement stmt) {
        String selectedService = null;
        List<ResolveInfo> availableRecognitionServices =
                mContext.getPackageManager().queryIntentServices(
                        new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
        int numAvailable = availableRecognitionServices.size();
        
        if (numAvailable == 0) {
            Log.w(TAG, "no available voice recognition services found");
        } else {
            if (numAvailable > 1) {
                Log.w(TAG, "more than one voice recognition service found, picking first");
            }
            
            ServiceInfo serviceInfo = availableRecognitionServices.get(0).serviceInfo;
            selectedService =
                    new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToString();
        }
        
        loadSetting(stmt, Settings.Secure.VOICE_RECOGNITION_SERVICE,
                selectedService == null ? "" : selectedService);
    }

    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
        stmt.bindString(1, key);
        stmt.bindString(2, value.toString());