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 */
14package com.android.settings.display;
15
16import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
17
18import android.app.admin.DevicePolicyManager;
19import android.content.Context;
20import android.os.UserHandle;
21import android.os.UserManager;
22import android.provider.Settings;
23import android.support.v7.preference.Preference;
24import android.util.Log;
25
26import com.android.settings.R;
27import com.android.settings.TimeoutListPreference;
28import com.android.settings.core.PreferenceControllerMixin;
29import com.android.settingslib.RestrictedLockUtils;
30import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
31import com.android.settingslib.core.AbstractPreferenceController;
32
33public class TimeoutPreferenceController extends AbstractPreferenceController implements
34        PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
35
36    private static final String TAG = "TimeoutPrefContr";
37
38    /** If there is no setting in the provider, use this. */
39    public static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
40
41    private final String mScreenTimeoutKey;
42
43    public TimeoutPreferenceController(Context context, String key) {
44        super(context);
45        mScreenTimeoutKey = key;
46    }
47
48    @Override
49    public boolean isAvailable() {
50        return true;
51    }
52
53    @Override
54    public String getPreferenceKey() {
55        return mScreenTimeoutKey;
56    }
57
58    @Override
59    public void updateState(Preference preference) {
60        final TimeoutListPreference timeoutListPreference = (TimeoutListPreference) preference;
61        final long currentTimeout = Settings.System.getLong(mContext.getContentResolver(),
62                SCREEN_OFF_TIMEOUT, FALLBACK_SCREEN_TIMEOUT_VALUE);
63        timeoutListPreference.setValue(String.valueOf(currentTimeout));
64        final DevicePolicyManager dpm =
65                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
66        if (dpm != null) {
67            final RestrictedLockUtils.EnforcedAdmin admin =
68                    RestrictedLockUtils.checkIfMaximumTimeToLockIsSet(mContext);
69            final long maxTimeout =
70                    dpm.getMaximumTimeToLock(null /* admin */, UserHandle.myUserId());
71            timeoutListPreference.removeUnusableTimeouts(maxTimeout, admin);
72        }
73        updateTimeoutPreferenceDescription(timeoutListPreference, currentTimeout);
74
75        EnforcedAdmin admin = RestrictedLockUtils.checkIfRestrictionEnforced(
76                        mContext, UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
77                        UserHandle.myUserId());
78        if(admin != null) {
79            timeoutListPreference.removeUnusableTimeouts(0/* disable all*/, admin);
80        }
81    }
82
83    @Override
84    public boolean onPreferenceChange(Preference preference, Object newValue) {
85        try {
86            int value = Integer.parseInt((String) newValue);
87            Settings.System.putInt(mContext.getContentResolver(), SCREEN_OFF_TIMEOUT, value);
88            updateTimeoutPreferenceDescription((TimeoutListPreference) preference, value);
89        } catch (NumberFormatException e) {
90            Log.e(TAG, "could not persist screen timeout setting", e);
91        }
92        return true;
93    }
94
95    public static CharSequence getTimeoutDescription(
96            long currentTimeout, CharSequence[] entries, CharSequence[] values) {
97        if (currentTimeout < 0 || entries == null || values == null
98                || values.length != entries.length) {
99            return null;
100        }
101
102        for (int i = 0; i < values.length; i++) {
103            long timeout = Long.parseLong(values[i].toString());
104            if (currentTimeout == timeout) {
105                return entries[i];
106            }
107        }
108        return null;
109    }
110
111    private void updateTimeoutPreferenceDescription(TimeoutListPreference preference,
112            long currentTimeout) {
113        final CharSequence[] entries = preference.getEntries();
114        final CharSequence[] values = preference.getEntryValues();
115        final String summary;
116        if (preference.isDisabledByAdmin()) {
117            summary = mContext.getString(com.android.settings.R.string.disabled_by_policy_title);
118        } else {
119            final CharSequence timeoutDescription = getTimeoutDescription(
120                    currentTimeout, entries, values);
121            summary = timeoutDescription == null
122                    ? ""
123                    : mContext.getString(R.string.screen_timeout_summary, timeoutDescription);
124        }
125        preference.setSummary(summary);
126    }
127
128}
129