1 /* 2 * Copyright (C) 2020 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.systemui.car.systembar; 18 19 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE; 20 21 import android.app.role.RoleManager; 22 import android.content.Context; 23 import android.content.res.TypedArray; 24 import android.os.Bundle; 25 import android.os.RemoteException; 26 import android.util.AttributeSet; 27 import android.util.Log; 28 29 import com.android.internal.app.AssistUtils; 30 import com.android.internal.app.IVoiceInteractionSessionListener; 31 import com.android.internal.app.IVoiceInteractionSessionShowCallback; 32 33 /** 34 * AssitantButton is a ui component that will trigger the Voice Interaction Service. 35 */ 36 public class AssitantButton extends CarSystemBarButton { 37 private static final String TAG = "AssistantButton"; 38 private final AssistUtils mAssistUtils; 39 private final IVoiceInteractionSessionShowCallback mShowCallback = 40 new IVoiceInteractionSessionShowCallback.Stub() { 41 @Override 42 public void onFailed() { 43 Log.w(TAG, "Failed to show VoiceInteractionSession"); 44 } 45 46 @Override 47 public void onShown() { 48 Log.d(TAG, "IVoiceInteractionSessionShowCallback onShown()"); 49 } 50 }; 51 AssitantButton(Context context, AttributeSet attrs)52 public AssitantButton(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 mAssistUtils = new AssistUtils(context); 55 setOnClickListener(v -> showAssistant()); 56 mAssistUtils.registerVoiceInteractionSessionListener( 57 new IVoiceInteractionSessionListener.Stub() { 58 @Override 59 public void onVoiceSessionShown() throws RemoteException { 60 assistantSetSelected(/* selected= */ true); 61 } 62 63 @Override 64 public void onVoiceSessionHidden() throws RemoteException { 65 assistantSetSelected(/* selected= */ false); 66 } 67 68 @Override 69 public void onSetUiHints(Bundle hints) { 70 } 71 } 72 ); 73 } 74 showAssistant()75 private void showAssistant() { 76 final Bundle args = new Bundle(); 77 mAssistUtils.showSessionForActiveService(args, 78 SHOW_SOURCE_ASSIST_GESTURE, mShowCallback, /*activityToken=*/ null); 79 } 80 81 @Override setUpIntents(TypedArray typedArray)82 protected void setUpIntents(TypedArray typedArray) { 83 // left blank because for the assistant button Intent will not be passed from the layout. 84 } 85 86 @Override getRoleName()87 protected String getRoleName() { 88 return RoleManager.ROLE_ASSISTANT; 89 } 90 91 @Override setSelected(boolean selected)92 public void setSelected(boolean selected) { 93 // override to no-op as AssistantButton will maintain its own selected state by listening to 94 // the actual voice interaction session. 95 } 96 assistantSetSelected(boolean selected)97 private void assistantSetSelected(boolean selected) { 98 if (hasSelectionState()) { 99 getContext().getMainExecutor().execute( 100 () -> AssitantButton.super.setSelected(selected)); 101 } 102 } 103 } 104