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.qc; 18 19 import static com.android.car.qc.QCItem.QC_ACTION_SLIDER_VALUE; 20 import static com.android.car.settings.qc.QCUtils.getActionDisabledDialogIntent; 21 import static com.android.car.settings.qc.QCUtils.getAvailabilityStatusForZoneFromXml; 22 import static com.android.car.settings.qc.SettingsQCRegistry.BRIGHTNESS_SLIDER_URI; 23 import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX; 24 import static com.android.settingslib.display.BrightnessUtils.convertGammaToLinear; 25 import static com.android.settingslib.display.BrightnessUtils.convertLinearToGamma; 26 27 import android.app.PendingIntent; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.hardware.display.DisplayManager; 31 import android.net.Uri; 32 import android.os.PowerManager; 33 import android.os.UserHandle; 34 import android.os.UserManager; 35 import android.provider.Settings; 36 37 import androidx.annotation.VisibleForTesting; 38 39 import com.android.car.qc.QCItem; 40 import com.android.car.qc.QCList; 41 import com.android.car.qc.QCRow; 42 import com.android.car.qc.QCSlider; 43 import com.android.car.settings.CarSettingsApplication; 44 import com.android.car.settings.R; 45 import com.android.car.settings.common.Logger; 46 import com.android.car.settings.enterprise.EnterpriseUtils; 47 import com.android.internal.display.BrightnessSynchronizer; 48 49 /** 50 * QCItem for showing a brightness slider. 51 */ 52 public class BrightnessSlider extends SettingsQCItem { 53 private static final Logger LOG = new Logger(BrightnessSlider.class); 54 private final int mMaximumBacklight; 55 private final int mMinimumBacklight; 56 private final Context mContextForUser; 57 private final Context mContext; 58 private final boolean mIsVisibleBackgroundUsersSupported; 59 private DisplayManager mDisplayManager; 60 BrightnessSlider(Context context)61 public BrightnessSlider(Context context) { 62 super(context); 63 setAvailabilityStatusForZone(getAvailabilityStatusForZoneFromXml(context, 64 R.xml.display_settings_fragment, R.string.pk_brightness_level)); 65 PowerManager powerManager = context.getSystemService(PowerManager.class); 66 mMaximumBacklight = powerManager.getMaximumScreenBrightnessSetting(); 67 mMinimumBacklight = powerManager.getMinimumScreenBrightnessSetting(); 68 mContext = context; 69 mContextForUser = context 70 .createContextAsUser( 71 UserHandle.of(UserHandle.myUserId()), /* flags= */ 0); 72 UserManager userManager = context.getSystemService(UserManager.class); 73 mIsVisibleBackgroundUsersSupported = 74 userManager != null ? userManager.isVisibleBackgroundUsersSupported() : false; 75 if (mIsVisibleBackgroundUsersSupported) { 76 mDisplayManager = context.getSystemService(DisplayManager.class); 77 } 78 } 79 80 @Override getQCItem()81 QCItem getQCItem() { 82 if (isHiddenForZone()) { 83 return null; 84 } 85 QCList.Builder listBuilder = new QCList.Builder() 86 .addRow(getBrightnessRowBuilder().build()); 87 88 return listBuilder.build(); 89 } 90 91 @Override getUri()92 Uri getUri() { 93 return BRIGHTNESS_SLIDER_URI; 94 } 95 96 @Override onNotifyChange(Intent intent)97 void onNotifyChange(Intent intent) { 98 int value = intent.getIntExtra(QC_ACTION_SLIDER_VALUE, Integer.MIN_VALUE); 99 if (value == Integer.MIN_VALUE) { 100 return; 101 } 102 int linear = convertGammaToLinear(value, mMinimumBacklight, mMaximumBacklight); 103 104 if (mIsVisibleBackgroundUsersSupported) { 105 if (mDisplayManager != null) { 106 float linearFloat = BrightnessSynchronizer.brightnessIntToFloat(linear); 107 mDisplayManager.setBrightness(getMyOccupantZoneDisplayId(), linearFloat); 108 } 109 } else { 110 Settings.System.putInt(mContextForUser.getContentResolver(), 111 Settings.System.SCREEN_BRIGHTNESS, linear); 112 } 113 } 114 getBrightnessRowBuilder()115 protected QCRow.Builder getBrightnessRowBuilder() { 116 String userRestriction = UserManager.DISALLOW_CONFIG_BRIGHTNESS; 117 boolean hasDpmRestrictions = EnterpriseUtils.hasUserRestrictionByDpm(getContext(), 118 userRestriction); 119 boolean hasUmRestrictions = EnterpriseUtils.hasUserRestrictionByUm(getContext(), 120 userRestriction); 121 122 boolean isReadOnlyForZone = isReadOnlyForZone(); 123 PendingIntent disabledPendingIntent = isReadOnlyForZone 124 ? QCUtils.getDisabledToastBroadcastIntent(getContext()) 125 : getActionDisabledDialogIntent(getContext(), userRestriction); 126 127 return new QCRow.Builder() 128 .setTitle(getContext().getString(R.string.qc_display_brightness)) 129 .addSlider(new QCSlider.Builder() 130 .setMax(GAMMA_SPACE_MAX) 131 .setValue(getSeekbarValue()) 132 .setInputAction(getBroadcastIntent()) 133 .setEnabled(!hasUmRestrictions && !hasDpmRestrictions 134 && isWritableForZone()) 135 .setClickableWhileDisabled(hasDpmRestrictions || isReadOnlyForZone) 136 .setDisabledClickAction(disabledPendingIntent) 137 .build() 138 ); 139 } 140 141 @VisibleForTesting getSeekbarValue()142 int getSeekbarValue() { 143 int gamma = GAMMA_SPACE_MAX; 144 if (mIsVisibleBackgroundUsersSupported) { 145 if (mDisplayManager != null) { 146 float linearFloat = mDisplayManager.getBrightness(getMyOccupantZoneDisplayId()); 147 int linear = BrightnessSynchronizer.brightnessFloatToInt(linearFloat); 148 gamma = convertLinearToGamma(linear, mMinimumBacklight, mMaximumBacklight); 149 } 150 } else { 151 try { 152 int linear = Settings.System.getInt(mContextForUser.getContentResolver(), 153 Settings.System.SCREEN_BRIGHTNESS); 154 gamma = convertLinearToGamma(linear, mMinimumBacklight, mMaximumBacklight); 155 } catch (Settings.SettingNotFoundException e) { 156 LOG.w("Can't find setting for SCREEN_BRIGHTNESS."); 157 } 158 } 159 return gamma; 160 } 161 getMyOccupantZoneDisplayId()162 private int getMyOccupantZoneDisplayId() { 163 return ((CarSettingsApplication) mContext.getApplicationContext()) 164 .getMyOccupantZoneDisplayId(); 165 } 166 } 167