PrintSettingsFragment.java revision d9f156ddf072775c894db1ca3c3fe8989be4dbeb
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
19bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.app.ActivityManager;
20bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.app.LoaderManager.LoaderCallbacks;
21bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.content.AsyncTaskLoader;
222d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ComponentName;
232d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ContentResolver;
242d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Context;
252d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Intent;
26bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.content.Loader;
272d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.PackageManager;
282d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.ResolveInfo;
292d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.database.ContentObserver;
302d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.net.Uri;
312d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Bundle;
322d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Handler;
332d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Message;
342d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.preference.Preference;
35bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.preference.PreferenceCategory;
362d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.preference.PreferenceScreen;
37bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJob;
38bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJobId;
39bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJobInfo;
40bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintManager;
41bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintManager.PrintJobStateChangeListener;
422d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.printservice.PrintServiceInfo;
432d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.provider.Settings;
442d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.text.TextUtils;
45bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.text.format.DateUtils;
46bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.util.Log;
472d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.Menu;
482d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.MenuInflater;
492d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.MenuItem;
502d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.View;
51bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.view.ViewGroup;
522d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.widget.Switch;
532d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.widget.TextView;
542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
552d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.internal.content.PackageMonitor;
562d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.DialogCreatable;
572d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.R;
582d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.SettingsPreferenceFragment;
592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
60bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport java.text.DateFormat;
61bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport java.util.ArrayList;
622d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport java.util.List;
632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav/**
652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Fragment with the top level print settings.
662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav */
672d531653595344ed7e61c093dca308b9ba7ec185Svetoslavpublic class PrintSettingsFragment extends SettingsPreferenceFragment implements DialogCreatable {
682d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    static final char ENABLED_PRINT_SERVICES_SEPARATOR = ':';
702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
71bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final int LOADER_ID_PRINT_JOBS_LOADER = 1;
72bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
73bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final String PRINT_JOBS_CATEGORY = "print_jobs_category";
74bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final String PRINT_SERVICES_CATEGORY = "print_services_category";
75bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
762d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    // Extras passed to sub-fragments.
77bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_PREFERENCE_KEY = "EXTRA_PREFERENCE_KEY";
78bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_CHECKED = "EXTRA_CHECKED";
79bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_TITLE = "EXTRA_TITLE";
80bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ENABLE_WARNING_TITLE = "EXTRA_ENABLE_WARNING_TITLE";
81bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ENABLE_WARNING_MESSAGE = "EXTRA_ENABLE_WARNING_MESSAGE";
82bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SETTINGS_TITLE = "EXTRA_SETTINGS_TITLE";
83bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SETTINGS_COMPONENT_NAME = "EXTRA_SETTINGS_COMPONENT_NAME";
84bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ADD_PRINTERS_TITLE = "EXTRA_ADD_PRINTERS_TITLE";
85bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "EXTRA_ADD_PRINTERS_COMPONENT_NAME";
86bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SERVICE_COMPONENT_NAME = "EXTRA_SERVICE_COMPONENT_NAME";
87bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
88bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
892d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
900ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav    private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
910ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            "EXTRA_PRINT_SERVICE_COMPONENT_NAME";
920ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav
932d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
942d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
952d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final Handler mHandler = new Handler() {
962d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
972d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void dispatchMessage(Message msg) {
982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
1002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
1012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final SettingsContentObserver mSettingsContentObserver =
1032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            new SettingsContentObserver(mHandler) {
1042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
1052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onChange(boolean selfChange, Uri uri) {
1062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
1072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
1082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
1092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
110bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PreferenceCategory mActivePrintJobsCategory;
111bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PreferenceCategory mPrintServicesCategory;
112bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
113bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PrintJobsController mPrintJobsController;
114bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
1152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onCreate(Bundle icicle) {
1172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onCreate(icicle);
1182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        addPreferencesFromResource(R.xml.print_settings);
119bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
120bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        mActivePrintJobsCategory = (PreferenceCategory) findPreference(
121bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PRINT_JOBS_CATEGORY);
122bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        mPrintServicesCategory= (PreferenceCategory) findPreference(
123bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PRINT_SERVICES_CATEGORY);
124bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        getPreferenceScreen().removePreference(mActivePrintJobsCategory);
125bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
126bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        mPrintJobsController = new PrintJobsController();
127bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_JOBS_LOADER,
128bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                null, mPrintJobsController);
1292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onResume() {
1332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onResume();
1342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
1352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.register(getContentResolver());
1362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        updateServicesPreferences();
1372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        setHasOptionsMenu(true);
138bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        startSubSettingsIfNeeded();
1392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onPause() {
1432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.unregister();
1442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.unregister(getContentResolver());
1452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onPause();
1462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
1492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
1502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onCreateOptionsMenu(menu, inflater);
1515c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav        String searchUri = Settings.Secure.getString(getContentResolver(),
1525c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav                Settings.Secure.PRINT_SERVICE_SEARCH_URI);
1535c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav        if (!TextUtils.isEmpty(searchUri)) {
1545c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav            MenuItem menuItem = menu.add(R.string.print_menu_item_add_service);
1555c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav            menuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM);
1565c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav            menuItem.setIntent(new Intent(Intent.ACTION_VIEW,Uri.parse(searchUri)));
1575c3052936883038d25b2afe52c2dd023e9aa6812Svetoslav        }
1582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
160bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    @Override
161bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    public void onViewCreated(View view, Bundle savedInstanceState) {
162bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        super.onViewCreated(view, savedInstanceState);
163bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        ViewGroup contentRoot = (ViewGroup) getListView().getParent();
164bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        View emptyView = getActivity().getLayoutInflater().inflate(
165bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    R.layout.empty_print_state, contentRoot, false);
166bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        TextView textView = (TextView) emptyView.findViewById(R.id.message);
167bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        textView.setText(R.string.print_no_services_installed);
168bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        contentRoot.addView(emptyView);
169bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        getListView().setEmptyView(emptyView);
170bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
171bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
1722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private void updateServicesPreferences() {
173bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        if (getPreferenceScreen().findPreference(PRINT_SERVICES_CATEGORY) == null) {
174bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().addPreference(mPrintServicesCategory);
175bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        } else {
176bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Since services category is auto generated we have to do a pass
177bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // to generate it since services can come and go.
178bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintServicesCategory.removeAll();
179bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
1802d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        List<ComponentName> enabledServices = SettingsUtils
1822d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                .readEnabledPrintServices(getActivity());
1832d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1842d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        List<ResolveInfo> installedServices = getActivity().getPackageManager()
1852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                .queryIntentServices(
1862d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
1872d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
1882d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1892d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        final int installedServiceCount = installedServices.size();
1902d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        for (int i = 0; i < installedServiceCount; i++) {
1912d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ResolveInfo installedService = installedServices.get(i);
1922d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1932d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
1942d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    getActivity());
1952d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1962d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String title = installedService.loadLabel(getPackageManager()).toString();
1972d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setTitle(title);
1982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ComponentName componentName = new ComponentName(
2002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.packageName,
2012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.name);
2022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setKey(componentName.flattenToString());
2032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setOrder(i);
2052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setFragment(PrintServiceSettingsFragment.class.getName());
2062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setPersistent(false);
2072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            final boolean serviceEnabled = enabledServices.contains(componentName);
2092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (serviceEnabled) {
2102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_on));
2112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            } else {
2122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_off));
2132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            Bundle extras = preference.getExtras();
2162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
2172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
2182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_TITLE, title);
2192d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2202d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
2212d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService, getActivity());
2222d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2232d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            CharSequence applicationLabel = installedService.loadLabel(getPackageManager());
2242d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2252d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_ENABLE_WARNING_TITLE, getString(
2262d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    R.string.print_service_security_warning_title, applicationLabel));
2272d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_ENABLE_WARNING_MESSAGE, getString(
2282d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    R.string.print_service_security_warning_summary, applicationLabel));
2292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String settingsClassName = printServiceInfo.getSettingsActivityName();
2312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(settingsClassName)) {
2322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_TITLE,
2332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_settings));
2342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
2352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
2362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                settingsClassName).flattenToString());
2372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2382d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
2402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(addPrinterClassName)) {
2412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
2422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_add_printers));
2432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
2442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
2452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                addPrinterClassName).flattenToString());
2462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
2492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
250bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintServicesCategory.addPreference(preference);
2512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
253bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        if (mPrintServicesCategory.getPreferenceCount() == 0) {
254bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().removePreference(mPrintServicesCategory);
2552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
258bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private void startSubSettingsIfNeeded() {
2590ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        if (getArguments() == null) {
2600ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            return;
2610ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        }
2620ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        String componentName = getArguments().getString(EXTRA_PRINT_SERVICE_COMPONENT_NAME);
2630ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        if (componentName != null) {
2640ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            getArguments().remove(EXTRA_PRINT_SERVICE_COMPONENT_NAME);
2650ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            Preference prereference = findPreference(componentName);
2660ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            if (prereference != null) {
2670ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav                prereference.performClick(getPreferenceScreen());
2680ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            }
2690ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        }
2700ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav    }
2710ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav
2722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private class SettingsPackageMonitor extends PackageMonitor {
2732d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2742d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAdded(String packageName, int uid) {
2752d531653595344ed7e61c093dca308b9ba7ec185Svetoslav           mHandler.obtainMessage().sendToTarget();
2762d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2772d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2782d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2792d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAppeared(String packageName, int reason) {
2802d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2822d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2832d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2842d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageDisappeared(String packageName, int reason) {
2852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2862d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2872d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2882d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
2892d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageRemoved(String packageName, int uid) {
2902d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
2912d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2922d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
2932d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2942d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public static class ToggleSwitch extends Switch {
2952d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2962d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        private OnBeforeCheckedChangeListener mOnBeforeListener;
2972d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public static interface OnBeforeCheckedChangeListener {
2992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked);
3002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public ToggleSwitch(Context context) {
3032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super(context);
3042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setOnBeforeCheckedChangeListener(OnBeforeCheckedChangeListener listener) {
3072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mOnBeforeListener = listener;
3082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setChecked(boolean checked) {
3122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (mOnBeforeListener != null
3132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    && mOnBeforeListener.onBeforeCheckedChanged(this, checked)) {
3142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                return;
3152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
3162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super.setChecked(checked);
3172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3192d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void setCheckedInternal(boolean checked) {
3202d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super.setChecked(checked);
3212d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3222d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
3232d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3242d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private static abstract class SettingsContentObserver extends ContentObserver {
3252d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3262d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public SettingsContentObserver(Handler handler) {
3272d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super(handler);
3282d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void register(ContentResolver contentResolver) {
3312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
3322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
3332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void unregister(ContentResolver contentResolver) {
3362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.unregisterContentObserver(this);
3372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3382d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public abstract void onChange(boolean selfChange, Uri uri);
3412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
342bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
343bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private final class PrintJobsController implements LoaderCallbacks<List<PrintJobInfo>> {
344bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
345bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
346bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public Loader<List<PrintJobInfo>> onCreateLoader(int id, Bundle args) {
347bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (id == LOADER_ID_PRINT_JOBS_LOADER) {
348bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                return new PrintJobsLoader(getActivity());
349bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
350bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            return null;
351bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
352bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
353bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
354bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void onLoadFinished(Loader<List<PrintJobInfo>> loader,
355bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                List<PrintJobInfo> printJobs) {
356bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (printJobs == null || printJobs.isEmpty()) {
357bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                getPreferenceScreen().removePreference(mActivePrintJobsCategory);
358bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            } else {
359bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                if (getPreferenceScreen().findPreference(PRINT_JOBS_CATEGORY) == null) {
360bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    getPreferenceScreen().addPreference(mActivePrintJobsCategory);
361bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
362bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
363bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mActivePrintJobsCategory.removeAll();
364bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
365bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                final int printJobCount = printJobs.size();
366bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                for (int i = 0; i < printJobCount; i++) {
367bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    PrintJobInfo printJob = printJobs.get(i);
368bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
369bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    PreferenceScreen preference = getPreferenceManager()
370bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            .createPreferenceScreen(getActivity());
371bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
372bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setPersistent(false);
373bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setFragment(PrintJobSettingsFragment.class.getName());
374bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setKey(printJob.getId().flattenToString());
375bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
376bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    switch (printJob.getState()) {
377bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_QUEUED:
378bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_STARTED: {
379bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setTitle(getString(
380bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    R.string.print_printing_state_title_template,
381bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getLabel()));
382bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
383bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
384bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_FAILED: {
385bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setTitle(getString(
386bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    R.string.print_failed_state_title_template,
387bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getLabel()));
388bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
389bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
390bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_BLOCKED: {
391bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setTitle(getString(
392bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    R.string.print_blocked_state_title_template,
393bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getLabel()));
394bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
395bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
396bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
397bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setSummary(getString(R.string.print_job_summary,
398bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            printJob.getPrinterName(), DateUtils.formatSameDayTime(
399bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getCreationTime(), printJob.getCreationTime(),
400bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    DateFormat.SHORT, DateFormat.SHORT)));
401bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
402bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    switch (printJob.getState()) {
403bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_QUEUED:
404bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_STARTED: {
405bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setIcon(com.android.internal.R.drawable.ic_print);
406bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
407bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
408bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_FAILED:
409bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_BLOCKED: {
410bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setIcon(com.android.internal.R.drawable.ic_print_error);
411bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
412bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
413bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
414bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    Bundle extras = preference.getExtras();
415d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav                    extras.putString(EXTRA_PRINT_JOB_ID, printJob.getId().flattenToString());
416bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
417bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    mActivePrintJobsCategory.addPreference(preference);
418bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
419bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
420bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
421bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
422bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
423bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void onLoaderReset(Loader<List<PrintJobInfo>> loader) {
424bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().removePreference(mActivePrintJobsCategory);
425bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
426bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
427bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
428bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final class PrintJobsLoader extends AsyncTaskLoader<List<PrintJobInfo>> {
429bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
430bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private static final String LOG_TAG = "PrintJobsLoader";
431bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
432d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav        private static final boolean DEBUG = false;
433bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
434bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private List <PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>();
435bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
436bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private final PrintManager mPrintManager;
437bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
438bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private PrintJobStateChangeListener mPrintJobStateChangeListener;
439bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
440bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public PrintJobsLoader(Context context) {
441bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            super(context);
442bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintManager = ((PrintManager) context.getSystemService(
443bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(
444bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            ActivityManager.getCurrentUser());
445bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
446bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
447bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
448bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void deliverResult(List<PrintJobInfo> printJobs) {
449bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (isStarted()) {
450bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                super.deliverResult(printJobs);
451bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
452bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
453bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
454bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
455bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onStartLoading() {
456bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
457bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onStartLoading()");
458bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
459bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // If we already have a result, deliver it immediately.
460bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (!mPrintJobs.isEmpty()) {
461bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                deliverResult(new ArrayList<PrintJobInfo>(mPrintJobs));
462bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
463bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Start watching for changes.
464bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobStateChangeListener == null) {
465bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintJobStateChangeListener = new PrintJobStateChangeListener() {
466bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    @Override
467d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav                    public void onPrintJobStateChanged(PrintJobId printJobId) {
468bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        onForceLoad();
469bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
470bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                };
471bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintManager.addPrintJobStateChangeListener(
472bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        mPrintJobStateChangeListener);
473bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
474bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // If the data changed or we have no data - load it now.
475bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobs.isEmpty()) {
476bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                onForceLoad();
477bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
478bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
479bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
480bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
481bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onStopLoading() {
482bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
483bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onStopLoading()");
484bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
485bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Cancel the load in progress if possible.
486bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            onCancelLoad();
487bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
488bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
489bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
490bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onReset() {
491bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
492bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onReset()");
493bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
494bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Stop loading.
495bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            onStopLoading();
496bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Clear the cached result.
497bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintJobs.clear();
498bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Stop watching for changes.
499bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobStateChangeListener != null) {
500bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintManager.removePrintJobStateChangeListener(
501bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        mPrintJobStateChangeListener);
502bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintJobStateChangeListener = null;
503bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
504bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
505bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
506bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
507bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public List<PrintJobInfo> loadInBackground() {
508bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            List<PrintJobInfo> printJobInfos = null;
509bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            List<PrintJob> printJobs = mPrintManager.getPrintJobs();
510bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            final int printJobCount = printJobs.size();
511bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            for (int i = 0; i < printJobCount; i++) {
512bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PrintJobInfo printJob = printJobs.get(i).getInfo();
513bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                if (shouldShowToUser(printJob)) {
514bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    if (printJobInfos == null) {
515bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        printJobInfos = new ArrayList<PrintJobInfo>();
516bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
517bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    printJobInfos.add(printJob);
518bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
519bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
520bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            return printJobInfos;
521bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
522bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
523bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private static boolean shouldShowToUser(PrintJobInfo printJob) {
524bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            switch (printJob.getState()) {
525bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                case PrintJobInfo.STATE_QUEUED:
526bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                case PrintJobInfo.STATE_STARTED:
527bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                case PrintJobInfo.STATE_BLOCKED:
528bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                case PrintJobInfo.STATE_FAILED: {
529bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    return true;
530bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
531bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
532bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            return false;
533bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
534bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
5352d531653595344ed7e61c093dca308b9ba7ec185Svetoslav}
536