1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 package com.android.settings.display;
15 
16 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
17 
18 import android.app.admin.DevicePolicyManager;
19 import android.content.Context;
20 import android.os.UserHandle;
21 import android.os.UserManager;
22 import android.provider.Settings;
23 import android.util.Log;
24 
25 import androidx.preference.Preference;
26 
27 import com.android.settings.R;
28 import com.android.settings.core.PreferenceControllerMixin;
29 import com.android.settingslib.RestrictedLockUtils;
30 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
31 import com.android.settingslib.RestrictedLockUtilsInternal;
32 import com.android.settingslib.core.AbstractPreferenceController;
33 
34 public class TimeoutPreferenceController extends AbstractPreferenceController implements
35         PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
36 
37     private static final String TAG = "TimeoutPrefContr";
38 
39     /** If there is no setting in the provider, use this. */
40     public static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
41 
42     private final String mScreenTimeoutKey;
43 
TimeoutPreferenceController(Context context, String key)44     public TimeoutPreferenceController(Context context, String key) {
45         super(context);
46         mScreenTimeoutKey = key;
47     }
48 
49     @Override
isAvailable()50     public boolean isAvailable() {
51         return true;
52     }
53 
54     @Override
getPreferenceKey()55     public String getPreferenceKey() {
56         return mScreenTimeoutKey;
57     }
58 
59     @Override
updateState(Preference preference)60     public void updateState(Preference preference) {
61         final TimeoutListPreference timeoutListPreference = (TimeoutListPreference) preference;
62         final long currentTimeout = Settings.System.getLong(mContext.getContentResolver(),
63                 SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
64         timeoutListPreference.setValue(String.valueOf(currentTimeout));
65         final DevicePolicyManager dpm =
66                 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
67         if (dpm != null) {
68             final RestrictedLockUtils.EnforcedAdmin admin =
69                     RestrictedLockUtilsInternal.checkIfMaximumTimeToLockIsSet(mContext);
70             final long maxTimeout =
71                     dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
72             timeoutListPreference.removeUnusableTimeouts(maxTimeout, admin);
73         }
74         updateTimeoutPreferenceDescription(timeoutListPreference,
75                 Long.parseLong(timeoutListPreference.getValue()));
76 
77         final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
78                 mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
79                 UserHandle.myUserId());
80         if (admin != null) {
81             timeoutListPreference.removeUnusableTimeouts(0/* disable all*/, admin);
82         }
83     }
84 
85     @Override
onPreferenceChange(Preference preference, Object newValue)86     public boolean onPreferenceChange(Preference preference, Object newValue) {
87         try {
88             int value = Integer.parseInt((String) newValue);
89             Settings.System.putInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
90             updateTimeoutPreferenceDescription((TimeoutListPreference) preference, value);
91         } catch (NumberFormatException e) {
92             Log.e(TAG, "could not persist screen timeout setting", e);
93         }
94         return true;
95     }
96 
getTimeoutDescription( long currentTimeout, CharSequence[] entries, CharSequence[] values)97     public static CharSequence getTimeoutDescription(
98             long currentTimeout, CharSequence[] entries, CharSequence[] values) {
99         if (currentTimeout < 0 || entries == null || values == null
100                 || values.length != entries.length) {
101             return null;
102         }
103 
104         for (int i = 0; i < values.length; i++) {
105             long timeout = Long.parseLong(values[i].toString());
106             if (currentTimeout == timeout) {
107                 return entries[i];
108             }
109         }
110         return null;
111     }
112 
updateTimeoutPreferenceDescription(TimeoutListPreference preference, long currentTimeout)113     private void updateTimeoutPreferenceDescription(TimeoutListPreference preference,
114             long currentTimeout) {
115         final CharSequence[] entries = preference.getEntries();
116         final CharSequence[] values = preference.getEntryValues();
117         final String summary;
118         if (preference.isDisabledByAdmin()) {
119             summary = mContext.getString(com.android.settings.R.string.disabled_by_policy_title);
120         } else {
121             final CharSequence timeoutDescription = getTimeoutDescription(
122                     currentTimeout, entries, values);
123             summary = timeoutDescription == null
124                     ? ""
125                     : mContext.getString(R.string.screen_timeout_summary, timeoutDescription);
126         }
127         preference.setSummary(summary);
128     }
129 
130 }
131