/* * Copyright (C) 2010 The Android Open Source 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. */ package com.android.server; import com.android.internal.content.PackageMonitor; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Binder; import android.provider.Settings; import android.speech.RecognitionService; import android.text.TextUtils; import android.util.Slog; import java.util.List; public class RecognitionManagerService extends Binder { final static String TAG = "RecognitionManagerService"; final Context mContext; final MyPackageMonitor mMonitor; class MyPackageMonitor extends PackageMonitor { public void onSomePackagesChanged() { ComponentName comp = getCurRecognizer(); if (comp == null) { if (anyPackagesAppearing()) { comp = findAvailRecognizer(null); if (comp != null) { setCurRecognizer(comp); } } return; } int change = isPackageDisappearing(comp.getPackageName()); if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) { setCurRecognizer(findAvailRecognizer(null)); } else if (isPackageModified(comp.getPackageName())) { setCurRecognizer(findAvailRecognizer(comp.getPackageName())); } } } RecognitionManagerService(Context context) { mContext = context; mMonitor = new MyPackageMonitor(); mMonitor.register(context, true); } public void systemReady() { ComponentName comp = getCurRecognizer(); if (comp != null) { // See if the current recognizer is no longer available. try { mContext.getPackageManager().getServiceInfo(comp, 0); } catch (NameNotFoundException e) { setCurRecognizer(null); } } else { comp = findAvailRecognizer(null); if (comp != null) { setCurRecognizer(comp); } } } ComponentName findAvailRecognizer(String prefPackage) { List<ResolveInfo> available = mContext.getPackageManager().queryIntentServices( new Intent(RecognitionService.SERVICE_INTERFACE), 0); int numAvailable = available.size(); if (numAvailable == 0) { Slog.w(TAG, "no available voice recognition services found"); return null; } else { if (prefPackage != null) { for (int i=0; i<numAvailable; i++) { ServiceInfo serviceInfo = available.get(i).serviceInfo; if (prefPackage.equals(serviceInfo.packageName)) { return new ComponentName(serviceInfo.packageName, serviceInfo.name); } } } if (numAvailable > 1) { Slog.w(TAG, "more than one voice recognition service found, picking first"); } ServiceInfo serviceInfo = available.get(0).serviceInfo; return new ComponentName(serviceInfo.packageName, serviceInfo.name); } } ComponentName getCurRecognizer() { String curRecognizer = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); if (TextUtils.isEmpty(curRecognizer)) { return null; } return ComponentName.unflattenFromString(curRecognizer); } void setCurRecognizer(ComponentName comp) { Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE, comp != null ? comp.flattenToShortString() : ""); } }