diff --git a/src/com/android/settings/PrintingSettings.java b/src/com/android/settings/PrintingSettings.java
deleted file mode 100644
index 723bdc9..0000000
--- a/src/com/android/settings/PrintingSettings.java
+++ /dev/null
@@ -1,587 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.preference.Preference;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceCategory;
-import android.preference.PreferenceScreen;
-import android.printservice.PrintServiceInfo;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.text.TextUtils.SimpleStringSplitter;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import com.android.internal.content.PackageMonitor;
-import com.android.settings.PrintingSettings.ToggleSwitch.OnBeforeCheckedChangeListener;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Activity with the printing settings.
- */
-public class PrintingSettings extends SettingsPreferenceFragment implements DialogCreatable {
-
-    private static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':';
-
-    // Preference categories
-    private static final String SERVICES_CATEGORY = "services_category";
-
-    // Extras passed to sub-fragments.
-    private static final String EXTRA_PREFERENCE_KEY = "preference_key";
-    private static final String EXTRA_CHECKED = "checked";
-    private static final String EXTRA_TITLE = "title";
-    private static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title";
-    private static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message";
-    private static final String EXTRA_SETTINGS_TITLE = "settings_title";
-    private static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
-    private static final String EXTRA_ADD_PRINTERS_TITLE = "add_printers_title";
-    private static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "add_printers_component_name";
-    private static final String EXTRA_SERVICE_COMPONENT_NAME = "service_component_name";
-
-    // Auxiliary members.
-    private final static SimpleStringSplitter sStringColonSplitter =
-            new SimpleStringSplitter(ENABLED_PRINT_SERVICES_SEPARATOR);
-
-    private static final List<ResolveInfo> sInstalledServicesList = new ArrayList<ResolveInfo>();
-
-    private static final Set<ComponentName> sEnabledServiceNameSet = new HashSet<ComponentName>();
-
-    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
-
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void dispatchMessage(Message msg) {
-            super.dispatchMessage(msg);
-            loadInstalledServices(getActivity());
-            loadEnabledServices(getActivity());
-            updateServicesPreferences();
-        }
-    };
-
-    private final SettingsContentObserver mSettingsContentObserver =
-            new SettingsContentObserver(mHandler) {
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            loadInstalledServices(getActivity());
-            loadEnabledServices(getActivity());
-            updateServicesPreferences();
-        }
-    };
-
-    // Preference controls.
-    private PreferenceCategory mServicesCategory;
-
-    private Preference mNoServicesMessagePreference;
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-        addPreferencesFromResource(R.xml.print_settings);
-        mServicesCategory = (PreferenceCategory) findPreference(SERVICES_CATEGORY);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
-        mSettingsContentObserver.register(getContentResolver());
-        loadInstalledServices(getActivity());
-        loadEnabledServices(getActivity());
-        updateServicesPreferences();
-    }
-
-    @Override
-    public void onPause() {
-        mSettingsPackageMonitor.unregister();
-        mSettingsContentObserver.unregister(getContentResolver());
-        super.onPause();
-    }
-
-    private void updateServicesPreferences() {
-        // Since services category is auto generated we have to do a pass
-        // to generate it since services can come and go.
-        mServicesCategory.removeAll();
-
-       final int installedServiceCount = sInstalledServicesList.size();
-        for (int i = 0; i < installedServiceCount; i++) {
-            ResolveInfo installedService = sInstalledServicesList.get(i);
-
-            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
-                    getActivity());
-
-            String title = installedService.loadLabel(getPackageManager()).toString();
-            preference.setTitle(title);
-
-            ComponentName componentName = new ComponentName(
-                    installedService.serviceInfo.packageName,
-                    installedService.serviceInfo.name);
-            preference.setKey(componentName.flattenToString());
-
-            final boolean serviceEnabled = sEnabledServiceNameSet.contains(componentName);
-            if (serviceEnabled) {
-                preference.setSummary(getString(R.string.print_feature_state_on));
-            } else {
-                preference.setSummary(getString(R.string.print_feature_state_off));
-            }
-
-            preference.setOrder(i);
-            preference.setFragment(TogglePrintServicePreferenceFragment.class.getName());
-            preference.setPersistent(false);
-
-            Bundle extras = preference.getExtras();
-            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
-            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
-            extras.putString(EXTRA_TITLE, title);
-
-            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
-                    installedService, getActivity());
-
-            CharSequence applicationLabel = installedService.loadLabel(getPackageManager());
-
-            extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
-                    R.string.print_service_security_warning_title, applicationLabel));
-            extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
-                    R.string.print_service_security_warning_summary, applicationLabel));
-
-            String settingsClassName = printServiceInfo.getSettingsActivityName();
-            if (!TextUtils.isEmpty(settingsClassName)) {
-                extras.putString(EXTRA_SETTINGS_TITLE,
-                        getString(R.string.print_menu_item_settings));
-                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
-                        new ComponentName(installedService.serviceInfo.packageName,
-                                settingsClassName).flattenToString());
-            }
-
-            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
-            if (!TextUtils.isEmpty(addPrinterClassName)) {
-                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
-                        getString(R.string.print_menu_item_add_printers));
-                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
-                        new ComponentName(installedService.serviceInfo.packageName,
-                                addPrinterClassName).flattenToString());
-            }
-
-            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
-
-            mServicesCategory.addPreference(preference);
-        }
-
-        if (mServicesCategory.getPreferenceCount() == 0) {
-            if (mNoServicesMessagePreference == null) {
-                mNoServicesMessagePreference = new Preference(getActivity()) {
-                    @Override
-                    protected void onBindView(View view) {
-                        super.onBindView(view);
-                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
-                        String title = getString(R.string.print_no_services_installed);
-                        summaryView.setText(title);
-                    }
-                };
-                mNoServicesMessagePreference.setPersistent(false);
-                mNoServicesMessagePreference.setLayoutResource(
-                        R.layout.text_description_preference);
-                mNoServicesMessagePreference.setSelectable(false);
-            }
-            mServicesCategory.addPreference(mNoServicesMessagePreference);
-        }
-    }
-
-    private static void loadInstalledServices(Context context) {
-        sInstalledServicesList.clear();
-        List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentServices(
-                    new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
-                    PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
-        final int resolveInfoCount = resolveInfos.size();
-        for (int i = 0, count = resolveInfoCount; i < count; i++) {
-            ResolveInfo resolveInfo = resolveInfos.get(i);
-            sInstalledServicesList.add(resolveInfo);
-        }
-    }
-
-    private static void loadEnabledServices(Context context) {
-        sEnabledServiceNameSet.clear();
-
-        String enabledServicesSetting = Settings.Secure.getString(context
-                .getContentResolver(), Settings.Secure.ENABLED_PRINT_SERVICES);
-        if (enabledServicesSetting == null) {
-            enabledServicesSetting = "";
-        }
-
-        SimpleStringSplitter colonSplitter = sStringColonSplitter;
-        colonSplitter.setString(enabledServicesSetting);
-
-        while (colonSplitter.hasNext()) {
-            String componentNameString = colonSplitter.next();
-            ComponentName enabledService = ComponentName.unflattenFromString(
-                    componentNameString);
-            sEnabledServiceNameSet.add(enabledService);
-        }
-    }
-
-    private class SettingsPackageMonitor extends PackageMonitor {
-        @Override
-        public void onPackageAdded(String packageName, int uid) {
-           mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageAppeared(String packageName, int reason) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageDisappeared(String packageName, int reason) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-
-        @Override
-        public void onPackageRemoved(String packageName, int uid) {
-            mHandler.obtainMessage().sendToTarget();
-        }
-    }
-
-    public static class ToggleSwitch extends Switch {
-
-        private OnBeforeCheckedChangeListener mOnBeforeListener;
-
-        public static interface OnBeforeCheckedChangeListener {
-            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
-        }
-
-        public ToggleSwitch(Context context) {
-            super(context);
-        }
-
-        public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
-            mOnBeforeListener = listener;
-        }
-
-        @Override
-        public void setChecked(boolean checked) {
-            if (mOnBeforeListener != null
-                    && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
-                return;
-            }
-            super.setChecked(checked);
-        }
-
-        public void setCheckedInternal(boolean checked) {
-            super.setChecked(checked);
-        }
-    }
-
-    public static class TogglePrintServicePreferenceFragment
-            extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
-
-        private static final int DIALOG_ID_ENABLE_WARNING = 1;
-
-        private final SettingsContentObserver mSettingsContentObserver =
-                new SettingsContentObserver(new Handler()) {
-            @Override
-            public void onChange(boolean selfChange, Uri uri) {
-                String settingValue = Settings.Secure.getString(getContentResolver(),
-                        Settings.Secure.ENABLED_PRINT_SERVICES);
-                final boolean enabled = settingValue.contains(mComponentName);
-                mToggleSwitch.setCheckedInternal(enabled);
-            }
-        };
-
-        private CharSequence mEnableWarningTitle;
-        private CharSequence mEnableWarningMessage;
-
-        private String mComponentName;
-
-        @Override
-        public void onResume() {
-            mSettingsContentObserver.register(getContentResolver());
-            super.onResume();
-        }
-
-        @Override
-        public void onPause() {
-            mSettingsContentObserver.unregister(getContentResolver());
-            super.onPause();
-        }
-
-        @Override
-        public void onPreferenceToggled(String preferenceKey, boolean enabled) {
-            Set<ComponentName> enabledServices = sEnabledServiceNameSet;
-            ComponentName toggledService = ComponentName.unflattenFromString(preferenceKey);
-            if (enabled) {
-                enabledServices.add(toggledService);
-            } else {
-                enabledServices.remove(toggledService);
-            }
-            StringBuilder enabledServicesBuilder = new StringBuilder();
-            for (ComponentName enabledService : enabledServices) {
-                enabledServicesBuilder.append(enabledService.flattenToString());
-                enabledServicesBuilder.append(ENABLED_PRINT_SERVICES_SEPARATOR);
-            }
-            final int enabledServicesBuilderLength = enabledServicesBuilder.length();
-            if (enabledServicesBuilderLength > 0) {
-                enabledServicesBuilder.deleteCharAt(enabledServicesBuilderLength - 1);
-            }
-            Settings.Secure.putString(getContentResolver(),
-                    Settings.Secure.ENABLED_PRINT_SERVICES,
-                    enabledServicesBuilder.toString());
-        }
-
-        @Override
-        public Dialog onCreateDialog(int dialogId) {
-            CharSequence title = null;
-            CharSequence message = null;
-            switch (dialogId) {
-                case DIALOG_ID_ENABLE_WARNING:
-                    title = mEnableWarningTitle;
-                    message = mEnableWarningMessage;
-                    break;
-                default:
-                    throw new IllegalArgumentException();
-            }
-            return new AlertDialog.Builder(getActivity())
-                    .setTitle(title)
-                    .setIconAttribute(android.R.attr.alertDialogIcon)
-                    .setMessage(message)
-                    .setCancelable(true)
-                    .setPositiveButton(android.R.string.ok, this)
-                    .setNegativeButton(android.R.string.cancel, this)
-                    .create();
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            final boolean checked;
-            switch (which) {
-                case DialogInterface.BUTTON_POSITIVE:
-                    checked = true;
-                    mToggleSwitch.setCheckedInternal(checked);
-                    getArguments().putBoolean(EXTRA_CHECKED, checked);
-                    onPreferenceToggled(mPreferenceKey, checked);
-                    break;
-                case DialogInterface.BUTTON_NEGATIVE:
-                    checked = false;
-                    mToggleSwitch.setCheckedInternal(checked);
-                    getArguments().putBoolean(EXTRA_CHECKED, checked);
-                    onPreferenceToggled(mPreferenceKey, checked);
-                    break;
-                default:
-                    throw new IllegalArgumentException();
-            }
-        }
-
-        @Override
-        protected void onInstallActionBarToggleSwitch() {
-            super.onInstallActionBarToggleSwitch();
-            mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
-                @Override
-                public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
-                    if (checked) {
-                        if (!TextUtils.isEmpty(mEnableWarningMessage)) {
-                            toggleSwitch.setCheckedInternal(false);
-                            getArguments().putBoolean(EXTRA_CHECKED, false);
-                            showDialog(DIALOG_ID_ENABLE_WARNING);
-                            return true;
-                        }
-                        onPreferenceToggled(mPreferenceKey, true);
-                    } else {
-                        onPreferenceToggled(mPreferenceKey, false);
-                    }
-                    return false;
-                }
-            });
-        }
-
-        @Override
-        protected void onProcessArguments(Bundle arguments) {
-            super.onProcessArguments(arguments);
-            // Settings title and intent.
-            String settingsTitle = arguments.getString(EXTRA_SETTINGS_TITLE);
-            String settingsComponentName = arguments.getString(EXTRA_SETTINGS_COMPONENT_NAME);
-            if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
-                Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                        ComponentName.unflattenFromString(settingsComponentName.toString()));
-                if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) {
-                    mSettingsTitle = settingsTitle;
-                    mSettingsIntent = settingsIntent;
-                    setHasOptionsMenu(true);
-                }
-            }
-            // Add printers title and intent.
-            String addPrintersTitle = arguments.getString(EXTRA_ADD_PRINTERS_TITLE);
-            String addPrintersComponentName =
-                    arguments.getString(EXTRA_ADD_PRINTERS_COMPONENT_NAME);
-            if (!TextUtils.isEmpty(addPrintersTitle)
-                    && !TextUtils.isEmpty(addPrintersComponentName)) {
-                Intent addPritnersIntent = new Intent(Intent.ACTION_MAIN).setComponent(
-                        ComponentName.unflattenFromString(addPrintersComponentName.toString()));
-                if (!getPackageManager().queryIntentActivities(addPritnersIntent, 0).isEmpty()) {
-                    mAddPrintersTitle = addPrintersTitle;
-                    mAddPrintersIntent = addPritnersIntent;
-                    setHasOptionsMenu(true);
-                }
-            }
-            // Enable warning title.
-            mEnableWarningTitle = arguments.getCharSequence(
-                    PrintingSettings.EXTRA_ENABLE_WARNING_TITLE);
-            // Enable warning message.
-            mEnableWarningMessage = arguments.getCharSequence(
-                    PrintingSettings.EXTRA_ENABLE_WARNING_MESSAGE);
-            // Component name.
-            mComponentName = arguments.getString(EXTRA_SERVICE_COMPONENT_NAME);
-        }
-    }
-
-    public static abstract class ToggleFeaturePreferenceFragment
-            extends SettingsPreferenceFragment {
-
-        protected ToggleSwitch mToggleSwitch;
-
-        protected String mPreferenceKey;
-
-        protected CharSequence mSettingsTitle;
-        protected Intent mSettingsIntent;
-
-        protected CharSequence mAddPrintersTitle;
-        protected Intent mAddPrintersIntent;
-
-        // TODO: Showing sub-sub fragment does not handle the activity title
-        // so we do it but this is wrong. Do a real fix when there is time.
-        private CharSequence mOldActivityTitle;
-
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
-                    getActivity());
-            setPreferenceScreen(preferenceScreen);
-        }
-
-        @Override
-        public void onViewCreated(View view, Bundle savedInstanceState) {
-            super.onViewCreated(view, savedInstanceState);
-            onInstallActionBarToggleSwitch();
-            onProcessArguments(getArguments());
-            getListView().setDivider(null);
-            getListView().setEnabled(false);
-        }
-
-        @Override
-        public void onDestroyView() {
-            getActivity().getActionBar().setCustomView(null);
-            if (mOldActivityTitle != null) {
-                getActivity().getActionBar().setTitle(mOldActivityTitle);
-            }
-            mToggleSwitch.setOnBeforeCheckedChangeListener(null);
-            super.onDestroyView();
-        }
-
-        protected abstract void onPreferenceToggled(String preferenceKey, boolean enabled);
-
-        @Override
-        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-            super.onCreateOptionsMenu(menu, inflater);
-            if (!TextUtils.isEmpty(mSettingsTitle) && mSettingsIntent != null) {
-                MenuItem menuItem = menu.add(mSettingsTitle);
-                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-                menuItem.setIntent(mSettingsIntent);
-            }
-            if (!TextUtils.isEmpty(mAddPrintersTitle) && mAddPrintersIntent != null) {
-                MenuItem menuItem = menu.add(mAddPrintersTitle);
-                menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
-                menuItem.setIntent(mAddPrintersIntent);
-            }
-        }
-
-        protected void onInstallActionBarToggleSwitch() {
-            mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity());
-        }
-
-        private ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) {
-            ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
-            final int padding = activity.getResources().getDimensionPixelSize(
-                    R.dimen.action_bar_switch_padding);
-            toggleSwitch.setPaddingRelative(0, 0, padding, 0);
-            activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
-                    ActionBar.DISPLAY_SHOW_CUSTOM);
-            activity.getActionBar().setCustomView(toggleSwitch,
-                    new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
-                            ActionBar.LayoutParams.WRAP_CONTENT,
-                            Gravity.CENTER_VERTICAL | Gravity.END));
-            return toggleSwitch;
-        }
-
-        protected void onProcessArguments(Bundle arguments) {
-            // Key.
-            mPreferenceKey = arguments.getString(EXTRA_PREFERENCE_KEY);
-            // Enabled.
-            final boolean enabled = arguments.getBoolean(EXTRA_CHECKED);
-            mToggleSwitch.setCheckedInternal(enabled);
-            // Title.
-            PreferenceActivity activity = (PreferenceActivity) getActivity();
-            if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
-                mOldActivityTitle = getActivity().getTitle();
-                String title = arguments.getString(EXTRA_TITLE);
-                getActivity().getActionBar().setTitle(title);
-            }
-        }
-    }
-
-    private static abstract class SettingsContentObserver extends ContentObserver {
-
-        public SettingsContentObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register(ContentResolver contentResolver) {
-            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
-        }
-
-        public void unregister(ContentResolver contentResolver) {
-            contentResolver.unregisterContentObserver(this);
-        }
-
-        @Override
-        public abstract void onChange(boolean selfChange, Uri uri);
-    }
-}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index a58d2b7..35fe885 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -19,13 +19,11 @@
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
-import android.app.Fragment;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.RestrictionEntry;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
@@ -56,9 +54,6 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.settings.accessibility.AccessibilitySettings;
 import com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment;
