• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 android.car.builtin.util;
18 
19 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_PUSH_TO_TALK;
20 
21 import android.annotation.NonNull;
22 import android.annotation.SystemApi;
23 import android.app.ActivityManager;
24 import android.car.builtin.annotation.AddedIn;
25 import android.car.builtin.annotation.PlatformVersion;
26 import android.content.Context;
27 import android.os.Bundle;
28 import android.os.RemoteException;
29 
30 import com.android.internal.annotations.VisibleForTesting;
31 import com.android.internal.app.AssistUtils;
32 import com.android.internal.app.IVoiceInteractionSessionListener;
33 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
34 
35 import java.util.Objects;
36 
37 /**
38  * Class to wrap {@link AssistUtils}.
39  * @hide
40  */
41 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
42 public final class AssistUtilsHelper {
43 
44     private static final String TAG = AssistUtilsHelper.class.getSimpleName();
45 
46     @VisibleForTesting
47     @AddedIn(PlatformVersion.TIRAMISU_0)
48     static final String EXTRA_CAR_PUSH_TO_TALK =
49             "com.android.car.input.EXTRA_CAR_PUSH_TO_TALK";
50 
51     /**
52      * Determines if there is a voice interaction session running.
53      *
54      * @param context used to build the assist utils.
55      * @return {@code true} if a session is running, {@code false} otherwise.
56      */
57     @AddedIn(PlatformVersion.TIRAMISU_0)
isSessionRunning(@onNull Context context)58     public static boolean isSessionRunning(@NonNull Context context) {
59         AssistUtils assistUtils = getAssistUtils(context);
60 
61         return assistUtils.isSessionRunning();
62     }
63 
64     /**
65      * Hides the current voice interaction session running
66      *
67      * @param context used to build the assist utils.
68      */
69     @AddedIn(PlatformVersion.TIRAMISU_0)
hideCurrentSession(@onNull Context context)70     public static void hideCurrentSession(@NonNull Context context) {
71         AssistUtils assistUtils = getAssistUtils(context);
72 
73         assistUtils.hideCurrentSession();
74     }
75 
76     /**
77      * Registers a listener to monitor when the voice sessions are shown or hidden.
78      *
79      * @param context used to build the assist utils.
80      * @param sessionListener listener that will receive shown or hidden voice sessions callback.
81      */
82     // TODO(b/221604866) : Add unregister method
83     @AddedIn(PlatformVersion.TIRAMISU_0)
registerVoiceInteractionSessionListenerHelper(@onNull Context context, @NonNull VoiceInteractionSessionListenerHelper sessionListener)84     public static void registerVoiceInteractionSessionListenerHelper(@NonNull Context context,
85             @NonNull VoiceInteractionSessionListenerHelper sessionListener) {
86         Objects.requireNonNull(sessionListener, "Session listener must not be null.");
87 
88         AssistUtils assistUtils = getAssistUtils(context);
89 
90         assistUtils.registerVoiceInteractionSessionListener(
91                 new InternalVoiceInteractionSessionListener(sessionListener));
92     }
93 
94     /**
95      * Shows the {@link android.service.voice.VoiceInteractionSession.SHOW_SOURCE_PUSH_TO_TALK}
96      * session for active service, if the assistant component is active for the current user.
97      *
98      * @return whether the assistant component is active for the current user.
99      */
100     @AddedIn(PlatformVersion.TIRAMISU_0)
showPushToTalkSessionForActiveService(@onNull Context context, @NonNull VoiceInteractionSessionShowCallbackHelper callback)101     public static boolean showPushToTalkSessionForActiveService(@NonNull Context context,
102             @NonNull VoiceInteractionSessionShowCallbackHelper callback) {
103         Objects.requireNonNull(callback, "On shown callback must not be null.");
104 
105         AssistUtils assistUtils = getAssistUtils(context);
106         int currentUserId = ActivityManager.getCurrentUser();
107 
108 
109         if (assistUtils.getAssistComponentForUser(currentUserId) == null) {
110             Slogf.d(TAG, "showPushToTalkSessionForActiveService(): no component for user %d",
111                     currentUserId);
112             return false;
113         }
114 
115         Bundle args = new Bundle();
116         args.putBoolean(EXTRA_CAR_PUSH_TO_TALK, true);
117 
118         IVoiceInteractionSessionShowCallback callbackWrapper =
119                 new InternalVoiceInteractionSessionShowCallback(callback);
120 
121         return assistUtils.showSessionForActiveService(args, SHOW_SOURCE_PUSH_TO_TALK,
122                 callbackWrapper, /* activityToken= */ null);
123     }
124 
getAssistUtils(@onNull Context context)125     private static AssistUtils getAssistUtils(@NonNull Context context) {
126         Objects.requireNonNull(context, "Context must not be null.");
127         return new AssistUtils(context);
128     }
129 
130     /**
131      * See {@link IVoiceInteractionSessionShowCallback}
132      */
133     public interface VoiceInteractionSessionShowCallbackHelper {
134         /**
135          * See {@link IVoiceInteractionSessionShowCallback#onFailed()}
136          */
137         @AddedIn(PlatformVersion.TIRAMISU_1)
onFailed()138         void onFailed();
139 
140         /**
141          * See {@link IVoiceInteractionSessionShowCallback#onShow()}
142          */
143         @AddedIn(PlatformVersion.TIRAMISU_1)
onShown()144         void onShown();
145     }
146 
147     /**
148      * See {@link IVoiceInteractionSessionListener}
149      */
150     public interface VoiceInteractionSessionListenerHelper {
151 
152         /**
153          * See {@link IVoiceInteractionSessionListener#onVoiceSessionShown()}
154          */
155         @AddedIn(PlatformVersion.TIRAMISU_1)
onVoiceSessionShown()156         void onVoiceSessionShown();
157 
158         /**
159          * See {@link IVoiceInteractionSessionListener#onVoiceSessionHidden()}
160          */
161         @AddedIn(PlatformVersion.TIRAMISU_1)
onVoiceSessionHidden()162         void onVoiceSessionHidden();
163     }
164 
165     private static final class InternalVoiceInteractionSessionShowCallback extends
166             IVoiceInteractionSessionShowCallback.Stub {
167         private final VoiceInteractionSessionShowCallbackHelper mCallbackHelper;
168 
InternalVoiceInteractionSessionShowCallback( VoiceInteractionSessionShowCallbackHelper callbackHelper)169         InternalVoiceInteractionSessionShowCallback(
170                 VoiceInteractionSessionShowCallbackHelper callbackHelper) {
171             mCallbackHelper = callbackHelper;
172         }
173 
174         @Override
onFailed()175         public void onFailed() {
176             mCallbackHelper.onFailed();
177         }
178 
179         @Override
onShown()180         public void onShown() {
181             mCallbackHelper.onShown();
182         }
183     }
184 
185     private static final class InternalVoiceInteractionSessionListener extends
186             IVoiceInteractionSessionListener.Stub {
187 
188         private final VoiceInteractionSessionListenerHelper mListenerHelper;
189 
InternalVoiceInteractionSessionListener( VoiceInteractionSessionListenerHelper listenerHelper)190         InternalVoiceInteractionSessionListener(
191                 VoiceInteractionSessionListenerHelper listenerHelper) {
192             mListenerHelper = listenerHelper;
193         }
194 
195         @Override
onVoiceSessionShown()196         public void onVoiceSessionShown() throws RemoteException {
197             mListenerHelper.onVoiceSessionShown();
198         }
199 
200         @Override
onVoiceSessionHidden()201         public void onVoiceSessionHidden() throws RemoteException {
202             mListenerHelper.onVoiceSessionHidden();
203         }
204 
205         @Override
onSetUiHints(Bundle args)206         public void onSetUiHints(Bundle args) throws RemoteException {
207             Slogf.d(TAG, "onSetUiHints() not used");
208         }
209 
210         @Override
onVoiceSessionWindowVisibilityChanged(boolean visible)211         public void onVoiceSessionWindowVisibilityChanged(boolean visible)
212                 throws RemoteException {
213             Slogf.d(TAG, "onVoiceSessionWindowVisibilityChanged() not used");
214         }
215     }
216 
AssistUtilsHelper()217     private AssistUtilsHelper() {
218         throw new UnsupportedOperationException("contains only static members");
219     }
220 }
221