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 com.android.car.settings.privacy; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.hardware.SensorPrivacyManager; 22 23 import com.android.car.settings.common.FragmentController; 24 import com.android.car.settings.common.PreferenceController; 25 import com.android.car.ui.preference.CarUiTwoActionSwitchPreference; 26 import com.android.internal.annotations.VisibleForTesting; 27 28 /** Business logic for controlling the mute mic setting. */ 29 public class MuteMicTogglePreferenceController 30 extends PreferenceController<CarUiTwoActionSwitchPreference> { 31 32 private SensorPrivacyManager mSensorPrivacyManager; 33 34 private SensorPrivacyManager.OnSensorPrivacyChangedListener mListener = 35 new SensorPrivacyManager.OnSensorPrivacyChangedListener() { 36 @Override 37 public void onSensorPrivacyChanged(int sensor, boolean enabled) { 38 refreshUi(); 39 } 40 }; 41 MuteMicTogglePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)42 public MuteMicTogglePreferenceController(Context context, String preferenceKey, 43 FragmentController fragmentController, CarUxRestrictions uxRestrictions) { 44 this(context, preferenceKey, fragmentController, uxRestrictions, 45 SensorPrivacyManager.getInstance(context)); 46 } 47 48 @VisibleForTesting MuteMicTogglePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, SensorPrivacyManager sensorPrivacyManager)49 MuteMicTogglePreferenceController(Context context, String preferenceKey, 50 FragmentController fragmentController, CarUxRestrictions uxRestrictions, 51 SensorPrivacyManager sensorPrivacyManager) { 52 super(context, preferenceKey, fragmentController, uxRestrictions); 53 mSensorPrivacyManager = sensorPrivacyManager; 54 } 55 56 @Override getPreferenceType()57 protected Class<CarUiTwoActionSwitchPreference> getPreferenceType() { 58 return CarUiTwoActionSwitchPreference.class; 59 } 60 61 @Override onCreateInternal()62 protected void onCreateInternal() { 63 getPreference().setOnSecondaryActionClickListener(isChecked -> { 64 // Settings UX currently shows "checked means mic is enabled", but the underlying API is 65 // inversely written around "is mic muted?" So we must be careful when doing 66 // comparisons. 67 boolean isMicMuted = mSensorPrivacyManager.isSensorPrivacyEnabled( 68 SensorPrivacyManager.Sensors.MICROPHONE); 69 if (isChecked == isMicMuted) { 70 // UX and underlying API state for mic do not match, so update sensor privacy 71 mSensorPrivacyManager.setSensorPrivacyForProfileGroup( 72 SensorPrivacyManager.Sources.SETTINGS, 73 SensorPrivacyManager.Sensors.MICROPHONE, 74 !isChecked); 75 } 76 }); 77 } 78 79 @Override onStartInternal()80 protected void onStartInternal() { 81 mSensorPrivacyManager.addSensorPrivacyListener( 82 SensorPrivacyManager.Sensors.MICROPHONE, mListener); 83 } 84 85 @Override onStopInternal()86 protected void onStopInternal() { 87 mSensorPrivacyManager.removeSensorPrivacyListener(SensorPrivacyManager.Sensors.MICROPHONE, 88 mListener); 89 } 90 91 @Override getAvailabilityStatus()92 protected int getAvailabilityStatus() { 93 boolean hasFeatureMicToggle = mSensorPrivacyManager.supportsSensorToggle( 94 SensorPrivacyManager.Sensors.MICROPHONE); 95 return hasFeatureMicToggle ? AVAILABLE : UNSUPPORTED_ON_DEVICE; 96 } 97 98 @Override updateState(CarUiTwoActionSwitchPreference preference)99 protected void updateState(CarUiTwoActionSwitchPreference preference) { 100 preference.setSecondaryActionChecked(!mSensorPrivacyManager.isSensorPrivacyEnabled( 101 SensorPrivacyManager.Sensors.MICROPHONE)); 102 } 103 } 104