Home | History | Annotate | Download | only in notification
      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.notification;
     18 
     19 import android.content.Context;
     20 import android.graphics.drawable.Drawable;
     21 import android.support.v7.preference.DropDownPreference;
     22 import android.support.v7.preference.PreferenceViewHolder;
     23 import android.util.AttributeSet;
     24 import android.view.View;
     25 import android.view.ViewGroup;
     26 import android.widget.AdapterView;
     27 import android.widget.AdapterView.OnItemSelectedListener;
     28 import android.widget.ArrayAdapter;
     29 import android.widget.Spinner;
     30 import android.widget.TextView;
     31 
     32 import com.android.settings.R;
     33 import com.android.settingslib.RestrictedLockUtils;
     34 import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
     35 import com.android.settingslib.RestrictedPreferenceHelper;
     36 
     37 import java.util.ArrayList;
     38 import java.util.List;
     39 
     40 public class RestrictedDropDownPreference extends DropDownPreference {
     41     private final RestrictedPreferenceHelper mHelper;
     42     private ReselectionSpinner mSpinner;
     43     private List<RestrictedItem> mRestrictedItems = new ArrayList<>();
     44     private boolean mUserClicked = false;
     45     private OnPreferenceClickListener mPreClickListener;
     46 
     47     public RestrictedDropDownPreference(Context context, AttributeSet attrs) {
     48         super(context, attrs);
     49         setLayoutResource(R.layout.restricted_preference_dropdown);
     50         setWidgetLayoutResource(R.layout.restricted_icon);
     51         mHelper = new RestrictedPreferenceHelper(context, this, attrs);
     52     }
     53 
     54     @Override
     55     protected ArrayAdapter createAdapter() {
     56         return new RestrictedArrayItemAdapter(getContext());
     57     }
     58 
     59     @Override
     60     public void setValue(String value) {
     61         if (getRestrictedItemForEntryValue(value) != null) {
     62             return;
     63         }
     64         super.setValue(value);
     65     }
     66 
     67     @Override
     68     public void onBindViewHolder(PreferenceViewHolder view) {
     69         mSpinner = (ReselectionSpinner) view.itemView.findViewById(R.id.spinner);
     70         mSpinner.setPreference(this);
     71         super.onBindViewHolder(view);
     72         mHelper.onBindViewHolder(view);
     73         mSpinner.setOnItemSelectedListener(mItemSelectedListener);
     74         final View restrictedIcon = view.findViewById(R.id.restricted_icon);
     75         if (restrictedIcon != null) {
     76             restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
     77         }
     78     }
     79 
     80     private boolean isRestrictedForEntry(CharSequence entry) {
     81         if (entry == null) {
     82             return false;
     83         }
     84         for (RestrictedItem item : mRestrictedItems) {
     85             if (entry.equals(item.entry)) {
     86                 return true;
     87             }
     88         }
     89         return false;
     90     }
     91 
     92     private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) {
     93         if (entryValue == null) {
     94             return null;
     95         }
     96         for (RestrictedItem item : mRestrictedItems) {
     97             if (entryValue.equals(item.entryValue)) {
     98                 return item;
     99             }
    100         }
    101         return null;
    102     }
    103 
    104     private RestrictedItem getRestrictedItemForPosition(int position) {
    105         if (position < 0 || position >= getEntryValues().length) {
    106             return null;
    107         }
    108         CharSequence entryValue = getEntryValues()[position];
    109         return getRestrictedItemForEntryValue(entryValue);
    110     }
    111 
    112     public void addRestrictedItem(RestrictedItem item) {
    113         mRestrictedItems.add(item);
    114     }
    115 
    116     public void clearRestrictedItems() {
    117         mRestrictedItems.clear();
    118     }
    119 
    120     @Override
    121     public void performClick() {
    122         if (mPreClickListener != null && mPreClickListener.onPreferenceClick(this)) {
    123             return;
    124         }
    125         if (!mHelper.performClick()) {
    126             mUserClicked = true;
    127             super.performClick();
    128         }
    129     }
    130 
    131     @Override
    132     public void setEnabled(boolean enabled) {
    133         if (enabled && isDisabledByAdmin()) {
    134             mHelper.setDisabledByAdmin(null);
    135             return;
    136         }
    137         super.setEnabled(enabled);
    138     }
    139 
    140     public void setDisabledByAdmin(EnforcedAdmin admin) {
    141         if (mHelper.setDisabledByAdmin(admin)) {
    142             notifyChanged();
    143         }
    144     }
    145 
    146     /**
    147      * Similar to {@link #setOnPreferenceClickListener(OnPreferenceClickListener)}, but can
    148      * preempt {@link #onClick()}.
    149      */
    150     public void setOnPreClickListener(OnPreferenceClickListener l) {
    151         mPreClickListener = l;
    152     }
    153 
    154     public boolean isDisabledByAdmin() {
    155         return mHelper.isDisabledByAdmin();
    156     }
    157 
    158     private void setUserClicked(boolean userClicked) {
    159         mUserClicked = userClicked;
    160     }
    161 
    162     private boolean isUserClicked() {
    163         return mUserClicked;
    164     }
    165 
    166     private final OnItemSelectedListener mItemSelectedListener = new OnItemSelectedListener() {
    167         @Override
    168         public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
    169             if (mUserClicked) {
    170                 mUserClicked = false;
    171             } else {
    172                 return;
    173             }
    174             if (position >= 0 && position < getEntryValues().length) {
    175                 String value = getEntryValues()[position].toString();
    176                 RestrictedItem item = getRestrictedItemForEntryValue(value);
    177                 if (item != null) {
    178                     RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
    179                             item.enforcedAdmin);
    180                     mSpinner.setSelection(findIndexOfValue(getValue()));
    181                 } else if (!value.equals(getValue()) && callChangeListener(value)) {
    182                     setValue(value);
    183                 }
    184             }
    185         }
    186 
    187         @Override
    188         public void onNothingSelected(AdapterView<?> parent) {
    189             // noop
    190         }
    191     };
    192 
    193     /**
    194      * Extension of {@link ArrayAdapter} which updates the state of the dropdown item
    195      * depending on whether it is restricted by the admin.
    196      */
    197     private class RestrictedArrayItemAdapter extends ArrayAdapter<String> {
    198         private static final int TEXT_RES_ID = android.R.id.text1;
    199         public RestrictedArrayItemAdapter(Context context) {
    200             super(context, R.layout.spinner_dropdown_restricted_item, TEXT_RES_ID);
    201         }
    202 
    203         @Override
    204         public View getDropDownView(int position, View convertView, ViewGroup parent) {
    205             View rootView = super.getView(position, convertView, parent);
    206             CharSequence entry = getItem(position);
    207             boolean isEntryRestricted = isRestrictedForEntry(entry);
    208             TextView text = (TextView) rootView.findViewById(TEXT_RES_ID);
    209             if (text != null) {
    210                 text.setEnabled(!isEntryRestricted);
    211             }
    212             View restrictedIcon = rootView.findViewById(R.id.restricted_icon);
    213             if (restrictedIcon != null) {
    214                 restrictedIcon.setVisibility(isEntryRestricted ? View.VISIBLE : View.GONE);
    215             }
    216             return rootView;
    217         }
    218     }
    219 
    220     /**
    221      * Extension of {@link Spinner} which triggers the admin support dialog on user clicking a
    222      * restricted item even if was already selected.
    223      */
    224     public static class ReselectionSpinner extends Spinner {
    225         private RestrictedDropDownPreference pref;
    226 
    227         public ReselectionSpinner(Context context, AttributeSet attrs) {
    228             super(context, attrs);
    229         }
    230 
    231         public void setPreference(RestrictedDropDownPreference pref) {
    232             this.pref = pref;
    233         }
    234 
    235         @Override
    236         public void setSelection(int position) {
    237             int previousSelectedPosition = getSelectedItemPosition();
    238             super.setSelection(position);
    239             if (position == previousSelectedPosition && pref.isUserClicked()) {
    240                 pref.setUserClicked(false);
    241                 RestrictedItem item = pref.getRestrictedItemForPosition(position);
    242                 if (item != null) {
    243                     RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
    244                             item.enforcedAdmin);
    245                 }
    246             }
    247         }
    248     }
    249 
    250     public static class RestrictedItem {
    251         public final CharSequence entry;
    252         public final CharSequence entryValue;
    253         public final EnforcedAdmin enforcedAdmin;
    254 
    255         public RestrictedItem(CharSequence entry, CharSequence entryValue,
    256                 EnforcedAdmin enforcedAdmin) {
    257             this.entry = entry;
    258             this.entryValue = entryValue;
    259             this.enforcedAdmin = enforcedAdmin;
    260         }
    261     }
    262 }