Advertisement
Guest User

Settings PreferenceActivity

a guest
Feb 11th, 2013
677
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 34.87 KB | None | 0 0
  1. /*
  2.  * Copyright (C) 2008 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 com.android.internal.util.ArrayUtils;
  20. import com.android.settings.accounts.AccountSyncSettings;
  21. import com.android.settings.accounts.AuthenticatorHelper;
  22. import com.android.settings.accounts.ManageAccountsSettings;
  23. import com.android.settings.applications.ManageApplications;
  24. import com.android.settings.bluetooth.BluetoothEnabler;
  25. import com.android.settings.deviceinfo.Memory;
  26. import com.android.settings.fuelgauge.PowerUsageSummary;
  27. import com.android.settings.profiles.ProfileEnabler;
  28. import com.android.settings.wifi.WifiEnabler;
  29.  
  30. import android.accounts.Account;
  31. import android.accounts.AccountManager;
  32. import android.accounts.OnAccountsUpdateListener;
  33. import android.content.ComponentName;
  34. import android.content.Context;
  35. import android.content.Intent;
  36. import android.content.pm.ActivityInfo;
  37. import android.content.pm.PackageManager;
  38. import android.content.pm.PackageManager.NameNotFoundException;
  39. import android.content.pm.ResolveInfo;
  40. import android.graphics.drawable.Drawable;
  41. import android.os.Bundle;
  42. import android.os.INetworkManagementService;
  43. import android.os.RemoteException;
  44. import android.os.ServiceManager;
  45. import android.os.UserId;
  46. import android.preference.Preference;
  47. import android.preference.PreferenceActivity;
  48. import android.preference.PreferenceActivity.Header;
  49. import android.preference.PreferenceFragment;
  50. import android.text.TextUtils;
  51. import android.util.Log;
  52. import android.view.LayoutInflater;
  53. import android.view.View;
  54. import android.view.View.OnClickListener;
  55. import android.view.ViewGroup;
  56. import android.widget.ArrayAdapter;
  57. import android.widget.BaseAdapter;
  58. import android.widget.Button;
  59. import android.widget.ImageView;
  60. import android.widget.ListAdapter;
  61. import android.widget.Switch;
  62. import android.widget.TextView;
  63.  
  64. import java.util.ArrayList;
  65. import java.util.Collections;
  66. import java.util.Comparator;
  67. import java.util.HashMap;
  68. import java.util.List;
  69.  
  70. /**
  71.  * Top-level settings activity to handle single pane and double pane UI layout.
  72.  */
  73. public class Settings extends PreferenceActivity
  74.         implements ButtonBarHandler, OnAccountsUpdateListener {
  75.  
  76.     private static final String LOG_TAG = "Settings";
  77.  
  78.     private static final String META_DATA_KEY_HEADER_ID =
  79.         "com.android.settings.TOP_LEVEL_HEADER_ID";
  80.     private static final String META_DATA_KEY_FRAGMENT_CLASS =
  81.         "com.android.settings.FRAGMENT_CLASS";
  82.     private static final String META_DATA_KEY_PARENT_TITLE =
  83.         "com.android.settings.PARENT_FRAGMENT_TITLE";
  84.     private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =
  85.         "com.android.settings.PARENT_FRAGMENT_CLASS";
  86.  
  87.     private static final String EXTRA_CLEAR_UI_OPTIONS = "settings:remove_ui_options";
  88.  
  89.     private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";
  90.     private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";
  91.  
  92.     private String mFragmentClass;
  93.     private int mTopLevelHeaderId;
  94.     private Header mFirstHeader;
  95.     private Header mCurrentHeader;
  96.     private Header mParentHeader;
  97.     private boolean mInLocalHeaderSwitch;
  98.  
  99.     // Show only these settings for restricted users
  100.     private int[] SETTINGS_FOR_RESTRICTED = {
  101.             R.id.wifi_settings,
  102.             R.id.bluetooth_settings,
  103.             R.id.sound_settings,
  104.             R.id.display_settings,
  105.             R.id.security_settings,
  106.             R.id.account_settings,
  107.             R.id.about_settings
  108.     };
  109.  
  110.     private boolean mEnableUserManagement = false;
  111.  
  112.     // TODO: Update Call Settings based on airplane mode state.
  113.  
  114.     protected HashMap<Integer, Integer> mHeaderIndexMap = new HashMap<Integer, Integer>();
  115.  
  116.     private AuthenticatorHelper mAuthenticatorHelper;
  117.     private Header mLastHeader;
  118.     private boolean mListeningToAccountUpdates;
  119.  
  120.     @Override
  121.     protected void onCreate(Bundle savedInstanceState) {
  122.         if (getIntent().getBooleanExtra(EXTRA_CLEAR_UI_OPTIONS, false)) {
  123.             getWindow().setUiOptions(0);
  124.         }
  125.  
  126.         if (android.provider.Settings.Secure.getInt(getContentResolver(), "multiuser_enabled", -1)
  127.                 > 0) {
  128.             mEnableUserManagement = true;
  129.         }
  130.  
  131.         mAuthenticatorHelper = new AuthenticatorHelper();
  132.         mAuthenticatorHelper.updateAuthDescriptions(this);
  133.         mAuthenticatorHelper.onAccountsUpdated(this, null);
  134.  
  135.         getMetaData();
  136.         mInLocalHeaderSwitch = true;
  137.         super.onCreate(savedInstanceState);
  138.         mInLocalHeaderSwitch = false;
  139.  
  140.         if (!onIsHidingHeaders() && onIsMultiPane()) {
  141.             highlightHeader(mTopLevelHeaderId);
  142.             // Force the title so that it doesn't get overridden by a direct launch of
  143.             // a specific settings screen.
  144.             setTitle(R.string.settings_label);
  145.         }
  146.  
  147.         // Retrieve any saved state
  148.         if (savedInstanceState != null) {
  149.             mCurrentHeader = savedInstanceState.getParcelable(SAVE_KEY_CURRENT_HEADER);
  150.             mParentHeader = savedInstanceState.getParcelable(SAVE_KEY_PARENT_HEADER);
  151.         }
  152.  
  153.         // If the current header was saved, switch to it
  154.         if (savedInstanceState != null && mCurrentHeader != null) {
  155.             //switchToHeaderLocal(mCurrentHeader);
  156.             showBreadCrumbs(mCurrentHeader.title, null);
  157.         }
  158.  
  159.         if (mParentHeader != null) {
  160.             setParentTitle(mParentHeader.title, null, new OnClickListener() {
  161.                 public void onClick(View v) {
  162.                     switchToParent(mParentHeader.fragment);
  163.                 }
  164.             });
  165.         }
  166.  
  167.         // Override up navigation for multi-pane, since we handle it in the fragment breadcrumbs
  168.         if (onIsMultiPane()) {
  169.             getActionBar().setDisplayHomeAsUpEnabled(false);
  170.             getActionBar().setHomeButtonEnabled(false);
  171.         }
  172.     }
  173.  
  174.     @Override
  175.     protected void onSaveInstanceState(Bundle outState) {
  176.         super.onSaveInstanceState(outState);
  177.  
  178.         // Save the current fragment, if it is the same as originally launched
  179.         if (mCurrentHeader != null) {
  180.             outState.putParcelable(SAVE_KEY_CURRENT_HEADER, mCurrentHeader);
  181.         }
  182.         if (mParentHeader != null) {
  183.             outState.putParcelable(SAVE_KEY_PARENT_HEADER, mParentHeader);
  184.         }
  185.     }
  186.  
  187.     @Override
  188.     public void onResume() {
  189.         super.onResume();
  190.  
  191.         ListAdapter listAdapter = getListAdapter();
  192.         if (listAdapter instanceof HeaderAdapter) {
  193.             ((HeaderAdapter) listAdapter).resume();
  194.         }
  195.         invalidateHeaders();
  196.     }
  197.  
  198.     @Override
  199.     public void onPause() {
  200.         super.onPause();
  201.  
  202.         ListAdapter listAdapter = getListAdapter();
  203.         if (listAdapter instanceof HeaderAdapter) {
  204.             ((HeaderAdapter) listAdapter).pause();
  205.         }
  206.     }
  207.  
  208.     @Override
  209.     public void onDestroy() {
  210.         super.onDestroy();
  211.         if (mListeningToAccountUpdates) {
  212.             AccountManager.get(this).removeOnAccountsUpdatedListener(this);
  213.         }
  214.     }
  215.  
  216.     private void switchToHeaderLocal(Header header) {
  217.         mInLocalHeaderSwitch = true;
  218.         switchToHeader(header);
  219.         mInLocalHeaderSwitch = false;
  220.     }
  221.  
  222.     @Override
  223.     public void switchToHeader(Header header) {
  224.         if (!mInLocalHeaderSwitch) {
  225.             mCurrentHeader = null;
  226.             mParentHeader = null;
  227.         }
  228.         super.switchToHeader(header);
  229.     }
  230.  
  231.     /**
  232.      * Switch to parent fragment and store the grand parent's info
  233.      * @param className name of the activity wrapper for the parent fragment.
  234.      */
  235.     private void switchToParent(String className) {
  236.         final ComponentName cn = new ComponentName(this, className);
  237.         try {
  238.             final PackageManager pm = getPackageManager();
  239.             final ActivityInfo parentInfo = pm.getActivityInfo(cn, PackageManager.GET_META_DATA);
  240.  
  241.             if (parentInfo != null && parentInfo.metaData != null) {
  242.                 String fragmentClass = parentInfo.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
  243.                 CharSequence fragmentTitle = parentInfo.loadLabel(pm);
  244.                 Header parentHeader = new Header();
  245.                 parentHeader.fragment = fragmentClass;
  246.                 parentHeader.title = fragmentTitle;
  247.                 mCurrentHeader = parentHeader;
  248.  
  249.                 switchToHeaderLocal(parentHeader);
  250.                 highlightHeader(mTopLevelHeaderId);
  251.  
  252.                 mParentHeader = new Header();
  253.                 mParentHeader.fragment
  254.                         = parentInfo.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
  255.                 mParentHeader.title = parentInfo.metaData.getString(META_DATA_KEY_PARENT_TITLE);
  256.             }
  257.         } catch (NameNotFoundException nnfe) {
  258.             Log.w(LOG_TAG, "Could not find parent activity : " + className);
  259.         }
  260.     }
  261.  
  262.     @Override
  263.     public void onNewIntent(Intent intent) {
  264.         super.onNewIntent(intent);
  265.  
  266.         // If it is not launched from history, then reset to top-level
  267.         if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0
  268.                 && mFirstHeader != null && !onIsHidingHeaders() && onIsMultiPane()) {
  269.             switchToHeaderLocal(mFirstHeader);
  270.         }
  271.     }
  272.  
  273.     private void highlightHeader(int id) {
  274.         if (id != 0) {
  275.             Integer index = mHeaderIndexMap.get(id);
  276.             if (index != null) {
  277.                 getListView().setItemChecked(index, true);
  278.                 getListView().smoothScrollToPosition(index);
  279.             }
  280.         }
  281.     }
  282.  
  283.     @Override
  284.     public Intent getIntent() {
  285.         Intent superIntent = super.getIntent();
  286.         String startingFragment = getStartingFragmentClass(superIntent);
  287.         // This is called from super.onCreate, isMultiPane() is not yet reliable
  288.         // Do not use onIsHidingHeaders either, which relies itself on this method
  289.         if (startingFragment != null && !onIsMultiPane()) {
  290.             Intent modIntent = new Intent(superIntent);
  291.             modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
  292.             Bundle args = superIntent.getExtras();
  293.             if (args != null) {
  294.                 args = new Bundle(args);
  295.             } else {
  296.                 args = new Bundle();
  297.             }
  298.             args.putParcelable("intent", superIntent);
  299.             modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, superIntent.getExtras());
  300.             return modIntent;
  301.         }
  302.         return superIntent;
  303.     }
  304.  
  305.     /**
  306.      * Checks if the component name in the intent is different from the Settings class and
  307.      * returns the class name to load as a fragment.
  308.      */
  309.     protected String getStartingFragmentClass(Intent intent) {
  310.         if (mFragmentClass != null) return mFragmentClass;
  311.  
  312.         String intentClass = intent.getComponent().getClassName();
  313.         if (intentClass.equals(getClass().getName())) return null;
  314.  
  315.         if ("com.android.settings.ManageApplications".equals(intentClass)
  316.                 || "com.android.settings.RunningServices".equals(intentClass)
  317.                 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
  318.             // Old names of manage apps.
  319.             intentClass = com.android.settings.applications.ManageApplications.class.getName();
  320.         }
  321.  
  322.         return intentClass;
  323.     }
  324.  
  325.     /**
  326.      * Override initial header when an activity-alias is causing Settings to be launched
  327.      * for a specific fragment encoded in the android:name parameter.
  328.      */
  329.     @Override
  330.     public Header onGetInitialHeader() {
  331.         String fragmentClass = getStartingFragmentClass(super.getIntent());
  332.         if (fragmentClass != null) {
  333.             Header header = new Header();
  334.             header.fragment = fragmentClass;
  335.             header.title = getTitle();
  336.             header.fragmentArguments = getIntent().getExtras();
  337.             mCurrentHeader = header;
  338.             return header;
  339.         }
  340.  
  341.         return mFirstHeader;
  342.     }
  343.  
  344.     @Override
  345.     public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
  346.             int titleRes, int shortTitleRes) {
  347.         Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,
  348.                 titleRes, shortTitleRes);
  349.  
  350.         // some fragments want to avoid split actionbar
  351.         if (DataUsageSummary.class.getName().equals(fragmentName) ||
  352.                 PowerUsageSummary.class.getName().equals(fragmentName) ||
  353.                 AccountSyncSettings.class.getName().equals(fragmentName) ||
  354.                 UserDictionarySettings.class.getName().equals(fragmentName) ||
  355.                 Memory.class.getName().equals(fragmentName) ||
  356.                 ManageApplications.class.getName().equals(fragmentName) ||
  357.                 WirelessSettings.class.getName().equals(fragmentName) ||
  358.                 SoundSettings.class.getName().equals(fragmentName) ||
  359.                 PrivacySettings.class.getName().equals(fragmentName) ||
  360.                 ManageAccountsSettings.class.getName().equals(fragmentName)) {
  361.             intent.putExtra(EXTRA_CLEAR_UI_OPTIONS, true);
  362.         }
  363.  
  364.         intent.setClass(this, SubSettings.class);
  365.         return intent;
  366.     }
  367.  
  368.     /**
  369.      * Populate the activity with the top-level headers.
  370.      */
  371.     @Override
  372.     public void onBuildHeaders(List<Header> headers) {
  373.         loadHeadersFromResource(R.xml.settings_headers, headers);
  374.  
  375.         updateHeaderList(headers);
  376.     }
  377.  
  378.     private void updateHeaderList(List<Header> target) {
  379.         int i = 0;
  380.         while (i < target.size()) {
  381.             Header header = target.get(i);
  382.             // Ids are integers, so downcasting
  383.             int id = (int) header.id;
  384.             if (id == R.id.dock_settings) {
  385.                 if (!needsDockSettings())
  386.                     target.remove(header);
  387.             } else if (id == R.id.operator_settings || id == R.id.manufacturer_settings ||
  388.                     id == R.id.advanced_settings) {
  389.                 Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
  390.             } else if (id == R.id.launcher_settings) {
  391.                 Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
  392.                 launcherIntent.addCategory(Intent.CATEGORY_HOME);
  393.                 launcherIntent.addCategory(Intent.CATEGORY_DEFAULT);
  394.  
  395.                 Intent launcherPreferencesIntent = new Intent(Intent.ACTION_MAIN);
  396.                 launcherPreferencesIntent.addCategory("com.cyanogenmod.category.LAUNCHER_PREFERENCES");
  397.  
  398.                 ActivityInfo defaultLauncher = getPackageManager().resolveActivity(launcherIntent, PackageManager.MATCH_DEFAULT_ONLY).activityInfo;
  399.                 launcherPreferencesIntent.setPackage(defaultLauncher.packageName);
  400.                 ResolveInfo launcherPreferences = getPackageManager().resolveActivity(launcherPreferencesIntent, 0);
  401.                 if (launcherPreferences != null) {
  402.                     header.intent = new Intent().setClassName(launcherPreferences.activityInfo.packageName,
  403.                             launcherPreferences.activityInfo.name);
  404.                 } else {
  405.                     target.remove(header);
  406.                 }
  407.             } else if (id == R.id.wifi_settings) {
  408.                 // Remove WiFi Settings if WiFi service is not available.
  409.                 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
  410.                     target.remove(header);
  411.                 }
  412.             } else if (id == R.id.bluetooth_settings) {
  413.                 // Remove Bluetooth Settings if Bluetooth service is not available.
  414.                 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
  415.                     target.remove(header);
  416.                 }
  417.             } else if (id == R.id.data_usage_settings) {
  418.                 // Remove data usage when kernel module not enabled
  419.                 final INetworkManagementService netManager = INetworkManagementService.Stub
  420.                         .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
  421.                 try {
  422.                     if (!netManager.isBandwidthControlEnabled()) {
  423.                         target.remove(header);
  424.                     }
  425.                 } catch (RemoteException e) {
  426.                     // ignored
  427.                 }
  428.             } else if (id == R.id.account_settings) {
  429.                 int headerIndex = i + 1;
  430.                 i = insertAccountsHeaders(target, headerIndex);
  431.             } else if (id == R.id.user_settings) {
  432.                 if (!mEnableUserManagement
  433.                         || !UserId.MU_ENABLED || UserId.myUserId() != 0
  434.                         || !getResources().getBoolean(R.bool.enable_user_management)
  435.                         || Utils.isMonkeyRunning()) {
  436.                     target.remove(header);
  437.                 }
  438.             }
  439.             if (UserId.MU_ENABLED && UserId.myUserId() != 0
  440.                     && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
  441.                 target.remove(header);
  442.             }
  443.  
  444.             // Increment if the current one wasn't removed by the Utils code.
  445.             if (target.get(i) == header) {
  446.                 // Hold on to the first header, when we need to reset to the top-level
  447.                 if (mFirstHeader == null &&
  448.                         HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {
  449.                     mFirstHeader = header;
  450.                 }
  451.                 mHeaderIndexMap.put(id, i);
  452.                 i++;
  453.             }
  454.         }
  455.     }
  456.  
  457.     private int insertAccountsHeaders(List<Header> target, int headerIndex) {
  458.         String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
  459.         List<Header> accountHeaders = new ArrayList<Header>(accountTypes.length);
  460.         for (String accountType : accountTypes) {
  461.             CharSequence label = mAuthenticatorHelper.getLabelForType(this, accountType);
  462.             if (label == null) {
  463.                 continue;
  464.             }
  465.  
  466.             Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
  467.             boolean skipToAccount = accounts.length == 1
  468.                     && !mAuthenticatorHelper.hasAccountPreferences(accountType);
  469.             Header accHeader = new Header();
  470.             accHeader.title = label;
  471.             if (accHeader.extras == null) {
  472.                 accHeader.extras = new Bundle();
  473.             }
  474.             if (skipToAccount) {
  475.                 accHeader.breadCrumbTitleRes = R.string.account_sync_settings_title;
  476.                 accHeader.breadCrumbShortTitleRes = R.string.account_sync_settings_title;
  477.                 accHeader.fragment = AccountSyncSettings.class.getName();
  478.                 accHeader.fragmentArguments = new Bundle();
  479.                 // Need this for the icon
  480.                 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
  481.                 accHeader.extras.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
  482.                 accHeader.fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
  483.                         accounts[0]);
  484.             } else {
  485.                 accHeader.breadCrumbTitle = label;
  486.                 accHeader.breadCrumbShortTitle = label;
  487.                 accHeader.fragment = ManageAccountsSettings.class.getName();
  488.                 accHeader.fragmentArguments = new Bundle();
  489.                 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
  490.                 accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE,
  491.                         accountType);
  492.                 if (!isMultiPane()) {
  493.                     accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
  494.                             label.toString());
  495.                 }
  496.             }
  497.             accountHeaders.add(accHeader);
  498.         }
  499.  
  500.         // Sort by label
  501.         Collections.sort(accountHeaders, new Comparator<Header>() {
  502.             @Override
  503.             public int compare(Header h1, Header h2) {
  504.                 return h1.title.toString().compareTo(h2.title.toString());
  505.             }
  506.         });
  507.  
  508.         for (Header header : accountHeaders) {
  509.             target.add(headerIndex++, header);
  510.         }
  511.         if (!mListeningToAccountUpdates) {
  512.             AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
  513.             mListeningToAccountUpdates = true;
  514.         }
  515.         return headerIndex;
  516.     }
  517.  
  518.     private boolean needsDockSettings() {
  519.         return getResources().getBoolean(R.bool.has_dock_settings);
  520.     }
  521.  
  522.     private void getMetaData() {
  523.         try {
  524.             ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
  525.                     PackageManager.GET_META_DATA);
  526.             if (ai == null || ai.metaData == null) return;
  527.             mTopLevelHeaderId = ai.metaData.getInt(META_DATA_KEY_HEADER_ID);
  528.             mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
  529.  
  530.             // Check if it has a parent specified and create a Header object
  531.             final int parentHeaderTitleRes = ai.metaData.getInt(META_DATA_KEY_PARENT_TITLE);
  532.             String parentFragmentClass = ai.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
  533.             if (parentFragmentClass != null) {
  534.                 mParentHeader = new Header();
  535.                 mParentHeader.fragment = parentFragmentClass;
  536.                 if (parentHeaderTitleRes != 0) {
  537.                     mParentHeader.title = getResources().getString(parentHeaderTitleRes);
  538.                 }
  539.             }
  540.         } catch (NameNotFoundException nnfe) {
  541.             // No recovery
  542.         }
  543.     }
  544.  
  545.     @Override
  546.     public boolean hasNextButton() {
  547.         return super.hasNextButton();
  548.     }
  549.  
  550.     @Override
  551.     public Button getNextButton() {
  552.         return super.getNextButton();
  553.     }
  554.  
  555.     private static class HeaderAdapter extends ArrayAdapter<Header> {
  556.         static final int HEADER_TYPE_CATEGORY = 0;
  557.         static final int HEADER_TYPE_NORMAL = 1;
  558.         static final int HEADER_TYPE_SWITCH = 2;
  559.         private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
  560.  
  561.         private final WifiEnabler mWifiEnabler;
  562.         private final BluetoothEnabler mBluetoothEnabler;
  563.         private final ProfileEnabler mProfileEnabler;
  564.  
  565.         private AuthenticatorHelper mAuthHelper;
  566.  
  567.         private static class HeaderViewHolder {
  568.             ImageView icon;
  569.             TextView title;
  570.             TextView summary;
  571.             Switch switch_;
  572.         }
  573.  
  574.         private LayoutInflater mInflater;
  575.  
  576.         static int getHeaderType(Header header) {
  577.             if (header.fragment == null && header.intent == null) {
  578.                 return HEADER_TYPE_CATEGORY;
  579.             } else if (header.id == R.id.wifi_settings
  580.                     || header.id == R.id.bluetooth_settings
  581.                     || header.id == R.id.profiles_settings) {
  582.                 return HEADER_TYPE_SWITCH;
  583.             } else {
  584.                 return HEADER_TYPE_NORMAL;
  585.             }
  586.         }
  587.  
  588.         @Override
  589.         public int getItemViewType(int position) {
  590.             Header header = getItem(position);
  591.             return getHeaderType(header);
  592.         }
  593.  
  594.         @Override
  595.         public boolean areAllItemsEnabled() {
  596.             return false; // because of categories
  597.         }
  598.  
  599.         @Override
  600.         public boolean isEnabled(int position) {
  601.             return getItemViewType(position) != HEADER_TYPE_CATEGORY;
  602.         }
  603.  
  604.         @Override
  605.         public int getViewTypeCount() {
  606.             return HEADER_TYPE_COUNT;
  607.         }
  608.  
  609.         @Override
  610.         public boolean hasStableIds() {
  611.             return true;
  612.         }
  613.  
  614.         public HeaderAdapter(Context context, List<Header> objects,
  615.                 AuthenticatorHelper authenticatorHelper) {
  616.             super(context, 0, objects);
  617.  
  618.             mAuthHelper = authenticatorHelper;
  619.             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  620.  
  621.             // Temp Switches provided as placeholder until the adapter replaces these with actual
  622.             // Switches inflated from their layouts. Must be done before adapter is set in super
  623.             mWifiEnabler = new WifiEnabler(context, new Switch(context));
  624.             mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
  625.             mProfileEnabler = new ProfileEnabler(context, null, new Switch(context));
  626.         }
  627.  
  628.         @Override
  629.         public View getView(int position, View convertView, ViewGroup parent) {
  630.             HeaderViewHolder holder;
  631.             Header header = getItem(position);
  632.             int headerType = getHeaderType(header);
  633.             View view = null;
  634.  
  635.             if (convertView == null || headerType == HEADER_TYPE_SWITCH) {
  636.                 holder = new HeaderViewHolder();
  637.                 switch (headerType) {
  638.                     case HEADER_TYPE_CATEGORY:
  639.                         view = new TextView(getContext(), null,
  640.                                 android.R.attr.listSeparatorTextViewStyle);
  641.                         holder.title = (TextView) view;
  642.                         break;
  643.  
  644.                     case HEADER_TYPE_SWITCH:
  645.                         view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
  646.                                 false);
  647.                         holder.icon = (ImageView) view.findViewById(R.id.icon);
  648.                         holder.title = (TextView)
  649.                                 view.findViewById(com.android.internal.R.id.title);
  650.                         holder.summary = (TextView)
  651.                                 view.findViewById(com.android.internal.R.id.summary);
  652.                         holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
  653.                         break;
  654.  
  655.                     case HEADER_TYPE_NORMAL:
  656.                         view = mInflater.inflate(
  657.                                 R.layout.preference_header_item, parent,
  658.                                 false);
  659.                         holder.icon = (ImageView) view.findViewById(R.id.icon);
  660.                         holder.title = (TextView)
  661.                                 view.findViewById(com.android.internal.R.id.title);
  662.                         holder.summary = (TextView)
  663.                                 view.findViewById(com.android.internal.R.id.summary);
  664.                         break;
  665.                 }
  666.                 view.setTag(holder);
  667.             } else {
  668.                 view = convertView;
  669.                 holder = (HeaderViewHolder) view.getTag();
  670.             }
  671.  
  672.             // All view fields must be updated every time, because the view may be recycled
  673.             switch (headerType) {
  674.                 case HEADER_TYPE_CATEGORY:
  675.                     holder.title.setText(header.getTitle(getContext().getResources()));
  676.                     break;
  677.  
  678.                 case HEADER_TYPE_SWITCH:
  679.                     // Would need a different treatment if the main menu had more switches
  680.                     if (header.id == R.id.wifi_settings) {
  681.                         mWifiEnabler.setSwitch(holder.switch_);
  682.                     } else if (header.id == R.id.bluetooth_settings) {
  683.                         mBluetoothEnabler.setSwitch(holder.switch_);
  684.                     } else if (header.id == R.id.profiles_settings) {
  685.                         mProfileEnabler.setSwitch(holder.switch_);
  686.                     }
  687.                     // No break, fall through on purpose to update common fields
  688.  
  689.                     //$FALL-THROUGH$
  690.                 case HEADER_TYPE_NORMAL:
  691.                     if (header.extras != null
  692.                             && header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
  693.                         String accType = header.extras.getString(
  694.                                 ManageAccountsSettings.KEY_ACCOUNT_TYPE);
  695.                         ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
  696.                         lp.width = getContext().getResources().getDimensionPixelSize(
  697.                                 R.dimen.header_icon_width);
  698.                         lp.height = lp.width;
  699.                         holder.icon.setLayoutParams(lp);
  700.                         Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
  701.                         holder.icon.setImageDrawable(icon);
  702.                     } else {
  703.                         holder.icon.setImageResource(header.iconRes);
  704.                     }
  705.                     holder.title.setText(header.getTitle(getContext().getResources()));
  706.                     CharSequence summary = header.getSummary(getContext().getResources());
  707.                     if (!TextUtils.isEmpty(summary)) {
  708.                         holder.summary.setVisibility(View.VISIBLE);
  709.                         holder.summary.setText(summary);
  710.                     } else {
  711.                         holder.summary.setVisibility(View.GONE);
  712.                     }
  713.                     break;
  714.             }
  715.  
  716.             return view;
  717.         }
  718.  
  719.         public void resume() {
  720.             mWifiEnabler.resume();
  721.             mBluetoothEnabler.resume();
  722.             mProfileEnabler.resume();
  723.         }
  724.  
  725.         public void pause() {
  726.             mWifiEnabler.pause();
  727.             mBluetoothEnabler.pause();
  728.             mProfileEnabler.pause();
  729.         }
  730.     }
  731.  
  732.     @Override
  733.     public void onHeaderClick(Header header, int position) {
  734.         boolean revert = false;
  735.         if (header.id == R.id.account_add) {
  736.             revert = true;
  737.         }
  738.  
  739.         super.onHeaderClick(header, position);
  740.  
  741.         if (revert && mLastHeader != null) {
  742.             highlightHeader((int) mLastHeader.id);
  743.         } else {
  744.             mLastHeader = header;
  745.         }
  746.     }
  747.  
  748.     @Override
  749.     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
  750.         // Override the fragment title for Wallpaper settings
  751.         int titleRes = pref.getTitleRes();
  752.         if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
  753.             titleRes = R.string.wallpaper_settings_fragment_title;
  754.         }
  755.         startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, pref.getTitle(),
  756.                 null, 0);
  757.         return true;
  758.     }
  759.  
  760.     public boolean shouldUpRecreateTask(Intent targetIntent) {
  761.         return super.shouldUpRecreateTask(new Intent(this, Settings.class));
  762.     }
  763.  
  764.     @Override
  765.     public void setListAdapter(ListAdapter adapter) {
  766.         if (adapter == null) {
  767.             super.setListAdapter(null);
  768.         } else {
  769.             super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
  770.         }
  771.     }
  772.  
  773.     @Override
  774.     public void onAccountsUpdated(Account[] accounts) {
  775.         mAuthenticatorHelper.onAccountsUpdated(this, accounts);
  776.         invalidateHeaders();
  777.     }
  778.  
  779.     /*
  780.      * Settings subclasses for launching independently.
  781.      */
  782.     public static class BluetoothSettingsActivity extends Settings { /* empty */ }
  783.     public static class WirelessSettingsActivity extends Settings { /* empty */ }
  784.     public static class TetherSettingsActivity extends Settings { /* empty */ }
  785.     public static class VpnSettingsActivity extends Settings { /* empty */ }
  786.     public static class DateTimeSettingsActivity extends Settings { /* empty */ }
  787.     public static class StorageSettingsActivity extends Settings { /* empty */ }
  788.     public static class WifiSettingsActivity extends Settings { /* empty */ }
  789.     public static class WifiP2pSettingsActivity extends Settings { /* empty */ }
  790.     public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ }
  791.     public static class KeyboardLayoutPickerActivity extends Settings { /* empty */ }
  792.     public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ }
  793.     public static class SpellCheckersSettingsActivity extends Settings { /* empty */ }
  794.     public static class LocalePickerActivity extends Settings { /* empty */ }
  795.     public static class UserDictionarySettingsActivity extends Settings { /* empty */ }
  796.     public static class SoundSettingsActivity extends Settings { /* empty */ }
  797.     public static class DisplaySettingsActivity extends Settings { /* empty */ }
  798.     public static class DeviceInfoSettingsActivity extends Settings { /* empty */ }
  799.     public static class ApplicationSettingsActivity extends Settings { /* empty */ }
  800.     public static class ManageApplicationsActivity extends Settings { /* empty */ }
  801.     public static class StorageUseActivity extends Settings { /* empty */ }
  802.     public static class DevelopmentSettingsActivity extends Settings { /* empty */ }
  803.     public static class AccessibilitySettingsActivity extends Settings { /* empty */ }
  804.     public static class SecuritySettingsActivity extends Settings { /* empty */ }
  805.     public static class LocationSettingsActivity extends Settings { /* empty */ }
  806.     public static class PrivacySettingsActivity extends Settings { /* empty */ }
  807.     public static class DockSettingsActivity extends Settings { /* empty */ }
  808.     public static class RunningServicesActivity extends Settings { /* empty */ }
  809.     public static class ManageAccountsSettingsActivity extends Settings { /* empty */ }
  810.     public static class PowerUsageSummaryActivity extends Settings { /* empty */ }
  811.     public static class AccountSyncSettingsActivity extends Settings { /* empty */ }
  812.     public static class AccountSyncSettingsInAddAccountActivity extends Settings { /* empty */ }
  813.     public static class CryptKeeperSettingsActivity extends Settings { /* empty */ }
  814.     public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }
  815.     public static class DataUsageSummaryActivity extends Settings { /* empty */ }
  816.     public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
  817.     public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
  818.     public static class AndroidBeamSettingsActivity extends Settings { /* empty */ }
  819.     public static class AnonymousStatsActivity extends Settings { /* empty */ }
  820.     public static class ApnSettingsActivity extends Settings { /* empty */ }
  821.     public static class ApnEditorActivity extends Settings { /* empty */ }
  822. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement