Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2017 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.tv.settings;
     18 
     19 import android.content.Context;
     20 import android.os.Bundle;
     21 import android.support.annotation.XmlRes;
     22 import android.support.v7.preference.Preference;
     23 import android.support.v7.preference.PreferenceManager;
     24 import android.support.v7.preference.PreferenceScreen;
     25 import android.util.ArraySet;
     26 import android.util.Log;
     27 
     28 import com.android.settingslib.core.AbstractPreferenceController;
     29 
     30 import java.util.ArrayList;
     31 import java.util.Collection;
     32 import java.util.List;
     33 import java.util.Set;
     34 import java.util.stream.Collectors;
     35 
     36 /**
     37  * Fragment for managing a screen of preferences controlled entirely through
     38  * {@link AbstractPreferenceController} objects. Based on DashboardFragment from mobile settings,
     39  * but without the Tile support.
     40  */
     41 public abstract class PreferenceControllerFragment extends SettingsPreferenceFragment {
     42     private static final String TAG = "PrefControllerFrag";
     43 
     44     private final Set<AbstractPreferenceController> mPreferenceControllers = new ArraySet<>();
     45 
     46     @Override
     47     public void onAttach(Context context) {
     48         super.onAttach(context);
     49         List<AbstractPreferenceController> controllers = onCreatePreferenceControllers(context);
     50         if (controllers == null) {
     51             controllers = new ArrayList<>();
     52         }
     53         mPreferenceControllers.addAll(controllers);
     54     }
     55 
     56     @Override
     57     public void onCreate(Bundle savedInstanceState) {
     58         super.onCreate(savedInstanceState);
     59         getPreferenceManager().setPreferenceComparisonCallback(
     60                 new PreferenceManager.SimplePreferenceComparisonCallback());
     61     }
     62 
     63     @Override
     64     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
     65         setPreferencesFromResource(getPreferenceScreenResId(), null);
     66         refreshAllPreferences();
     67     }
     68 
     69     @Override
     70     public void onResume() {
     71         super.onResume();
     72         updatePreferenceStates();
     73     }
     74 
     75     @Override
     76     public boolean onPreferenceTreeClick(Preference preference) {
     77         // Copy before iterating, in case a preference controller tries to update the list
     78         Collection<AbstractPreferenceController> controllers =
     79                 new ArrayList<>(mPreferenceControllers);
     80         // If preference contains intent, log it before handling.
     81         // Give all controllers a chance to handle click.
     82         for (AbstractPreferenceController controller : controllers) {
     83             if (controller.handlePreferenceTreeClick(preference)) {
     84                 return true;
     85             }
     86         }
     87         return super.onPreferenceTreeClick(preference);
     88     }
     89 
     90     @SuppressWarnings("unchecked")
     91     protected <T extends AbstractPreferenceController> T getOnePreferenceController(
     92             Class<T> clazz) {
     93         final List<AbstractPreferenceController> foundControllers =
     94                 mPreferenceControllers.stream()
     95                         .filter(clazz::isInstance).collect(Collectors.toList());
     96         if (foundControllers.size() > 0) {
     97             return (T) foundControllers.get(0);
     98         } else {
     99             return null;
    100         }
    101     }
    102 
    103     @SuppressWarnings("unchecked")
    104     protected  <T extends AbstractPreferenceController> Collection<T> getPreferenceControllers(
    105             Class<T> clazz) {
    106         return (Collection<T>) mPreferenceControllers.stream()
    107                 .filter(clazz::isInstance).collect(Collectors.toList());
    108     }
    109 
    110     protected void addPreferenceController(AbstractPreferenceController controller) {
    111         mPreferenceControllers.add(controller);
    112     }
    113 
    114     /**
    115      * Update state of each preference managed by PreferenceController.
    116      */
    117     protected void updatePreferenceStates() {
    118         Collection<AbstractPreferenceController> controllers =
    119                 new ArrayList<>(mPreferenceControllers);
    120         final PreferenceScreen screen = getPreferenceScreen();
    121         for (AbstractPreferenceController controller : controllers) {
    122             if (!controller.isAvailable()) {
    123                 continue;
    124             }
    125             final String key = controller.getPreferenceKey();
    126 
    127             final Preference preference = screen.findPreference(key);
    128             if (preference == null) {
    129                 Log.d(TAG, "Cannot find preference with key " + key
    130                         + " in Controller " + controller.getClass().getSimpleName());
    131                 continue;
    132             }
    133             controller.updateState(preference);
    134         }
    135     }
    136 
    137     private void refreshAllPreferences() {
    138         final PreferenceScreen screen = getPreferenceScreen();
    139         Collection<AbstractPreferenceController> controllers =
    140                 new ArrayList<>(mPreferenceControllers);
    141         for (AbstractPreferenceController controller : controllers) {
    142             controller.displayPreference(screen);
    143         }
    144     }
    145 
    146     /**
    147      * Get the res id for static preference xml for this fragment.
    148      */
    149     @XmlRes
    150     protected abstract int getPreferenceScreenResId();
    151 
    152     /**
    153      * Get a list of {@link AbstractPreferenceController} for this fragment.
    154      */
    155     protected abstract List<AbstractPreferenceController> onCreatePreferenceControllers(
    156             Context context);
    157 }
    158