1 /* 2 * Copyright (C) 2019 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.car.settings.applications.assist; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.ComponentName; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.database.ContentObserver; 24 import android.net.Uri; 25 import android.os.Handler; 26 import android.os.Looper; 27 import android.provider.Settings; 28 29 import androidx.annotation.Nullable; 30 import androidx.annotation.VisibleForTesting; 31 32 import com.android.car.settings.applications.defaultapps.DefaultAppsPickerEntryBasePreferenceController; 33 import com.android.car.settings.common.FragmentController; 34 import com.android.internal.app.AssistUtils; 35 import com.android.settingslib.applications.DefaultAppInfo; 36 37 import java.util.Objects; 38 39 /** 40 * Business logic to show the currently selected default voice input service and also link to the 41 * service settings, if it exists. 42 */ 43 public class DefaultVoiceInputPickerEntryPreferenceController extends 44 DefaultAppsPickerEntryBasePreferenceController { 45 46 private static final Uri ASSIST_URI = Settings.Secure.getUriFor(Settings.Secure.ASSISTANT); 47 48 @VisibleForTesting 49 final ContentObserver mSettingObserver = new ContentObserver( 50 new Handler(Looper.getMainLooper())) { 51 @Override 52 public void onChange(boolean selfChange, Uri uri) { 53 super.onChange(selfChange, uri); 54 55 if (ASSIST_URI.equals(uri)) { 56 refreshUi(); 57 } 58 } 59 }; 60 61 private final VoiceInputInfoProvider mVoiceInputInfoProvider; 62 private final AssistUtils mAssistUtils; 63 DefaultVoiceInputPickerEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)64 public DefaultVoiceInputPickerEntryPreferenceController(Context context, String preferenceKey, 65 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 66 this(context, preferenceKey, fragmentController, uxRestrictions, 67 new VoiceInputInfoProvider(context), new AssistUtils(context)); 68 } 69 70 @VisibleForTesting DefaultVoiceInputPickerEntryPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, VoiceInputInfoProvider voiceInputInfoProvider, AssistUtils assistUtils)71 DefaultVoiceInputPickerEntryPreferenceController(Context context, String preferenceKey, 72 FragmentController fragmentController, CarUxRestrictions uxRestrictions, 73 VoiceInputInfoProvider voiceInputInfoProvider, AssistUtils assistUtils) { 74 super(context, preferenceKey, fragmentController, uxRestrictions); 75 mVoiceInputInfoProvider = voiceInputInfoProvider; 76 mAssistUtils = assistUtils; 77 } 78 79 @Override getAvailabilityStatus()80 protected int getAvailabilityStatus() { 81 ComponentName currentVoiceService = VoiceInputUtils.getCurrentService(getContext()); 82 ComponentName currentAssist = mAssistUtils.getAssistComponentForUser( 83 getCurrentProcessUserId()); 84 85 return Objects.equals(currentAssist, currentVoiceService) ? CONDITIONALLY_UNAVAILABLE 86 : AVAILABLE; 87 } 88 89 @Override onStartInternal()90 protected void onStartInternal() { 91 getContext().getContentResolver().registerContentObserver(ASSIST_URI, 92 /* notifyForDescendants= */ false, mSettingObserver); 93 } 94 95 @Override onStopInternal()96 protected void onStopInternal() { 97 getContext().getContentResolver().unregisterContentObserver(mSettingObserver); 98 } 99 100 @Nullable 101 @Override getCurrentDefaultAppInfo()102 protected DefaultAppInfo getCurrentDefaultAppInfo() { 103 VoiceInputInfoProvider.VoiceInputInfo info = mVoiceInputInfoProvider.getInfoForComponent( 104 VoiceInputUtils.getCurrentService(getContext())); 105 return (info == null) ? null : new DefaultVoiceInputServiceInfo(getContext(), 106 getContext().getPackageManager(), getCurrentProcessUserId(), info, 107 /* enabled= */ true); 108 } 109 110 @Nullable 111 @Override getSettingIntent(@ullable DefaultAppInfo info)112 protected Intent getSettingIntent(@Nullable DefaultAppInfo info) { 113 if (info instanceof DefaultVoiceInputServiceInfo) { 114 return ((DefaultVoiceInputServiceInfo) info).getSettingIntent(); 115 } 116 return null; 117 } 118 } 119