-import com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment;
-import com.android.settings.ChooseLockPassword.ChooseLockPasswordFragment;
-import com.android.settings.ChooseLockPattern.ChooseLockPatternFragment;
 import com.android.settings.accounts.AccountSyncSettings;
 import com.android.settings.accounts.AuthenticatorHelper;
 import com.android.settings.accounts.ManageAccountsSettings;
@@ -76,8 +71,9 @@
 import com.android.settings.location.LocationSettings;
 import com.android.settings.nfc.AndroidBeam;
 import com.android.settings.nfc.PaymentSettings;
+import com.android.settings.print.PrintServiceSettingsFragment;
+import com.android.settings.print.PrintSettingsFragment;
 import com.android.settings.tts.TextToSpeechSettings;
-import com.android.settings.users.AppRestrictionsFragment;
 import com.android.settings.users.UserSettings;
 import com.android.settings.vpn2.VpnSettings;
 import com.android.settings.wfd.WifiDisplaySettings;
@@ -334,7 +330,7 @@
         UserSettings.class.getName(),
         NotificationAccessSettings.class.getName(),
         ManageAccountsSettings.class.getName(),
-        PrintingSettings.class.getName(),
+        PrintSettingsFragment.class.getName(),
         TrustedCredentialsSettings.class.getName(),
         PaymentSettings.class.getName()
     };
