1 /*
2  * Copyright (C) 2016 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.app.admin.DevicePolicyResources.Strings.Settings.OTHER_OPTIONS_DISABLED_BY_ADMIN;
20 
21 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
22 
23 import android.app.Dialog;
24 import android.app.admin.DevicePolicyManager;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.util.AttributeSet;
28 import android.util.Log;
29 import android.view.LayoutInflater;
30 import android.view.View;
31 import android.widget.TextView;
32 
33 import androidx.appcompat.app.AlertDialog.Builder;
34 
35 import com.android.settings.R;
36 import com.android.settings.RestrictedListPreference;
37 import com.android.settingslib.RestrictedLockUtils;
38 
39 import java.util.ArrayList;
40 
41 
42 public class TimeoutListPreference extends RestrictedListPreference {
43     private static final String TAG = "TimeoutListPreference";
44     private EnforcedAdmin mAdmin;
45     private final CharSequence[] mInitialEntries;
46     private final CharSequence[] mInitialValues;
47 
TimeoutListPreference(Context context, AttributeSet attrs)48     public TimeoutListPreference(Context context, AttributeSet attrs) {
49         super(context, attrs);
50         mInitialEntries = getEntries();
51         mInitialValues = getEntryValues();
52     }
53 
54     @Override
onPrepareDialogBuilder(Builder builder, DialogInterface.OnClickListener listener)55     protected void onPrepareDialogBuilder(Builder builder,
56             DialogInterface.OnClickListener listener) {
57         super.onPrepareDialogBuilder(builder, listener);
58         if (mAdmin != null) {
59             updateTextOnDialog(builder);
60         } else {
61             builder.setView(null);
62         }
63     }
64 
updateTextOnDialog(Builder builder)65     private void updateTextOnDialog(Builder builder) {
66         LayoutInflater inflater = getContext().getSystemService(LayoutInflater.class);
67         DevicePolicyManager devicePolicyManager = getContext()
68                 .getSystemService(DevicePolicyManager.class);
69         View v = inflater.inflate(R.layout.admin_disabled_other_options_footer, null);
70         builder.setView(v);
71         TextView textView = v.findViewById(R.id.admin_disabled_other_options_text);
72         String replacementText = devicePolicyManager.getResources().getString(
73                 OTHER_OPTIONS_DISABLED_BY_ADMIN, () -> null);
74         if (replacementText != null) {
75             textView.setText(replacementText);
76         }
77     }
78 
79     @Override
onDialogCreated(Dialog dialog)80     protected void onDialogCreated(Dialog dialog) {
81         super.onDialogCreated(dialog);
82         dialog.create();
83         if (mAdmin != null) {
84             View footerView = dialog.findViewById(R.id.admin_disabled_other_options);
85             footerView.findViewById(R.id.admin_more_details_link).setOnClickListener(
86                     new View.OnClickListener() {
87                         @Override
88                         public void onClick(View view) {
89                             RestrictedLockUtils.sendShowAdminSupportDetailsIntent(
90                                     getContext(), mAdmin);
91                         }
92                     });
93         }
94     }
95 
removeUnusableTimeouts(long maxTimeout, EnforcedAdmin admin)96     public void removeUnusableTimeouts(long maxTimeout, EnforcedAdmin admin) {
97         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
98                 Context.DEVICE_POLICY_SERVICE);
99         if (dpm == null) {
100             return;
101         }
102 
103         if (admin == null && mAdmin == null && !isDisabledByAdmin()) {
104             return;
105         }
106         if (admin == null) {
107             maxTimeout = Long.MAX_VALUE;
108         }
109 
110         ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
111         ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
112         for (int i = 0; i < mInitialValues.length; ++i) {
113             long timeout = Long.parseLong(mInitialValues[i].toString());
114             if (timeout <= maxTimeout) {
115                 revisedEntries.add(mInitialEntries[i]);
116                 revisedValues.add(mInitialValues[i]);
117             }
118         }
119 
120         // If there are no possible options for the user, then set this preference as disabled
121         // by admin, otherwise remove the padlock in case it was set earlier.
122         if (revisedValues.size() == 0) {
123             setDisabledByAdmin(admin);
124             return;
125         } else {
126             setDisabledByAdmin(null);
127         }
128 
129         if (revisedEntries.size() != getEntries().length) {
130             final int userPreference = Integer.parseInt(getValue());
131             setEntries(revisedEntries.toArray(new CharSequence[0]));
132             setEntryValues(revisedValues.toArray(new CharSequence[0]));
133             mAdmin = admin;
134             if (userPreference <= maxTimeout) {
135                 setValue(String.valueOf(userPreference));
136             } else if (revisedValues.size() > 0
137                     && Long.parseLong(revisedValues.get(revisedValues.size() - 1).toString())
138                             == maxTimeout) {
139                 // If the last one happens to be the same as the max timeout, select that
140                 setValue(String.valueOf(maxTimeout));
141             } else {
142                 // The selected time out value is longer than the max timeout allowed by the admin.
143                 // Select the largest value from the list by default.
144                 Log.w(TAG, "Default to longest timeout. Value disabled by admin:" + userPreference);
145                 setValue(revisedValues.get(revisedValues.size() - 1).toString());
146             }
147         }
148     }
149 }
150