Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2010 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.Dialog;
     20 import android.app.DialogFragment;
     21 import android.app.Fragment;
     22 import android.content.ContentResolver;
     23 import android.content.DialogInterface;
     24 import android.content.pm.PackageManager;
     25 import android.os.Bundle;
     26 import android.preference.PreferenceActivity;
     27 import android.preference.PreferenceFragment;
     28 import android.util.Log;
     29 import android.widget.Button;
     30 
     31 /**
     32  * Base class for Settings fragments, with some helper functions and dialog management.
     33  */
     34 public class SettingsPreferenceFragment extends PreferenceFragment implements DialogCreatable {
     35 
     36     private static final String TAG = "SettingsPreferenceFragment";
     37 
     38     private SettingsDialogFragment mDialogFragment;
     39 
     40     @Override
     41     public void onActivityCreated(Bundle savedInstanceState) {
     42         super.onActivityCreated(savedInstanceState);
     43     }
     44 
     45     /*
     46      * The name is intentionally made different from Activity#finish(), so that
     47      * users won't misunderstand its meaning.
     48      */
     49     public final void finishFragment() {
     50         getActivity().onBackPressed();
     51     }
     52 
     53     // Some helpers for functions used by the settings fragments when they were activities
     54 
     55     /**
     56      * Returns the ContentResolver from the owning Activity.
     57      */
     58     protected ContentResolver getContentResolver() {
     59         return getActivity().getContentResolver();
     60     }
     61 
     62     /**
     63      * Returns the specified system service from the owning Activity.
     64      */
     65     protected Object getSystemService(final String name) {
     66         return getActivity().getSystemService(name);
     67     }
     68 
     69     /**
     70      * Returns the PackageManager from the owning Activity.
     71      */
     72     protected PackageManager getPackageManager() {
     73         return getActivity().getPackageManager();
     74     }
     75 
     76     @Override
     77     public void onDetach() {
     78         if (isRemoving()) {
     79             if (mDialogFragment != null) {
     80                 mDialogFragment.dismiss();
     81                 mDialogFragment = null;
     82             }
     83         }
     84         super.onDetach();
     85     }
     86 
     87     // Dialog management
     88 
     89     protected void showDialog(int dialogId) {
     90         if (mDialogFragment != null) {
     91             Log.e(TAG, "Old dialog fragment not null!");
     92         }
     93         mDialogFragment = new SettingsDialogFragment(this, dialogId);
     94         mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
     95     }
     96 
     97     public Dialog onCreateDialog(int dialogId) {
     98         return null;
     99     }
    100 
    101     protected void removeDialog(int dialogId) {
    102         // mDialogFragment may not be visible yet in parent fragment's onResume().
    103         // To be able to dismiss dialog at that time, don't check
    104         // mDialogFragment.isVisible().
    105         if (mDialogFragment != null && mDialogFragment.getDialogId() == dialogId) {
    106             mDialogFragment.dismiss();
    107         }
    108         mDialogFragment = null;
    109     }
    110 
    111     /**
    112      * Sets the OnCancelListener of the dialog shown. This method can only be
    113      * called after showDialog(int) and before removeDialog(int). The method
    114      * does nothing otherwise.
    115      */
    116     protected void setOnCancelListener(DialogInterface.OnCancelListener listener) {
    117         if (mDialogFragment != null) {
    118             mDialogFragment.mOnCancelListener = listener;
    119         }
    120     }
    121 
    122     /**
    123      * Sets the OnDismissListener of the dialog shown. This method can only be
    124      * called after showDialog(int) and before removeDialog(int). The method
    125      * does nothing otherwise.
    126      */
    127     protected void setOnDismissListener(DialogInterface.OnDismissListener listener) {
    128         if (mDialogFragment != null) {
    129             mDialogFragment.mOnDismissListener = listener;
    130         }
    131     }
    132 
    133     public static class SettingsDialogFragment extends DialogFragment {
    134         private static final String KEY_DIALOG_ID = "key_dialog_id";
    135         private static final String KEY_PARENT_FRAGMENT_ID = "key_parent_fragment_id";
    136 
    137         private int mDialogId;
    138 
    139         private Fragment mParentFragment;
    140 
    141         private DialogInterface.OnCancelListener mOnCancelListener;
    142         private DialogInterface.OnDismissListener mOnDismissListener;
    143 
    144         public SettingsDialogFragment() {
    145             /* do nothing */
    146         }
    147 
    148         public SettingsDialogFragment(DialogCreatable fragment, int dialogId) {
    149             mDialogId = dialogId;
    150             if (!(fragment instanceof Fragment)) {
    151                 throw new IllegalArgumentException("fragment argument must be an instance of "
    152                         + Fragment.class.getName());
    153             }
    154             mParentFragment = (Fragment) fragment;
    155         }
    156 
    157         @Override
    158         public void onSaveInstanceState(Bundle outState) {
    159             super.onSaveInstanceState(outState);
    160             if (mParentFragment != null) {
    161                 outState.putInt(KEY_DIALOG_ID, mDialogId);
    162                 outState.putInt(KEY_PARENT_FRAGMENT_ID, mParentFragment.getId());
    163             }
    164         }
    165 
    166         @Override
    167         public Dialog onCreateDialog(Bundle savedInstanceState) {
    168             if (savedInstanceState != null) {
    169                 mDialogId = savedInstanceState.getInt(KEY_DIALOG_ID, 0);
    170                 int mParentFragmentId = savedInstanceState.getInt(KEY_PARENT_FRAGMENT_ID, -1);
    171                 if (mParentFragmentId > -1) {
    172                     mParentFragment = getFragmentManager().findFragmentById(mParentFragmentId);
    173                     if (!(mParentFragment instanceof DialogCreatable)) {
    174                         throw new IllegalArgumentException(
    175                                 KEY_PARENT_FRAGMENT_ID + " must implement "
    176                                         + DialogCreatable.class.getName());
    177                     }
    178                 }
    179                 // This dialog fragment could be created from non-SettingsPreferenceFragment
    180                 if (mParentFragment instanceof SettingsPreferenceFragment) {
    181                     // restore mDialogFragment in mParentFragment
    182                     ((SettingsPreferenceFragment) mParentFragment).mDialogFragment = this;
    183                 }
    184             }
    185             return ((DialogCreatable) mParentFragment).onCreateDialog(mDialogId);
    186         }
    187 
    188         @Override
    189         public void onCancel(DialogInterface dialog) {
    190             super.onCancel(dialog);
    191             if (mOnCancelListener != null) {
    192                 mOnCancelListener.onCancel(dialog);
    193             }
    194         }
    195 
    196         @Override
    197         public void onDismiss(DialogInterface dialog) {
    198             super.onDismiss(dialog);
    199             if (mOnDismissListener != null) {
    200                 mOnDismissListener.onDismiss(dialog);
    201             }
    202         }
    203 
    204         public int getDialogId() {
    205             return mDialogId;
    206         }
    207 
    208         @Override
    209         public void onDetach() {
    210             super.onDetach();
    211 
    212             // This dialog fragment could be created from non-SettingsPreferenceFragment
    213             if (mParentFragment instanceof SettingsPreferenceFragment) {
    214                 // in case the dialog is not explicitly removed by removeDialog()
    215                 if (((SettingsPreferenceFragment) mParentFragment).mDialogFragment == this) {
    216                     ((SettingsPreferenceFragment) mParentFragment).mDialogFragment = null;
    217                 }
    218             }
    219         }
    220     }
    221 
    222     protected boolean hasNextButton() {
    223         return ((ButtonBarHandler)getActivity()).hasNextButton();
    224     }
    225 
    226     protected Button getNextButton() {
    227         return ((ButtonBarHandler)getActivity()).getNextButton();
    228     }
    229 
    230     public void finish() {
    231         getActivity().onBackPressed();
    232     }
    233 
    234     public boolean startFragment(
    235             Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
    236         if (getActivity() instanceof PreferenceActivity) {
    237             PreferenceActivity preferenceActivity = (PreferenceActivity)getActivity();
    238             preferenceActivity.startPreferencePanel(fragmentClass, extras,
    239                     R.string.lock_settings_picker_title, null, caller, requestCode);
    240             return true;
    241         } else {
    242             Log.w(TAG, "Parent isn't PreferenceActivity, thus there's no way to launch the "
    243                     + "given Fragment (name: " + fragmentClass + ", requestCode: " + requestCode
    244                     + ")");
    245             return false;
    246         }
    247     }
    248 
    249 }
    250