• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.settings.display;
18 
19 import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
20 
21 import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
22 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
23 import static com.android.settings.display.UtilsKt.isAdaptiveSleepSupported;
24 
25 import android.Manifest;
26 import android.app.settings.SettingsEnums;
27 import android.content.Context;
28 import android.content.pm.PackageManager;
29 import android.hardware.SensorPrivacyManager;
30 import android.os.PowerManager;
31 import android.os.UserManager;
32 import android.provider.Settings;
33 
34 import androidx.preference.PreferenceScreen;
35 
36 import com.android.settings.R;
37 import com.android.settings.bluetooth.RestrictionUtils;
38 import com.android.settings.overlay.FeatureFactory;
39 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
40 import com.android.settingslib.RestrictedSwitchPreference;
41 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
42 
43 import com.google.common.annotations.VisibleForTesting;
44 
45 // LINT.IfChange
46 /** The controller for Screen attention switch preference. */
47 public class AdaptiveSleepPreferenceController {
48     public static final String PREFERENCE_KEY = Settings.Secure.ADAPTIVE_SLEEP;
49     private static final int DEFAULT_VALUE = 0;
50     private final SensorPrivacyManager mPrivacyManager;
51     private final RestrictionUtils mRestrictionUtils;
52     private final PackageManager mPackageManager;
53     private final Context mContext;
54     private final MetricsFeatureProvider mMetricsFeatureProvider;
55     private final PowerManager mPowerManager;
56 
57     @VisibleForTesting
58     RestrictedSwitchPreference mPreference;
59 
AdaptiveSleepPreferenceController(Context context, RestrictionUtils restrictionUtils)60     public AdaptiveSleepPreferenceController(Context context, RestrictionUtils restrictionUtils) {
61         mContext = context;
62         mRestrictionUtils = restrictionUtils;
63         mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
64         mPrivacyManager = SensorPrivacyManager.getInstance(context);
65         mPowerManager = context.getSystemService(PowerManager.class);
66         mPackageManager = context.getPackageManager();
67     }
68 
AdaptiveSleepPreferenceController(Context context)69     public AdaptiveSleepPreferenceController(Context context) {
70         this(context, new RestrictionUtils());
71     }
72 
73     /**
74      * Adds the controlled preference to the provided preference screen.
75      */
addToScreen(PreferenceScreen screen)76     public void addToScreen(PreferenceScreen screen) {
77         updatePreference();
78         screen.addPreference(mPreference);
79     }
80 
81     /**
82      * Updates the appearance of the preference.
83      */
updatePreference()84     public void updatePreference() {
85         initializePreference();
86         final EnforcedAdmin enforcedAdmin = mRestrictionUtils.checkIfRestrictionEnforced(mContext,
87                 UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT);
88         if (enforcedAdmin != null) {
89             mPreference.setDisabledByAdmin(enforcedAdmin);
90         } else {
91             mPreference.setChecked(isChecked());
92             mPreference.setEnabled(hasSufficientPermission(mPackageManager) && !isCameraLocked()
93                     && !isPowerSaveMode());
94         }
95     }
96 
97     @VisibleForTesting
initializePreference()98     void initializePreference() {
99         if (mPreference == null) {
100             mPreference = new RestrictedSwitchPreference(mContext);
101             mPreference.setTitle(R.string.adaptive_sleep_title);
102             mPreference.setSummary(R.string.adaptive_sleep_description);
103             mPreference.setChecked(isChecked());
104             mPreference.setKey(PREFERENCE_KEY);
105             mPreference.setOnPreferenceClickListener(preference -> {
106                 final boolean isChecked = ((RestrictedSwitchPreference) preference).isChecked();
107                 mMetricsFeatureProvider.action(mContext,
108                         SettingsEnums.ACTION_SCREEN_ATTENTION_CHANGED,
109                         isChecked);
110                 Settings.Secure.putInt(mContext.getContentResolver(),
111                         Settings.Secure.ADAPTIVE_SLEEP, isChecked ? 1 : DEFAULT_VALUE);
112                 return true;
113             });
114         }
115     }
116 
117     @VisibleForTesting
isChecked()118     boolean isChecked() {
119         return hasSufficientPermission(mContext.getPackageManager()) && !isCameraLocked()
120                 && !isPowerSaveMode() && Settings.Secure.getInt(mContext.getContentResolver(),
121                 Settings.Secure.ADAPTIVE_SLEEP, DEFAULT_VALUE)
122                 != DEFAULT_VALUE;
123     }
124 
125     /**
126      * Need this because all controller tests use RoboElectric. No easy way to mock this service,
127      * so we mock the call we need
128      */
129     @VisibleForTesting
isCameraLocked()130     boolean isCameraLocked() {
131         return mPrivacyManager.isSensorPrivacyEnabled(CAMERA);
132     }
133 
134     @VisibleForTesting
isPowerSaveMode()135     boolean isPowerSaveMode() {
136         return mPowerManager.isPowerSaveMode();
137     }
138 
isControllerAvailable(Context context)139     public static int isControllerAvailable(Context context) {
140         return isAdaptiveSleepSupported(context)
141                 ? AVAILABLE_UNSEARCHABLE
142                 : UNSUPPORTED_ON_DEVICE;
143     }
144 
hasSufficientPermission(PackageManager packageManager)145     static boolean hasSufficientPermission(PackageManager packageManager) {
146         final String attentionPackage = packageManager.getAttentionServicePackageName();
147         return attentionPackage != null && packageManager.checkPermission(
148                 Manifest.permission.CAMERA, attentionPackage) == PackageManager.PERMISSION_GRANTED;
149     }
150 }
151 // LINT.ThenChange(AdaptiveSleepPreference.kt)
152