1 /* 2 * Copyright (C) 2024 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 static com.android.car.settings.enterprise.EnterpriseUtils.getAvailabilityStatusRestricted; 20 import static com.android.car.settings.enterprise.EnterpriseUtils.hasUserRestrictionByDpm; 21 import static com.android.car.settings.enterprise.EnterpriseUtils.onClickWhileDisabled; 22 23 import android.annotation.FlaggedApi; 24 import android.car.drivingstate.CarUxRestrictions; 25 import android.content.Context; 26 import android.hardware.SensorPrivacyManager; 27 import android.os.UserManager; 28 29 import com.android.car.settings.R; 30 import com.android.car.settings.common.FragmentController; 31 import com.android.car.ui.preference.CarUiSwitchPreference; 32 import com.android.internal.annotations.VisibleForTesting; 33 import com.android.internal.camera.flags.Flags; 34 35 /** 36 * Displays a toggle to turn off camera access for required apps. 37 */ 38 @FlaggedApi(Flags.FLAG_CAMERA_PRIVACY_ALLOWLIST) 39 public final class CameraRequiredAppsTogglePreferenceController 40 extends CameraPrivacyBasePreferenceController<CarUiSwitchPreference> { 41 private boolean mRequiredAppsToggleAvailable; 42 CameraRequiredAppsTogglePreferenceController( Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)43 public CameraRequiredAppsTogglePreferenceController( 44 Context context, 45 String preferenceKey, 46 FragmentController fragmentController, 47 CarUxRestrictions uxRestrictions) { 48 this(context, preferenceKey, fragmentController, uxRestrictions, 49 SensorPrivacyManager.getInstance(context)); 50 } 51 52 @VisibleForTesting CameraRequiredAppsTogglePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions, SensorPrivacyManager sensorPrivacyManager)53 CameraRequiredAppsTogglePreferenceController(Context context, String preferenceKey, 54 FragmentController fragmentController, CarUxRestrictions uxRestrictions, 55 SensorPrivacyManager sensorPrivacyManager) { 56 super(context, preferenceKey, fragmentController, uxRestrictions, sensorPrivacyManager); 57 mRequiredAppsToggleAvailable = context.getResources() 58 .getBoolean(R.bool.config_show_camera_required_apps_toggle); 59 } 60 61 @Override getPreferenceType()62 protected Class<CarUiSwitchPreference> getPreferenceType() { 63 return CarUiSwitchPreference.class; 64 } 65 66 @Override getDefaultAvailabilityStatus()67 protected int getDefaultAvailabilityStatus() { 68 if (!mRequiredAppsToggleAvailable) { 69 return CONDITIONALLY_UNAVAILABLE; 70 } else { 71 return getAvailabilityStatusRestricted(getContext(), 72 UserManager.DISALLOW_CAMERA_TOGGLE); 73 } 74 } 75 76 @Override handlePreferenceChanged(CarUiSwitchPreference preference, Object newValue)77 protected boolean handlePreferenceChanged(CarUiSwitchPreference preference, 78 Object newValue) { 79 boolean isChecked = (Boolean) newValue; 80 int state = getSensorPrivacyManager().getSensorPrivacyState( 81 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, 82 SensorPrivacyManager.Sensors.CAMERA); 83 boolean isCameraMutedForRequiredApps = (state == SensorPrivacyManager.StateTypes.ENABLED); 84 if (isChecked == isCameraMutedForRequiredApps) { 85 int newState; 86 if (isChecked) { 87 newState = SensorPrivacyManager.StateTypes.ENABLED_EXCEPT_ALLOWLISTED_APPS; 88 } else { 89 newState = SensorPrivacyManager.StateTypes.ENABLED; 90 } 91 92 getSensorPrivacyManager().setSensorPrivacyStateForProfileGroup( 93 SensorPrivacyManager.Sources.SETTINGS, 94 SensorPrivacyManager.Sensors.CAMERA, 95 newState); 96 } 97 return true; 98 } 99 100 @Override updateState(CarUiSwitchPreference preference)101 protected void updateState(CarUiSwitchPreference preference) { 102 int state = getSensorPrivacyManager().getSensorPrivacyState( 103 SensorPrivacyManager.TOGGLE_TYPE_SOFTWARE, 104 SensorPrivacyManager.Sensors.CAMERA); 105 boolean isCameraMutedForRequiredApps = (state == SensorPrivacyManager.StateTypes.ENABLED); 106 preference.setChecked(!isCameraMutedForRequiredApps); 107 if (state == SensorPrivacyManager.StateTypes.DISABLED) { 108 getPreference().setEnabled(false); 109 } else { 110 getPreference().setEnabled(true); 111 } 112 if (hasUserRestrictionByDpm(getContext(), UserManager.DISALLOW_CAMERA_TOGGLE)) { 113 setClickableWhileDisabled(preference, /* clickable= */ true, p -> 114 onClickWhileDisabled(getContext(), getFragmentController(), 115 UserManager.DISALLOW_CAMERA_TOGGLE)); 116 } 117 } 118 } 119