Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 1 | /* |
| 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 | |
| 17 | package com.android.server.voiceinteraction; |
| 18 | |
Winson Chung | fc3ec4c | 2017-06-01 15:35:48 -0700 | [diff] [blame] | 19 | import static android.app.ActivityManager.START_ASSISTANT_HIDDEN_SESSION; |
| 20 | import static android.app.ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION; |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 21 | import static android.app.ActivityManager.START_VOICE_HIDDEN_SESSION; |
| 22 | import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION; |
Wale Ogunwale | 0568aed | 2017-09-08 13:29:37 -0700 | [diff] [blame] | 23 | import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 24 | |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 25 | import android.annotation.NonNull; |
| 26 | import android.annotation.Nullable; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 27 | import android.app.ActivityManager; |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 28 | import android.app.ActivityOptions; |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 29 | import android.app.ActivityTaskManager; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 30 | import android.app.IActivityManager; |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 31 | import android.app.IActivityTaskManager; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 32 | import android.content.BroadcastReceiver; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 33 | import android.content.ComponentName; |
| 34 | import android.content.Context; |
| 35 | import android.content.Intent; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 36 | import android.content.IntentFilter; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 37 | import android.content.ServiceConnection; |
| 38 | import android.content.pm.PackageManager; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 39 | import android.os.Bundle; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 40 | import android.os.Handler; |
| 41 | import android.os.IBinder; |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 42 | import android.os.RemoteCallback; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 43 | import android.os.RemoteException; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 44 | import android.os.ServiceManager; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 45 | import android.os.UserHandle; |
| 46 | import android.service.voice.IVoiceInteractionService; |
| 47 | import android.service.voice.IVoiceInteractionSession; |
| 48 | import android.service.voice.VoiceInteractionService; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 49 | import android.service.voice.VoiceInteractionServiceInfo; |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 50 | import android.util.PrintWriterPrinter; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 51 | import android.util.Slog; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 52 | import android.view.IWindowManager; |
Sandeep | d701820 | 2014-07-10 15:15:39 -0700 | [diff] [blame] | 53 | |
Amith Yamasani | c45a990 | 2019-04-05 16:29:30 -0700 | [diff] [blame] | 54 | import com.android.internal.app.IVoiceActionCheckCallback; |
Jorim Jaggi | 225d3b5 | 2015-04-01 11:18:57 -0700 | [diff] [blame] | 55 | import com.android.internal.app.IVoiceInteractionSessionShowCallback; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 56 | import com.android.internal.app.IVoiceInteractor; |
Amith Yamasani | e8222e5 | 2016-04-08 15:28:47 -0700 | [diff] [blame] | 57 | import com.android.server.LocalServices; |
Amith Yamasani | c45a990 | 2019-04-05 16:29:30 -0700 | [diff] [blame] | 58 | import com.android.server.wm.ActivityTaskManagerInternal; |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 59 | import com.android.server.wm.ActivityTaskManagerInternal.ActivityTokens; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 60 | |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 61 | import java.io.FileDescriptor; |
| 62 | import java.io.PrintWriter; |
Winson Chung | da2818f | 2017-10-23 16:25:49 -0700 | [diff] [blame] | 63 | import java.util.ArrayList; |
Amith Yamasani | e8222e5 | 2016-04-08 15:28:47 -0700 | [diff] [blame] | 64 | import java.util.List; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 65 | |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 66 | class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback { |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 67 | final static String TAG = "VoiceInteractionServiceManager"; |
| 68 | |
Dianne Hackborn | 4e88bcd | 2015-07-01 13:41:03 -0700 | [diff] [blame] | 69 | final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction"; |
| 70 | |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 71 | final boolean mValid; |
| 72 | |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 73 | final Context mContext; |
| 74 | final Handler mHandler; |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 75 | final VoiceInteractionManagerService.VoiceInteractionManagerServiceStub mServiceStub; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 76 | final int mUser; |
| 77 | final ComponentName mComponent; |
| 78 | final IActivityManager mAm; |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 79 | final IActivityTaskManager mAtm; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 80 | final VoiceInteractionServiceInfo mInfo; |
| 81 | final ComponentName mSessionComponentName; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 82 | final IWindowManager mIWindowManager; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 83 | boolean mBound = false; |
| 84 | IVoiceInteractionService mService; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 85 | |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 86 | VoiceInteractionSessionConnection mActiveSession; |
Dianne Hackborn | 1de1186 | 2015-07-15 14:20:51 -0700 | [diff] [blame] | 87 | int mDisabledShowContext; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 88 | |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 89 | 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 Hackborn | 4e88bcd | 2015-07-01 13:41:03 -0700 | [diff] [blame] | 93 | String reason = intent.getStringExtra("reason"); |
Dianne Hackborn | 57dd737 | 2015-07-27 18:11:14 -0700 | [diff] [blame] | 94 | if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason) && !"dream".equals(reason)) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 95 | synchronized (mServiceStub) { |
Dianne Hackborn | 4e88bcd | 2015-07-01 13:41:03 -0700 | [diff] [blame] | 96 | if (mActiveSession != null && mActiveSession.mSession != null) { |
| 97 | try { |
| 98 | mActiveSession.mSession.closeSystemDialogs(); |
| 99 | } catch (RemoteException e) { |
| 100 | } |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 101 | } |
| 102 | } |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | }; |
| 107 | |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 108 | final ServiceConnection mConnection = new ServiceConnection() { |
| 109 | @Override |
| 110 | public void onServiceConnected(ComponentName name, IBinder service) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 111 | synchronized (mServiceStub) { |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 112 | mService = IVoiceInteractionService.Stub.asInterface(service); |
Dianne Hackborn | fee756f | 2014-07-16 17:31:10 -0700 | [diff] [blame] | 113 | try { |
| 114 | mService.ready(); |
| 115 | } catch (RemoteException e) { |
| 116 | } |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 117 | } |
| 118 | } |
| 119 | |
| 120 | @Override |
| 121 | public void onServiceDisconnected(ComponentName name) { |
| 122 | mService = null; |
| 123 | } |
| 124 | }; |
| 125 | |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 126 | VoiceInteractionManagerServiceImpl(Context context, Handler handler, |
| 127 | VoiceInteractionManagerService.VoiceInteractionManagerServiceStub stub, |
Felipe Leme | d9b98da | 2019-05-21 17:54:18 -0700 | [diff] [blame] | 128 | int userHandle, ComponentName service) { |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 129 | mContext = context; |
| 130 | mHandler = handler; |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 131 | mServiceStub = stub; |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 132 | mUser = userHandle; |
| 133 | mComponent = service; |
Sudheer Shanka | dc589ac | 2016-11-10 15:30:17 -0800 | [diff] [blame] | 134 | mAm = ActivityManager.getService(); |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 135 | mAtm = ActivityTaskManager.getService(); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 136 | VoiceInteractionServiceInfo info; |
| 137 | try { |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 138 | info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser); |
Dianne Hackborn | c83189b | 2015-11-16 18:07:35 -0800 | [diff] [blame] | 139 | } catch (PackageManager.NameNotFoundException e) { |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 140 | Slog.w(TAG, "Voice interaction service not found: " + service, e); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 141 | mInfo = null; |
| 142 | mSessionComponentName = null; |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 143 | mIWindowManager = null; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 144 | 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 Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 151 | mIWindowManager = null; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 152 | mValid = false; |
| 153 | return; |
| 154 | } |
| 155 | mValid = true; |
| 156 | mSessionComponentName = new ComponentName(service.getPackageName(), |
| 157 | mInfo.getSessionService()); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 158 | 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 Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 163 | } |
| 164 | |
Jorim Jaggi | b09f8e2 | 2015-04-15 15:11:48 -0700 | [diff] [blame] | 165 | public boolean showSessionLocked(Bundle args, int flags, |
Dianne Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 166 | IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) { |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 167 | if (mActiveSession == null) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 168 | mActiveSession = new VoiceInteractionSessionConnection(mServiceStub, |
| 169 | mSessionComponentName, mUser, mContext, this, |
Felipe Leme | d9b98da | 2019-05-21 17:54:18 -0700 | [diff] [blame] | 170 | mInfo.getServiceInfo().applicationInfo.uid, mHandler); |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 171 | } |
Amith Yamasani | e8222e5 | 2016-04-08 15:28:47 -0700 | [diff] [blame] | 172 | List<IBinder> activityTokens = null; |
Winson Chung | da2818f | 2017-10-23 16:25:49 -0700 | [diff] [blame] | 173 | if (activityToken != null) { |
| 174 | activityTokens = new ArrayList<>(); |
| 175 | activityTokens.add(activityToken); |
| 176 | } else { |
Amith Yamasani | e8222e5 | 2016-04-08 15:28:47 -0700 | [diff] [blame] | 177 | // Let's get top activities from all visible stacks |
Wale Ogunwale | 6767eae | 2018-05-03 15:52:51 -0700 | [diff] [blame] | 178 | activityTokens = LocalServices.getService(ActivityTaskManagerInternal.class) |
Amith Yamasani | e8222e5 | 2016-04-08 15:28:47 -0700 | [diff] [blame] | 179 | .getTopVisibleActivities(); |
| 180 | } |
Dianne Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 181 | return mActiveSession.showLocked(args, flags, mDisabledShowContext, showCallback, |
Winson Chung | da2818f | 2017-10-23 16:25:49 -0700 | [diff] [blame] | 182 | activityTokens); |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 183 | } |
| 184 | |
jiayuzhou | 21a353b | 2018-08-16 16:09:43 -0700 | [diff] [blame] | 185 | 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 Jaggi | b835dd7 | 2015-06-08 12:28:42 -0700 | [diff] [blame] | 202 | public boolean hideSessionLocked() { |
Dianne Hackborn | d59a5d5 | 2015-04-04 14:52:14 -0700 | [diff] [blame] | 203 | if (mActiveSession != null) { |
| 204 | return mActiveSession.hideLocked(); |
| 205 | } |
| 206 | return false; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 207 | } |
| 208 | |
Dianne Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 209 | public boolean deliverNewSessionLocked(IBinder token, |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 210 | IVoiceInteractionSession session, IVoiceInteractor interactor) { |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 211 | if (mActiveSession == null || token != mActiveSession.mToken) { |
| 212 | Slog.w(TAG, "deliverNewSession does not match active session"); |
| 213 | return false; |
| 214 | } |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 215 | mActiveSession.deliverNewSessionLocked(session, interactor); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 216 | return true; |
| 217 | } |
| 218 | |
Philip P. Moltmann | 9c5226f | 2020-01-10 08:53:43 -0800 | [diff] [blame^] | 219 | public int startVoiceActivityLocked(@Nullable String callingFeatureId, int callingPid, |
| 220 | int callingUid, IBinder token, Intent intent, String resolvedType) { |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 221 | try { |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 222 | if (mActiveSession == null || token != mActiveSession.mToken) { |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 223 | Slog.w(TAG, "startVoiceActivity does not match active session"); |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 224 | return START_VOICE_NOT_ACTIVE_SESSION; |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 225 | } |
Dianne Hackborn | d59a5d5 | 2015-04-04 14:52:14 -0700 | [diff] [blame] | 226 | if (!mActiveSession.mShown) { |
| 227 | Slog.w(TAG, "startVoiceActivity not allowed on hidden session"); |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 228 | return START_VOICE_HIDDEN_SESSION; |
Dianne Hackborn | d59a5d5 | 2015-04-04 14:52:14 -0700 | [diff] [blame] | 229 | } |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 230 | 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. Moltmann | 9c5226f | 2020-01-10 08:53:43 -0800 | [diff] [blame^] | 233 | return mAtm.startVoiceActivity(mComponent.getPackageName(), callingFeatureId, |
| 234 | callingPid, callingUid, intent, resolvedType, mActiveSession.mSession, |
| 235 | mActiveSession.mInteractor, 0, null, null, mUser); |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 236 | } catch (RemoteException e) { |
| 237 | throw new IllegalStateException("Unexpected remote error", e); |
| 238 | } |
| 239 | } |
| 240 | |
Philip P. Moltmann | 9c5226f | 2020-01-10 08:53:43 -0800 | [diff] [blame^] | 241 | public int startAssistantActivityLocked(@Nullable String callingFeatureId, int callingPid, |
| 242 | int callingUid, IBinder token, Intent intent, String resolvedType) { |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 243 | try { |
| 244 | if (mActiveSession == null || token != mActiveSession.mToken) { |
| 245 | Slog.w(TAG, "startAssistantActivity does not match active session"); |
Winson Chung | fc3ec4c | 2017-06-01 15:35:48 -0700 | [diff] [blame] | 246 | return START_ASSISTANT_NOT_ACTIVE_SESSION; |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 247 | } |
| 248 | if (!mActiveSession.mShown) { |
| 249 | Slog.w(TAG, "startAssistantActivity not allowed on hidden session"); |
Winson Chung | fc3ec4c | 2017-06-01 15:35:48 -0700 | [diff] [blame] | 250 | return START_ASSISTANT_HIDDEN_SESSION; |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 251 | } |
| 252 | intent = new Intent(intent); |
| 253 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
Wale Ogunwale | 0568aed | 2017-09-08 13:29:37 -0700 | [diff] [blame] | 254 | final ActivityOptions options = ActivityOptions.makeBasic(); |
| 255 | options.setLaunchActivityType(ACTIVITY_TYPE_ASSISTANT); |
Philip P. Moltmann | 9c5226f | 2020-01-10 08:53:43 -0800 | [diff] [blame^] | 256 | return mAtm.startAssistantActivity(mComponent.getPackageName(), callingFeatureId, |
| 257 | callingPid, callingUid, intent, resolvedType, options.toBundle(), mUser); |
Winson Chung | 8347163 | 2016-12-13 11:02:12 -0800 | [diff] [blame] | 258 | } catch (RemoteException e) { |
| 259 | throw new IllegalStateException("Unexpected remote error", e); |
| 260 | } |
| 261 | } |
| 262 | |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 263 | public void requestDirectActionsLocked(@NonNull IBinder token, int taskId, |
Svet Ganov | 3b6be08 | 2019-04-28 10:21:01 -0700 | [diff] [blame] | 264 | @NonNull IBinder assistToken, @Nullable RemoteCallback cancellationCallback, |
| 265 | @NonNull RemoteCallback callback) { |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 266 | 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 Ganov | 3b6be08 | 2019-04-28 10:21:01 -0700 | [diff] [blame] | 279 | mActiveSession.mInteractor, cancellationCallback, callback); |
Sunny Goyal | d40c345 | 2019-03-20 12:46:55 -0700 | [diff] [blame] | 280 | } 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 Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 313 | public void setKeepAwakeLocked(IBinder token, boolean keepAwake) { |
Dianne Hackborn | 3d07c94 | 2015-03-13 18:02:54 -0700 | [diff] [blame] | 314 | try { |
| 315 | if (mActiveSession == null || token != mActiveSession.mToken) { |
| 316 | Slog.w(TAG, "setKeepAwake does not match active session"); |
| 317 | return; |
| 318 | } |
Wale Ogunwale | f673393 | 2018-06-27 05:14:34 -0700 | [diff] [blame] | 319 | mAtm.setVoiceKeepAwake(mActiveSession.mSession, keepAwake); |
Dianne Hackborn | 3d07c94 | 2015-03-13 18:02:54 -0700 | [diff] [blame] | 320 | } catch (RemoteException e) { |
| 321 | throw new IllegalStateException("Unexpected remote error", e); |
| 322 | } |
| 323 | } |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 324 | |
Dianne Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 325 | public void closeSystemDialogsLocked(IBinder token) { |
Dianne Hackborn | 4e88bcd | 2015-07-01 13:41:03 -0700 | [diff] [blame] | 326 | 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 Yamasani | 0af6fa7 | 2016-01-17 15:36:19 -0800 | [diff] [blame] | 337 | public void finishLocked(IBinder token, boolean finishTask) { |
| 338 | if (mActiveSession == null || (!finishTask && token != mActiveSession.mToken)) { |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 339 | Slog.w(TAG, "finish does not match active session"); |
| 340 | return; |
| 341 | } |
Amith Yamasani | 0af6fa7 | 2016-01-17 15:36:19 -0800 | [diff] [blame] | 342 | mActiveSession.cancelLocked(finishTask); |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 343 | mActiveSession = null; |
| 344 | } |
| 345 | |
Dianne Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 346 | public void setDisabledShowContextLocked(int callingUid, int flags) { |
Dianne Hackborn | 1de1186 | 2015-07-15 14:20:51 -0700 | [diff] [blame] | 347 | 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 Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 355 | public int getDisabledShowContextLocked(int callingUid) { |
Dianne Hackborn | 1de1186 | 2015-07-15 14:20:51 -0700 | [diff] [blame] | 356 | 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 Hackborn | 17f6935 | 2015-07-17 18:04:14 -0700 | [diff] [blame] | 364 | 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 Yamasani | 0af6fa7 | 2016-01-17 15:36:19 -0800 | [diff] [blame] | 373 | public boolean supportsLocalVoiceInteraction() { |
| 374 | return mInfo.getSupportsLocalInteraction(); |
| 375 | } |
| 376 | |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 377 | 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 Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 387 | pw.print(" mUser="); pw.println(mUser); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 388 | pw.print(" mComponent="); pw.println(mComponent.flattenToShortString()); |
| 389 | pw.print(" Session service="); pw.println(mInfo.getSessionService()); |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 390 | pw.println(" Service info:"); |
| 391 | mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), " "); |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 392 | pw.print(" Recognition service="); pw.println(mInfo.getRecognitionService()); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 393 | pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity()); |
Dianne Hackborn | 958b9d2 | 2015-10-09 16:09:25 -0700 | [diff] [blame] | 394 | pw.print(" Supports assist="); pw.println(mInfo.getSupportsAssist()); |
| 395 | pw.print(" Supports launch from keyguard="); |
| 396 | pw.println(mInfo.getSupportsLaunchFromKeyguard()); |
Dianne Hackborn | 1de1186 | 2015-07-15 14:20:51 -0700 | [diff] [blame] | 397 | if (mDisabledShowContext != 0) { |
| 398 | pw.print(" mDisabledShowContext="); |
| 399 | pw.println(Integer.toHexString(mDisabledShowContext)); |
| 400 | } |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 401 | 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 Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 408 | void startLocked() { |
| 409 | Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE); |
| 410 | intent.setComponent(mComponent); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 411 | mBound = mContext.bindServiceAsUser(intent, mConnection, |
Michal Karpinski | e069b00 | 2019-03-07 16:15:14 +0000 | [diff] [blame] | 412 | Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE |
Amith Yamasani | c45a990 | 2019-04-05 16:29:30 -0700 | [diff] [blame] | 413 | | Context.BIND_INCLUDE_CAPABILITIES |
Michal Karpinski | e069b00 | 2019-03-07 16:15:14 +0000 | [diff] [blame] | 414 | | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser)); |
Dianne Hackborn | 18f0d35 | 2014-04-25 17:06:18 -0700 | [diff] [blame] | 415 | if (!mBound) { |
| 416 | Slog.w(TAG, "Failed binding to voice interaction service " + mComponent); |
| 417 | } |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 418 | } |
| 419 | |
Selim Cinek | e70d653 | 2015-04-24 16:46:13 -0700 | [diff] [blame] | 420 | 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 Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 432 | void shutdownLocked() { |
James Cook | 496767c | 2015-05-22 15:52:29 -0700 | [diff] [blame] | 433 | // 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 Yamasani | 0af6fa7 | 2016-01-17 15:36:19 -0800 | [diff] [blame] | 436 | mActiveSession.cancelLocked(false); |
James Cook | 496767c | 2015-05-22 15:52:29 -0700 | [diff] [blame] | 437 | mActiveSession = null; |
| 438 | } |
Sandeep Siddhartha | 8ef360f | 2014-07-28 16:40:11 -0700 | [diff] [blame] | 439 | try { |
| 440 | if (mService != null) { |
| 441 | mService.shutdown(); |
| 442 | } |
| 443 | } catch (RemoteException e) { |
| 444 | Slog.w(TAG, "RemoteException in shutdown", e); |
| 445 | } |
| 446 | |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 447 | if (mBound) { |
| 448 | mContext.unbindService(mConnection); |
| 449 | mBound = false; |
| 450 | } |
Dianne Hackborn | c03c916 | 2014-05-02 10:45:59 -0700 | [diff] [blame] | 451 | if (mValid) { |
| 452 | mContext.unregisterReceiver(mBroadcastReceiver); |
| 453 | } |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 454 | } |
Sandeep Siddhartha | 6daae96 | 2014-07-21 10:31:34 -0700 | [diff] [blame] | 455 | |
| 456 | void notifySoundModelsChangedLocked() { |
| 457 | if (mService == null) { |
| 458 | Slog.w(TAG, "Not bound to voice interaction service " + mComponent); |
Selim Cinek | e70d653 | 2015-04-24 16:46:13 -0700 | [diff] [blame] | 459 | return; |
Sandeep Siddhartha | 6daae96 | 2014-07-21 10:31:34 -0700 | [diff] [blame] | 460 | } |
| 461 | try { |
| 462 | mService.soundModelsChanged(); |
| 463 | } catch (RemoteException e) { |
| 464 | Slog.w(TAG, "RemoteException while calling soundModelsChanged", e); |
| 465 | } |
| 466 | } |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 467 | |
| 468 | @Override |
| 469 | public void sessionConnectionGone(VoiceInteractionSessionConnection connection) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 470 | synchronized (mServiceStub) { |
Amith Yamasani | 0af6fa7 | 2016-01-17 15:36:19 -0800 | [diff] [blame] | 471 | finishLocked(connection.mToken, false); |
Dianne Hackborn | ffeecb1 | 2015-02-25 11:08:11 -0800 | [diff] [blame] | 472 | } |
| 473 | } |
Annie Chin | ecb9f3e | 2016-06-27 16:01:52 -0700 | [diff] [blame] | 474 | |
| 475 | @Override |
| 476 | public void onSessionShown(VoiceInteractionSessionConnection connection) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 477 | mServiceStub.onSessionShown(); |
Annie Chin | ecb9f3e | 2016-06-27 16:01:52 -0700 | [diff] [blame] | 478 | } |
| 479 | |
| 480 | @Override |
| 481 | public void onSessionHidden(VoiceInteractionSessionConnection connection) { |
Annie Chin | d953ab6 | 2016-07-07 11:57:33 -0700 | [diff] [blame] | 482 | mServiceStub.onSessionHidden(); |
Annie Chin | ecb9f3e | 2016-06-27 16:01:52 -0700 | [diff] [blame] | 483 | } |
Dianne Hackborn | 91097de | 2014-04-04 18:02:06 -0700 | [diff] [blame] | 484 | } |