PrintSettingsFragment.java revision 2d531653595344ed7e61c093dca308b9ba7ec185
12d531653595344ed7e61c093dca308b9ba7ec185Svetoslav/*
22d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Copyright (C) 2013 The Android Open Source Project
32d531653595344ed7e61c093dca308b9ba7ec185Svetoslav *
42d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Licensed under the Apache License, Version 2.0 (the "License");
52d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * you may not use this file except in compliance with the License.
62d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * You may obtain a copy of the License at
72d531653595344ed7e61c093dca308b9ba7ec185Svetoslav *
82d531653595344ed7e61c093dca308b9ba7ec185Svetoslav *      http://www.apache.org/licenses/LICENSE-2.0
92d531653595344ed7e61c093dca308b9ba7ec185Svetoslav *
102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Unless required by applicable law or agreed to in writing, software
112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * distributed under the License is distributed on an "AS IS" BASIS,
122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * See the License for the specific language governing permissions and
142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * limitations under the License.
152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav */
162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
172d531653595344ed7e61c093dca308b9ba7ec185Svetoslavpackage com.android.settings.print;
182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
192d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ComponentName;
202d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ContentResolver;
212d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Context;
222d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Intent;
232d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.PackageManager;
242d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.ResolveInfo;
252d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.database.ContentObserver;
262d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.net.Uri;
272d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Bundle;
282d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Handler;
292d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Message;
302d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.preference.Preference;
312d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.preference.PreferenceScreen;
322d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.printservice.PrintServiceInfo;
332d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.provider.Settings;
342d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.text.TextUtils;
352d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.Menu;
362d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.MenuInflater;
372d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.MenuItem;
382d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.View;
392d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.widget.Switch;
402d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.widget.TextView;
412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
422d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.internal.content.PackageMonitor;
432d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.DialogCreatable;
442d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.R;
452d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.SettingsPreferenceFragment;
462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
472d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport java.util.List;
482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav/**
502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Fragment with the top level print settings.
512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav */
522d531653595344ed7e61c093dca308b9ba7ec185Svetoslavpublic class PrintSettingsFragment extends SettingsPreferenceFragment implements DialogCreatable {
532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':';
552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    // Extras passed to sub-fragments.
572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_PREFERENCE_KEY = "preference_key";
582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_CHECKED = "checked";
592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_TITLE = "title";
602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_ENABLE_WARNING_TITLE = "enable_warning_title";
612d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_ENABLE_WARNING_MESSAGE = "enable_warning_message";
622d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_SETTINGS_TITLE = "settings_title";
632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_SETTINGS_COMPONENT_NAME = "settings_component_name";
642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_ADD_PRINTERS_TITLE = "add_printers_title";
652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "add_printers_component_name";
662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final String EXTRA_SERVICE_COMPONENT_NAME = "service_component_name";
672d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
682d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final Handler mHandler = new Handler() {
712d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void dispatchMessage(Message msg) {
732d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
742d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
752d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
762d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
772d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final SettingsContentObserver mSettingsContentObserver =
782d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            new SettingsContentObserver(mHandler) {
792d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
802d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onChange(boolean selfChange, Uri uri) {
812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
822d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
832d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
842d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private Preference mNoServicesMessagePreference;
862d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
872d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
882d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onCreate(Bundle icicle) {
892d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onCreate(icicle);
902d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        addPreferencesFromResource(R.xml.print_settings);
912d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        getActivity().getActionBar().setTitle(R.string.print_settings_title);
922d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
932d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
942d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
952d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onResume() {
962d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onResume();
972d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.register(getContentResolver());
992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        updateServicesPreferences();
1002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        setHasOptionsMenu(true);
1012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onPause() {
1052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.unregister();
1062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.unregister(getContentResolver());
1072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onPause();
1082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
1122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onCreateOptionsMenu(menu, inflater);
1132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        inflater.inflate(R.menu.print_settings, menu);
1142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        MenuItem menuItem = menu.findItem(R.id.print_menu_item_download_print_service);
1152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
1162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                Uri.parse(getString(R.string.download_print_service_query))));
1172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1192d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private void updateServicesPreferences() {
1202d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        // Since services category is auto generated we have to do a pass
1212d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        // to generate it since services can come and go.
1222d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        getPreferenceScreen().removeAll();
1232d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1242d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        List<ComponentName> enabledServices = SettingsUtils
1252d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                .readEnabledPrintServices(getActivity());
1262d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1272d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        List<ResolveInfo> installedServices = getActivity().getPackageManager()
1282d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                .queryIntentServices(
1292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
1302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
1312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        final int installedServiceCount = installedServices.size();
1332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        for (int i = 0; i < installedServiceCount; i++) {
1342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ResolveInfo installedService = installedServices.get(i);
1352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
1372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    getActivity());
1382d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String title = installedService.loadLabel(getPackageManager()).toString();
1402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setTitle(title);
1412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ComponentName componentName = new ComponentName(
1432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.packageName,
1442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.name);
1452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setKey(componentName.flattenToString());
1462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setOrder(i);
1482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setFragment(PrintServiceSettingsFragment.class.getName());
1492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setPersistent(false);
1502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            final boolean serviceEnabled = enabledServices.contains(componentName);
1522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (serviceEnabled) {
1532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_on));
1542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            } else {
1552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_off));
1562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
1572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            Bundle extras = preference.getExtras();
1592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
1602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
1612d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_TITLE, title);
1622d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
1642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService, getActivity());
1652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            CharSequence applicationLabel = installedService.loadLabel(getPackageManager());
1672d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1682d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
1692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    R.string.print_service_security_warning_title, applicationLabel));
1702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
1712d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    R.string.print_service_security_warning_summary, applicationLabel));
1722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1732d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String settingsClassName = printServiceInfo.getSettingsActivityName();
1742d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(settingsClassName)) {
1752d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_TITLE,
1762d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_settings));
1772d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
1782d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
1792d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                settingsClassName).flattenToString());
1802d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
1812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1822d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
1832d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(addPrinterClassName)) {
1842d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
1852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_add_printers));
1862d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
1872d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
1882d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                addPrinterClassName).flattenToString());
1892d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
1902d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1912d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
1922d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1932d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            getPreferenceScreen().addPreference(preference);
1942d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
1952d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1962d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        if (getPreferenceScreen().getPreferenceCount() == 0) {
1972d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (mNoServicesMessagePreference == null) {
1982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                mNoServicesMessagePreference = new Preference(getActivity()) {
1992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    @Override
2002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    protected void onBindView(View view) {
2012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        super.onBindView(view);
2022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        TextView summaryView = (TextView) view.findViewById(R.id.summary);
2032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        String title = getString(R.string.print_no_services_installed);
2042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        summaryView.setText(title);
2052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    }
2062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                };
2072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                mNoServicesMessagePreference.setPersistent(false);
2082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                mNoServicesMessagePreference.setLayoutResource(
2092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        R.layout.text_description_preference);
2102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                mNoServicesMessagePreference.setSelectable(false);
2112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            getPreferenceScreen().addPreference(mNoServicesMessagePreference);
2132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private class SettingsPackageMonitor extends PackageMonitor {
2172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAdded(String packageName, int uid) {
2192d531653595344ed7e61c093dca308b9ba7ec185Svetoslav           mHandler.obtainMessage().sendToTarget();
2202d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2212d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2222d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2232d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAppeared(String packageName, int reason) {
2242d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2252d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2262d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2272d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2282d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageDisappeared(String packageName, int reason) {
2292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageRemoved(String packageName, int uid) {
2342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2382d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public static class ToggleSwitch extends Switch {
2392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        private OnBeforeCheckedChangeListener mOnBeforeListener;
2412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public static interface OnBeforeCheckedChangeListener {
2432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
2442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public ToggleSwitch(Context context) {
2472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super(context);
2482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
2512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mOnBeforeListener = listener;
2522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setChecked(boolean checked) {
2562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (mOnBeforeListener != null
2572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
2582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                return;
2592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super.setChecked(checked);
2612d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2622d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setCheckedInternal(boolean checked) {
2642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super.setChecked(checked);
2652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2672d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2682d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private static abstract class SettingsContentObserver extends ContentObserver {
2692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public SettingsContentObserver(Handler handler) {
2712d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super(handler);
2722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2732d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2742d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void register(ContentResolver contentResolver) {
2752d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
2762d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
2772d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2782d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2792d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void unregister(ContentResolver contentResolver) {
2802d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.unregisterContentObserver(this);
2812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2822d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2832d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2842d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public abstract void onChange(boolean selfChange, Uri uri);
2852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2862d531653595344ed7e61c093dca308b9ba7ec185Svetoslav}
287