RecognitionManagerService.java revision f80a9b2f8a841d32c7398ebbf4cba82b02e9f167
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 if (comp != null) { 93 // See if the current recognizer is no longer available. 94 try { 95 mIPm.getServiceInfo(comp, 0, userHandle); 96 } catch (RemoteException e) { 97 comp = findAvailRecognizer(null, userHandle); 98 if (comp != null) { 99 setCurRecognizer(comp, userHandle); 100 } 101 } 102 } else { 103 comp = findAvailRecognizer(null, userHandle); 104 if (comp != null) { 105 setCurRecognizer(comp, userHandle); 106 } 107 } 108 } 109 110 ComponentName findAvailRecognizer(String prefPackage, int userHandle) { 111 List<ResolveInfo> available = 112 mContext.getPackageManager().queryIntentServicesAsUser( 113 new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle); 114 int numAvailable = available.size(); 115 116 if (numAvailable == 0) { 117 Slog.w(TAG, "no available voice recognition services found for user " + userHandle); 118 return null; 119 } else { 120 if (prefPackage != null) { 121 for (int i=0; i<numAvailable; i++) { 122 ServiceInfo serviceInfo = available.get(i).serviceInfo; 123 if (prefPackage.equals(serviceInfo.packageName)) { 124 return new ComponentName(serviceInfo.packageName, serviceInfo.name); 125 } 126 } 127 } 128 if (numAvailable > 1) { 129 Slog.w(TAG, "more than one voice recognition service found, picking first"); 130 } 131 132 ServiceInfo serviceInfo = available.get(0).serviceInfo; 133 return new ComponentName(serviceInfo.packageName, serviceInfo.name); 134 } 135 } 136 137 ComponentName getCurRecognizer(int userHandle) { 138 String curRecognizer = Settings.Secure.getStringForUser( 139 mContext.getContentResolver(), 140 Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle); 141 if (TextUtils.isEmpty(curRecognizer)) { 142 return null; 143 } 144 if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer 145 + " user=" + userHandle); 146 return ComponentName.unflattenFromString(curRecognizer); 147 } 148 149 void setCurRecognizer(ComponentName comp, int userHandle) { 150 Settings.Secure.putStringForUser(mContext.getContentResolver(), 151 Settings.Secure.VOICE_RECOGNITION_SERVICE, 152 comp != null ? comp.flattenToShortString() : "", userHandle); 153 if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp 154 + " user=" + userHandle); 155 } 156 157 BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 158 public void onReceive(Context context, Intent intent) { 159 String action = intent.getAction(); 160 if (DEBUG) Slog.i(TAG, "received " + action); 161 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { 162 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 163 if (userHandle > 0) { 164 initForUser(userHandle); 165 } 166 } 167 } 168 }; 169} 170