• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.settings.accessibility;
17 
18 import static com.android.settings.accessibility.DaltonizerPreferenceUtil.isSecureAccessibilityDaltonizerEnabled;
19 import static com.android.settings.accessibility.DaltonizerPreferenceUtil.getSecureAccessibilityDaltonizerValue;
20 
21 import android.content.ContentResolver;
22 import android.content.Context;
23 import android.database.ContentObserver;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.provider.Settings;
27 
28 import androidx.annotation.NonNull;
29 import androidx.annotation.Nullable;
30 import androidx.lifecycle.DefaultLifecycleObserver;
31 import androidx.lifecycle.LifecycleOwner;
32 import androidx.preference.Preference;
33 import androidx.preference.PreferenceScreen;
34 
35 import com.android.server.accessibility.Flags;
36 import com.android.settings.R;
37 import com.android.settings.core.SliderPreferenceController;
38 import com.android.settings.widget.SeekBarPreference;
39 
40 /**
41  * The controller of the seekbar preference for the saturation level of color correction.
42  */
43 public class DaltonizerSaturationSeekbarPreferenceController
44         extends SliderPreferenceController
45         implements DefaultLifecycleObserver {
46 
47     private static final int DEFAULT_SATURATION_LEVEL = 7;
48     private static final int SATURATION_MAX = 10;
49     private static final int SATURATION_MIN = 1;
50 
51     private int mSliderPosition;
52     private final ContentResolver mContentResolver;
53 
54     @Nullable
55     private SeekBarPreference mPreference;
56 
57     public final ContentObserver mContentObserver = new ContentObserver(
58             new Handler(Looper.getMainLooper())) {
59         @Override
60         public void onChange(boolean selfChange) {
61             if (mPreference != null) {
62                 updateState(mPreference);
63             }
64         }
65     };
66 
DaltonizerSaturationSeekbarPreferenceController(Context context, String preferenceKey)67     public DaltonizerSaturationSeekbarPreferenceController(Context context,
68             String preferenceKey) {
69         super(context, preferenceKey);
70         mContentResolver = context.getContentResolver();
71         mSliderPosition = Settings.Secure.getInt(
72                 mContentResolver,
73                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL,
74                 DEFAULT_SATURATION_LEVEL);
75         setSliderPosition(mSliderPosition);
76         // TODO: Observer color correction on/off and enable/disable based on secure settings.
77     }
78 
79     @Override
onStart(@onNull LifecycleOwner owner)80     public void onStart(@NonNull LifecycleOwner owner) {
81         if (!isAvailable()) return;
82         mContentResolver.registerContentObserver(
83                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
84                 true,
85                 mContentObserver
86         );
87         mContentResolver.registerContentObserver(
88                 Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
89                 true,
90                 mContentObserver
91         );
92     }
93 
94     @Override
onStop(@onNull LifecycleOwner owner)95     public void onStop(@NonNull LifecycleOwner owner) {
96         if (!isAvailable()) return;
97         mContentResolver.unregisterContentObserver(mContentObserver);
98         mPreference = null;
99     }
100 
101     @Override
displayPreference(PreferenceScreen screen)102     public void displayPreference(PreferenceScreen screen) {
103         super.displayPreference(screen);
104         SeekBarPreference preference = screen.findPreference(getPreferenceKey());
105         mPreference = preference;
106         preference.setMax(getMax());
107         preference.setMin(getMin());
108         preference.setProgress(mSliderPosition);
109         preference.setContinuousUpdates(true);
110     }
111 
112     @Override
getAvailabilityStatus()113     public int getAvailabilityStatus() {
114         if (Flags.enableColorCorrectionSaturation()) {
115             return shouldSeekBarEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
116         }
117         return CONDITIONALLY_UNAVAILABLE;
118     }
119 
120     @Override
getSliderPosition()121     public int getSliderPosition() {
122         return mSliderPosition;
123     }
124 
125     @Override
setSliderPosition(int position)126     public boolean setSliderPosition(int position) {
127         if (position < getMin() || position > getMax()) {
128             return false;
129         }
130         mSliderPosition = position;
131         Settings.Secure.putInt(
132                 mContentResolver,
133                 Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_SATURATION_LEVEL,
134                 mSliderPosition);
135         return true;
136     }
137 
138     @Override
updateState(Preference preference)139     public void updateState(Preference preference) {
140         if (preference == null) {
141             return;
142         }
143 
144         var shouldSeekbarEnabled = shouldSeekBarEnabled();
145         // setSummary not working yet on SeekBarPreference.
146         String summary = shouldSeekbarEnabled
147                 ? ""
148                 : mContext.getString(R.string.daltonizer_saturation_unavailable_summary);
149         preference.setSummary(summary);
150         preference.setEnabled(shouldSeekbarEnabled);
151     }
152 
153     @Override
getMax()154     public int getMax() {
155         return SATURATION_MAX;
156     }
157 
158     @Override
getMin()159     public int getMin() {
160         return SATURATION_MIN;
161     }
162 
shouldSeekBarEnabled()163     private boolean shouldSeekBarEnabled() {
164         boolean enabled = isSecureAccessibilityDaltonizerEnabled(mContentResolver);
165         int mode = getSecureAccessibilityDaltonizerValue(mContentResolver);
166 
167         // mode == 0 is gray scale where saturation level isn't applicable.
168         // mode == -1 is disabled and also default.
169         return enabled && mode != -1 && mode != 0;
170     }
171 }
172