121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn/* 221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * Copyright (C) 2010 The Android Open Source Project 321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * 421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * you may not use this file except in compliance with the License. 621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * You may obtain a copy of the License at 721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * 821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * 1021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * Unless required by applicable law or agreed to in writing, software 1121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * See the License for the specific language governing permissions and 1421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn * limitations under the License. 1521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn */ 1621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 1721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornpackage com.android.server; 1821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor; 2021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 2121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.ComponentName; 2221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.Context; 2321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.Intent; 2421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.ResolveInfo; 2521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.ServiceInfo; 2621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 2721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.os.Binder; 2821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.provider.Settings; 2921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.speech.RecognitionService; 3021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.text.TextUtils; 318a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 3221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport java.util.List; 3421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornpublic class RecognitionManagerService extends Binder { 3621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final static String TAG = "RecognitionManagerService"; 3721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final Context mContext; 3921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final MyPackageMonitor mMonitor; 4021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 4121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn class MyPackageMonitor extends PackageMonitor { 4221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onSomePackagesChanged() { 4321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName comp = getCurRecognizer(); 4421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (comp == null) { 4521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (anyPackagesAppearing()) { 4621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn comp = findAvailRecognizer(null); 4721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (comp != null) { 4821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setCurRecognizer(comp); 4921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 5021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 5121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 5221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 5321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 5421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int change = isPackageDisappearing(comp.getPackageName()); 5521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (change == PACKAGE_PERMANENT_CHANGE 5621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || change == PACKAGE_TEMPORARY_CHANGE) { 5721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setCurRecognizer(findAvailRecognizer(null)); 5821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 5921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else if (isPackageModified(comp.getPackageName())) { 6021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setCurRecognizer(findAvailRecognizer(comp.getPackageName())); 6121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 6221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 6321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 6421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 6521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn RecognitionManagerService(Context context) { 6621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext = context; 6721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mMonitor = new MyPackageMonitor(); 68d0d7503fd3e941113094532f28986f49b11b5fdbDianne Hackborn mMonitor.register(context, null, true); 6921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 7021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 7121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void systemReady() { 7221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName comp = getCurRecognizer(); 7321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (comp != null) { 7421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn // See if the current recognizer is no longer available. 7521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn try { 7621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext.getPackageManager().getServiceInfo(comp, 0); 7721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } catch (NameNotFoundException e) { 78ddf322915ba87ef0bf604406ae441c63b371fda0Bjorn Bringert comp = findAvailRecognizer(null); 79ddf322915ba87ef0bf604406ae441c63b371fda0Bjorn Bringert if (comp != null) { 80ddf322915ba87ef0bf604406ae441c63b371fda0Bjorn Bringert setCurRecognizer(comp); 81ddf322915ba87ef0bf604406ae441c63b371fda0Bjorn Bringert } 8221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 8321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else { 8421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn comp = findAvailRecognizer(null); 8521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (comp != null) { 8621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setCurRecognizer(comp); 8721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 8821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 8921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 9021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 9121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName findAvailRecognizer(String prefPackage) { 9221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn List<ResolveInfo> available = 9321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext.getPackageManager().queryIntentServices( 9421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn new Intent(RecognitionService.SERVICE_INTERFACE), 0); 9521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int numAvailable = available.size(); 9621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 9721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (numAvailable == 0) { 988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "no available voice recognition services found"); 9921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return null; 10021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } else { 10121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (prefPackage != null) { 10221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=0; i<numAvailable; i++) { 10321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ServiceInfo serviceInfo = available.get(i).serviceInfo; 10421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (prefPackage.equals(serviceInfo.packageName)) { 10521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return new ComponentName(serviceInfo.packageName, serviceInfo.name); 10621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 10721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 10821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 10921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (numAvailable > 1) { 1108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "more than one voice recognition service found, picking first"); 11121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 11221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 11321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ServiceInfo serviceInfo = available.get(0).serviceInfo; 11421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return new ComponentName(serviceInfo.packageName, serviceInfo.name); 11521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 11621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 11721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 11821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn ComponentName getCurRecognizer() { 11921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String curRecognizer = Settings.Secure.getString( 12021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn mContext.getContentResolver(), 12121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Settings.Secure.VOICE_RECOGNITION_SERVICE); 12221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (TextUtils.isEmpty(curRecognizer)) { 12321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return null; 12421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 12521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return ComponentName.unflattenFromString(curRecognizer); 12621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 12721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 12821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn void setCurRecognizer(ComponentName comp) { 12921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Settings.Secure.putString(mContext.getContentResolver(), 13021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Settings.Secure.VOICE_RECOGNITION_SERVICE, 13121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn comp != null ? comp.flattenToShortString() : ""); 13221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 13321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn} 134