blob: a62b03ca82e41a7be0cf609de6127478da78e2c0 [file] [log] [blame]
Dianne Hackborn91097de2014-04-04 18:02:06 -07001/*
2 * Copyright (C) 2014 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.voiceinteraction;
18
Winson Chungfc3ec4c2017-06-01 15:35:48 -070019import static android.app.ActivityManager.START_ASSISTANT_HIDDEN_SESSION;
20import static android.app.ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION;
Winson Chung83471632016-12-13 11:02:12 -080021import static android.app.ActivityManager.START_VOICE_HIDDEN_SESSION;
22import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION;
Wale Ogunwale0568aed2017-09-08 13:29:37 -070023import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
Winson Chung83471632016-12-13 11:02:12 -080024
Sunny Goyald40c3452019-03-20 12:46:55 -070025import android.annotation.NonNull;
26import android.annotation.Nullable;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070027import android.app.ActivityManager;
Winson Chung83471632016-12-13 11:02:12 -080028import android.app.ActivityOptions;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070029import android.app.ActivityTaskManager;
Dianne Hackborn91097de2014-04-04 18:02:06 -070030import android.app.IActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import android.app.IActivityTaskManager;
Dianne Hackbornc03c9162014-05-02 10:45:59 -070032import android.content.BroadcastReceiver;
Dianne Hackborn91097de2014-04-04 18:02:06 -070033import android.content.ComponentName;
34import android.content.Context;
35import android.content.Intent;
Dianne Hackbornc03c9162014-05-02 10:45:59 -070036import android.content.IntentFilter;
Dianne Hackborn91097de2014-04-04 18:02:06 -070037import android.content.ServiceConnection;
38import android.content.pm.PackageManager;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070039import android.os.Bundle;
Dianne Hackborn91097de2014-04-04 18:02:06 -070040import android.os.Handler;
41import android.os.IBinder;
Sunny Goyald40c3452019-03-20 12:46:55 -070042import android.os.RemoteCallback;
Dianne Hackborn91097de2014-04-04 18:02:06 -070043import android.os.RemoteException;
Dianne Hackbornc03c9162014-05-02 10:45:59 -070044import android.os.ServiceManager;
Dianne Hackborn91097de2014-04-04 18:02:06 -070045import android.os.UserHandle;
46import android.service.voice.IVoiceInteractionService;
47import android.service.voice.IVoiceInteractionSession;
48import android.service.voice.VoiceInteractionService;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070049import android.service.voice.VoiceInteractionServiceInfo;
Dianne Hackborn958b9d22015-10-09 16:09:25 -070050import android.util.PrintWriterPrinter;
Dianne Hackborn91097de2014-04-04 18:02:06 -070051import android.util.Slog;
Dianne Hackbornc03c9162014-05-02 10:45:59 -070052import android.view.IWindowManager;
Sandeepd7018202014-07-10 15:15:39 -070053
Amith Yamasanic45a9902019-04-05 16:29:30 -070054import com.android.internal.app.IVoiceActionCheckCallback;
Jorim Jaggi225d3b52015-04-01 11:18:57 -070055import com.android.internal.app.IVoiceInteractionSessionShowCallback;
Dianne Hackborn91097de2014-04-04 18:02:06 -070056import com.android.internal.app.IVoiceInteractor;
Amith Yamasanie8222e52016-04-08 15:28:47 -070057import com.android.server.LocalServices;
Amith Yamasanic45a9902019-04-05 16:29:30 -070058import com.android.server.wm.ActivityTaskManagerInternal;
Sunny Goyald40c3452019-03-20 12:46:55 -070059import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens;
Dianne Hackborn91097de2014-04-04 18:02:06 -070060
Dianne Hackborn18f0d352014-04-25 17:06:18 -070061import java.io.FileDescriptor;
62import java.io.PrintWriter;
Winson Chungda2818f2017-10-23 16:25:49 -070063import java.util.ArrayList;
Amith Yamasanie8222e52016-04-08 15:28:47 -070064import java.util.List;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070065
Dianne Hackbornffeecb12015-02-25 11:08:11 -080066class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
Dianne Hackborn91097de2014-04-04 18:02:06 -070067 final static String TAG = "VoiceInteractionServiceManager";
68
Dianne Hackborn4e88bcd2015-07-01 13:41:03 -070069 final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";
70
Dianne Hackborn18f0d352014-04-25 17:06:18 -070071 final boolean mValid;
72
Dianne Hackborn91097de2014-04-04 18:02:06 -070073 final Context mContext;
74 final Handler mHandler;
Annie Chind953ab62016-07-07 11:57:33 -070075 final VoiceInteractionManagerService.VoiceInteractionManagerServiceStub mServiceStub;
Dianne Hackborn91097de2014-04-04 18:02:06 -070076 final int mUser;
77 final ComponentName mComponent;
78 final IActivityManager mAm;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070079 final IActivityTaskManager mAtm;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070080 final VoiceInteractionServiceInfo mInfo;
81 final ComponentName mSessionComponentName;
Dianne Hackbornc03c9162014-05-02 10:45:59 -070082 final IWindowManager mIWindowManager;
Dianne Hackborn91097de2014-04-04 18:02:06 -070083 boolean mBound = false;
84 IVoiceInteractionService mService;
Dianne Hackborn18f0d352014-04-25 17:06:18 -070085
Dianne Hackbornffeecb12015-02-25 11:08:11 -080086 VoiceInteractionSessionConnection mActiveSession;
Dianne Hackborn1de11862015-07-15 14:20:51 -070087 int mDisabledShowContext;
Dianne Hackborn91097de2014-04-04 18:02:06 -070088
Dianne Hackbornc03c9162014-05-02 10:45:59 -070089 final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
90 @Override
91 public void onReceive(Context context, Intent intent) {
92 if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
Dianne Hackborn4e88bcd2015-07-01 13:41:03 -070093 String reason = intent.getStringExtra("reason");
Dianne Hackborn57dd7372015-07-27 18:11:14 -070094 if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason) && !"dream".equals(reason)) {
Annie Chind953ab62016-07-07 11:57:33 -070095 synchronized (mServiceStub) {
Dianne Hackborn4e88bcd2015-07-01 13:41:03 -070096 if (mActiveSession != null && mActiveSession.mSession != null) {
97 try {
98 mActiveSession.mSession.closeSystemDialogs();
99 } catch (RemoteException e) {
100 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700101 }
102 }
103 }
104 }
105 }
106 };
107
Dianne Hackborn91097de2014-04-04 18:02:06 -0700108 final ServiceConnection mConnection = new ServiceConnection() {
109 @Override
110 public void onServiceConnected(ComponentName name, IBinder service) {
Annie Chind953ab62016-07-07 11:57:33 -0700111 synchronized (mServiceStub) {
Dianne Hackborn91097de2014-04-04 18:02:06 -0700112 mService = IVoiceInteractionService.Stub.asInterface(service);
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700113 try {
114 mService.ready();
115 } catch (RemoteException e) {
116 }
Dianne Hackborn91097de2014-04-04 18:02:06 -0700117 }
118 }
119
120 @Override
121 public void onServiceDisconnected(ComponentName name) {
122 mService = null;
123 }
124 };
125
Annie Chind953ab62016-07-07 11:57:33 -0700126 VoiceInteractionManagerServiceImpl(Context context, Handler handler,
127 VoiceInteractionManagerService.VoiceInteractionManagerServiceStub stub,
Felipe Lemed9b98da2019-05-21 17:54:18 -0700128 int userHandle, ComponentName service) {
Dianne Hackborn91097de2014-04-04 18:02:06 -0700129 mContext = context;
130 mHandler = handler;
Annie Chind953ab62016-07-07 11:57:33 -0700131 mServiceStub = stub;
Dianne Hackborn91097de2014-04-04 18:02:06 -0700132 mUser = userHandle;
133 mComponent = service;
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800134 mAm = ActivityManager.getService();
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700135 mAtm = ActivityTaskManager.getService();
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700136 VoiceInteractionServiceInfo info;
137 try {
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700138 info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
Dianne Hackbornc83189b2015-11-16 18:07:35 -0800139 } catch (PackageManager.NameNotFoundException e) {
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700140 Slog.w(TAG, "Voice interaction service not found: " + service, e);
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700141 mInfo = null;
142 mSessionComponentName = null;
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700143 mIWindowManager = null;
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700144 mValid = false;
145 return;
146 }
147 mInfo = info;
148 if (mInfo.getParseError() != null) {
149 Slog.w(TAG, "Bad voice interaction service: " + mInfo.getParseError());
150 mSessionComponentName = null;
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700151 mIWindowManager = null;
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700152 mValid = false;
153 return;
154 }
155 mValid = true;
156 mSessionComponentName = new ComponentName(service.getPackageName(),
157 mInfo.getSessionService());
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700158 mIWindowManager = IWindowManager.Stub.asInterface(
159 ServiceManager.getService(Context.WINDOW_SERVICE));
160 IntentFilter filter = new IntentFilter();
161 filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
162 mContext.registerReceiver(mBroadcastReceiver, filter, null, handler);
Dianne Hackborn91097de2014-04-04 18:02:06 -0700163 }
164
Jorim Jaggib09f8e22015-04-15 15:11:48 -0700165 public boolean showSessionLocked(Bundle args, int flags,
Dianne Hackborn17f69352015-07-17 18:04:14 -0700166 IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
Dianne Hackbornffeecb12015-02-25 11:08:11 -0800167 if (mActiveSession == null) {
Annie Chind953ab62016-07-07 11:57:33 -0700168 mActiveSession = new VoiceInteractionSessionConnection(mServiceStub,
169 mSessionComponentName, mUser, mContext, this,
Felipe Lemed9b98da2019-05-21 17:54:18 -0700170 mInfo.getServiceInfo().applicationInfo.uid, mHandler);
Dianne Hackborn91097de2014-04-04 18:02:06 -0700171 }
Amith Yamasanie8222e52016-04-08 15:28:47 -0700172 List<IBinder> activityTokens = null;
Winson Chungda2818f2017-10-23 16:25:49 -0700173 if (activityToken != null) {
174 activityTokens = new ArrayList<>();
175 activityTokens.add(activityToken);
176 } else {
Amith Yamasanie8222e52016-04-08 15:28:47 -0700177 // Let's get top activities from all visible stacks
Wale Ogunwale6767eae2018-05-03 15:52:51 -0700178 activityTokens = LocalServices.getService(ActivityTaskManagerInternal.class)
Amith Yamasanie8222e52016-04-08 15:28:47 -0700179 .getTopVisibleActivities();
180 }
Dianne Hackborn17f69352015-07-17 18:04:14 -0700181 return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback,
Winson Chungda2818f2017-10-23 16:25:49 -0700182 activityTokens);
Dianne Hackbornffeecb12015-02-25 11:08:11 -0800183 }
184
jiayuzhou21a353b2018-08-16 16:09:43 -0700185 public void getActiveServiceSupportedActions(List<String> commands,
186 IVoiceActionCheckCallback callback) {
187 if (mService == null) {
188 Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
189 try {
190 callback.onComplete(null);
191 } catch (RemoteException e) {
192 }
193 return;
194 }
195 try {
196 mService.getActiveServiceSupportedActions(commands, callback);
197 } catch (RemoteException e) {
198 Slog.w(TAG, "RemoteException while calling getActiveServiceSupportedActions", e);
199 }
200 }
201
Jorim Jaggib835dd72015-06-08 12:28:42 -0700202 public boolean hideSessionLocked() {
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700203 if (mActiveSession != null) {
204 return mActiveSession.hideLocked();
205 }
206 return false;
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700207 }
208
Dianne Hackborn17f69352015-07-17 18:04:14 -0700209 public boolean deliverNewSessionLocked(IBinder token,
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700210 IVoiceInteractionSession session, IVoiceInteractor interactor) {
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700211 if (mActiveSession == null || token != mActiveSession.mToken) {
212 Slog.w(TAG, "deliverNewSession does not match active session");
213 return false;
214 }
Dianne Hackbornffeecb12015-02-25 11:08:11 -0800215 mActiveSession.deliverNewSessionLocked(session, interactor);
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700216 return true;
217 }
218
Philip P. Moltmannee295092020-02-10 08:46:26 -0800219 public int startVoiceActivityLocked(@Nullable String callingFeatureId, int callingPid,
220 int callingUid, IBinder token, Intent intent, String resolvedType) {
Dianne Hackborn91097de2014-04-04 18:02:06 -0700221 try {
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700222 if (mActiveSession == null || token != mActiveSession.mToken) {
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700223 Slog.w(TAG, "startVoiceActivity does not match active session");
Winson Chung83471632016-12-13 11:02:12 -0800224 return START_VOICE_NOT_ACTIVE_SESSION;
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700225 }
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700226 if (!mActiveSession.mShown) {
227 Slog.w(TAG, "startVoiceActivity not allowed on hidden session");
Winson Chung83471632016-12-13 11:02:12 -0800228 return START_VOICE_HIDDEN_SESSION;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700229 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700230 intent = new Intent(intent);
231 intent.addCategory(Intent.CATEGORY_VOICE);
232 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
Philip P. Moltmannee295092020-02-10 08:46:26 -0800233 return mAtm.startVoiceActivity(mComponent.getPackageName(), callingFeatureId,
234 callingPid, callingUid, intent, resolvedType, mActiveSession.mSession,
235 mActiveSession.mInteractor, 0, null, null, mUser);
Dianne Hackborn91097de2014-04-04 18:02:06 -0700236 } catch (RemoteException e) {
237 throw new IllegalStateException("Unexpected remote error", e);
238 }
239 }
240
Philip P. Moltmannee295092020-02-10 08:46:26 -0800241 public int startAssistantActivityLocked(@Nullable String callingFeatureId, int callingPid,
242 int callingUid, IBinder token, Intent intent, String resolvedType) {
Winson Chung83471632016-12-13 11:02:12 -0800243 try {
244 if (mActiveSession == null || token != mActiveSession.mToken) {
245 Slog.w(TAG, "startAssistantActivity does not match active session");
Winson Chungfc3ec4c2017-06-01 15:35:48 -0700246 return START_ASSISTANT_NOT_ACTIVE_SESSION;
Winson Chung83471632016-12-13 11:02:12 -0800247 }
248 if (!mActiveSession.mShown) {
249 Slog.w(TAG, "startAssistantActivity not allowed on hidden session");
Winson Chungfc3ec4c2017-06-01 15:35:48 -0700250 return START_ASSISTANT_HIDDEN_SESSION;
Winson Chung83471632016-12-13 11:02:12 -0800251 }
252 intent = new Intent(intent);
253 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Wale Ogunwale0568aed2017-09-08 13:29:37 -0700254 final ActivityOptions options = ActivityOptions.makeBasic();
255 options.setLaunchActivityType(ACTIVITY_TYPE_ASSISTANT);
Philip P. Moltmannee295092020-02-10 08:46:26 -0800256 return mAtm.startAssistantActivity(mComponent.getPackageName(), callingFeatureId,
257 callingPid, callingUid, intent, resolvedType, options.toBundle(), mUser);
Winson Chung83471632016-12-13 11:02:12 -0800258 } catch (RemoteException e) {
259 throw new IllegalStateException("Unexpected remote error", e);
260 }
261 }
262
Sunny Goyald40c3452019-03-20 12:46:55 -0700263 public void requestDirectActionsLocked(@NonNull IBinder token, int taskId,
Svet Ganov3b6be082019-04-28 10:21:01 -0700264 @NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback,
265 @NonNull RemoteCallback callback) {
Sunny Goyald40c3452019-03-20 12:46:55 -0700266 if (mActiveSession == null || token != mActiveSession.mToken) {
267 Slog.w(TAG, "requestDirectActionsLocked does not match active session");
268 callback.sendResult(null);
269 return;
270 }
271 final ActivityTokens tokens = LocalServices.getService(
272 ActivityTaskManagerInternal.class).getTopActivityForTask(taskId);
273 if (tokens == null || tokens.getAssistToken() != assistToken) {
274 Slog.w(TAG, "Unknown activity to query for direct actions");
275 callback.sendResult(null);
276 } else {
277 try {
278 tokens.getApplicationThread().requestDirectActions(tokens.getActivityToken(),
Svet Ganov3b6be082019-04-28 10:21:01 -0700279 mActiveSession.mInteractor, cancellationCallback, callback);
Sunny Goyald40c3452019-03-20 12:46:55 -0700280 } catch (RemoteException e) {
281 Slog.w("Unexpected remote error", e);
282 callback.sendResult(null);
283 }
284 }
285 }
286
287 void performDirectActionLocked(@NonNull IBinder token, @NonNull String actionId,
288 @Nullable Bundle arguments, int taskId, IBinder assistToken,
289 @Nullable RemoteCallback cancellationCallback,
290 @NonNull RemoteCallback resultCallback) {
291 if (mActiveSession == null || token != mActiveSession.mToken) {
292 Slog.w(TAG, "performDirectActionLocked does not match active session");
293 resultCallback.sendResult(null);
294 return;
295 }
296 final ActivityTokens tokens = LocalServices.getService(
297 ActivityTaskManagerInternal.class).getTopActivityForTask(taskId);
298 if (tokens == null || tokens.getAssistToken() != assistToken) {
299 Slog.w(TAG, "Unknown activity to perform a direct action");
300 resultCallback.sendResult(null);
301 } else {
302 try {
303 tokens.getApplicationThread().performDirectAction(tokens.getActivityToken(),
304 actionId, arguments, cancellationCallback,
305 resultCallback);
306 } catch (RemoteException e) {
307 Slog.w("Unexpected remote error", e);
308 resultCallback.sendResult(null);
309 }
310 }
311 }
312
Dianne Hackborn17f69352015-07-17 18:04:14 -0700313 public void setKeepAwakeLocked(IBinder token, boolean keepAwake) {
Dianne Hackborn3d07c942015-03-13 18:02:54 -0700314 try {
315 if (mActiveSession == null || token != mActiveSession.mToken) {
316 Slog.w(TAG, "setKeepAwake does not match active session");
317 return;
318 }
Wale Ogunwalef6733932018-06-27 05:14:34 -0700319 mAtm.setVoiceKeepAwake(mActiveSession.mSession, keepAwake);
Dianne Hackborn3d07c942015-03-13 18:02:54 -0700320 } catch (RemoteException e) {
321 throw new IllegalStateException("Unexpected remote error", e);
322 }
323 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700324
Dianne Hackborn17f69352015-07-17 18:04:14 -0700325 public void closeSystemDialogsLocked(IBinder token) {
Dianne Hackborn4e88bcd2015-07-01 13:41:03 -0700326 try {
327 if (mActiveSession == null || token != mActiveSession.mToken) {
328 Slog.w(TAG, "closeSystemDialogs does not match active session");
329 return;
330 }
331 mAm.closeSystemDialogs(CLOSE_REASON_VOICE_INTERACTION);
332 } catch (RemoteException e) {
333 throw new IllegalStateException("Unexpected remote error", e);
334 }
335 }
336
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800337 public void finishLocked(IBinder token, boolean finishTask) {
338 if (mActiveSession == null || (!finishTask && token != mActiveSession.mToken)) {
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700339 Slog.w(TAG, "finish does not match active session");
340 return;
341 }
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800342 mActiveSession.cancelLocked(finishTask);
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700343 mActiveSession = null;
344 }
345
Dianne Hackborn17f69352015-07-17 18:04:14 -0700346 public void setDisabledShowContextLocked(int callingUid, int flags) {
Dianne Hackborn1de11862015-07-15 14:20:51 -0700347 int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
348 if (callingUid != activeUid) {
349 throw new SecurityException("Calling uid " + callingUid
350 + " does not match active uid " + activeUid);
351 }
352 mDisabledShowContext = flags;
353 }
354
Dianne Hackborn17f69352015-07-17 18:04:14 -0700355 public int getDisabledShowContextLocked(int callingUid) {
Dianne Hackborn1de11862015-07-15 14:20:51 -0700356 int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
357 if (callingUid != activeUid) {
358 throw new SecurityException("Calling uid " + callingUid
359 + " does not match active uid " + activeUid);
360 }
361 return mDisabledShowContext;
362 }
363
Dianne Hackborn17f69352015-07-17 18:04:14 -0700364 public int getUserDisabledShowContextLocked(int callingUid) {
365 int activeUid = mInfo.getServiceInfo().applicationInfo.uid;
366 if (callingUid != activeUid) {
367 throw new SecurityException("Calling uid " + callingUid
368 + " does not match active uid " + activeUid);
369 }
370 return mActiveSession != null ? mActiveSession.getUserDisabledShowContextLocked() : 0;
371 }
372
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800373 public boolean supportsLocalVoiceInteraction() {
374 return mInfo.getSupportsLocalInteraction();
375 }
376
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700377 public void dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args) {
378 if (!mValid) {
379 pw.print(" NOT VALID: ");
380 if (mInfo == null) {
381 pw.println("no info");
382 } else {
383 pw.println(mInfo.getParseError());
384 }
385 return;
386 }
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700387 pw.print(" mUser="); pw.println(mUser);
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700388 pw.print(" mComponent="); pw.println(mComponent.flattenToShortString());
389 pw.print(" Session service="); pw.println(mInfo.getSessionService());
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700390 pw.println(" Service info:");
391 mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), " ");
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700392 pw.print(" Recognition service="); pw.println(mInfo.getRecognitionService());
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700393 pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity());
Dianne Hackborn958b9d22015-10-09 16:09:25 -0700394 pw.print(" Supports assist="); pw.println(mInfo.getSupportsAssist());
395 pw.print(" Supports launch from keyguard=");
396 pw.println(mInfo.getSupportsLaunchFromKeyguard());
Dianne Hackborn1de11862015-07-15 14:20:51 -0700397 if (mDisabledShowContext != 0) {
398 pw.print(" mDisabledShowContext=");
399 pw.println(Integer.toHexString(mDisabledShowContext));
400 }
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700401 pw.print(" mBound="); pw.print(mBound); pw.print(" mService="); pw.println(mService);
402 if (mActiveSession != null) {
403 pw.println(" Active session:");
404 mActiveSession.dump(" ", pw);
405 }
406 }
407
Dianne Hackborn91097de2014-04-04 18:02:06 -0700408 void startLocked() {
409 Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
410 intent.setComponent(mComponent);
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700411 mBound = mContext.bindServiceAsUser(intent, mConnection,
Michal Karpinskie069b002019-03-07 16:15:14 +0000412 Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
Amith Yamasanic45a9902019-04-05 16:29:30 -0700413 | Context.BIND_INCLUDE_CAPABILITIES
Michal Karpinskie069b002019-03-07 16:15:14 +0000414 | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
Dianne Hackborn18f0d352014-04-25 17:06:18 -0700415 if (!mBound) {
416 Slog.w(TAG, "Failed binding to voice interaction service " + mComponent);
417 }
Dianne Hackborn91097de2014-04-04 18:02:06 -0700418 }
419
Selim Cineke70d6532015-04-24 16:46:13 -0700420 public void launchVoiceAssistFromKeyguard() {
421 if (mService == null) {
422 Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
423 return;
424 }
425 try {
426 mService.launchVoiceAssistFromKeyguard();
427 } catch (RemoteException e) {
428 Slog.w(TAG, "RemoteException while calling launchVoiceAssistFromKeyguard", e);
429 }
430 }
431
Dianne Hackborn91097de2014-04-04 18:02:06 -0700432 void shutdownLocked() {
James Cook496767c2015-05-22 15:52:29 -0700433 // If there is an active session, cancel it to allow it to clean up its window and other
434 // state.
435 if (mActiveSession != null) {
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800436 mActiveSession.cancelLocked(false);
James Cook496767c2015-05-22 15:52:29 -0700437 mActiveSession = null;
438 }
Sandeep Siddhartha8ef360f2014-07-28 16:40:11 -0700439 try {
440 if (mService != null) {
441 mService.shutdown();
442 }
443 } catch (RemoteException e) {
444 Slog.w(TAG, "RemoteException in shutdown", e);
445 }
446
Dianne Hackborn91097de2014-04-04 18:02:06 -0700447 if (mBound) {
448 mContext.unbindService(mConnection);
449 mBound = false;
450 }
Dianne Hackbornc03c9162014-05-02 10:45:59 -0700451 if (mValid) {
452 mContext.unregisterReceiver(mBroadcastReceiver);
453 }
Dianne Hackborn91097de2014-04-04 18:02:06 -0700454 }
Sandeep Siddhartha6daae962014-07-21 10:31:34 -0700455
456 void notifySoundModelsChangedLocked() {
457 if (mService == null) {
458 Slog.w(TAG, "Not bound to voice interaction service " + mComponent);
Selim Cineke70d6532015-04-24 16:46:13 -0700459 return;
Sandeep Siddhartha6daae962014-07-21 10:31:34 -0700460 }
461 try {
462 mService.soundModelsChanged();
463 } catch (RemoteException e) {
464 Slog.w(TAG, "RemoteException while calling soundModelsChanged", e);
465 }
466 }
Dianne Hackbornffeecb12015-02-25 11:08:11 -0800467
468 @Override
469 public void sessionConnectionGone(VoiceInteractionSessionConnection connection) {
Annie Chind953ab62016-07-07 11:57:33 -0700470 synchronized (mServiceStub) {
Amith Yamasani0af6fa72016-01-17 15:36:19 -0800471 finishLocked(connection.mToken, false);
Dianne Hackbornffeecb12015-02-25 11:08:11 -0800472 }
473 }
Annie Chinecb9f3e2016-06-27 16:01:52 -0700474
475 @Override
476 public void onSessionShown(VoiceInteractionSessionConnection connection) {
Annie Chind953ab62016-07-07 11:57:33 -0700477 mServiceStub.onSessionShown();
Annie Chinecb9f3e2016-06-27 16:01:52 -0700478 }
479
480 @Override
481 public void onSessionHidden(VoiceInteractionSessionConnection connection) {
Annie Chind953ab62016-07-07 11:57:33 -0700482 mServiceStub.onSessionHidden();
Annie Chinecb9f3e2016-06-27 16:01:52 -0700483 }
Dianne Hackborn91097de2014-04-04 18:02:06 -0700484}