• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import android.app.ActivityManager;
20 import android.app.AlertDialog;
21 import android.app.KeyguardManager;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.os.Bundle;
26 import android.os.RemoteException;
27 import android.os.UserManager;
28 import android.support.annotation.VisibleForTesting;
29 import android.support.v14.preference.ListPreferenceDialogFragment;
30 import android.support.v7.preference.PreferenceViewHolder;
31 import android.util.AttributeSet;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.AdapterView;
35 import android.widget.ArrayAdapter;
36 import android.widget.CheckedTextView;
37 import android.widget.ImageView;
38 import android.widget.ListAdapter;
39 import android.widget.ListView;
40 
41 import com.android.settings.Utils;
42 import com.android.settingslib.RestrictedLockUtils;
43 import com.android.settingslib.RestrictedPreferenceHelper;
44 
45 import java.util.ArrayList;
46 import java.util.List;
47 
48 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
49 
50 public class RestrictedListPreference extends CustomListPreference {
51     private final RestrictedPreferenceHelper mHelper;
52     private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
53     private boolean mRequiresActiveUnlockedProfile = false;
54     private int mProfileUserId;
55 
RestrictedListPreference(Context context, AttributeSet attrs)56     public RestrictedListPreference(Context context, AttributeSet attrs) {
57         super(context, attrs);
58         setWidgetLayoutResource(R.layout.restricted_icon);
59         mHelper = new RestrictedPreferenceHelper(context, this, attrs);
60     }
61 
RestrictedListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)62     public RestrictedListPreference(Context context, AttributeSet attrs,
63             int defStyleAttr, int defStyleRes) {
64         super(context, attrs, defStyleAttr, defStyleRes);
65         mHelper = new RestrictedPreferenceHelper(context, this, attrs);
66     }
67 
68     @Override
onBindViewHolder(PreferenceViewHolder holder)69     public void onBindViewHolder(PreferenceViewHolder holder) {
70         super.onBindViewHolder(holder);
71         mHelper.onBindViewHolder(holder);
72         final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
73         if (restrictedIcon != null) {
74             restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
75         }
76     }
77 
78     @Override
performClick()79     public void performClick() {
80         if (mRequiresActiveUnlockedProfile) {
81             // Check if the profile is started, first.
82             if (Utils.startQuietModeDialogIfNecessary(getContext(), UserManager.get(getContext()),
83                     mProfileUserId)) {
84                 return;
85             }
86 
87             // Next, check if the profile is unlocked.
88             KeyguardManager manager =
89                     (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
90             if (manager.isDeviceLocked(mProfileUserId)) {
91                 Intent intent = manager.createConfirmDeviceCredentialIntent(
92                         null, null, mProfileUserId);
93                 getContext().startActivity(intent);
94                 return;
95             }
96         }
97 
98         if (!mHelper.performClick()) {
99             super.performClick();
100         }
101     }
102 
103     @Override
setEnabled(boolean enabled)104     public void setEnabled(boolean enabled) {
105         if (enabled && isDisabledByAdmin()) {
106             mHelper.setDisabledByAdmin(null);
107             return;
108         }
109         super.setEnabled(enabled);
110     }
111 
setDisabledByAdmin(EnforcedAdmin admin)112     public void setDisabledByAdmin(EnforcedAdmin admin) {
113         if (mHelper.setDisabledByAdmin(admin)) {
114             notifyChanged();
115         }
116     }
117 
isDisabledByAdmin()118     public boolean isDisabledByAdmin() {
119         return mHelper.isDisabledByAdmin();
120     }
121 
setRequiresActiveUnlockedProfile(boolean reqState)122     public void setRequiresActiveUnlockedProfile(boolean reqState) {
123         mRequiresActiveUnlockedProfile = reqState;
124     }
125 
setProfileUserId(int profileUserId)126     public void setProfileUserId(int profileUserId) {
127         mProfileUserId = profileUserId;
128     }
129 
isRestrictedForEntry(CharSequence entry)130     public boolean isRestrictedForEntry(CharSequence entry) {
131         if (entry == null) {
132             return false;
133         }
134         for (RestrictedItem item : mRestrictedItems) {
135             if (entry.equals(item.entry)) {
136                 return true;
137             }
138         }
139         return false;
140     }
141 
addRestrictedItem(RestrictedItem item)142     public void addRestrictedItem(RestrictedItem item) {
143         mRestrictedItems.add(item);
144     }
145 
clearRestrictedItems()146     public void clearRestrictedItems() {
147         mRestrictedItems.clear();
148     }
149 
getRestrictedItemForEntryValue(CharSequence entryValue)150     private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) {
151         if (entryValue == null) {
152             return null;
153         }
154         for (RestrictedItem item : mRestrictedItems) {
155             if (entryValue.equals(item.entryValue)) {
156                 return item;
157             }
158         }
159         return null;
160     }
161 
createListAdapter()162     protected ListAdapter createListAdapter() {
163         return new RestrictedArrayAdapter(getContext(), getEntries(),
164                 getSelectedValuePos());
165     }
166 
getSelectedValuePos()167     public int getSelectedValuePos() {
168         final String selectedValue = getValue();
169         final int selectedIndex =
170                 (selectedValue == null) ? -1 : findIndexOfValue(selectedValue);
171         return selectedIndex;
172     }
173 
174     @Override
onPrepareDialogBuilder(AlertDialog.Builder builder, DialogInterface.OnClickListener listener)175     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
176             DialogInterface.OnClickListener listener) {
177         builder.setAdapter(createListAdapter(), listener);
178     }
179 
180 
181     public class RestrictedArrayAdapter extends ArrayAdapter<CharSequence> {
182         private final int mSelectedIndex;
RestrictedArrayAdapter(Context context, CharSequence[] objects, int selectedIndex)183         public RestrictedArrayAdapter(Context context, CharSequence[] objects, int selectedIndex) {
184             super(context, R.layout.restricted_dialog_singlechoice, R.id.text1, objects);
185             mSelectedIndex = selectedIndex;
186         }
187 
188         @Override
getView(int position, View convertView, ViewGroup parent)189         public View getView(int position, View convertView, ViewGroup parent) {
190             View root = super.getView(position, convertView, parent);
191             CharSequence entry = getItem(position);
192             CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1);
193             ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon);
194             if (isRestrictedForEntry(entry)) {
195                 text.setEnabled(false);
196                 text.setChecked(false);
197                 padlock.setVisibility(View.VISIBLE);
198             } else {
199                 if (mSelectedIndex != -1) {
200                     text.setChecked(position == mSelectedIndex);
201                 }
202                 if (!text.isEnabled()) {
203                     text.setEnabled(true);
204                 }
205                 padlock.setVisibility(View.GONE);
206             }
207             return root;
208         }
209 
210         @Override
hasStableIds()211         public boolean hasStableIds() {
212             return true;
213         }
214 
215         @Override
getItemId(int position)216         public long getItemId(int position) {
217             return position;
218         }
219     }
220 
221     public static class RestrictedListPreferenceDialogFragment extends
222             CustomListPreference.CustomListPreferenceDialogFragment {
223         private int mLastCheckedPosition = AdapterView.INVALID_POSITION;
224 
newInstance(String key)225         public static ListPreferenceDialogFragment newInstance(String key) {
226             final ListPreferenceDialogFragment fragment
227                     = new RestrictedListPreferenceDialogFragment();
228             final Bundle b = new Bundle(1);
229             b.putString(ARG_KEY, key);
230             fragment.setArguments(b);
231             return fragment;
232         }
233 
getCustomizablePreference()234         private RestrictedListPreference getCustomizablePreference() {
235             return (RestrictedListPreference) getPreference();
236         }
237 
238         @Override
getOnItemClickListener()239         protected DialogInterface.OnClickListener getOnItemClickListener() {
240             return new DialogInterface.OnClickListener() {
241                 public void onClick(DialogInterface dialog, int which) {
242                     final RestrictedListPreference preference = getCustomizablePreference();
243                     if (which < 0 || which >= preference.getEntryValues().length) {
244                         return;
245                     }
246                     String entryValue = preference.getEntryValues()[which].toString();
247                     RestrictedItem item = preference.getRestrictedItemForEntryValue(entryValue);
248                     if (item != null) {
249                         ListView listView = ((AlertDialog) dialog).getListView();
250                         listView.setItemChecked(getLastCheckedPosition(), true);
251                         RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
252                                 item.enforcedAdmin);
253                     } else {
254                         setClickedDialogEntryIndex(which);
255                     }
256 
257                     if (getCustomizablePreference().isAutoClosePreference()) {
258                         /*
259                          * Clicking on an item simulates the positive button
260                          * click, and dismisses the dialog.
261                          */
262                         RestrictedListPreferenceDialogFragment.this.onClick(dialog,
263                                 DialogInterface.BUTTON_POSITIVE);
264                         dialog.dismiss();
265                     }
266                 }
267             };
268         }
269 
getLastCheckedPosition()270         private int getLastCheckedPosition() {
271             if (mLastCheckedPosition == AdapterView.INVALID_POSITION) {
272                 mLastCheckedPosition = ((RestrictedListPreference) getCustomizablePreference())
273                         .getSelectedValuePos();
274             }
275             return mLastCheckedPosition;
276         }
277 
setCheckedPosition(int checkedPosition)278         private void setCheckedPosition(int checkedPosition) {
279             mLastCheckedPosition = checkedPosition;
280         }
281 
282         @Override
setClickedDialogEntryIndex(int which)283         protected void setClickedDialogEntryIndex(int which) {
284             super.setClickedDialogEntryIndex(which);
285             mLastCheckedPosition = which;
286         }
287     }
288 
289     public static class RestrictedItem {
290         public final CharSequence entry;
291         public final CharSequence entryValue;
292         public final EnforcedAdmin enforcedAdmin;
293 
294         public RestrictedItem(CharSequence entry, CharSequence entryValue,
295                 EnforcedAdmin enforcedAdmin) {
296             this.entry = entry;
297             this.entryValue = entryValue;
298             this.enforcedAdmin = enforcedAdmin;
299         }
300     }
301 }
302