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