PrintSettingsFragment.java revision 24264eb2508d54de473b00b934807d2a0881b0aa
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
19738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmannimport android.app.Activity;
20bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.app.LoaderManager.LoaderCallbacks;
210ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onukiimport android.content.ActivityNotFoundException;
22bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.content.AsyncTaskLoader;
232d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ComponentName;
242d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.ContentResolver;
252d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Context;
262d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.Intent;
27bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.content.Loader;
282d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.PackageManager;
292d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.content.pm.ResolveInfo;
302d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.database.ContentObserver;
310ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onukiimport android.graphics.drawable.Drawable;
322d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.net.Uri;
332d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Bundle;
342d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Handler;
352d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.os.Message;
36bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJob;
37bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJobId;
38bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintJobInfo;
39bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintManager;
40bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.print.PrintManager.PrintJobStateChangeListener;
412d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.printservice.PrintServiceInfo;
42d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslavimport android.provider.SearchIndexableResource;
432d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.provider.Settings;
4439b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference;
4539b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceCategory;
4639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceScreen;
472d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.text.TextUtils;
48bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.text.format.DateUtils;
49bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.util.Log;
502d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.view.View;
510ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onukiimport android.view.View.OnClickListener;
52bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport android.view.ViewGroup;
530ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onukiimport android.widget.Button;
542d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport android.widget.TextView;
55738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
562d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.internal.content.PackageMonitor;
579d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wrenimport com.android.internal.logging.MetricsProto.MetricsEvent;
582d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.DialogCreatable;
592d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport com.android.settings.R;
6032ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Makimport com.android.settings.utils.ProfileSettingsPreferenceFragment;
61738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmannimport com.android.settings.dashboard.SummaryLoader;
62d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslavimport com.android.settings.search.BaseSearchIndexProvider;
637e920da6564032ddcc40db95925083ef59d19e58Fabrice Di Meglioimport com.android.settings.search.Indexable;
64d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslavimport com.android.settings.search.SearchIndexableRaw;
652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
66bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport java.text.DateFormat;
67bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganovimport java.util.ArrayList;
682d531653595344ed7e61c093dca308b9ba7ec185Svetoslavimport java.util.List;
692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav/**
712d531653595344ed7e61c093dca308b9ba7ec185Svetoslav * Fragment with the top level print settings.
722d531653595344ed7e61c093dca308b9ba7ec185Svetoslav */
7332ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Makpublic class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
7432ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Mak        implements DialogCreatable, Indexable, OnClickListener {
750ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    public static final String TAG = "PrintSettingsFragment";
76bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final int LOADER_ID_PRINT_JOBS_LOADER = 1;
77bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
78bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final String PRINT_JOBS_CATEGORY = "print_jobs_category";
79bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final String PRINT_SERVICES_CATEGORY = "print_services_category";
80bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
812d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    // Extras passed to sub-fragments.
82bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_PREFERENCE_KEY = "EXTRA_PREFERENCE_KEY";
83bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_CHECKED = "EXTRA_CHECKED";
84bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_TITLE = "EXTRA_TITLE";
85bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SETTINGS_TITLE = "EXTRA_SETTINGS_TITLE";
86bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SETTINGS_COMPONENT_NAME = "EXTRA_SETTINGS_COMPONENT_NAME";
87bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ADD_PRINTERS_TITLE = "EXTRA_ADD_PRINTERS_TITLE";
88bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_ADD_PRINTERS_COMPONENT_NAME = "EXTRA_ADD_PRINTERS_COMPONENT_NAME";
89bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_SERVICE_COMPONENT_NAME = "EXTRA_SERVICE_COMPONENT_NAME";
90bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
91bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    static final String EXTRA_PRINT_JOB_ID = "EXTRA_PRINT_JOB_ID";
922d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
930ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav    private static final String EXTRA_PRINT_SERVICE_COMPONENT_NAME =
940ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            "EXTRA_PRINT_SERVICE_COMPONENT_NAME";
950ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav
960ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    private static final int ORDER_LAST = 1000;
970ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
992d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1002d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final Handler mHandler = new Handler() {
1012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
1022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void dispatchMessage(Message msg) {
1032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
1042d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
1052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
1062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private final SettingsContentObserver mSettingsContentObserver =
1082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            new SettingsContentObserver(mHandler) {
1092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
1102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onChange(boolean selfChange, Uri uri) {
1112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            updateServicesPreferences();
1122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
1132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    };
1142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
115bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PreferenceCategory mActivePrintJobsCategory;
116bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PreferenceCategory mPrintServicesCategory;
117bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
118bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private PrintJobsController mPrintJobsController;
1190ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    private Button mAddNewServiceButton;
120fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghina
121fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghina    @Override
1228a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    protected int getMetricsCategory() {
1239d1bfd1e8de6e46137a9571507c03526880d6a46Chris Wren        return MetricsEvent.PRINT_SETTINGS;
1248a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    }
1258a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren
1268a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren    @Override
12723acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    protected int getHelpResource() {
12823acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk        return R.string.help_uri_printing;
12923acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    }
13023acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk
13123acc2bb8af7da000d72a8c1d8c28a2792200348Jason Monk    @Override
1322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    public void onCreate(Bundle icicle) {
1332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        super.onCreate(icicle);
1342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        addPreferencesFromResource(R.xml.print_settings);
135bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
136bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        mActivePrintJobsCategory = (PreferenceCategory) findPreference(
137bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PRINT_JOBS_CATEGORY);
138d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        mPrintServicesCategory = (PreferenceCategory) findPreference(
139bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PRINT_SERVICES_CATEGORY);
140bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        getPreferenceScreen().removePreference(mActivePrintJobsCategory);
141bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
142bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        mPrintJobsController = new PrintJobsController();
143bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        getActivity().getLoaderManager().initLoader(LOADER_ID_PRINT_JOBS_LOADER,
144bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                null, mPrintJobsController);
1452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
14899f0bd4aa6480f76fb7740ada8101bff84c1feb3Philip P. Moltmann    public void onStart() {
14999f0bd4aa6480f76fb7740ada8101bff84c1feb3Philip P. Moltmann        super.onStart();
1502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
1512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.register(getContentResolver());
1522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        updateServicesPreferences();
1532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        setHasOptionsMenu(true);
154bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        startSubSettingsIfNeeded();
1552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
15899f0bd4aa6480f76fb7740ada8101bff84c1feb3Philip P. Moltmann    public void onStop() {
1592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsPackageMonitor.unregister();
1602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        mSettingsContentObserver.unregister(getContentResolver());
16199f0bd4aa6480f76fb7740ada8101bff84c1feb3Philip P. Moltmann        super.onStop();
1622d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
1632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
1642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    @Override
165bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    public void onViewCreated(View view, Bundle savedInstanceState) {
166bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        super.onViewCreated(view, savedInstanceState);
167bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        ViewGroup contentRoot = (ViewGroup) getListView().getParent();
168bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        View emptyView = getActivity().getLayoutInflater().inflate(
169d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav                R.layout.empty_print_state, contentRoot, false);
170bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        TextView textView = (TextView) emptyView.findViewById(R.id.message);
171bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        textView.setText(R.string.print_no_services_installed);
1720ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
1730ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        final Intent addNewServiceIntent = createAddNewServiceIntentOrNull();
1740ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        if (addNewServiceIntent != null) {
1750ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            mAddNewServiceButton = (Button) emptyView.findViewById(R.id.add_new_service);
1760ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            mAddNewServiceButton.setOnClickListener(this);
1770ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            // The empty is used elsewhere too so it's hidden by default.
1780ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            mAddNewServiceButton.setVisibility(View.VISIBLE);
1790ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        }
1800ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
181bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        contentRoot.addView(emptyView);
18239b467482d1bf256a111c757e9b7621c6f523271Jason Monk        setEmptyView(emptyView);
18332ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Mak    }
184fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghina
18532ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Mak    @Override
18632ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Mak    protected String getIntentActionString() {
18732ccffc07c47d6e30b4198c74a8f2d2fbb8a799dTony Mak        return Settings.ACTION_PRINT_SETTINGS;
188bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
189bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
1902d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private void updateServicesPreferences() {
191bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        if (getPreferenceScreen().findPreference(PRINT_SERVICES_CATEGORY) == null) {
192bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().addPreference(mPrintServicesCategory);
193bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        } else {
194bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Since services category is auto generated we have to do a pass
195bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // to generate it since services can come and go.
196bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintServicesCategory.removeAll();
197bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
1982d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
199fae4a88530d306ac92b0df0a114885b29a623554Philip P. Moltmann        List<ComponentName> disabledServices = PrintSettingsUtils
200fae4a88530d306ac92b0df0a114885b29a623554Philip P. Moltmann                .readDisabledPrintServices(getActivity());
2012d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2020ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        final PackageManager pm = getActivity().getPackageManager();
2030ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
2040ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        List<ResolveInfo> installedServices = pm
2052d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                .queryIntentServices(
2062d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new Intent(android.printservice.PrintService.SERVICE_INTERFACE),
2072d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
2082d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2092d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        final int installedServiceCount = installedServices.size();
2102d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        for (int i = 0; i < installedServiceCount; i++) {
2112d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ResolveInfo installedService = installedServices.get(i);
2122d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2132d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PreferenceScreen preference = getPreferenceManager().createPreferenceScreen(
2142d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    getActivity());
2152d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2162d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String title = installedService.loadLabel(getPackageManager()).toString();
2172d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setTitle(title);
2182d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2192d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            ComponentName componentName = new ComponentName(
2202d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.packageName,
2212d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService.serviceInfo.name);
2222d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setKey(componentName.flattenToString());
2232d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2242d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setOrder(i);
2252d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setFragment(PrintServiceSettingsFragment.class.getName());
2262d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            preference.setPersistent(false);
2272d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
228fae4a88530d306ac92b0df0a114885b29a623554Philip P. Moltmann            final boolean serviceEnabled = !disabledServices.contains(componentName);
2292d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (serviceEnabled) {
2302d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_on));
2312d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            } else {
2322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                preference.setSummary(getString(R.string.print_feature_state_off));
2332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2350ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            final Drawable drawable = installedService.loadIcon(pm);
2360ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            if (drawable != null) {
2370ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                preference.setIcon(drawable);
2380ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            }
2390ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
2402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            Bundle extras = preference.getExtras();
2412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_PREFERENCE_KEY, preference.getKey());
2422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putBoolean(EXTRA_CHECKED, serviceEnabled);
2432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_TITLE, title);
2442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            PrintServiceInfo printServiceInfo = PrintServiceInfo.create(
2462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                    installedService, getActivity());
2472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String settingsClassName = printServiceInfo.getSettingsActivityName();
2492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(settingsClassName)) {
2502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_TITLE,
2512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_settings));
2522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_SETTINGS_COMPONENT_NAME,
2532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
2542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                settingsClassName).flattenToString());
2552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            String addPrinterClassName = printServiceInfo.getAddPrintersActivityName();
2582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            if (!TextUtils.isEmpty(addPrinterClassName)) {
2592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_TITLE,
2602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        getString(R.string.print_menu_item_add_printers));
2612d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                extras.putString(EXTRA_ADD_PRINTERS_COMPONENT_NAME,
2622d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                        new ComponentName(installedService.serviceInfo.packageName,
2632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav                                addPrinterClassName).flattenToString());
2642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            }
2652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
2662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            extras.putString(EXTRA_SERVICE_COMPONENT_NAME, componentName.flattenToString());
2672d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
268bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintServicesCategory.addPreference(preference);
2692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
2702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
271bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        if (mPrintServicesCategory.getPreferenceCount() == 0) {
272bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().removePreference(mPrintServicesCategory);
2730ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        } else {
2740ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            final Preference addNewServicePreference = newAddServicePreferenceOrNull();
2750ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            if (addNewServicePreference != null) {
2760ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                mPrintServicesCategory.addPreference(addNewServicePreference);
2770ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            }
2780ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        }
2790ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    }
2800ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
2810ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    private Preference newAddServicePreferenceOrNull() {
2820ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        final Intent addNewServiceIntent = createAddNewServiceIntentOrNull();
2830ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        if (addNewServiceIntent == null) {
2840ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            return null;
2852d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
28639b467482d1bf256a111c757e9b7621c6f523271Jason Monk        Preference preference = new Preference(getPrefContext());
2870ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        preference.setTitle(R.string.print_menu_item_add_service);
2880ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        preference.setIcon(R.drawable.ic_menu_add);
2890ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        preference.setOrder(ORDER_LAST);
2900ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        preference.setIntent(addNewServiceIntent);
2910ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        preference.setPersistent(false);
2920ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        return preference;
2930ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    }
2940ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
2950ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    private Intent createAddNewServiceIntentOrNull() {
2960ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        final String searchUri = Settings.Secure.getString(getContentResolver(),
2970ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                Settings.Secure.PRINT_SERVICE_SEARCH_URI);
2980ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        if (TextUtils.isEmpty(searchUri)) {
2990ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            return null;
3000ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        }
3010ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        return new Intent(Intent.ACTION_VIEW, Uri.parse(searchUri));
3022d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
3032d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
304bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private void startSubSettingsIfNeeded() {
3050ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        if (getArguments() == null) {
3060ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            return;
3070ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        }
3080ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        String componentName = getArguments().getString(EXTRA_PRINT_SERVICE_COMPONENT_NAME);
3090ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        if (componentName != null) {
3100ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            getArguments().remove(EXTRA_PRINT_SERVICE_COMPONENT_NAME);
3110ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            Preference prereference = findPreference(componentName);
3120ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            if (prereference != null) {
31339b467482d1bf256a111c757e9b7621c6f523271Jason Monk                prereference.performClick();
3140ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav            }
3150ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav        }
3160ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav    }
3170ad40283bb6b811c26874af3fccf25745f63de8dSvetoslav
318fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghina    @Override
3190ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    public void onClick(View v) {
3200ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        if (mAddNewServiceButton == v) {
3210ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            final Intent addNewServiceIntent = createAddNewServiceIntentOrNull();
3220ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            if (addNewServiceIntent != null) { // check again just in case.
3230ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                try {
3240ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                    startActivity(addNewServiceIntent);
3250ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                } catch (ActivityNotFoundException e) {
3260ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                    Log.w(TAG, "Unable to start activity", e);
3270ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki                }
3280ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki            }
3290ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki        }
3300ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki    }
3310ec96fe64cea4d27e866fc2dc17b799cf9c265a4Makoto Onuki
3322d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private class SettingsPackageMonitor extends PackageMonitor {
3332d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3342d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAdded(String packageName, int uid) {
335d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            mHandler.obtainMessage().sendToTarget();
3362d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3372d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3382d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3392d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageAppeared(String packageName, int reason) {
3402d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
3412d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3422d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3432d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3442d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageDisappeared(String packageName, int reason) {
3452d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
3462d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3472d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3482d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3492d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void onPackageRemoved(String packageName, int uid) {
3502d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            mHandler.obtainMessage().sendToTarget();
3512d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3522d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
3532d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3542d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    private static abstract class SettingsContentObserver extends ContentObserver {
3552d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3562d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public SettingsContentObserver(Handler handler) {
3572d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            super(handler);
3582d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3592d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3602d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void register(ContentResolver contentResolver) {
3612d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.registerContentObserver(Settings.Secure.getUriFor(
362fae4a88530d306ac92b0df0a114885b29a623554Philip P. Moltmann                    Settings.Secure.DISABLED_PRINT_SERVICES), false, this);
3632d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3642d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3652d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public void unregister(ContentResolver contentResolver) {
3662d531653595344ed7e61c093dca308b9ba7ec185Svetoslav            contentResolver.unregisterContentObserver(this);
3672d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        }
3682d531653595344ed7e61c093dca308b9ba7ec185Svetoslav
3692d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        @Override
3702d531653595344ed7e61c093dca308b9ba7ec185Svetoslav        public abstract void onChange(boolean selfChange, Uri uri);
3712d531653595344ed7e61c093dca308b9ba7ec185Svetoslav    }
372bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
373bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private final class PrintJobsController implements LoaderCallbacks<List<PrintJobInfo>> {
374bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
375bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
376bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public Loader<List<PrintJobInfo>> onCreateLoader(int id, Bundle args) {
377bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (id == LOADER_ID_PRINT_JOBS_LOADER) {
378bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                return new PrintJobsLoader(getActivity());
379bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
380bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            return null;
381bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
382bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
383bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
384bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void onLoadFinished(Loader<List<PrintJobInfo>> loader,
385bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                List<PrintJobInfo> printJobs) {
386bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (printJobs == null || printJobs.isEmpty()) {
387bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                getPreferenceScreen().removePreference(mActivePrintJobsCategory);
388bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            } else {
389bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                if (getPreferenceScreen().findPreference(PRINT_JOBS_CATEGORY) == null) {
390bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    getPreferenceScreen().addPreference(mActivePrintJobsCategory);
391bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
392bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
393bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mActivePrintJobsCategory.removeAll();
394bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
395bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                final int printJobCount = printJobs.size();
396bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                for (int i = 0; i < printJobCount; i++) {
397bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    PrintJobInfo printJob = printJobs.get(i);
398bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
399bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    PreferenceScreen preference = getPreferenceManager()
400bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            .createPreferenceScreen(getActivity());
401bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
402bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setPersistent(false);
403bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setFragment(PrintJobSettingsFragment.class.getName());
404bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setKey(printJob.getId().flattenToString());
405bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
406bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    switch (printJob.getState()) {
407bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_QUEUED:
408bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_STARTED: {
40997e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            if (!printJob.isCancelling()) {
41097e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                preference.setTitle(getString(
41197e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        R.string.print_printing_state_title_template,
41297e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        printJob.getLabel()));
41397e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            } else {
41497e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                preference.setTitle(getString(
41597e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        R.string.print_cancelling_state_title_template,
41697e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        printJob.getLabel()));
41797e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            }
418bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
419bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
420bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_FAILED: {
421bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            preference.setTitle(getString(
422bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    R.string.print_failed_state_title_template,
423bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getLabel()));
424bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
425bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
426bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_BLOCKED: {
42797e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            if (!printJob.isCancelling()) {
42897e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                preference.setTitle(getString(
42997e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        R.string.print_blocked_state_title_template,
43097e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        printJob.getLabel()));
43197e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            } else {
43297e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                preference.setTitle(getString(
43397e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        R.string.print_cancelling_state_title_template,
43497e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                                        printJob.getLabel()));
43597e962cd36e1a2bbadc264ec9ce8627a7decf268Svetoslav                            }
436bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
437bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
438bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
439bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    preference.setSummary(getString(R.string.print_job_summary,
440bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                            printJob.getPrinterName(), DateUtils.formatSameDayTime(
441bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    printJob.getCreationTime(), printJob.getCreationTime(),
442bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                                    DateFormat.SHORT, DateFormat.SHORT)));
443bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
444bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    switch (printJob.getState()) {
445bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_QUEUED:
446bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_STARTED: {
447031e8b14322ec0a4ec3620de920fd5966290625cSvetoslav                            preference.setIcon(R.drawable.ic_print);
448bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
449bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
450bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_FAILED:
451bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        case PrintJobInfo.STATE_BLOCKED: {
452031e8b14322ec0a4ec3620de920fd5966290625cSvetoslav                            preference.setIcon(R.drawable.ic_print_error);
453bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        } break;
454bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
455bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
456bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    Bundle extras = preference.getExtras();
457d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav                    extras.putString(EXTRA_PRINT_JOB_ID, printJob.getId().flattenToString());
458bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
459bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    mActivePrintJobsCategory.addPreference(preference);
460bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
461bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
462bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
463bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
464bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
465bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void onLoaderReset(Loader<List<PrintJobInfo>> loader) {
466bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            getPreferenceScreen().removePreference(mActivePrintJobsCategory);
467bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
468bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
469bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
470bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    private static final class PrintJobsLoader extends AsyncTaskLoader<List<PrintJobInfo>> {
471bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
472bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private static final String LOG_TAG = "PrintJobsLoader";
473bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
474d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav        private static final boolean DEBUG = false;
475bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
476d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        private List<PrintJobInfo> mPrintJobs = new ArrayList<PrintJobInfo>();
477bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
478bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private final PrintManager mPrintManager;
479bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
480bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        private PrintJobStateChangeListener mPrintJobStateChangeListener;
481bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
482bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public PrintJobsLoader(Context context) {
483bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            super(context);
484bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintManager = ((PrintManager) context.getSystemService(
485bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    Context.PRINT_SERVICE)).getGlobalPrintManagerForUser(
4866cfe7996541d608438fa7bec2cbad813ace93a4fSvetoslav                    context.getUserId());
487bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
488bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
489bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
490bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public void deliverResult(List<PrintJobInfo> printJobs) {
491bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (isStarted()) {
492bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                super.deliverResult(printJobs);
493bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
494bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
495bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
496bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
497bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onStartLoading() {
498bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
499bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onStartLoading()");
500bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
501bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // If we already have a result, deliver it immediately.
502bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (!mPrintJobs.isEmpty()) {
503bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                deliverResult(new ArrayList<PrintJobInfo>(mPrintJobs));
504bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
505bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Start watching for changes.
506bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobStateChangeListener == null) {
507bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintJobStateChangeListener = new PrintJobStateChangeListener() {
508bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    @Override
509d9f156ddf072775c894db1ca3c3fe8989be4dbebSvetoslav                    public void onPrintJobStateChanged(PrintJobId printJobId) {
510bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        onForceLoad();
511bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
512bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                };
513bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintManager.addPrintJobStateChangeListener(
514bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        mPrintJobStateChangeListener);
515bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
516bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // If the data changed or we have no data - load it now.
517bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobs.isEmpty()) {
518bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                onForceLoad();
519bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
520bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
521bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
522bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
523bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onStopLoading() {
524bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
525bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onStopLoading()");
526bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
527bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Cancel the load in progress if possible.
528bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            onCancelLoad();
529bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
530bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
531bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
532bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        protected void onReset() {
533bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (DEBUG) {
534bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                Log.i(LOG_TAG, "onReset()");
535bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
536bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Stop loading.
537bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            onStopLoading();
538bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Clear the cached result.
539bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            mPrintJobs.clear();
540bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            // Stop watching for changes.
541bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            if (mPrintJobStateChangeListener != null) {
542bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintManager.removePrintJobStateChangeListener(
543bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        mPrintJobStateChangeListener);
544bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                mPrintJobStateChangeListener = null;
545bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
546bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
547bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
548bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        @Override
549bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        public List<PrintJobInfo> loadInBackground() {
550bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            List<PrintJobInfo> printJobInfos = null;
551bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            List<PrintJob> printJobs = mPrintManager.getPrintJobs();
552bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            final int printJobCount = printJobs.size();
553bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            for (int i = 0; i < printJobCount; i++) {
554bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                PrintJobInfo printJob = printJobs.get(i).getInfo();
555bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                if (shouldShowToUser(printJob)) {
556bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    if (printJobInfos == null) {
557bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                        printJobInfos = new ArrayList<PrintJobInfo>();
558bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    }
559bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                    printJobInfos.add(printJob);
560bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov                }
561bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
562bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            return printJobInfos;
563bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
56443335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann    }
565bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov
56643335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann    /**
56743335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann     * Should the print job the shown to the user in the settings app.
56843335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann     *
56943335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann     * @param printJob The print job in question.
57043335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann     * @return true iff the print job should be shown.
57143335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann     */
57243335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann    private static boolean shouldShowToUser(PrintJobInfo printJob) {
57343335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann        switch (printJob.getState()) {
57443335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            case PrintJobInfo.STATE_QUEUED:
57543335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            case PrintJobInfo.STATE_STARTED:
57643335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            case PrintJobInfo.STATE_BLOCKED:
57743335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            case PrintJobInfo.STATE_FAILED: {
57843335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann                return true;
579bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov            }
580bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov        }
58143335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann        return false;
582bc2c3db8f923b9ee25345f5ebbad9f6c762a1e23Svetoslav Ganov    }
583d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
584738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    /**
585738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann     * Provider for the print settings summary
586738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann     */
587738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    private static class PrintSummaryProvider
588738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            implements SummaryLoader.SummaryProvider, PrintJobStateChangeListener {
589738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        private final Context mContext;
590738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        private final PrintManager mPrintManager;
591738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        private final SummaryLoader mSummaryLoader;
592738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
593738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        /**
594738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann         * Create a new {@link PrintSummaryProvider}.
595738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann         *
596738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann         * @param context The context this provider is for
597738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann         * @param summaryLoader The summary load using this provider
598738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann         */
599738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        public PrintSummaryProvider(Context context, SummaryLoader summaryLoader) {
600738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            mContext = context;
601738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            mSummaryLoader = summaryLoader;
602738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            mPrintManager = ((PrintManager) context.getSystemService(Context.PRINT_SERVICE))
603738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann                    .getGlobalPrintManagerForUser(context.getUserId());
604738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        }
605738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
606738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        @Override
607738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        public void setListening(boolean isListening) {
60824264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann            if (mPrintManager != null) {
60924264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                if (isListening) {
61024264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                    mPrintManager.addPrintJobStateChangeListener(this);
61124264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                    onPrintJobStateChanged(null);
61224264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                } else {
61324264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                    mPrintManager.removePrintJobStateChangeListener(this);
61424264eb2508d54de473b00b934807d2a0881b0aaPhilip P. Moltmann                }
615738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            }
616738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        }
617738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
618738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        @Override
619738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        public void onPrintJobStateChanged(PrintJobId printJobId) {
62043335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            List<PrintJob> printJobs = mPrintManager.getPrintJobs();
621738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
62243335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            int numActivePrintJobs = 0;
62343335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            final int numPrintJobs = printJobs.size();
62443335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            for (int i = 0; i < numPrintJobs; i++) {
62543335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann                if (shouldShowToUser(printJobs.get(i).getInfo())) {
62643335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann                    numActivePrintJobs++;
62743335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann                }
62843335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            }
62943335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann
63043335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann            mSummaryLoader.setSummary(this, mContext.getResources().getQuantityString(
63143335444ef9089e3b68ad759ee28303cbb4bcc5aPhilip P. Moltmann                    R.plurals.print_settings_title, numActivePrintJobs, numActivePrintJobs));
632738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        }
633738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    }
634738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
635738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    /**
636738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann     * A factory for {@link PrintSummaryProvider providers} the settings app can use to read the
637738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann     * print summary.
638738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann     */
639738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY
640738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            = new SummaryLoader.SummaryProviderFactory() {
641738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        @Override
642738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
643738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann                SummaryLoader summaryLoader) {
644738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann            return new PrintSummaryProvider(activity, summaryLoader);
645738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann        }
646738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann    };
647738e6db7b83f591a5883183255c9d1163d3b7f9aPhilip P. Moltmann
648d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
649d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            new BaseSearchIndexProvider() {
650d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        @Override
651d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
652d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            List<SearchIndexableRaw> indexables = new ArrayList<SearchIndexableRaw>();
653d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
654d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            PackageManager packageManager = context.getPackageManager();
655d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            PrintManager printManager = (PrintManager) context.getSystemService(
656d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav                    Context.PRINT_SERVICE);
657d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
6587476f5b904f16a0b330a99fc0f7d900a722554eaFabrice Di Meglio            String screenTitle = context.getResources().getString(R.string.print_settings);
659d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio            SearchIndexableRaw data = new SearchIndexableRaw(context);
660d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio            data.title = screenTitle;
661d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio            data.screenTitle = screenTitle;
662d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio            indexables.add(data);
663d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
664d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio            // Indexing all services, regardless if enabled.
665d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            List<PrintServiceInfo> services = printManager.getInstalledPrintServices();
666d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            final int serviceCount = services.size();
667d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            for (int i = 0; i < serviceCount; i++) {
668d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav                PrintServiceInfo service = services.get(i);
669c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio
670c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio                ComponentName componentName = new ComponentName(
671c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio                        service.getResolveInfo().serviceInfo.packageName,
672c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio                        service.getResolveInfo().serviceInfo.name);
673c853a4282d0511d4a6886dfa95000c4dddff6a31Fabrice Di Meglio
674d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data = new SearchIndexableRaw(context);
675d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data.key = componentName.flattenToString();
676d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data.title = service.getResolveInfo().loadLabel(packageManager).toString();
677d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data.summaryOn = context.getString(R.string.print_feature_state_on);
678d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data.summaryOff = context.getString(R.string.print_feature_state_off);
679d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                data.screenTitle = screenTitle;
680d729029b904d43c5c6d06f1d95004fe35445873dFabrice Di Meglio                indexables.add(data);
681d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            }
682d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
683d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            return indexables;
684d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        }
685d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav
686d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        @Override
687d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
688d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav                boolean enabled) {
689d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            List<SearchIndexableResource> indexables = new ArrayList<SearchIndexableResource>();
690d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            SearchIndexableResource indexable = new SearchIndexableResource(context);
691d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            indexable.xmlResId = R.xml.print_settings;
692d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            indexables.add(indexable);
693d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav            return indexables;
694d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav        }
695d78d44d32ae76e4eab843504114446dec3b22ed3Svetoslav    };
696fe47a8dc89fe0393dae16b1c2152c901feab4dcbAlexandra Gherghina}
697