@@ -495,7 +491,9 @@
                 BluetoothSettings.class.getName().equals(fragmentName) ||
                 DreamSettings.class.getName().equals(fragmentName) ||
                 LocationSettings.class.getName().equals(fragmentName) ||
-                ToggleAccessibilityServicePreferenceFragment.class.getName().equals(fragmentName)) {
+                ToggleAccessibilityServicePreferenceFragment.class.getName().equals(fragmentName) ||
+                PrintSettingsFragment.class.getName().equals(fragmentName) ||
+                PrintServiceSettingsFragment.class.getName().equals(fragmentName)) {
             intent.putExtra(EXTRA_UI_OPTIONS, ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
         }
 
diff --git a/src/com/android/settings/print/PrintServiceSettingsFragment.java b/src/com/android/settings/print/PrintServiceSettingsFragment.java
new file mode 100644
index 0000000..c65e43e
--- /dev/null
+++ b/src/com/android/settings/print/PrintServiceSettingsFragment.java
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.print;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.LoaderManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.PreferenceActivity;
+import android.print.PrintManager;
+import android.print.PrinterDiscoverySession;
+import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
+import android.print.PrinterId;
+import android.print.PrinterInfo;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settings.print.PrintSettingsFragment.ToggleSwitch;
+import com.android.settings.print.PrintSettingsFragment.ToggleSwitch.OnBeforeCheckedChangeListener;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Fragment with print service settings.
+ */
+public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
+        implements DialogInterface.OnClickListener {
+
+    private static final int LOADER_ID_PRINTERS_LOADER = 1;
+
+    private static final int DIALOG_ID_ENABLE_WARNING = 1;
+
+    private final SettingsContentObserver mSettingsContentObserver =
+            new SettingsContentObserver(new Handler()) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            List<ComponentName> services = SettingsUtils.readEnabledPrintServices(getActivity());
+            final boolean enabled = services.contains(mComponentName);
+            mToggleSwitch.setCheckedInternal(enabled);
+        }
+    };
+
+    protected ToggleSwitch mToggleSwitch;
+
+    protected String mPreferenceKey;
+
+    protected CharSequence mSettingsTitle;
+    protected Intent mSettingsIntent;
+
+    protected CharSequence mAddPrintersTitle;
+    protected Intent mAddPrintersIntent;
+
+    private CharSequence mEnableWarningTitle;
+    private CharSequence mEnableWarningMessage;
+
+    private ComponentName mComponentName;
+
+    // TODO: Showing sub-sub fragment does not handle the activity title
+    // so we do it but this is wrong. Do a real fix when there is time.
+    private CharSequence mOldActivityTitle;
+
+    @Override
+    public void onResume() {
+        mSettingsContentObserver.register(getContentResolver());
+        super.onResume();
+    }
+
+    @Override
+    public void onPause() {
+        mSettingsContentObserver.unregister(getContentResolver());
+        super.onPause();
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+        onInstallActionBarToggleSwitch();
+        processArguments(getArguments());
+        getListView().setAdapter(new PrintersAdapter());
+    }
+
+    @Override
+    public void onDestroyView() {
+        getActivity().getActionBar().setCustomView(null);
+        if (mOldActivityTitle != null) {
+            getActivity().getActionBar().setTitle(mOldActivityTitle);
+        }
+        mToggleSwitch.setOnBeforeCheckedChangeListener(null);
+        super.onDestroyView();
+    }
+
+    private void onPreferenceToggled(String preferenceKey, boolean enabled) {
+        ComponentName service = ComponentName.unflattenFromString(preferenceKey);
+        List<ComponentName> services = SettingsUtils.readEnabledPrintServices(getActivity());
+        if (enabled) {
+            services.add(service);
+        } else {
+            services.remove(service);
+        }
+        SettingsUtils.writeEnabledPrintServices(getActivity(), services);
+    }
+
+    @Override
+    public Dialog onCreateDialog(int dialogId) {
+        CharSequence title = null;
+        CharSequence message = null;
+        switch (dialogId) {
+            case DIALOG_ID_ENABLE_WARNING:
+                title = mEnableWarningTitle;
+                message = mEnableWarningMessage;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        return new AlertDialog.Builder(getActivity())
+                .setTitle(title)
+                .setIconAttribute(android.R.attr.alertDialogIcon)
+                .setMessage(message)
+                .setCancelable(true)
+                .setPositiveButton(android.R.string.ok, this)
+                .setNegativeButton(android.R.string.cancel, this)
+                .create();
+    }
+
+    @Override
+    public void onClick(DialogInterface dialog, int which) {
+        final boolean checked;
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                checked = true;
+                mToggleSwitch.setCheckedInternal(checked);
+                getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                break;
+            case DialogInterface.BUTTON_NEGATIVE:
+                checked = false;
+                mToggleSwitch.setCheckedInternal(checked);
+                getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, checked);
+                onPreferenceToggled(mPreferenceKey, checked);
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+    }
+
+    protected void onInstallActionBarToggleSwitch() {
+        mToggleSwitch = createAndAddActionBarToggleSwitch(getActivity());
+        mToggleSwitch.setOnBeforeCheckedChangeListener(new OnBeforeCheckedChangeListener() {
+            @Override
+            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
+                if (checked) {
+                    if (!TextUtils.isEmpty(mEnableWarningMessage)) {
+                        toggleSwitch.setCheckedInternal(false);
+                        getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, false);
+                        showDialog(DIALOG_ID_ENABLE_WARNING);
+                        return true;
+                    }
+                    onPreferenceToggled(mPreferenceKey, true);
+                } else {
+                    onPreferenceToggled(mPreferenceKey, false);
+                }
+                return false;
+            }
+        });
+    }
+
+    private void processArguments(Bundle arguments) {
+        // Key.
+        mPreferenceKey = arguments.getString(PrintSettingsFragment.EXTRA_PREFERENCE_KEY);
+
+        // Enabled.
+        final boolean enabled = arguments.getBoolean(PrintSettingsFragment.EXTRA_CHECKED);
+        mToggleSwitch.setCheckedInternal(enabled);
+
+        // Title.
+        PreferenceActivity activity = (PreferenceActivity) getActivity();
+        if (!activity.onIsMultiPane() || activity.onIsHidingHeaders()) {
+            mOldActivityTitle = getActivity().getTitle();
+            String title = arguments.getString(PrintSettingsFragment.EXTRA_TITLE);
+            getActivity().getActionBar().setTitle(title);
+        }
+
+        // Settings title and intent.
+        String settingsTitle = arguments.getString(PrintSettingsFragment.EXTRA_SETTINGS_TITLE);
+        String settingsComponentName = arguments.getString(
+                PrintSettingsFragment.EXTRA_SETTINGS_COMPONENT_NAME);
+        if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
+            Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
+                    ComponentName.unflattenFromString(settingsComponentName.toString()));
+            if (!getPackageManager().queryIntentActivities(settingsIntent, 0).isEmpty()) {
+                mSettingsTitle = settingsTitle;
+                mSettingsIntent = settingsIntent;
+                setHasOptionsMenu(true);
+            }
+        }
+
+        // Add printers title and intent.
+        String addPrintersTitle = arguments.getString(
+                PrintSettingsFragment.EXTRA_ADD_PRINTERS_TITLE);
+        String addPrintersComponentName =
+                arguments.getString(PrintSettingsFragment.EXTRA_ADD_PRINTERS_COMPONENT_NAME);
+        if (!TextUtils.isEmpty(addPrintersTitle)
+                && !TextUtils.isEmpty(addPrintersComponentName)) {
+            Intent addPritnersIntent = new Intent(Intent.ACTION_MAIN).setComponent(
+                    ComponentName.unflattenFromString(addPrintersComponentName.toString()));
+            if (!getPackageManager().queryIntentActivities(addPritnersIntent, 0).isEmpty()) {
+                mAddPrintersTitle = addPrintersTitle;
+                mAddPrintersIntent = addPritnersIntent;
+                setHasOptionsMenu(true);
+            }
+        }
+
+        // Enable warning title.
+        mEnableWarningTitle = arguments.getCharSequence(
+                PrintSettingsFragment.EXTRA_ENABLE_WARNING_TITLE);
+
+        // Enable warning message.
+        mEnableWarningMessage = arguments.getCharSequence(
+                PrintSettingsFragment.EXTRA_ENABLE_WARNING_MESSAGE);
+
+        // Component name.
+        mComponentName = ComponentName.unflattenFromString(arguments
+                .getString(PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME));
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.print_service_settings, menu);
+
+        MenuItem addPrinters = menu.findItem(R.id.print_menu_item_add_printer);
+        if (!TextUtils.isEmpty(mAddPrintersTitle) && mAddPrintersIntent != null) {
+            addPrinters.setIntent(mAddPrintersIntent);
+        } else {
+            menu.removeItem(R.id.print_menu_item_add_printer);
+        }
+
+        MenuItem settings = menu.findItem(R.id.print_menu_item_settings);
+        if (!TextUtils.isEmpty(mSettingsTitle) && mSettingsIntent != null) {
+            settings.setIntent(mSettingsIntent);
+        } else {
+            menu.removeItem(R.id.print_menu_item_settings);
+        }
+
+        MenuItem uninstall = menu.findItem(R.id.print_menu_item_uninstall);
+        Intent uninstallIntent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE,
+                Uri.parse("package:" + mComponentName.getPackageName()));
+        uninstall.setIntent(uninstallIntent);
+    }
+
+    private ToggleSwitch createAndAddActionBarToggleSwitch(Activity activity) {
+        ToggleSwitch toggleSwitch = new ToggleSwitch(activity);
+        final int padding = activity.getResources().getDimensionPixelSize(
+                R.dimen.action_bar_switch_padding);
+        toggleSwitch.setPaddingRelative(0, 0, padding, 0);
+        activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
+                ActionBar.DISPLAY_SHOW_CUSTOM);
+        activity.getActionBar().setCustomView(toggleSwitch,
+                new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT,
+                        ActionBar.LayoutParams.WRAP_CONTENT,
+                        Gravity.CENTER_VERTICAL | Gravity.END));
+        return toggleSwitch;
+    }
+
+    private static abstract class SettingsContentObserver extends ContentObserver {
+
+    public SettingsContentObserver(Handler handler) {
+        super(handler);
+    }
+
+    public void register(ContentResolver contentResolver) {
+        contentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
+    }
+
+    public void unregister(ContentResolver contentResolver) {
+        contentResolver.unregisterContentObserver(this);
+    }
+
+    @Override
+    public abstract void onChange(boolean selfChange, Uri uri);
+
+    }
+
+    private final class PrintersAdapter extends BaseAdapter
+            implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>{
+        private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
+
+        public PrintersAdapter() {
+            getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
+        }
+
+        @Override
+        public int getCount() {
+            return mPrinters.size();
+        }
+
+        @Override
+        public Object getItem(int position) {
+            return mPrinters.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (convertView == null) {
+                convertView = getActivity().getLayoutInflater().inflate(
+                        R.layout.preference, parent, false);
+            }
+
+            PrinterInfo printer = (PrinterInfo) getItem(position);
+            CharSequence title = printer.getName();
+            CharSequence subtitle = null;
+            try {
+                PackageInfo packageInfo = getPackageManager().getPackageInfo(
+                        printer.getId().getServiceName().getPackageName(), 0);
+                        subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
+            } catch (NameNotFoundException nnfe) {
+                /* ignore */
+            }
+
+            TextView titleView = (TextView) convertView.findViewById(android.R.id.title);
+            titleView.setText(title);
+
+            TextView subtitleView = (TextView) convertView.findViewById(android.R.id.summary);
+            if (!TextUtils.isEmpty(subtitle)) {
+                subtitleView.setText(subtitle);
+                subtitleView.setVisibility(View.VISIBLE);
+            } else {
+                subtitleView.setText(null);
+                subtitleView.setVisibility(View.GONE);
+            }
+
+            return convertView;
+        }
+
+        @Override
+        public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
+            if (id == LOADER_ID_PRINTERS_LOADER) {
+                return new PrintersLoader(getActivity());
+            }
+            return null;
+        }
+
+        @Override
+        public void onLoadFinished(Loader<List<PrinterInfo>> loader,
+                List<PrinterInfo> printers) {
+            mPrinters.clear();
+            final int printerCount = printers.size();
+            for (int i = 0; i < printerCount; i++) {
+                PrinterInfo printer = printers.get(i);
+                if (printer.getId().getServiceName().equals(mComponentName)) {
+                    mPrinters.add(printer);
+                }
+            }
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
+            mPrinters.clear();
+            notifyDataSetInvalidated();
+        }
+    }
+
+    private static class PrintersLoader extends Loader<List<PrinterInfo>> {
+
+        private static final String LOG_TAG = "PrintersLoader";
+
+        private static final boolean DEBUG = true && Build.IS_DEBUGGABLE;
+
+        private final Map<PrinterId, PrinterInfo> mPrinters =
+                new LinkedHashMap<PrinterId, PrinterInfo>();
+
+        private PrinterDiscoverySession mDiscoverySession;
+
+        public PrintersLoader(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void deliverResult(List<PrinterInfo> printers) {
+            if (isStarted()) {
+                super.deliverResult(printers);
+            }
+        }
+
+        @Override
+        protected void onStartLoading() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onStartLoading()");
+            }
+            // The contract is that if we already have a valid,
+            // result the we have to deliver it immediately.
+            if (!mPrinters.isEmpty()) {
+                deliverResult(new ArrayList<PrinterInfo>(mPrinters.values()));
+            }
+            // We want to start discovery at this point.
+            onForceLoad();
+        }
+
+        @Override
+        protected void onStopLoading() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onStopLoading()");
+            }
+            onCancelLoad();
+        }
+
+        @Override
+        protected void onForceLoad() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onForceLoad()");
+            }
+            loadInternal();
+        }
+
+        @Override
+        protected boolean onCancelLoad() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onCancelLoad()");
+            }
+            return cancelInternal();
+        }
+
+        @Override
+        protected void onReset() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onReset()");
+            }
+            onStopLoading();
+            mPrinters.clear();
+            if (mDiscoverySession != null) {
+                mDiscoverySession.destroy();
+                mDiscoverySession = null;
+            }
+        }
+
+        @Override
+        protected void onAbandon() {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "onAbandon()");
+            }
+            onStopLoading();
+        }
+
+        private boolean cancelInternal() {
+            if (mDiscoverySession != null
+                    && mDiscoverySession.isPrinterDiscoveryStarted()) {
+                mDiscoverySession.stopPrinterDiscovery();
+                return true;
+            }
+            return false;
+        }
+
+        private void loadInternal() {
+            if (mDiscoverySession == null) {
+                PrintManager printManager = (PrintManager) getContext()
+                        .getSystemService(Context.PRINT_SERVICE);
+                mDiscoverySession = printManager.createPrinterDiscoverySession();
+                mDiscoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() {
+                    @Override
+                    public void onPrintersChanged() {
+                        deliverResult(new ArrayList<PrinterInfo>(
+                                mDiscoverySession.getPrinters()));
+                    }
+                });
+            }
+            mDiscoverySession.startPrinterDisovery(null);
+        }
+    }
+}
+
diff --git a/src/com/android/settings/print/PrintSettingsFragment.java b/src/com/android/settings/print/PrintSettingsFragment.java
new file mode 100644
index 0000000..6e7f528
--- /dev/null
+++ b/src/com/android/settings/print/PrintSettingsFragment.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.print;
+
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.printservice.PrintServiceInfo;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.internal.content.PackageMonitor;
+import com.android.settings.DialogCreatable;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.util.List;
+
+/**
+ * Fragment with the top level print settings.
+ */
+public class PrintSettingsFragment extends SettingsPreferenceFragment implements DialogCreatable {
+
+    static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':';
+
+    // Extras passed to sub-fragments.
+    static final String EXTRA_PREFERENCE_KEY = "preference_key";
+    static final String EXTRA_CHECKED = "checked";
+    static final String EXTRA_TITLE = "title";
+    static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title";
+    static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message";
+    static final String EXTRA_SETTINGS_TITLE = "settings_title";
+    static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
+    static final String EXTRA_ADD_PRINTERS_TITLE = "add_printers_title";
+    static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "add_printers_component_name";
+    static final String EXTRA_SERVICE_COMPONENT_NAME = "service_component_name";
+
+    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void dispatchMessage(Message msg) {
+            updateServicesPreferences();
+        }
+    };
+
+    private final SettingsContentObserver mSettingsContentObserver =
+            new SettingsContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            updateServicesPreferences();
+        }
+    };
+
+    private Preference mNoServicesMessagePreference;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        addPreferencesFromResource(R.xml.print_settings);
+        getActivity().getActionBar().setTitle(R.string.print_settings_title);
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
+        mSettingsContentObserver.register(getContentResolver());
+        updateServicesPreferences();
+        setHasOptionsMenu(true);
+    }
+
+    @Override
+    public void onPause() {
+        mSettingsPackageMonitor.unregister();
+        mSettingsContentObserver.unregister(getContentResolver());
+        super.onPause();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.print_settings, menu);
+        MenuItem menuItem = menu.findItem(R.id.print_menu_item_download_print_service);
+        menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
+                Uri.parse(getString(R.string.download_print_service_query))));
+    }
+
+    private void updateServicesPreferences() {
+        // Since services category is auto generated we have to do a pass
+        // to generate it since services can come and go.
+        getPreferenceScreen().removeAll();
+
+        List<ComponentName> enabledServices = SettingsUtils
+                .readEnabledPrintServices(getActivity());
+
+        List<ResolveInfo> installedServices = getActivity().getPackageManager()
+                .queryIntentServices(
+                        new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
+                        PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+
+        final int installedServiceCount = installedServices.size();
+        for (int i = 0; i < installedServiceCount; i++) {
+            ResolveInfo installedService = installedServices.get(i);
+
+            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
+                    getActivity());
+
+            String title = installedService.loadLabel(getPackageManager()).toString();
+            preference.setTitle(title);
+
+            ComponentName componentName = new ComponentName(
+                    installedService.serviceInfo.packageName,
+                    installedService.serviceInfo.name);
+            preference.setKey(componentName.flattenToString());
+
+            preference.setOrder(i);
+            preference.setFragment(PrintServiceSettingsFragment.class.getName());
+            preference.setPersistent(false);
+
+            final boolean serviceEnabled = enabledServices.contains(componentName);
+            if (serviceEnabled) {
+                preference.setSummary(getString(R.string.print_feature_state_on));
+            } else {
+                preference.setSummary(getString(R.string.print_feature_state_off));
+            }
+
+            Bundle extras = preference.getExtras();
+            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
+            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
+            extras.putString(EXTRA_TITLE, title);
+
+            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
+                    installedService, getActivity());
+
+            CharSequence applicationLabel = installedService.loadLabel(getPackageManager());
+
+            extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
+                    R.string.print_service_security_warning_title, applicationLabel));
+            extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
+                    R.string.print_service_security_warning_summary, applicationLabel));
+
+            String settingsClassName = printServiceInfo.getSettingsActivityName();
+            if (!TextUtils.isEmpty(settingsClassName)) {
+                extras.putString(EXTRA_SETTINGS_TITLE,
+                        getString(R.string.print_menu_item_settings));
+                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
+                        new ComponentName(installedService.serviceInfo.packageName,
+                                settingsClassName).flattenToString());
+            }
+
+            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
+            if (!TextUtils.isEmpty(addPrinterClassName)) {
+                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
+                        getString(R.string.print_menu_item_add_printers));
+                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
+                        new ComponentName(installedService.serviceInfo.packageName,
+                                addPrinterClassName).flattenToString());
+            }
+
+            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
+
+            getPreferenceScreen().addPreference(preference);
+        }
+
+        if (getPreferenceScreen().getPreferenceCount() == 0) {
+            if (mNoServicesMessagePreference == null) {
+                mNoServicesMessagePreference = new Preference(getActivity()) {
+                    @Override
+                    protected void onBindView(View view) {
+                        super.onBindView(view);
+                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
+                        String title = getString(R.string.print_no_services_installed);
+                        summaryView.setText(title);
+                    }
+                };
+                mNoServicesMessagePreference.setPersistent(false);
+                mNoServicesMessagePreference.setLayoutResource(
+                        R.layout.text_description_preference);
+                mNoServicesMessagePreference.setSelectable(false);
+            }
+            getPreferenceScreen().addPreference(mNoServicesMessagePreference);
+        }
+    }
+
+    private class SettingsPackageMonitor extends PackageMonitor {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+           mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageAppeared(String packageName, int reason) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageDisappeared(String packageName, int reason) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+    }
+
+    public static class ToggleSwitch extends Switch {
+
+        private OnBeforeCheckedChangeListener mOnBeforeListener;
+
+        public static interface OnBeforeCheckedChangeListener {
+            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
+        }
+
+        public ToggleSwitch(Context context) {
+            super(context);
+        }
+
+        public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
+            mOnBeforeListener = listener;
+        }
+
+        @Override
+        public void setChecked(boolean checked) {
+            if (mOnBeforeListener != null
+                    && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
+                return;
+            }
+            super.setChecked(checked);
+        }
+
+        public void setCheckedInternal(boolean checked) {
+            super.setChecked(checked);
+        }
+    }
+
+    private static abstract class SettingsContentObserver extends ContentObserver {
+
+        public SettingsContentObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void register(ContentResolver contentResolver) {
+            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
+        }
+
+        public void unregister(ContentResolver contentResolver) {
+            contentResolver.unregisterContentObserver(this);
+        }
+
+        @Override
+        public abstract void onChange(boolean selfChange, Uri uri);
+    }
+}
diff --git a/src/com/android/settings/print/SettingsUtils.java b/src/com/android/settings/print/SettingsUtils.java
new file mode 100644
index 0000000..37827e6
--- /dev/null
+++ b/src/com/android/settings/print/SettingsUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.print;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.provider.Settings;
+import android.text.TextUtils.SimpleStringSplitter;
+
+import java.util.ArrayList;import java.util.List;
+
+/**
+ * Helper methods for reading and writing to print settings.
+ */
+public class SettingsUtils {
+
+    private static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':';
+
+    private SettingsUtils() {
+        /* do nothing */
+    }
+
+    public static List<ComponentName> readEnabledPrintServices(Context context) {
+        List<ComponentName> enabledServices = new ArrayList<ComponentName>();
+
+        String enabledServicesSetting = Settings.Secure.getString(context
+                .getContentResolver(), Settings.Secure.ENABLED_PRINT_SERVICES);
+        if (enabledServicesSetting == null) {
+            return enabledServices;
+        }
+
+        SimpleStringSplitter colonSplitter = new SimpleStringSplitter(
+                ENABLED_PRINT_SERVICES_SEPARATOR);
+        colonSplitter.setString(enabledServicesSetting);
+
+        while (colonSplitter.hasNext()) {
+            String componentNameString = colonSplitter.next();
+            ComponentName enabledService = ComponentName.unflattenFromString(
+                    componentNameString);
+            enabledServices.add(enabledService);
+        }
+
+        return enabledServices;
+    }
+
+    public static void writeEnabledPrintServices(Context context,
+            List<ComponentName> services) {
+        StringBuilder builder = new StringBuilder();
+        final int serviceCount = services.size();
+        for (int i = 0; i < serviceCount; i++) {
+            ComponentName service = services.get(i);
+            if (builder.length() > 0) {
+                builder.append(ENABLED_PRINT_SERVICES_SEPARATOR);
+            }
+            builder.append(service.flattenToString());
+        }
+        Settings.Secure.putString(context.getContentResolver(),
+                Settings.Secure.ENABLED_PRINT_SERVICES,
+                builder.toString());
+    }
+}
