diff options
Diffstat (limited to 'services/core/java/com/android/server/RecognitionManagerService.java')
-rw-r--r-- | services/core/java/com/android/server/RecognitionManagerService.java | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/RecognitionManagerService.java b/services/core/java/com/android/server/RecognitionManagerService.java new file mode 100644 index 0000000..c2e749d --- /dev/null +++ b/services/core/java/com/android/server/RecognitionManagerService.java @@ -0,0 +1,167 @@ +/* + * 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.app.AppGlobals; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.IPackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.os.Binder; +import android.os.RemoteException; +import android.os.UserHandle; +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"; + + private final Context mContext; + private final MyPackageMonitor mMonitor; + private final IPackageManager mIPm; + + private static final boolean DEBUG = false; + + class MyPackageMonitor extends PackageMonitor { + public void onSomePackagesChanged() { + int userHandle = getChangingUserId(); + if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle); + ComponentName comp = getCurRecognizer(userHandle); + if (comp == null) { + if (anyPackagesAppearing()) { + comp = findAvailRecognizer(null, userHandle); + if (comp != null) { + setCurRecognizer(comp, userHandle); + } + } + return; + } + + int change = isPackageDisappearing(comp.getPackageName()); + if (change == PACKAGE_PERMANENT_CHANGE + || change == PACKAGE_TEMPORARY_CHANGE) { + setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle); + + } else if (isPackageModified(comp.getPackageName())) { + setCurRecognizer(findAvailRecognizer(comp.getPackageName(), userHandle), + userHandle); + } + } + } + + RecognitionManagerService(Context context) { + mContext = context; + mMonitor = new MyPackageMonitor(); + mMonitor.register(context, null, UserHandle.ALL, true); + mIPm = AppGlobals.getPackageManager(); + mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, + new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); + } + + public void systemReady() { + initForUser(UserHandle.USER_OWNER); + } + + private void initForUser(int userHandle) { + if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle); + ComponentName comp = getCurRecognizer(userHandle); + ServiceInfo info = null; + if (comp != null) { + // See if the current recognizer is still available. + try { + info = mIPm.getServiceInfo(comp, 0, userHandle); + } catch (RemoteException e) { + } + } + if (info == null) { + comp = findAvailRecognizer(null, userHandle); + if (comp != null) { + setCurRecognizer(comp, userHandle); + } + } + } + + ComponentName findAvailRecognizer(String prefPackage, int userHandle) { + List<ResolveInfo> available = + mContext.getPackageManager().queryIntentServicesAsUser( + new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle); + int numAvailable = available.size(); + + if (numAvailable == 0) { + Slog.w(TAG, "no available voice recognition services found for user " + userHandle); + 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(int userHandle) { + String curRecognizer = Settings.Secure.getStringForUser( + mContext.getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle); + if (TextUtils.isEmpty(curRecognizer)) { + return null; + } + if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer + + " user=" + userHandle); + return ComponentName.unflattenFromString(curRecognizer); + } + + void setCurRecognizer(ComponentName comp, int userHandle) { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.VOICE_RECOGNITION_SERVICE, + comp != null ? comp.flattenToShortString() : "", userHandle); + if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp + + " user=" + userHandle); + } + + BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (DEBUG) Slog.i(TAG, "received " + action); + if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { + int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); + if (userHandle > 0) { + initForUser(userHandle); + } + } + } + }; +} |