1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server; 18 19import com.android.internal.content.PackageMonitor; 20 21import android.app.AppGlobals; 22import android.content.BroadcastReceiver; 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.content.IntentFilter; 27import android.content.pm.IPackageManager; 28import android.content.pm.ResolveInfo; 29import android.content.pm.ServiceInfo; 30import android.os.Binder; 31import android.os.RemoteException; 32import android.os.UserHandle; 33import android.provider.Settings; 34import android.speech.RecognitionService; 35import android.text.TextUtils; 36import android.util.Slog; 37 38import java.util.List; 39 40public class RecognitionManagerService extends Binder { 41 final static String TAG = "RecognitionManagerService"; 42 43 private final Context mContext; 44 private final MyPackageMonitor mMonitor; 45 private final IPackageManager mIPm; 46 47 private static final boolean DEBUG = false; 48 49 class MyPackageMonitor extends PackageMonitor { 50 public void onSomePackagesChanged() { 51 int userHandle = getChangingUserId(); 52 if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle); 53 ComponentName comp = getCurRecognizer(userHandle); 54 if (comp == null) { 55 if (anyPackagesAppearing()) { 56 comp = findAvailRecognizer(null, userHandle); 57 if (comp != null) { 58 setCurRecognizer(comp, userHandle); 59 } 60 } 61 return; 62 } 63 64 int change = isPackageDisappearing(comp.getPackageName()); 65 if (change == PACKAGE_PERMANENT_CHANGE 66 || change == PACKAGE_TEMPORARY_CHANGE) { 67 setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle); 68 69 } else if (isPackageModified(comp.getPackageName())) { 70 setCurRecognizer(findAvailRecognizer(comp.getPackageName(), userHandle), 71 userHandle); 72 } 73 } 74 } 75 76 RecognitionManagerService(Context context) { 77 mContext = context; 78 mMonitor = new MyPackageMonitor(); 79 mMonitor.register(context, null, UserHandle.ALL, true); 80 mIPm = AppGlobals.getPackageManager(); 81 mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, 82 new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null); 83 } 84 85 public void systemReady() { 86 initForUser(UserHandle.USER_OWNER); 87 } 88 89 private void initForUser(int userHandle) { 90 if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle); 91 ComponentName comp = getCurRecognizer(userHandle); 92 ServiceInfo info = null; 93 if (comp != null) { 94 // See if the current recognizer is still available. 95 try { 96 info = mIPm.getServiceInfo(comp, 0, userHandle); 97 } catch (RemoteException e) { 98 } 99 } 100 if (info == null) { 101 comp = findAvailRecognizer(null, userHandle); 102 if (comp != null) { 103 setCurRecognizer(comp, userHandle); 104 } 105 } 106 } 107 108 ComponentName findAvailRecognizer(String prefPackage, int userHandle) { 109 List<ResolveInfo> available = 110 mContext.getPackageManager().queryIntentServicesAsUser( 111 new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle); 112 int numAvailable = available.size(); 113 114 if (numAvailable == 0) { 115 Slog.w(TAG, "no available voice recognition services found for user " + userHandle); 116 return null; 117 } else { 118 if (prefPackage != null) { 119 for (int i=0; i<numAvailable; i++) { 120 ServiceInfo serviceInfo = available.get(i).serviceInfo; 121 if (prefPackage.equals(serviceInfo.packageName)) { 122 return new ComponentName(serviceInfo.packageName, serviceInfo.name); 123 } 124 } 125 } 126 if (numAvailable > 1) { 127 Slog.w(TAG, "more than one voice recognition service found, picking first"); 128 } 129 130 ServiceInfo serviceInfo = available.get(0).serviceInfo; 131 return new ComponentName(serviceInfo.packageName, serviceInfo.name); 132 } 133 } 134 135 ComponentName getCurRecognizer(int userHandle) { 136 String curRecognizer = Settings.Secure.getStringForUser( 137 mContext.getContentResolver(), 138 Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle); 139 if (TextUtils.isEmpty(curRecognizer)) { 140 return null; 141 } 142 if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer 143 + " user=" + userHandle); 144 return ComponentName.unflattenFromString(curRecognizer); 145 } 146 147 void setCurRecognizer(ComponentName comp, int userHandle) { 148 Settings.Secure.putStringForUser(mContext.getContentResolver(), 149 Settings.Secure.VOICE_RECOGNITION_SERVICE, 150 comp != null ? comp.flattenToShortString() : "", userHandle); 151 if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp 152 + " user=" + userHandle); 153 } 154 155 BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 156 public void onReceive(Context context, Intent intent) { 157 String action = intent.getAction(); 158 if (DEBUG) Slog.i(TAG, "received " + action); 159 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 160 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 161 if (userHandle > 0) { 162 initForUser(userHandle); 163 } 164 } 165 } 166 }; 167} 168