191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn/* 291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Copyright (C) 2014 The Android Open Source Project 391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * you may not use this file except in compliance with the License. 691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * You may obtain a copy of the License at 791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * 1091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * See the License for the specific language governing permissions and 1491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * limitations under the License. 1591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */ 1691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 1791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornpackage com.android.server.voiceinteraction; 1891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 1918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.Manifest; 2091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.app.ActivityManager; 21a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.app.AppGlobals; 2291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.ComponentName; 2391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.ContentResolver; 2491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Context; 2591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Intent; 26a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.content.pm.ApplicationInfo; 27a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.content.pm.IPackageManager; 2818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.pm.PackageManager; 29a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.content.pm.ResolveInfo; 30a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.content.pm.ServiceInfo; 3191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.database.ContentObserver; 32055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.IRecognitionStatusCallback; 33055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel; 34055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.ModuleProperties; 35055897208d659e9734a82def88be4a806ff55448Sandeep Siddharthaimport android.hardware.soundtrigger.SoundTrigger.RecognitionConfig; 3691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Binder; 3718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.os.Bundle; 3891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Handler; 3918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.os.IBinder; 40c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.os.Parcel; 41c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackbornimport android.os.RemoteException; 42d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackbornimport android.os.SystemProperties; 4391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.UserHandle; 4491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.provider.Settings; 4591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.service.voice.IVoiceInteractionService; 4691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.service.voice.IVoiceInteractionSession; 47a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.service.voice.VoiceInteractionService; 48a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.service.voice.VoiceInteractionServiceInfo; 49a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.speech.RecognitionService; 50a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.text.TextUtils; 5191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.Slog; 52d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep 5391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractionManagerService; 5491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractor; 5591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.content.PackageMonitor; 5691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.os.BackgroundThread; 5791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.server.SystemService; 5891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.server.UiThread; 5991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 6091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport java.io.FileDescriptor; 6191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport java.io.PrintWriter; 62a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport java.util.List; 6391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 6491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn/** 6591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * SystemService that publishes an IVoiceInteractionManagerService. 6691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */ 6791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornpublic class VoiceInteractionManagerService extends SystemService { 6891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn static final String TAG = "VoiceInteractionManagerService"; 69a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn static final boolean DEBUG = false; 7091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 7191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final Context mContext; 7291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final ContentResolver mResolver; 732883ba69751de69811a38f086ecbe4c2032ca87dSandeep Siddhartha final DatabaseHelper mDbHelper; 74055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha final SoundTriggerHelper mSoundTriggerHelper; 7591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 7691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public VoiceInteractionManagerService(Context context) { 7791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn super(context); 7891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mContext = context; 7991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mResolver = context.getContentResolver(); 802883ba69751de69811a38f086ecbe4c2032ca87dSandeep Siddhartha mDbHelper = new DatabaseHelper(context); 81efe0f9c7f2bdc10cfd28c186e68676e27b6944a1Sandeep Siddhartha mSoundTriggerHelper = new SoundTriggerHelper(context); 8291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 8391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 8491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 8591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void onStart() { 8691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn publishBinderService(Context.VOICE_INTERACTION_MANAGER_SERVICE, mServiceStub); 8791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 8891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 8991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 9091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void onBootPhase(int phase) { 9191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 9291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mServiceStub.systemRunning(isSafeMode()); 9391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 9491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 9591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 9691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 97a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn public void onStartUser(int userHandle) { 98a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mServiceStub.initForUser(userHandle); 99a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 100a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 101a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn @Override 10291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void onSwitchUser(int userHandle) { 10391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mServiceStub.switchUser(userHandle); 10491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 10591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 10691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn // implementation entry point and binder service 10791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn private final VoiceInteractionManagerServiceStub mServiceStub 10891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn = new VoiceInteractionManagerServiceStub(); 10991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 11091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub { 11191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 11291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn VoiceInteractionManagerServiceImpl mImpl; 11391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 11491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn private boolean mSafeMode; 11591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn private int mCurUser; 11691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 117c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn @Override 118c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 119c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn throws RemoteException { 120c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn try { 121c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return super.onTransact(code, data, reply, flags); 122c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } catch (RuntimeException e) { 123c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn // The activity manager only throws security exceptions, so let's 124c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn // log all others. 125c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (!(e instanceof SecurityException)) { 126c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn Slog.wtf(TAG, "VoiceInteractionManagerService Crash", e); 127c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 128c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn throw e; 129c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 130c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 131c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 132a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn public void initForUser(int userHandle) { 133a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle); 13416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn String curInteractorStr = Settings.Secure.getStringForUser( 13516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn mContext.getContentResolver(), 13616ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle); 137a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName curRecognizer = getCurRecognizer(userHandle); 13816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn VoiceInteractionServiceInfo curInteractorInfo = null; 139c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn if (curInteractorStr == null && curRecognizer != null 140c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn && !ActivityManager.isLowRamDeviceStatic()) { 14116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // If there is no interactor setting, that means we are upgrading 14216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // from an older platform version. If the current recognizer is not 14316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // set or matches the preferred recognizer, then we want to upgrade 14416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // the user to have the default voice interaction service enabled. 145c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn // Note that we don't do this for low-RAM devices, since we aren't 146c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn // supporting voice interaction services there. 14716ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn curInteractorInfo = findAvailInteractor(userHandle, curRecognizer); 14816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (curInteractorInfo != null) { 14916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // Looks good! We'll apply this one. To make it happen, we clear the 15016ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // recognizer so that we don't think we have anything set and will 15116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // re-apply the settings. 15216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn curRecognizer = null; 15316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 15416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 15516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn 156c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn // If we are on a svelte device, make sure an interactor is not currently 157c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn // enabled; if it is, turn it off. 158c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) { 159c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn if (!TextUtils.isEmpty(curInteractorStr)) { 160c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn setCurInteractor(null, userHandle); 161c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn curInteractorStr = ""; 162c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn } 163c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn } 164c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn 165a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curRecognizer != null) { 166a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // If we already have at least a recognizer, then we probably want to 167a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // leave things as they are... unless something has disappeared. 168a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn IPackageManager pm = AppGlobals.getPackageManager(); 169a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ServiceInfo interactorInfo = null; 170a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ServiceInfo recognizerInfo = null; 17116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn ComponentName curInteractor = !TextUtils.isEmpty(curInteractorStr) 17216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn ? ComponentName.unflattenFromString(curInteractorStr) : null; 173a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn try { 174a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn recognizerInfo = pm.getServiceInfo(curRecognizer, 0, userHandle); 175a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curInteractor != null) { 176a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn interactorInfo = pm.getServiceInfo(curInteractor, 0, userHandle); 177a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 178a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } catch (RemoteException e) { 179a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 180a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // If the apps for the currently set components still exist, then all is okay. 181a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (recognizerInfo != null && (curInteractor == null || interactorInfo != null)) { 182a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return; 183a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 184a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 185a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 186c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn // Initializing settings, look for an interactor first (but only on non-svelte). 187c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) { 18816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn curInteractorInfo = findAvailInteractor(userHandle, null); 18916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 190c0e4aaad1ecd5df2608f10a644f3d8f60056d94cDianne Hackborn 19116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (curInteractorInfo != null) { 19216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn // Eventually it will be an error to not specify this. 19316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn setCurInteractor(new ComponentName(curInteractorInfo.getServiceInfo().packageName, 19416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn curInteractorInfo.getServiceInfo().name), userHandle); 19516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (curInteractorInfo.getRecognitionService() != null) { 19616ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn setCurRecognizer( 19716ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn new ComponentName(curInteractorInfo.getServiceInfo().packageName, 19816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn curInteractorInfo.getRecognitionService()), userHandle); 19916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn return; 200a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 201a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 202a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 203a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // No voice interactor, we'll just set up a simple recognizer. 204a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn curRecognizer = findAvailRecognizer(null, userHandle); 205a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curRecognizer != null) { 20616ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (curInteractorInfo == null) { 20716ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn setCurInteractor(null, userHandle); 20816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 209a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurRecognizer(curRecognizer, userHandle); 210a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 211a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 212a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 21391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void systemRunning(boolean safeMode) { 21491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mSafeMode = safeMode; 21591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 21691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mPackageMonitor.register(mContext, BackgroundThread.getHandler().getLooper(), 21791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn UserHandle.ALL, true); 21891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn new SettingsObserver(UiThread.getHandler()); 21991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 22091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn synchronized (this) { 22191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mCurUser = ActivityManager.getCurrentUser(); 222c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn switchImplementationIfNeededLocked(false); 22391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 22491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 22591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 22691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void switchUser(int userHandle) { 22791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn synchronized (this) { 22891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mCurUser = userHandle; 229c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn switchImplementationIfNeededLocked(false); 23091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 23191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 23291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 233c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn void switchImplementationIfNeededLocked(boolean force) { 23491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (!mSafeMode) { 23591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn String curService = Settings.Secure.getStringForUser( 23691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mResolver, Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser); 23791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn ComponentName serviceComponent = null; 23891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (curService != null && !curService.isEmpty()) { 23991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn try { 24091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn serviceComponent = ComponentName.unflattenFromString(curService); 24191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } catch (RuntimeException e) { 24291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn Slog.wtf(TAG, "Bad voice interaction service name " + curService, e); 24391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn serviceComponent = null; 24491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 24591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 246c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (force || mImpl == null || mImpl.mUser != mCurUser 24791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn || !mImpl.mComponent.equals(serviceComponent)) { 2485e33fb057c20b84418d96574abe861e9d05956ebSandeep Siddhartha mSoundTriggerHelper.stopAllRecognitions(); 24991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (mImpl != null) { 25091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mImpl.shutdownLocked(); 25191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 25291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn if (serviceComponent != null) { 25391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mImpl = new VoiceInteractionManagerServiceImpl(mContext, 25491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn UiThread.getHandler(), this, mCurUser, serviceComponent); 25591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mImpl.startLocked(); 25691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } else { 25791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn mImpl = null; 25891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 25991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 26091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 26191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 26291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 26316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn VoiceInteractionServiceInfo findAvailInteractor(int userHandle, ComponentName recognizer) { 264a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn List<ResolveInfo> available = 265a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mContext.getPackageManager().queryIntentServicesAsUser( 266a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn new Intent(VoiceInteractionService.SERVICE_INTERFACE), 0, userHandle); 267a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn int numAvailable = available.size(); 268a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 269a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (numAvailable == 0) { 270a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Slog.w(TAG, "no available voice interaction services found for user " + userHandle); 271a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return null; 272a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } else { 273a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // Find first system package. We never want to allow third party services to 274a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // be automatically selected, because those require approval of the user. 27516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn VoiceInteractionServiceInfo foundInfo = null; 276a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn for (int i=0; i<numAvailable; i++) { 277a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ServiceInfo cur = available.get(i).serviceInfo; 278a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if ((cur.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 27916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn ComponentName comp = new ComponentName(cur.packageName, cur.name); 28016ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn try { 28116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn VoiceInteractionServiceInfo info = new VoiceInteractionServiceInfo( 28216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn mContext.getPackageManager(), comp, userHandle); 28316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (info.getParseError() == null) { 28416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (recognizer == null || info.getServiceInfo().packageName.equals( 28516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn recognizer.getPackageName())) { 28616ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn if (foundInfo == null) { 28716ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn foundInfo = info; 28816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } else { 28916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn Slog.w(TAG, "More than one voice interaction service, " 29016ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn + "picking first " 29116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn + new ComponentName( 29216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn foundInfo.getServiceInfo().packageName, 29316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn foundInfo.getServiceInfo().name) 29416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn + " over " 29516ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn + new ComponentName(cur.packageName, cur.name)); 29616ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 29716ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 29816ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } else { 29916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn Slog.w(TAG, "Bad interaction service " + comp + ": " 30016ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn + info.getParseError()); 30116ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } 30216ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } catch (PackageManager.NameNotFoundException e) { 30316ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn Slog.w(TAG, "Failure looking up interaction service " + comp); 30416ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn } catch (RemoteException e) { 305a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 306a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 307a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 308a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 30916ec0808b5c19f8f33cdacb7b2e444eebfae7d21Dianne Hackborn return foundInfo; 310a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 311a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 312a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 313a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName getCurInteractor(int userHandle) { 314a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn String curInteractor = Settings.Secure.getStringForUser( 315a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mContext.getContentResolver(), 316a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle); 317a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (TextUtils.isEmpty(curInteractor)) { 318a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return null; 319a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 320a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "getCurInteractor curInteractor=" + curInteractor 321a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn + " user=" + userHandle); 322a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return ComponentName.unflattenFromString(curInteractor); 323a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 324a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 325a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn void setCurInteractor(ComponentName comp, int userHandle) { 326a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.putStringForUser(mContext.getContentResolver(), 327a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.VOICE_INTERACTION_SERVICE, 328a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn comp != null ? comp.flattenToShortString() : "", userHandle); 329a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "setCurInteractor comp=" + comp 330a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn + " user=" + userHandle); 331a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 332a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 333a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName findAvailRecognizer(String prefPackage, int userHandle) { 334a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn List<ResolveInfo> available = 335a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mContext.getPackageManager().queryIntentServicesAsUser( 336a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle); 337a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn int numAvailable = available.size(); 338a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 339a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (numAvailable == 0) { 340a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Slog.w(TAG, "no available voice recognition services found for user " + userHandle); 341a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return null; 342a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } else { 343a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (prefPackage != null) { 344a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn for (int i=0; i<numAvailable; i++) { 345a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ServiceInfo serviceInfo = available.get(i).serviceInfo; 346a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (prefPackage.equals(serviceInfo.packageName)) { 347a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return new ComponentName(serviceInfo.packageName, serviceInfo.name); 348a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 349a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 350a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 351a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (numAvailable > 1) { 352a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Slog.w(TAG, "more than one voice recognition service found, picking first"); 353a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 354a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 355a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ServiceInfo serviceInfo = available.get(0).serviceInfo; 356a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return new ComponentName(serviceInfo.packageName, serviceInfo.name); 357a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 358a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 359a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 360a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName getCurRecognizer(int userHandle) { 361a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn String curRecognizer = Settings.Secure.getStringForUser( 362a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mContext.getContentResolver(), 363a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle); 364a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (TextUtils.isEmpty(curRecognizer)) { 365a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return null; 366a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 367a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer 368a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn + " user=" + userHandle); 369a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return ComponentName.unflattenFromString(curRecognizer); 370a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 371a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 372a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn void setCurRecognizer(ComponentName comp, int userHandle) { 373a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.putStringForUser(mContext.getContentResolver(), 374a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn Settings.Secure.VOICE_RECOGNITION_SERVICE, 375a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn comp != null ? comp.flattenToShortString() : "", userHandle); 376a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp 377a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn + " user=" + userHandle); 378a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 379a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 38091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 381c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public void startSession(IVoiceInteractionService service, Bundle args) { 38291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn synchronized (this) { 383c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mImpl == null || mImpl.mService == null 384c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn || service.asBinder() != mImpl.mService.asBinder()) { 38591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn throw new SecurityException( 38691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn "Caller is not the current voice interaction service"); 38791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 38891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final int callingPid = Binder.getCallingPid(); 38991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final int callingUid = Binder.getCallingUid(); 39091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn final long caller = Binder.clearCallingIdentity(); 39191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn try { 392c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mImpl.startSessionLocked(callingPid, callingUid, args); 39391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } finally { 39491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn Binder.restoreCallingIdentity(caller); 39591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 39691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 39791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 39891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 39991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 400c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public boolean deliverNewSession(IBinder token, IVoiceInteractionSession session, 40118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn IVoiceInteractor interactor) { 40218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn synchronized (this) { 40318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (mImpl == null) { 404c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn throw new SecurityException( 405c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn "deliverNewSession without running voice interaction service"); 40618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 40718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final int callingPid = Binder.getCallingPid(); 40818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final int callingUid = Binder.getCallingUid(); 40918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn final long caller = Binder.clearCallingIdentity(); 41018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn try { 41118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return mImpl.deliverNewSessionLocked(callingPid, callingUid, token, session, 41218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn interactor); 41318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } finally { 41418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn Binder.restoreCallingIdentity(caller); 41518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 41618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 417c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 41818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 419c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn @Override 420c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public int startVoiceActivity(IBinder token, Intent intent, String resolvedType) { 421c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn synchronized (this) { 422c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mImpl == null) { 423c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn Slog.w(TAG, "startVoiceActivity without running voice interaction service"); 424c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return ActivityManager.START_CANCELED; 425c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 426c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final int callingPid = Binder.getCallingPid(); 427c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final int callingUid = Binder.getCallingUid(); 428c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final long caller = Binder.clearCallingIdentity(); 429d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackborn if (!SystemProperties.getBoolean("persist.test.voice_interaction", false)) { 430d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackborn throw new SecurityException("Voice interaction not supported"); 431d7c0395d26694c594c3e64b16ab647c971aeb422Dianne Hackborn } 432c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn try { 433c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return mImpl.startVoiceActivityLocked(callingPid, callingUid, token, 434c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn intent, resolvedType); 435c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } finally { 436c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn Binder.restoreCallingIdentity(caller); 437c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 438c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 439c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 440c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn 441c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn @Override 442c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn public void finish(IBinder token) { 443c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn synchronized (this) { 444c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn if (mImpl == null) { 445c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn Slog.w(TAG, "finish without running voice interaction service"); 446c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn return; 447c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 448c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final int callingPid = Binder.getCallingPid(); 449c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final int callingUid = Binder.getCallingUid(); 450c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn final long caller = Binder.clearCallingIdentity(); 451c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn try { 452c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn mImpl.finishLocked(callingPid, callingUid, token); 453c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } finally { 454c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn Binder.restoreCallingIdentity(caller); 455c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 456c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 45718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 45818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn 459055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha //----------------- Model management APIs --------------------------------// 460055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 46118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn @Override 4628cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha public KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId, String bcp47Locale) { 463d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep synchronized (this) { 464452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (mContext.checkCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES) 465452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha != PackageManager.PERMISSION_GRANTED) { 466452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha throw new SecurityException("Caller does not hold the permission " 467452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha + Manifest.permission.MANAGE_VOICE_KEYPHRASES); 468d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 469f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha } 470d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep 4718cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha if (bcp47Locale == null) { 4728cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha throw new IllegalArgumentException("Illegal argument(s) in getKeyphraseSoundModel"); 4738cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha } 4748cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha 4758cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha final int callingUid = UserHandle.getCallingUserId(); 476f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 477f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha try { 4788cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha return mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); 479f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha } finally { 480f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha Binder.restoreCallingIdentity(caller); 481d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 482d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 483d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep 484d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep @Override 485d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep public int updateKeyphraseSoundModel(KeyphraseSoundModel model) { 486d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep synchronized (this) { 487d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep if (mContext.checkCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES) 488d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep != PackageManager.PERMISSION_GRANTED) { 489d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep throw new SecurityException("Caller does not hold the permission " 490d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep + Manifest.permission.MANAGE_VOICE_KEYPHRASES); 491d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 492f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha if (model == null) { 493f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha throw new IllegalArgumentException("Model must not be null"); 494f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha } 495f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha } 496f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha 497f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 498f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha try { 499452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (mDbHelper.updateKeyphraseSoundModel(model)) { 500452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha synchronized (this) { 501452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha // Notify the voice interaction service of a change in sound models. 502452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (mImpl != null && mImpl.mService != null) { 503452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha mImpl.notifySoundModelsChangedLocked(); 504452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 505452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 506452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha return SoundTriggerHelper.STATUS_OK; 507f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha } else { 508452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha return SoundTriggerHelper.STATUS_ERROR; 509f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha } 510452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } finally { 511452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha Binder.restoreCallingIdentity(caller); 512452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 513452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 514452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha 515452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha @Override 5168cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha public int deleteKeyphraseSoundModel(int keyphraseId, String bcp47Locale) { 517452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha synchronized (this) { 518452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (mContext.checkCallingPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES) 519452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha != PackageManager.PERMISSION_GRANTED) { 520452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha throw new SecurityException("Caller does not hold the permission " 521452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha + Manifest.permission.MANAGE_VOICE_KEYPHRASES); 522452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 523452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 524452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha 5258cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha if (bcp47Locale == null) { 5268cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha throw new IllegalArgumentException( 5278cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha "Illegal argument(s) in deleteKeyphraseSoundModel"); 5288cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha } 5298cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha 5308cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha final int callingUid = UserHandle.getCallingUserId(); 531452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 532256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha boolean deleted = false; 533452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha try { 5348cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha deleted = mDbHelper.deleteKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); 535256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha return deleted ? SoundTriggerHelper.STATUS_OK : SoundTriggerHelper.STATUS_ERROR; 536256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha } finally { 537256e1a62673472d685232d88ad4d067eb82deeacSandeep Siddhartha if (deleted) { 538f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha synchronized (this) { 5396daae9622672e0b38fc2efed29f68061d749caccSandeep Siddhartha // Notify the voice interaction service of a change in sound models. 5406daae9622672e0b38fc2efed29f68061d749caccSandeep Siddhartha if (mImpl != null && mImpl.mService != null) { 5416daae9622672e0b38fc2efed29f68061d749caccSandeep Siddhartha mImpl.notifySoundModelsChangedLocked(); 542f8cf71d753b86895f987f682c80491aa2967e0c2Sandeep Siddhartha } 5432883ba69751de69811a38f086ecbe4c2032ca87dSandeep Siddhartha } 544d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 545f63bc523eadbe01ce0a5ad52868a5dccb3d5f6ddSandeep Siddhartha Binder.restoreCallingIdentity(caller); 546d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 547d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep } 548d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep 549055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha //----------------- SoundTrigger APIs --------------------------------// 550055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha @Override 5518cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha public boolean isEnrolledForKeyphrase(IVoiceInteractionService service, int keyphraseId, 5528cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha String bcp47Locale) { 553452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha synchronized (this) { 554452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (mImpl == null || mImpl.mService == null 555452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha || service.asBinder() != mImpl.mService.asBinder()) { 556452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha throw new SecurityException( 557452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha "Caller is not the current voice interaction service"); 558452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 559452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 560452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha 5618cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha if (bcp47Locale == null) { 5628cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha throw new IllegalArgumentException("Illegal argument(s) in isEnrolledForKeyphrase"); 5638cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha } 5648cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha 5658cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha final int callingUid = UserHandle.getCallingUserId(); 566452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 567452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha try { 5688cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha KeyphraseSoundModel model = 5698cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); 570452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha return model != null; 571452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } finally { 572452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha Binder.restoreCallingIdentity(caller); 573452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 574452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 575452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha 576452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha @Override 577055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha public ModuleProperties getDspModuleProperties(IVoiceInteractionService service) { 578055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha // Allow the call if this is the current voice interaction service. 579055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha synchronized (this) { 580055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha if (mImpl == null || mImpl.mService == null 581055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha || service == null || service.asBinder() != mImpl.mService.asBinder()) { 582055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha throw new SecurityException( 583055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha "Caller is not the current voice interaction service"); 584055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 585055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 586055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 587055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha try { 588055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha return mSoundTriggerHelper.moduleProperties; 589055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } finally { 590055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha Binder.restoreCallingIdentity(caller); 591055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 592055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 593055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 594055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 595055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha @Override 596055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha public int startRecognition(IVoiceInteractionService service, int keyphraseId, 5978cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha String bcp47Locale, IRecognitionStatusCallback callback, 5988cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha RecognitionConfig recognitionConfig) { 599055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha // Allow the call if this is the current voice interaction service. 600055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha synchronized (this) { 601055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha if (mImpl == null || mImpl.mService == null 602055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha || service == null || service.asBinder() != mImpl.mService.asBinder()) { 603055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha throw new SecurityException( 604055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha "Caller is not the current voice interaction service"); 605055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 606055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 6078cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha if (callback == null || recognitionConfig == null || bcp47Locale == null) { 608452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha throw new IllegalArgumentException("Illegal argument(s) in startRecognition"); 609452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 610452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 611452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha 6128cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha int callingUid = UserHandle.getCallingUserId(); 613452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 614452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha try { 6158cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha KeyphraseSoundModel soundModel = 6168cf8f71644643601fe8c3e9538fd00412b1ae8b1Sandeep Siddhartha mDbHelper.getKeyphraseSoundModel(keyphraseId, callingUid, bcp47Locale); 617452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha if (soundModel == null 618452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha || soundModel.uuid == null 619452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha || soundModel.keyphrases == null) { 620452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha Slog.w(TAG, "No matching sound model found in startRecognition"); 621452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha return SoundTriggerHelper.STATUS_ERROR; 622452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } else { 623055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha return mSoundTriggerHelper.startRecognition( 624055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha keyphraseId, soundModel, callback, recognitionConfig); 625055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 626452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } finally { 627452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha Binder.restoreCallingIdentity(caller); 628055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 629055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 630055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 631055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha @Override 632055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha public int stopRecognition(IVoiceInteractionService service, int keyphraseId, 633055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha IRecognitionStatusCallback callback) { 634055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha // Allow the call if this is the current voice interaction service. 635055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha synchronized (this) { 636055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha if (mImpl == null || mImpl.mService == null 637055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha || service == null || service.asBinder() != mImpl.mService.asBinder()) { 638055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha throw new SecurityException( 639055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha "Caller is not the current voice interaction service"); 640055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 641452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } 642055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 643452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha final long caller = Binder.clearCallingIdentity(); 644452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha try { 645452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha return mSoundTriggerHelper.stopRecognition(keyphraseId, callback); 646452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha } finally { 647452a642430e3f8abfa053e48893dd0edfb12799bSandeep Siddhartha Binder.restoreCallingIdentity(caller); 648055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 649055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha } 650055897208d659e9734a82def88be4a806ff55448Sandeep Siddhartha 651d7018200312e4e4dc3f67cf33dc90bf7ce585844Sandeep @Override 65291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 65318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) 65418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn != PackageManager.PERMISSION_GRANTED) { 65518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn pw.println("Permission Denial: can't dump PowerManager from from pid=" 65618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + Binder.getCallingPid() 65718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn + ", uid=" + Binder.getCallingUid()); 65818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return; 65918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 66018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn synchronized (this) { 66118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n"); 66218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn if (mImpl == null) { 66318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn pw.println(" (No active implementation)"); 66418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn return; 66518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 66618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn mImpl.dumpLocked(fd, pw, args); 66718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn } 6686b8556d2e320b631d3741bf064796efddb6e51dfSandeep Siddhartha mSoundTriggerHelper.dump(fd, pw, args); 66991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 67091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 67191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn class SettingsObserver extends ContentObserver { 67291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn SettingsObserver(Handler handler) { 67391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn super(handler); 67491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn ContentResolver resolver = mContext.getContentResolver(); 67591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn resolver.registerContentObserver(Settings.Secure.getUriFor( 67691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn Settings.Secure.VOICE_INTERACTION_SERVICE), false, this); 67791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 67891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 67991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override public void onChange(boolean selfChange) { 68091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn synchronized (VoiceInteractionManagerServiceStub.this) { 681c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn switchImplementationIfNeededLocked(false); 68291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 68391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 68491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 68591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 68691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn PackageMonitor mPackageMonitor = new PackageMonitor() { 68791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 68891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 68991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn return super.onHandleForceStop(intent, packages, uid, doit); 69091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 69191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 69291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 69391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn public void onHandleUserStop(Intent intent, int userHandle) { 69491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 69591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 69691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn @Override 697a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn public void onSomePackagesChanged() { 698a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn int userHandle = getChangingUserId(); 699a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle); 700a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 701a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName curInteractor = getCurInteractor(userHandle); 702a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn ComponentName curRecognizer = getCurRecognizer(userHandle); 703a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curRecognizer == null) { 704a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // Could a new recognizer appear when we don't have one pre-installed? 705a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (anyPackagesAppearing()) { 706a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn curRecognizer = findAvailRecognizer(null, userHandle); 707a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curRecognizer != null) { 708a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurRecognizer(curRecognizer, userHandle); 709a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 710a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 711a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return; 712a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 71391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 714a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (curInteractor != null) { 715a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn int change = isPackageDisappearing(curInteractor.getPackageName()); 716a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (change == PACKAGE_PERMANENT_CHANGE) { 717a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // The currently set interactor is permanently gone; fall back to 718a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // the default config. 719a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurInteractor(null, userHandle); 720a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurRecognizer(null, userHandle); 721a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn initForUser(userHandle); 722a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return; 723a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 724a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn 725a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn change = isPackageAppearing(curInteractor.getPackageName()); 726a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (change != PACKAGE_UNCHANGED) { 727a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // If current interactor is now appearing, for any reason, then 728a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // restart our connection with it. 729a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (mImpl != null && curInteractor.getPackageName().equals( 730a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn mImpl.mComponent.getPackageName())) { 731a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn switchImplementationIfNeededLocked(true); 732a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 733a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 734a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn return; 735c03c9167c2d9a1e22fb2b176b00a0524177fb037Dianne Hackborn } 73691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 737a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn // There is no interactor, so just deal with a simple recognizer. 738a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn int change = isPackageDisappearing(curRecognizer.getPackageName()); 739a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn if (change == PACKAGE_PERMANENT_CHANGE 740a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn || change == PACKAGE_TEMPORARY_CHANGE) { 741a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle); 74291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn 743a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } else if (isPackageModified(curRecognizer.getPackageName())) { 744a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn setCurRecognizer(findAvailRecognizer(curRecognizer.getPackageName(), 745a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn userHandle), userHandle); 746a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn } 74791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 74891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn }; 74991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn } 75091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn} 751