blob: 4f742843eb124a82a28a9faf31d706abbd73d1af [file] [log] [blame]
Adrian Roose9175082015-06-15 13:23:14 -07001/*
2 * Copyright (C) 2015 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.internal.app;
18
Adrian Roos2335bd62016-08-11 15:42:40 -070019import com.android.internal.R;
20
Adrian Roose9175082015-06-15 13:23:14 -070021import android.app.SearchManager;
22import android.content.ComponentName;
23import android.content.Context;
24import android.content.Intent;
Adrian Roos2335bd62016-08-11 15:42:40 -070025import android.content.pm.ApplicationInfo;
Jorim Jaggi165ce062015-07-06 16:18:11 -070026import android.content.pm.PackageManager;
27import android.content.pm.ResolveInfo;
28import android.os.Bundle;
Dianne Hackborn17f69352015-07-17 18:04:14 -070029import android.os.IBinder;
Adrian Roose9175082015-06-15 13:23:14 -070030import android.os.RemoteException;
31import android.os.ServiceManager;
32import android.provider.Settings;
33import android.util.Log;
34
35/**
36 * Utility method for dealing with the assistant aspects of
37 * {@link com.android.internal.app.IVoiceInteractionManagerService IVoiceInteractionManagerService}.
38 */
39public class AssistUtils {
40
41 private static final String TAG = "AssistUtils";
42
43 private final Context mContext;
44 private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
45
46 public AssistUtils(Context context) {
47 mContext = context;
48 mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface(
49 ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE));
50 }
51
Dianne Hackborn17f69352015-07-17 18:04:14 -070052 public boolean showSessionForActiveService(Bundle args, int sourceFlags,
53 IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
Adrian Roose9175082015-06-15 13:23:14 -070054 try {
Jorim Jaggie446dce2015-07-20 14:44:55 -070055 if (mVoiceInteractionManagerService != null) {
56 return mVoiceInteractionManagerService.showSessionForActiveService(args,
57 sourceFlags, showCallback, activityToken);
58 }
Adrian Roose9175082015-06-15 13:23:14 -070059 } catch (RemoteException e) {
60 Log.w(TAG, "Failed to call showSessionForActiveService", e);
61 }
Dianne Hackborn17f69352015-07-17 18:04:14 -070062 return false;
Adrian Roose9175082015-06-15 13:23:14 -070063 }
64
65 public void launchVoiceAssistFromKeyguard() {
66 try {
Jorim Jaggie446dce2015-07-20 14:44:55 -070067 if (mVoiceInteractionManagerService != null) {
68 mVoiceInteractionManagerService.launchVoiceAssistFromKeyguard();
69 }
Adrian Roose9175082015-06-15 13:23:14 -070070 } catch (RemoteException e) {
71 Log.w(TAG, "Failed to call launchVoiceAssistFromKeyguard", e);
72 }
73 }
74
75 public boolean activeServiceSupportsAssistGesture() {
76 try {
77 return mVoiceInteractionManagerService != null
78 && mVoiceInteractionManagerService.activeServiceSupportsAssist();
79 } catch (RemoteException e) {
80 Log.w(TAG, "Failed to call activeServiceSupportsAssistGesture", e);
81 return false;
82 }
83 }
84
85 public boolean activeServiceSupportsLaunchFromKeyguard() {
86 try {
87 return mVoiceInteractionManagerService != null
88 && mVoiceInteractionManagerService.activeServiceSupportsLaunchFromKeyguard();
89 } catch (RemoteException e) {
90 Log.w(TAG, "Failed to call activeServiceSupportsLaunchFromKeyguard", e);
91 return false;
92 }
93 }
94
95 public ComponentName getActiveServiceComponentName() {
96 try {
Jorim Jaggie446dce2015-07-20 14:44:55 -070097 if (mVoiceInteractionManagerService != null) {
98 return mVoiceInteractionManagerService.getActiveServiceComponentName();
99 } else {
100 return null;
101 }
Adrian Roose9175082015-06-15 13:23:14 -0700102 } catch (RemoteException e) {
103 Log.w(TAG, "Failed to call getActiveServiceComponentName", e);
104 return null;
105 }
106 }
107
108 public boolean isSessionRunning() {
109 try {
110 return mVoiceInteractionManagerService != null
111 && mVoiceInteractionManagerService.isSessionRunning();
112 } catch (RemoteException e) {
113 Log.w(TAG, "Failed to call isSessionRunning", e);
114 return false;
115 }
116 }
117
118 public void hideCurrentSession() {
119 try {
Jorim Jaggie446dce2015-07-20 14:44:55 -0700120 if (mVoiceInteractionManagerService != null) {
121 mVoiceInteractionManagerService.hideCurrentSession();
122 }
Adrian Roose9175082015-06-15 13:23:14 -0700123 } catch (RemoteException e) {
124 Log.w(TAG, "Failed to call hideCurrentSession", e);
125 }
126 }
127
Jorim Jaggi19695d92015-07-20 15:51:40 -0700128 public void onLockscreenShown() {
129 try {
130 if (mVoiceInteractionManagerService != null) {
131 mVoiceInteractionManagerService.onLockscreenShown();
132 }
133 } catch (RemoteException e) {
134 Log.w(TAG, "Failed to call onLockscreenShown", e);
135 }
136 }
137
Annie Chinecb9f3e2016-06-27 16:01:52 -0700138 public void registerVoiceInteractionSessionListener(IVoiceInteractionSessionListener listener) {
139 try {
140 if (mVoiceInteractionManagerService != null) {
141 mVoiceInteractionManagerService.registerVoiceInteractionSessionListener(listener);
142 }
143 } catch (RemoteException e) {
144 Log.w(TAG, "Failed to register voice interaction listener", e);
145 }
146 }
147
Adrian Roose9175082015-06-15 13:23:14 -0700148 public ComponentName getAssistComponentForUser(int userId) {
149 final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
150 Settings.Secure.ASSISTANT, userId);
151 if (setting != null) {
152 return ComponentName.unflattenFromString(setting);
153 }
154
Steve Elliott730d1d52018-09-25 15:23:38 +0000155 final String defaultSetting = mContext.getResources().getString(
156 R.string.config_defaultAssistantComponentName);
157 if (defaultSetting != null) {
158 return ComponentName.unflattenFromString(defaultSetting);
159 }
160
Adrian Roose9175082015-06-15 13:23:14 -0700161 // Fallback to keep backward compatible behavior when there is no user setting.
162 if (activeServiceSupportsAssistGesture()) {
163 return getActiveServiceComponentName();
164 }
Steven Wu3aa2cf72018-05-25 15:20:10 -0400165 final SearchManager searchManager =
166 (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
167 if (searchManager == null) {
168 return null;
169 }
170 final Intent intent = searchManager.getAssistIntent(false);
Jorim Jaggi165ce062015-07-06 16:18:11 -0700171 PackageManager pm = mContext.getPackageManager();
172 ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_DEFAULT_ONLY,
173 userId);
174 if (info != null) {
175 return new ComponentName(info.activityInfo.applicationInfo.packageName,
176 info.activityInfo.name);
Adrian Roose9175082015-06-15 13:23:14 -0700177 }
Adrian Roose9175082015-06-15 13:23:14 -0700178 return null;
179 }
180
Adrian Roos2335bd62016-08-11 15:42:40 -0700181 public static boolean isPreinstalledAssistant(Context context, ComponentName assistant) {
182 if (assistant == null) {
183 return false;
184 }
185 ApplicationInfo applicationInfo;
186 try {
187 applicationInfo = context.getPackageManager().getApplicationInfo(
188 assistant.getPackageName(), 0);
189 } catch (PackageManager.NameNotFoundException e) {
190 return false;
191 }
192 return applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp();
193 }
194
195 private static boolean isDisclosureEnabled(Context context) {
196 return Settings.Secure.getInt(context.getContentResolver(),
197 Settings.Secure.ASSIST_DISCLOSURE_ENABLED, 0) != 0;
198 }
199
200 /**
201 * @return if the disclosure animation should trigger for the given assistant.
202 *
203 * Third-party assistants will always need to disclose, while the user can configure this for
204 * pre-installed assistants.
205 */
206 public static boolean shouldDisclose(Context context, ComponentName assistant) {
207 if (!allowDisablingAssistDisclosure(context)) {
208 return true;
209 }
210
211 return isDisclosureEnabled(context) || !isPreinstalledAssistant(context, assistant);
212 }
213
214 public static boolean allowDisablingAssistDisclosure(Context context) {
215 return context.getResources().getBoolean(
216 com.android.internal.R.bool.config_allowDisablingAssistDisclosure);
217 }
Adrian Roose9175082015-06-15 13:23:14 -0700218}