1269403b032f965ff3847eb982c2f697229dc5a92Svetoslav/*
2269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Copyright (C) 2013 The Android Open Source Project
3269403b032f965ff3847eb982c2f697229dc5a92Svetoslav *
4269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * you may not use this file except in compliance with the License.
6269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * You may obtain a copy of the License at
7269403b032f965ff3847eb982c2f697229dc5a92Svetoslav *
8269403b032f965ff3847eb982c2f697229dc5a92Svetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9269403b032f965ff3847eb982c2f697229dc5a92Svetoslav *
10269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * Unless required by applicable law or agreed to in writing, software
11269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * See the License for the specific language governing permissions and
14269403b032f965ff3847eb982c2f697229dc5a92Svetoslav * limitations under the License.
15269403b032f965ff3847eb982c2f697229dc5a92Svetoslav */
16269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpackage com.android.printspooler.ui;
18269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
192e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmannimport android.annotation.NonNull;
20c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmannimport android.annotation.Nullable;
21269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.app.Activity;
2266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.app.LoaderManager;
233df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmannimport android.content.ComponentName;
24860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.content.Context;
25269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.content.Intent;
26bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.content.IntentSender.SendIntentException;
2766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.content.Loader;
28c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmannimport android.content.pm.ApplicationInfo;
29c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmannimport android.content.pm.PackageManager;
30264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganovimport android.database.DataSetObserver;
3139e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslavimport android.graphics.drawable.Drawable;
32c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmannimport android.os.Build;
33269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.os.Bundle;
34860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.print.PrintManager;
3566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.print.PrintServicesLoader;
36269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterId;
37269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.print.PrinterInfo;
38c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmannimport android.printservice.PrintService;
39269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.printservice.PrintServiceInfo;
400ea7d1e869ad618a7c8c2bbbb7f96729e7d84ed3Svetoslav Ganovimport android.provider.Settings;
41269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.text.TextUtils;
423df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmannimport android.util.ArrayMap;
43860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganovimport android.util.Log;
44443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmannimport android.util.TypedValue;
451c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslavimport android.view.ContextMenu;
461c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslavimport android.view.ContextMenu.ContextMenuInfo;
47269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.view.Menu;
48269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.view.MenuItem;
49269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.view.View;
50bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmannimport android.view.View.OnClickListener;
51269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.view.ViewGroup;
5253e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslavimport android.view.accessibility.AccessibilityManager;
53ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganovimport android.widget.AdapterView;
541c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslavimport android.widget.AdapterView.AdapterContextMenuInfo;
55269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.BaseAdapter;
56269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.Filter;
57269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.Filterable;
5839e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslavimport android.widget.ImageView;
5966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannimport android.widget.LinearLayout;
60269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.ListView;
61269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.SearchView;
62269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport android.widget.TextView;
631f46779f5ecaa9e71bf91474160007203b213fc2Philip P. Moltmannimport android.widget.Toast;
64269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
652e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmannimport com.android.internal.logging.MetricsLogger;
66383db5ebcc3a4a615faf249bf4f126f42e80b82eTamas Berghammerimport com.android.internal.logging.nano.MetricsProto.MetricsEvent;
67a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport com.android.printspooler.R;
68a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
69269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.ArrayList;
70269403b032f965ff3847eb982c2f697229dc5a92Svetoslavimport java.util.List;
71269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
72269403b032f965ff3847eb982c2f697229dc5a92Svetoslav/**
73a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * This is an activity for selecting a printer.
74269403b032f965ff3847eb982c2f697229dc5a92Svetoslav */
7566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmannpublic final class SelectPrinterActivity extends Activity implements
7666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> {
77269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
78860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov    private static final String LOG_TAG = "SelectPrinterFragment";
79860f8a6b663ca96d30d17da09eca8caf065aae62Svetoslav Ganov
8066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private static final int LOADER_ID_PRINT_REGISTRY = 1;
8166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private static final int LOADER_ID_PRINT_REGISTRY_INT = 2;
8266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private static final int LOADER_ID_ENABLED_PRINT_SERVICES = 3;
83269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
84c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    private static final int INFO_INTENT_REQUEST_CODE = 1;
85c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
8663ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann    public static final String INTENT_EXTRA_PRINTER = "INTENT_EXTRA_PRINTER";
87269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
8863ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann    private static final String EXTRA_PRINTER = "EXTRA_PRINTER";
891c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    private static final String EXTRA_PRINTER_ID = "EXTRA_PRINTER_ID";
901c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
9166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private static final String KEY_NOT_FIRST_CREATE = "KEY_NOT_FIRST_CREATE";
922e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    private static final String KEY_DID_SEARCH = "DID_SEARCH";
93c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    private static final String KEY_PRINTER_FOR_INFO_INTENT = "KEY_PRINTER_FOR_INFO_INTENT";
942e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
952e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    // Constants for MetricsLogger.count and MetricsLogger.histo
962e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    private static final String PRINTERS_LISTED_COUNT = "printers_listed";
972e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    private static final String PRINTERS_ICON_COUNT = "printers_icon";
982e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    private static final String PRINTERS_INFO_COUNT = "printers_info";
9966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
1003df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann    /** The currently enabled print services by their ComponentName */
1013df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann    private ArrayMap<ComponentName, PrintServiceInfo> mEnabledPrintServices;
102953639cb826ad5fb85fcc18cbc0833a9dedb8227Philip P. Moltmann
103a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private PrinterRegistry mPrinterRegistry;
104269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
105ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov    private ListView mListView;
106ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov
10756ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov    private AnnounceFilterResult mAnnounceFilterResult;
10856ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
1092e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    private boolean mDidSearch;
1102e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
111c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    /**
112c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     * Printer we are currently in the info intent for. This is only non-null while this activity
113c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     * started an info intent that has not yet returned
114c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     */
115c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    private @Nullable PrinterInfo mPrinterForInfoIntent;
116c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
11766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    private void startAddPrinterActivity() {
1182e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        MetricsLogger.action(this, MetricsEvent.ACTION_PRINT_SERVICE_ADD);
11966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        startActivity(new Intent(this, AddPrinterActivity.class));
12066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    }
12103755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann
122269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    @Override
123269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    public void onCreate(Bundle savedInstanceState) {
124269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        super.onCreate(savedInstanceState);
125309f6a0e1b2ec39bd516fdfe217a526fe4b8acf6Svetoslav        getActionBar().setIcon(R.drawable.ic_print);
126269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        setContentView(R.layout.select_printer_activity);
128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
1293af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann        getActionBar().setDisplayHomeAsUpEnabled(true);
1303af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann
1313df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann        mEnabledPrintServices = new ArrayMap<>();
1323df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann
13366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        mPrinterRegistry = new PrinterRegistry(this, null, LOADER_ID_PRINT_REGISTRY,
13466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                LOADER_ID_PRINT_REGISTRY_INT);
135ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov
136ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov        // Hook up the list view.
13751efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mListView = findViewById(android.R.id.list);
138264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        final DestinationAdapter adapter = new DestinationAdapter();
139264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        adapter.registerDataSetObserver(new DataSetObserver() {
140264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            @Override
141264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            public void onChanged() {
142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (!isFinishing() && adapter.getCount() <= 0) {
143264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov                    updateEmptyView(adapter);
144264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov                }
145264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            }
146264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov
147264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            @Override
148264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            public void onInvalidated() {
149a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (!isFinishing()) {
15024c686b8b56950d5a1881cc660e53816d47e5e03Svetoslav Ganov                    updateEmptyView(adapter);
15124c686b8b56950d5a1881cc660e53816d47e5e03Svetoslav Ganov                }
152264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            }
153264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        });
154ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov        mListView.setAdapter(adapter);
155ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov
156ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
157ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            @Override
158ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
1591c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                if (!((DestinationAdapter) mListView.getAdapter()).isActionable(position)) {
1601c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                    return;
1611c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                }
162a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
163ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov                PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position);
16466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
16566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (printer == null) {
16666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    startAddPrinterActivity();
16766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                } else {
16863ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann                    onPrinterSelected(printer);
16966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
17066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
17166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        });
17266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
17366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        findViewById(R.id.button).setOnClickListener(new OnClickListener() {
17466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            @Override public void onClick(View v) {
17566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                startAddPrinterActivity();
176ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            }
177ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov        });
178ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov
1791c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        registerForContextMenu(mListView);
1801f46779f5ecaa9e71bf91474160007203b213fc2Philip P. Moltmann
18166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        getLoaderManager().initLoader(LOADER_ID_ENABLED_PRINT_SERVICES, null, this);
18266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
18366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        // On first creation:
18466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        //
18566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        // If no services are installed, instantly open add printer dialog.
18666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        // If some are disabled and some are enabled show a toast to notify the user
18766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        if (savedInstanceState == null || !savedInstanceState.getBoolean(KEY_NOT_FIRST_CREATE)) {
18866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            List<PrintServiceInfo> allServices =
18966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    ((PrintManager) getSystemService(Context.PRINT_SERVICE))
19066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                            .getPrintServices(PrintManager.ALL_SERVICES);
19166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            boolean hasEnabledServices = false;
19266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            boolean hasDisabledServices = false;
19366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
19466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            if (allServices != null) {
19566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                final int numServices = allServices.size();
19666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                for (int i = 0; i < numServices; i++) {
19766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    if (allServices.get(i).isEnabled()) {
19866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                        hasEnabledServices = true;
19966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    } else {
20066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                        hasDisabledServices = true;
20166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    }
20266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
20366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
20466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
20566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            if (!hasEnabledServices) {
20666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                startAddPrinterActivity();
20766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } else if (hasDisabledServices) {
20866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                String disabledServicesSetting = Settings.Secure.getString(getContentResolver(),
20966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                        Settings.Secure.DISABLED_PRINT_SERVICES);
21066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (!TextUtils.isEmpty(disabledServicesSetting)) {
21166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    Toast.makeText(this, getString(R.string.print_services_disabled_toast),
21266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                            Toast.LENGTH_LONG).show();
21366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
21466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
2151f46779f5ecaa9e71bf91474160007203b213fc2Philip P. Moltmann        }
2162e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
2172e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        if (savedInstanceState != null) {
2182e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            mDidSearch = savedInstanceState.getBoolean(KEY_DID_SEARCH);
219c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            mPrinterForInfoIntent = savedInstanceState.getParcelable(KEY_PRINTER_FOR_INFO_INTENT);
2202e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        }
221269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
222269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
223269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    @Override
22466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    protected void onSaveInstanceState(Bundle outState) {
22566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        super.onSaveInstanceState(outState);
22666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        outState.putBoolean(KEY_NOT_FIRST_CREATE, true);
2272e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        outState.putBoolean(KEY_DID_SEARCH, mDidSearch);
228c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        outState.putParcelable(KEY_PRINTER_FOR_INFO_INTENT, mPrinterForInfoIntent);
22966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    }
23066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
23166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    @Override
232a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public boolean onCreateOptionsMenu(Menu menu) {
233a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        super.onCreateOptionsMenu(menu);
234a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
235a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        getMenuInflater().inflate(R.menu.select_printer_activity, menu);
236269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
237269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        MenuItem searchItem = menu.findItem(R.id.action_search);
238269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        SearchView searchView = (SearchView) searchItem.getActionView();
239269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
240269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            @Override
241269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            public boolean onQueryTextSubmit(String query) {
242269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                return true;
243269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
244269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
245269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            @Override
246269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            public boolean onQueryTextChange(String searchString) {
247ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov                ((DestinationAdapter) mListView.getAdapter()).getFilter().filter(searchString);
248269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                return true;
249269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
250269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        });
25156ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
25256ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            @Override
25356ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            public void onViewAttachedToWindow(View view) {
254a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (AccessibilityManager.getInstance(SelectPrinterActivity.this).isEnabled()) {
25553e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                    view.announceForAccessibility(getString(
25653e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                            R.string.print_search_box_shown_utterance));
25753e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                }
25856ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            }
25956ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            @Override
26056ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            public void onViewDetachedFromWindow(View view) {
261a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (!isFinishing() && AccessibilityManager.getInstance(
262a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        SelectPrinterActivity.this).isEnabled()) {
26353e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                    view.announceForAccessibility(getString(
26453e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                            R.string.print_search_box_hidden_utterance));
26553e8a26d6178c41c59c3dcad4a8a04ce2449f246Svetoslav                }
26656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            }
26756ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        });
268269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
269a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        return true;
270269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
271269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
272269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    @Override
2733af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann    public boolean onOptionsItemSelected(MenuItem item) {
2743af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann        if (item.getItemId() == android.R.id.home) {
2753af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann            finish();
2763af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann            return true;
2773af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann        } else {
2783af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann            return super.onOptionsItemSelected(item);
2793af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann        }
2803af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann    }
2813af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann
2823af7f8277fd99b8b52ef4ba7976fd6c614091352Philip P. Moltmann    @Override
2831c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
2841c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        if (view == mListView) {
2851c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            final int position = ((AdapterContextMenuInfo) menuInfo).position;
2861c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            PrinterInfo printer = (PrinterInfo) mListView.getAdapter().getItem(position);
2871c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
2881c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            menu.setHeaderTitle(printer.getName());
2891c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
2901c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            // Add the select menu item if applicable.
2911c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            if (printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
2921c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                MenuItem selectItem = menu.add(Menu.NONE, R.string.print_select_printer,
2931c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                        Menu.NONE, R.string.print_select_printer);
2941c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                Intent intent = new Intent();
29563ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann                intent.putExtra(EXTRA_PRINTER, printer);
2961c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                selectItem.setIntent(intent);
2971c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            }
2981c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
2991c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            // Add the forget menu item if applicable.
300a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            if (mPrinterRegistry.isFavoritePrinter(printer.getId())) {
3011c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                MenuItem forgetItem = menu.add(Menu.NONE, R.string.print_forget_printer,
3021c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                        Menu.NONE, R.string.print_forget_printer);
3031c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                Intent intent = new Intent();
3041c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                intent.putExtra(EXTRA_PRINTER_ID, printer.getId());
3051c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav                forgetItem.setIntent(intent);
3061c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            }
3071c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        }
3081c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    }
3091c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
3101c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    @Override
3111c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    public boolean onContextItemSelected(MenuItem item) {
3121c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        switch (item.getItemId()) {
3131c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            case R.string.print_select_printer: {
31463ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann                PrinterInfo printer = item.getIntent().getParcelableExtra(EXTRA_PRINTER);
31563ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann                onPrinterSelected(printer);
3161c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            } return true;
3171c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
3181c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            case R.string.print_forget_printer: {
319a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                PrinterId printerId = item.getIntent().getParcelableExtra(EXTRA_PRINTER_ID);
320a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                mPrinterRegistry.forgetFavoritePrinter(printerId);
3211c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            } return true;
3221c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        }
3231c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        return false;
3241c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav    }
3251c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav
32603755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    /**
32703755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann     * Adjust the UI if the enabled print services changed.
32803755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann     */
32903755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    private synchronized void onPrintServicesUpdate() {
330953639cb826ad5fb85fcc18cbc0833a9dedb8227Philip P. Moltmann        updateEmptyView((DestinationAdapter)mListView.getAdapter());
331a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        invalidateOptionsMenu();
332269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
333269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
33403755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    @Override
33503755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    public void onStart() {
33603755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann        super.onStart();
33703755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann        onPrintServicesUpdate();
33803755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    }
33903755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann
340269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    @Override
341ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav    public void onPause() {
342ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav        if (mAnnounceFilterResult != null) {
343ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav            mAnnounceFilterResult.remove();
344ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav        }
345ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav        super.onPause();
346ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav    }
347ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav
348ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav    @Override
34903755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    public void onStop() {
35003755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann        super.onStop();
35103755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann    }
35203755a1f12390be9ddfcce8c5ad3f887fa5ccf9fPhilip P. Moltmann
3532e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    @Override
3542e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    protected void onDestroy() {
3552e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        if (isFinishing()) {
3562e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            DestinationAdapter adapter = (DestinationAdapter) mListView.getAdapter();
3572e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            List<PrinterInfo> printers = adapter.getPrinters();
3582e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            int numPrinters = adapter.getPrinters().size();
3592e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3602e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            MetricsLogger.action(this, MetricsEvent.PRINT_ALL_PRINTERS, numPrinters);
3612e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            MetricsLogger.count(this, PRINTERS_LISTED_COUNT, numPrinters);
3622e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3632e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            int numInfoPrinters = 0;
3642e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            int numIconPrinters = 0;
3652e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            for (int i = 0; i < numPrinters; i++) {
3662e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                PrinterInfo printer = printers.get(i);
3672e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3682e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                if (printer.getInfoIntent() != null) {
3692e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                    numInfoPrinters++;
3702e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                }
3712e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3722e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                if (printer.getHasCustomPrinterIcon()) {
3732e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                    numIconPrinters++;
3742e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                }
3752e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            }
3762e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3772e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            MetricsLogger.count(this, PRINTERS_INFO_COUNT, numInfoPrinters);
3782e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            MetricsLogger.count(this, PRINTERS_ICON_COUNT, numIconPrinters);
3792e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        }
3802e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
3812e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        super.onDestroy();
3822e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann    }
3832e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
384c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    @Override
385c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
386c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        switch (requestCode) {
387c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            case INFO_INTENT_REQUEST_CODE:
388c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                if (resultCode == RESULT_OK &&
389c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        data != null &&
390c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        data.getBooleanExtra(PrintService.EXTRA_SELECT_PRINTER, false) &&
391c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        mPrinterForInfoIntent != null &&
392c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        mPrinterForInfoIntent.getStatus() != PrinterInfo.STATUS_UNAVAILABLE) {
393c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    onPrinterSelected(mPrinterForInfoIntent);
394c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                }
395c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                mPrinterForInfoIntent = null;
396c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                break;
397c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            default:
398c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                // not reached
399c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        }
400c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    }
401c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
40263ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann    private void onPrinterSelected(PrinterInfo printer) {
403a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        Intent intent = new Intent();
40463ce0b737c022281ce4c36e1d90ed9b0270512f0Philip P. Moltmann        intent.putExtra(INTENT_EXTRA_PRINTER, printer);
405a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        setResult(RESULT_OK, intent);
406a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        finish();
407a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
408a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
409264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov    public void updateEmptyView(DestinationAdapter adapter) {
410ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov        if (mListView.getEmptyView() == null) {
411a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            View emptyView = findViewById(R.id.empty_print_state);
412ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            mListView.setEmptyView(emptyView);
41324c686b8b56950d5a1881cc660e53816d47e5e03Svetoslav Ganov        }
41451efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        TextView titleView = findViewById(R.id.title);
415a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        View progressBar = findViewById(R.id.progress_bar);
416e951a139161db650ca711695f78a269e4daaf819Philip P. Moltmann        if (mEnabledPrintServices.size() == 0) {
417953639cb826ad5fb85fcc18cbc0833a9dedb8227Philip P. Moltmann            titleView.setText(R.string.print_no_print_services);
418953639cb826ad5fb85fcc18cbc0833a9dedb8227Philip P. Moltmann            progressBar.setVisibility(View.GONE);
419953639cb826ad5fb85fcc18cbc0833a9dedb8227Philip P. Moltmann        } else if (adapter.getUnfilteredCount() <= 0) {
420264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            titleView.setText(R.string.print_searching_for_printers);
421264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            progressBar.setVisibility(View.VISIBLE);
422264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        } else {
423264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            titleView.setText(R.string.print_no_printers);
424264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            progressBar.setVisibility(View.GONE);
425264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        }
426264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov    }
427264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov
428ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav    private void announceSearchResultIfNeeded() {
429a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (AccessibilityManager.getInstance(this).isEnabled()) {
430ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav            if (mAnnounceFilterResult == null) {
431ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav                mAnnounceFilterResult = new AnnounceFilterResult();
432ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav            }
433ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav            mAnnounceFilterResult.post();
43456ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        }
43556ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov    }
43656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
43766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    @Override
43866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) {
43966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        return new PrintServicesLoader((PrintManager) getSystemService(Context.PRINT_SERVICE), this,
44066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                PrintManager.ENABLED_SERVICES);
44166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    }
442a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
44366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    @Override
44466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    public void onLoadFinished(Loader<List<PrintServiceInfo>> loader,
4453df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            List<PrintServiceInfo> services) {
4463df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann        mEnabledPrintServices.clear();
4473df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann
4483df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann        if (services != null && !services.isEmpty()) {
4493df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            final int numServices = services.size();
4503df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            for (int i = 0; i < numServices; i++) {
4513df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann                PrintServiceInfo service = services.get(i);
4523df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann
4533df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann                mEnabledPrintServices.put(service.getComponentName(), service);
4543df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            }
45566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        }
456269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
45766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        onPrintServicesUpdate();
45866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    }
459269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
46066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    @Override
46166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann    public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) {
46266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        if (!isFinishing()) {
46366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            onLoadFinished(loader, null);
464269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
465269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
466269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
467c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    /**
468c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     * Return the target SDK of the package that defined the printer.
469c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     *
470c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     * @param printer The printer
471c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     *
472c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     * @return The target SDK that defined a printer.
473c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann     */
474c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    private int getTargetSDKOfPrintersService(@NonNull PrinterInfo printer) {
475c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        ApplicationInfo serviceAppInfo;
476c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        try {
477c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            serviceAppInfo = getPackageManager().getApplicationInfo(
478c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    printer.getId().getServiceName().getPackageName(), 0);
479c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        } catch (PackageManager.NameNotFoundException e) {
480c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            Log.e(LOG_TAG, "Could not find package that defined the printer", e);
481c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann            return Build.VERSION_CODES.KITKAT;
482c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        }
483c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
484c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann        return serviceAppInfo.targetSdkVersion;
485c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann    }
486c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
487a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private final class DestinationAdapter extends BaseAdapter implements Filterable {
488269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
489269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        private final Object mLock = new Object();
490269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
491a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        private final List<PrinterInfo> mPrinters = new ArrayList<>();
492269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
493a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        private final List<PrinterInfo> mFilteredPrinters = new ArrayList<>();
494269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
495269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        private CharSequence mLastSearchString;
496269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
4972e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        /**
4982e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann         * Get the currently known printers.
4992e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann         *
5002e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann         * @return The currently known printers
5012e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann         */
5022e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        @NonNull List<PrinterInfo> getPrinters() {
5032e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann            return mPrinters;
5042e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann        }
5052e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
506269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public DestinationAdapter() {
507a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            mPrinterRegistry.setOnPrintersChangeListener(new PrinterRegistry.OnPrintersChangeListener() {
508a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                @Override
509a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                public void onPrintersChanged(List<PrinterInfo> printers) {
510a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    synchronized (mLock) {
511a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mPrinters.clear();
512a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mPrinters.addAll(printers);
513a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mFilteredPrinters.clear();
514a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mFilteredPrinters.addAll(printers);
515a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        if (!TextUtils.isEmpty(mLastSearchString)) {
516a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                            getFilter().filter(mLastSearchString);
517a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        }
518a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    }
519a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    notifyDataSetChanged();
520a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
521a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
522a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                @Override
523a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                public void onPrintersInvalid() {
524a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    synchronized (mLock) {
525a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mPrinters.clear();
526a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        mFilteredPrinters.clear();
527a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    }
528a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    notifyDataSetInvalidated();
529a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
530a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            });
531269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
532269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
533269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
534269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public Filter getFilter() {
535269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return new Filter() {
536269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                @Override
537269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                protected FilterResults performFiltering(CharSequence constraint) {
538269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    synchronized (mLock) {
539269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        if (TextUtils.isEmpty(constraint)) {
540269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            return null;
541269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        }
542269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        FilterResults results = new FilterResults();
543a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        List<PrinterInfo> filteredPrinters = new ArrayList<>();
544269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        String constraintLowerCase = constraint.toString().toLowerCase();
545269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        final int printerCount = mPrinters.size();
546269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        for (int i = 0; i < printerCount; i++) {
547269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            PrinterInfo printer = mPrinters.get(i);
548e58d8ff1fbb9d53d9b2ae941fb00721e6195213ePhilip P. Moltmann                            String description = printer.getDescription();
549e58d8ff1fbb9d53d9b2ae941fb00721e6195213ePhilip P. Moltmann                            if (printer.getName().toLowerCase().contains(constraintLowerCase)
550e58d8ff1fbb9d53d9b2ae941fb00721e6195213ePhilip P. Moltmann                                    || description != null && description.toLowerCase()
551e58d8ff1fbb9d53d9b2ae941fb00721e6195213ePhilip P. Moltmann                                            .contains(constraintLowerCase)) {
552269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                                filteredPrinters.add(printer);
553269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            }
554269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        }
555269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        results.values = filteredPrinters;
556269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        results.count = filteredPrinters.size();
557269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        return results;
558269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    }
559269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
560269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
561269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                @Override
562269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                @SuppressWarnings("unchecked")
563269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                protected void publishResults(CharSequence constraint, FilterResults results) {
56456ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                    final boolean resultCountChanged;
565269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    synchronized (mLock) {
56656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                        final int oldPrinterCount = mFilteredPrinters.size();
567269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        mLastSearchString = constraint;
568269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        mFilteredPrinters.clear();
569269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        if (results == null) {
570269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            mFilteredPrinters.addAll(mPrinters);
571269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        } else {
572269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            List<PrinterInfo> printers = (List<PrinterInfo>) results.values;
573269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                            mFilteredPrinters.addAll(printers);
574269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                        }
57556ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                        resultCountChanged = (oldPrinterCount != mFilteredPrinters.size());
57656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                    }
57756ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                    if (resultCountChanged) {
578ebec46847d4bbd72161fb32282ab7a68effa00a7Svetoslav                        announceSearchResultIfNeeded();
579269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    }
5802e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann
5812e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                    if (!mDidSearch) {
5822e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                        MetricsLogger.action(SelectPrinterActivity.this,
5832e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                                MetricsEvent.ACTION_PRINTER_SEARCH);
5842e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                        mDidSearch = true;
5852e3012624b703a653fed44d4dc1b8904406c0d99Philip P. Moltmann                    }
586269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                    notifyDataSetChanged();
587269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                }
588269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            };
589269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
590269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
591264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        public int getUnfilteredCount() {
592264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            synchronized (mLock) {
593264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov                return mPrinters.size();
594264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov            }
595264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov        }
596264c566a7f7d829de48131ac6d811b3db6f520bcSvetoslav Ganov
597269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
598269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public int getCount() {
599269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            synchronized (mLock) {
60066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (mFilteredPrinters.isEmpty()) {
60166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return 0;
60266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                } else {
60366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    // Add "add printer" item to the end of the list. If the list is empty there is
60466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    // a link on the empty view
60566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return mFilteredPrinters.size() + 1;
60666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
60766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
60866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        }
60966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
61066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        @Override
61166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public int getViewTypeCount() {
61266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            return 2;
61366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        }
61466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
61566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        @Override
61666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann        public int getItemViewType(int position) {
61766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            // Use separate view types for the "add printer" item an the items referring to printers
61866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            if (getItem(position) == null) {
61966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return 0;
62066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } else {
62166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return 1;
622269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
623269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
624269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
625269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
626269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public Object getItem(int position) {
627269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            synchronized (mLock) {
62866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (position < mFilteredPrinters.size()) {
62966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return mFilteredPrinters.get(position);
63066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                } else {
63166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    // Return null to mark this as the "add printer item"
63266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    return null;
63366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
634269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
635269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
636269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
637269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
638269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public long getItemId(int position) {
639269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return position;
640269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
641269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
642269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
643a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public View getDropDownView(int position, View convertView, ViewGroup parent) {
644269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return getView(position, convertView, parent);
645269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
646269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
647269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        @Override
648269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        public View getView(int position, View convertView, ViewGroup parent) {
64966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            final PrinterInfo printer = (PrinterInfo) getItem(position);
65066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
65166c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            // Handle "add printer item"
65266c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            if (printer == null) {
65366c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                if (convertView == null) {
65466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                    convertView = getLayoutInflater().inflate(R.layout.add_printer_list_item,
65566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                            parent, false);
65666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                }
65766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
65866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return convertView;
65966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
66066c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
661269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (convertView == null) {
662a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                convertView = getLayoutInflater().inflate(
663ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov                        R.layout.printer_list_item, parent, false);
664269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
665269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
6661c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav            convertView.setEnabled(isActionable(position));
66769b91e0ecb8cef95c030f5076779e07d363a45f2Svetoslav Ganov
668a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
669a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            CharSequence title = printer.getName();
670bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            Drawable icon = printer.loadIcon(SelectPrinterActivity.this);
671269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
6723df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            PrintServiceInfo service = mEnabledPrintServices.get(printer.getId().getServiceName());
673bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
6743df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            CharSequence printServiceLabel = null;
6753df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann            if (service != null) {
6763df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann                printServiceLabel = service.getResolveInfo().loadLabel(getPackageManager())
6773df18a94657e1554ed1aca87b5aedbc2d7eb7a48Philip P. Moltmann                        .toString();
678bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
679bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
680bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            CharSequence description = printer.getDescription();
681bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann
682bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            CharSequence subtitle;
6835462e88c0272d08773ac6cd16cce435c32d2d9bfPhilip P. Moltmann            if (TextUtils.isEmpty(printServiceLabel)) {
684bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                subtitle = description;
6855462e88c0272d08773ac6cd16cce435c32d2d9bfPhilip P. Moltmann            } else if (TextUtils.isEmpty(description)) {
686bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                subtitle = printServiceLabel;
687bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            } else {
688bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                subtitle = getString(R.string.printer_extended_description_template,
689bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                        printServiceLabel, description);
690269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
691269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
692269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            TextView titleView = (TextView) convertView.findViewById(R.id.title);
693269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            titleView.setText(title);
694269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
695269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
696269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            if (!TextUtils.isEmpty(subtitle)) {
697269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                subtitleView.setText(subtitle);
698269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                subtitleView.setVisibility(View.VISIBLE);
699269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            } else {
700269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                subtitleView.setText(null);
701269403b032f965ff3847eb982c2f697229dc5a92Svetoslav                subtitleView.setVisibility(View.GONE);
702269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            }
703269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
70466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            LinearLayout moreInfoView = (LinearLayout) convertView.findViewById(R.id.more_info);
705bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            if (printer.getInfoIntent() != null) {
706bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                moreInfoView.setVisibility(View.VISIBLE);
707c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                moreInfoView.setOnClickListener(v -> {
708c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    Intent fillInIntent = new Intent();
709c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    fillInIntent.putExtra(PrintService.EXTRA_CAN_SELECT_PRINTER, true);
710c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann
711c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    try {
712c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        mPrinterForInfoIntent = printer;
713c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        startIntentSenderForResult(printer.getInfoIntent().getIntentSender(),
714c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                                INFO_INTENT_REQUEST_CODE, fillInIntent, 0, 0, 0);
715c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                    } catch (SendIntentException e) {
716c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        mPrinterForInfoIntent = null;
717c8d6f54be3c05d13c63d2eb353eef9c24964630cPhilip P. Moltmann                        Log.e(LOG_TAG, "Could not execute pending info intent: %s", e);
718bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                    }
719bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann                });
720443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann            } else {
721443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                moreInfoView.setVisibility(View.GONE);
722bb9f686b40743df2642b7d3b7778dbf7284ae665Philip P. Moltmann            }
72339e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav
72439e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav            ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
72539e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav            if (icon != null) {
72639e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav                iconView.setVisibility(View.VISIBLE);
727443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                if (!isActionable(position)) {
728443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                    icon.mutate();
729443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann
730443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                    TypedValue value = new TypedValue();
731443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                    getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, true);
732443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                    icon.setAlpha((int)(value.getFloat() * 255));
733443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                }
734443075ab9784f168fc7a73bb09dabf8bf7ab308ePhilip P. Moltmann                iconView.setImageDrawable(icon);
73539e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav            } else {
73639e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav                iconView.setVisibility(View.GONE);
73739e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav            }
73839e71de6b49d1cb67ce30b411cede8d4f40dc765Svetoslav
739269403b032f965ff3847eb982c2f697229dc5a92Svetoslav            return convertView;
740269403b032f965ff3847eb982c2f697229dc5a92Svetoslav        }
741269403b032f965ff3847eb982c2f697229dc5a92Svetoslav
7421c664b6defd20ab4a83c4a83d01b9ed8603f7c2cSvetoslav        public boolean isActionable(int position) {
74369b91e0ecb8cef95c030f5076779e07d363a45f2Svetoslav Ganov            PrinterInfo printer =  (PrinterInfo) getItem(position);
74466c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann
74566c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            if (printer == null) {
74666c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return true;
74766c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            } else {
74866c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann                return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE;
74966c96591e2ddb464c67e60dbf4193ef4ec8a620bPhilip P. Moltmann            }
75069b91e0ecb8cef95c030f5076779e07d363a45f2Svetoslav Ganov        }
751269403b032f965ff3847eb982c2f697229dc5a92Svetoslav    }
75256ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
75356ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov    private final class AnnounceFilterResult implements Runnable {
75456ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        private static final int SEARCH_RESULT_ANNOUNCEMENT_DELAY = 1000; // 1 sec
75556ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
75656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        public void post() {
75756ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            remove();
758ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            mListView.postDelayed(this, SEARCH_RESULT_ANNOUNCEMENT_DELAY);
75956ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        }
76056ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
76156ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        public void remove() {
762ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            mListView.removeCallbacks(this);
76356ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        }
76456ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov
76556ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        @Override
76656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        public void run() {
767ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            final int count = mListView.getAdapter().getCount();
76856ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            final String text;
76956ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            if (count <= 0) {
77056ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                text = getString(R.string.print_no_printers);
77156ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            } else {
772a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                text = getResources().getQuantityString(
77356ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov                    R.plurals.print_search_result_count_utterance, count, count);
77456ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov            }
775ed513d7e4a624a9f82e15923a7052d4c18a020a7Svetoslav Ganov            mListView.announceForAccessibility(text);
77656ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov        }
77756ddf1ffa5b7bd3b8d4b8b7d5c68d7e0e99e5e15Svetoslav Ganov    }
778269403b032f965ff3847eb982c2f697229dc5a92Svetoslav}
779