OSDN Git Service

Import translations. DO NOT MERGE
[android-x86/packages-apps-Settings.git] / src / com / android / settings / print / PrintServiceSettingsFragment.java
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.settings.print;
18
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.LoaderManager;
23 import android.content.ComponentName;
24 import android.content.ContentResolver;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.content.Intent;
28 import android.content.Loader;
29 import android.content.pm.PackageInfo;
30 import android.content.pm.PackageManager.NameNotFoundException;
31 import android.content.pm.ResolveInfo;
32 import android.database.ContentObserver;
33 import android.database.DataSetObserver;
34 import android.graphics.Color;
35 import android.graphics.drawable.ColorDrawable;
36 import android.graphics.drawable.Drawable;
37 import android.net.Uri;
38 import android.os.Bundle;
39 import android.os.Handler;
40 import android.print.PrintManager;
41 import android.print.PrinterDiscoverySession;
42 import android.print.PrinterDiscoverySession.OnPrintersChangeListener;
43 import android.print.PrinterId;
44 import android.print.PrinterInfo;
45 import android.text.TextUtils;
46 import android.util.Log;
47 import android.view.Menu;
48 import android.view.MenuInflater;
49 import android.view.MenuItem;
50 import android.view.View;
51 import android.view.ViewGroup;
52 import android.view.accessibility.AccessibilityManager;
53 import android.widget.BaseAdapter;
54 import android.widget.Filter;
55 import android.widget.Filterable;
56 import android.widget.ImageView;
57 import android.widget.ListView;
58 import android.widget.SearchView;
59 import android.widget.Switch;
60 import android.widget.TextView;
61
62 import com.android.settings.R;
63 import com.android.settings.SettingsActivity;
64 import com.android.settings.SettingsPreferenceFragment;
65
66 import java.util.ArrayList;
67 import java.util.LinkedHashMap;
68 import java.util.List;
69 import java.util.Map;
70
71 import com.android.settings.widget.SwitchBar;
72 import com.android.settings.widget.ToggleSwitch;
73
74 /**
75  * Fragment with print service settings.
76  */
77 public class PrintServiceSettingsFragment extends SettingsPreferenceFragment
78         implements DialogInterface.OnClickListener, SwitchBar.OnSwitchChangeListener {
79
80     private static final int LOADER_ID_PRINTERS_LOADER = 1;
81
82     private static final int DIALOG_ID_ENABLE_WARNING = 1;
83
84     private final SettingsContentObserver mSettingsContentObserver =
85             new SettingsContentObserver(new Handler()) {
86         @Override
87         public void onChange(boolean selfChange, Uri uri) {
88             updateUiForServiceState();
89         }
90     };
91
92     private final DataSetObserver mDataObserver = new DataSetObserver() {
93         @Override
94         public void onChanged() {
95             invalidateOptionsMenuIfNeeded();
96             updateEmptyView();
97         }
98
99         @Override
100         public void onInvalidated() {
101             invalidateOptionsMenuIfNeeded();
102         }
103
104         private void invalidateOptionsMenuIfNeeded() {
105             final int unfilteredItemCount = mPrintersAdapter.getUnfilteredCount();
106             if ((mLastUnfilteredItemCount <= 0 && unfilteredItemCount > 0)
107                     || mLastUnfilteredItemCount > 0 && unfilteredItemCount <= 0) {
108                 getActivity().invalidateOptionsMenu();
109             }
110             mLastUnfilteredItemCount = unfilteredItemCount;
111         }
112     };
113
114     private SwitchBar mSwitchBar;
115     private ToggleSwitch mToggleSwitch;
116
117     private String mPreferenceKey;
118
119     private CharSequence mSettingsTitle;
120     private Intent mSettingsIntent;
121
122     private CharSequence mAddPrintersTitle;
123     private Intent mAddPrintersIntent;
124
125     private CharSequence mEnableWarningTitle;
126     private CharSequence mEnableWarningMessage;
127
128     private ComponentName mComponentName;
129
130     private PrintersAdapter mPrintersAdapter;
131
132     // TODO: Showing sub-sub fragment does not handle the activity title
133     // so we do it but this is wrong. Do a real fix when there is time.
134     private CharSequence mOldActivityTitle;
135
136     private int mLastUnfilteredItemCount;
137
138     private boolean mServiceEnabled;
139
140     @Override
141     public void onResume() {
142         super.onResume();
143         mSettingsContentObserver.register(getContentResolver());
144         updateEmptyView();
145         updateUiForServiceState();
146     }
147
148     @Override
149     public void onPause() {
150         mSettingsContentObserver.unregister(getContentResolver());
151         super.onPause();
152     }
153
154     @Override
155     public void onViewCreated(View view, Bundle savedInstanceState) {
156         super.onViewCreated(view, savedInstanceState);
157         initComponents();
158         updateUiForArguments();
159     }
160
161     @Override
162     public void onDestroyView() {
163         if (mOldActivityTitle != null) {
164             getActivity().getActionBar().setTitle(mOldActivityTitle);
165         }
166         super.onDestroyView();
167         mSwitchBar.removeOnSwitchChangeListener(this);
168         mSwitchBar.hide();
169     }
170
171     private void onPreferenceToggled(String preferenceKey, boolean enabled) {
172         ComponentName service = ComponentName.unflattenFromString(preferenceKey);
173         List<ComponentName> services = PrintSettingsUtils.readEnabledPrintServices(getActivity());
174         if (enabled) {
175             services.add(service);
176         } else {
177             services.remove(service);
178         }
179         PrintSettingsUtils.writeEnabledPrintServices(getActivity(), services);
180     }
181
182     @Override
183     public Dialog onCreateDialog(int dialogId) {
184         CharSequence title = null;
185         CharSequence message = null;
186         switch (dialogId) {
187             case DIALOG_ID_ENABLE_WARNING:
188                 title = mEnableWarningTitle;
189                 message = mEnableWarningMessage;
190                 break;
191             default:
192                 throw new IllegalArgumentException();
193         }
194         return new AlertDialog.Builder(getActivity())
195                 .setTitle(title)
196                 .setMessage(message)
197                 .setCancelable(true)
198                 .setPositiveButton(android.R.string.ok, this)
199                 .setNegativeButton(android.R.string.cancel, this)
200                 .create();
201     }
202
203     @Override
204     public void onClick(DialogInterface dialog, int which) {
205         final boolean checked;
206         switch (which) {
207             case DialogInterface.BUTTON_POSITIVE:
208                 checked = true;
209                 mSwitchBar.setCheckedInternal(checked);
210                 getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, checked);
211                 onPreferenceToggled(mPreferenceKey, checked);
212                 break;
213             case DialogInterface.BUTTON_NEGATIVE:
214                 checked = false;
215                 mSwitchBar.setCheckedInternal(checked);
216                 getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, checked);
217                 onPreferenceToggled(mPreferenceKey, checked);
218                 break;
219             default:
220                 throw new IllegalArgumentException();
221         }
222     }
223
224     private void updateEmptyView() {
225         ListView listView = getListView();
226         ViewGroup contentRoot = (ViewGroup) listView.getParent();
227         View emptyView = listView.getEmptyView();
228         if (!mToggleSwitch.isChecked()) {
229             if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
230                 contentRoot.removeView(emptyView);
231                 emptyView = null;
232             }
233             if (emptyView == null) {
234                 emptyView = getActivity().getLayoutInflater().inflate(
235                         R.layout.empty_print_state, contentRoot, false);
236                 ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon);
237                 iconView.setContentDescription(getString(R.string.print_service_disabled));
238                 TextView textView = (TextView) emptyView.findViewById(R.id.message);
239                 textView.setText(R.string.print_service_disabled);
240                 contentRoot.addView(emptyView);
241                 listView.setEmptyView(emptyView);
242             }
243         } else if (mPrintersAdapter.getUnfilteredCount() <= 0) {
244             if (emptyView != null
245                     && emptyView.getId() != R.id.empty_printers_list_service_enabled) {
246                 contentRoot.removeView(emptyView);
247                 emptyView = null;
248             }
249             if (emptyView == null) {
250                 emptyView = getActivity().getLayoutInflater().inflate(
251                         R.layout.empty_printers_list_service_enabled, contentRoot, false);
252                 contentRoot.addView(emptyView);
253                 listView.setEmptyView(emptyView);
254             }
255         } else if (mPrintersAdapter.getCount() <= 0) {
256             if (emptyView != null && emptyView.getId() != R.id.empty_print_state) {
257                 contentRoot.removeView(emptyView);
258                 emptyView = null;
259             }
260             if (emptyView == null) {
261                 emptyView = getActivity().getLayoutInflater().inflate(
262                         R.layout.empty_print_state, contentRoot, false);
263                 ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon);
264                 iconView.setContentDescription(getString(R.string.print_no_printers_found));
265                 TextView textView = (TextView) emptyView.findViewById(R.id.message);
266                 textView.setText(R.string.print_no_printers_found);
267                 contentRoot.addView(emptyView);
268                 listView.setEmptyView(emptyView);
269             }
270         }
271     }
272
273     private void updateUiForServiceState() {
274         List<ComponentName> services = PrintSettingsUtils.readEnabledPrintServices(getActivity());
275         mServiceEnabled = services.contains(mComponentName);
276         if (mServiceEnabled) {
277             mSwitchBar.setCheckedInternal(true);
278             mPrintersAdapter.enable();
279         } else {
280             mSwitchBar.setCheckedInternal(false);
281             mPrintersAdapter.disable();
282         }
283         getActivity().invalidateOptionsMenu();
284     }
285
286     private void initComponents() {
287         mPrintersAdapter = new PrintersAdapter();
288         mPrintersAdapter.registerDataSetObserver(mDataObserver);
289
290         final SettingsActivity activity = (SettingsActivity) getActivity();
291
292         mSwitchBar = activity.getSwitchBar();
293         mSwitchBar.addOnSwitchChangeListener(this);
294         mSwitchBar.show();
295
296         mToggleSwitch = mSwitchBar.getSwitch();
297         mToggleSwitch.setOnBeforeCheckedChangeListener(new ToggleSwitch.OnBeforeCheckedChangeListener() {
298             @Override
299             public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) {
300                 if (checked) {
301                     if (!TextUtils.isEmpty(mEnableWarningMessage)) {
302                         mSwitchBar.setCheckedInternal(false);
303                         getArguments().putBoolean(PrintSettingsFragment.EXTRA_CHECKED, false);
304                         showDialog(DIALOG_ID_ENABLE_WARNING);
305                         return true;
306                     }
307                     onPreferenceToggled(mPreferenceKey, true);
308                 } else {
309                     onPreferenceToggled(mPreferenceKey, false);
310                 }
311                 return false;
312             }
313         });
314
315         getListView().setSelector(new ColorDrawable(Color.TRANSPARENT));
316         getListView().setAdapter(mPrintersAdapter);
317     }
318
319
320     @Override
321     public void onSwitchChanged(Switch switchView, boolean isChecked) {
322         updateEmptyView();
323     }
324
325     private void updateUiForArguments() {
326         Bundle arguments = getArguments();
327
328         // Key.
329         mPreferenceKey = arguments.getString(PrintSettingsFragment.EXTRA_PREFERENCE_KEY);
330
331         // Enabled.
332         final boolean enabled = arguments.getBoolean(PrintSettingsFragment.EXTRA_CHECKED);
333         mSwitchBar.setCheckedInternal(enabled);
334
335         // Settings title and intent.
336         String settingsTitle = arguments.getString(PrintSettingsFragment.EXTRA_SETTINGS_TITLE);
337         String settingsComponentName = arguments.getString(
338                 PrintSettingsFragment.EXTRA_SETTINGS_COMPONENT_NAME);
339         if (!TextUtils.isEmpty(settingsTitle) && !TextUtils.isEmpty(settingsComponentName)) {
340             Intent settingsIntent = new Intent(Intent.ACTION_MAIN).setComponent(
341                     ComponentName.unflattenFromString(settingsComponentName.toString()));
342             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
343                     settingsIntent, 0);
344             if (!resolvedActivities.isEmpty()) {
345                 // The activity is a component name, therefore it is one or none.
346                 if (resolvedActivities.get(0).activityInfo.exported) {
347                     mSettingsTitle = settingsTitle;
348                     mSettingsIntent = settingsIntent;
349                 }
350             }
351         }
352
353         // Add printers title and intent.
354         String addPrintersTitle = arguments.getString(
355                 PrintSettingsFragment.EXTRA_ADD_PRINTERS_TITLE);
356         String addPrintersComponentName =
357                 arguments.getString(PrintSettingsFragment.EXTRA_ADD_PRINTERS_COMPONENT_NAME);
358         if (!TextUtils.isEmpty(addPrintersTitle)
359                 && !TextUtils.isEmpty(addPrintersComponentName)) {
360             Intent addPritnersIntent = new Intent(Intent.ACTION_MAIN).setComponent(
361                     ComponentName.unflattenFromString(addPrintersComponentName.toString()));
362             List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities(
363                     addPritnersIntent, 0);
364             if (!resolvedActivities.isEmpty()) {
365                 // The activity is a component name, therefore it is one or none.
366                 if (resolvedActivities.get(0).activityInfo.exported) {
367                     mAddPrintersTitle = addPrintersTitle;
368                     mAddPrintersIntent = addPritnersIntent;
369                 }
370             }
371         }
372
373         // Enable warning title.
374         mEnableWarningTitle = arguments.getCharSequence(
375                 PrintSettingsFragment.EXTRA_ENABLE_WARNING_TITLE);
376
377         // Enable warning message.
378         mEnableWarningMessage = arguments.getCharSequence(
379                 PrintSettingsFragment.EXTRA_ENABLE_WARNING_MESSAGE);
380
381         // Component name.
382         mComponentName = ComponentName.unflattenFromString(arguments
383                 .getString(PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME));
384
385         setHasOptionsMenu(true);
386     }
387
388     @Override
389     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
390         super.onCreateOptionsMenu(menu, inflater);
391         inflater.inflate(R.menu.print_service_settings, menu);
392
393         MenuItem addPrinters = menu.findItem(R.id.print_menu_item_add_printer);
394         if (mServiceEnabled && !TextUtils.isEmpty(mAddPrintersTitle)
395                 && mAddPrintersIntent != null) {
396             addPrinters.setIntent(mAddPrintersIntent);
397         } else {
398             menu.removeItem(R.id.print_menu_item_add_printer);
399         }
400
401         MenuItem settings = menu.findItem(R.id.print_menu_item_settings);
402         if (mServiceEnabled && !TextUtils.isEmpty(mSettingsTitle)
403                 && mSettingsIntent != null) {
404             settings.setIntent(mSettingsIntent);
405         } else {
406             menu.removeItem(R.id.print_menu_item_settings);
407         }
408
409         MenuItem searchItem = menu.findItem(R.id.print_menu_item_search);
410         if (mServiceEnabled && mPrintersAdapter.getUnfilteredCount() > 0) {
411             SearchView searchView = (SearchView) searchItem.getActionView();
412             searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
413                 @Override
414                 public boolean onQueryTextSubmit(String query) {
415                     return true;
416                 }
417
418                 @Override
419                 public boolean onQueryTextChange(String searchString) {
420                     ((Filterable) getListView().getAdapter()).getFilter().filter(searchString);
421                     return true;
422                 }
423             });
424             searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
425                 @Override
426                 public void onViewAttachedToWindow(View view) {
427                     if (AccessibilityManager.getInstance(getActivity()).isEnabled()) {
428                         view.announceForAccessibility(getString(
429                                 R.string.print_search_box_shown_utterance));
430                     }
431                 }
432                 @Override
433                 public void onViewDetachedFromWindow(View view) {
434                     Activity activity = getActivity();
435                     if (activity != null && !activity.isFinishing()
436                             && AccessibilityManager.getInstance(activity).isEnabled()) {
437                         view.announceForAccessibility(getString(
438                                 R.string.print_search_box_hidden_utterance));
439                     }
440                 }
441             });
442         } else {
443             menu.removeItem(R.id.print_menu_item_search);
444         }
445     }
446
447     private static abstract class SettingsContentObserver extends ContentObserver {
448
449         public SettingsContentObserver(Handler handler) {
450             super(handler);
451         }
452
453         public void register(ContentResolver contentResolver) {
454             contentResolver.registerContentObserver(android.provider.Settings.Secure.getUriFor(
455                     android.provider.Settings.Secure.ENABLED_PRINT_SERVICES), false, this);
456         }
457
458         public void unregister(ContentResolver contentResolver) {
459             contentResolver.unregisterContentObserver(this);
460         }
461
462         @Override
463         public abstract void onChange(boolean selfChange, Uri uri);
464     }
465
466     private final class PrintersAdapter extends BaseAdapter
467             implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable {
468         private final Object mLock = new Object();
469
470         private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>();
471
472         private final List<PrinterInfo> mFilteredPrinters = new ArrayList<PrinterInfo>();
473
474         private CharSequence mLastSearchString;
475
476         public void enable() {
477             getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this);
478         }
479
480         public void disable() {
481             getLoaderManager().destroyLoader(LOADER_ID_PRINTERS_LOADER);
482             mPrinters.clear();
483         }
484
485         public int getUnfilteredCount() {
486             return mPrinters.size();
487         }
488
489         @Override
490         public Filter getFilter() {
491             return new Filter() {
492                 @Override
493                 protected FilterResults performFiltering(CharSequence constraint) {
494                     synchronized (mLock) {
495                         if (TextUtils.isEmpty(constraint)) {
496                             return null;
497                         }
498                         FilterResults results = new FilterResults();
499                         List<PrinterInfo> filteredPrinters = new ArrayList<PrinterInfo>();
500                         String constraintLowerCase = constraint.toString().toLowerCase();
501                         final int printerCount = mPrinters.size();
502                         for (int i = 0; i < printerCount; i++) {
503                             PrinterInfo printer = mPrinters.get(i);
504                             if (printer.getName().toLowerCase().contains(constraintLowerCase)) {
505                                 filteredPrinters.add(printer);
506                             }
507                         }
508                         results.values = filteredPrinters;
509                         results.count = filteredPrinters.size();
510                         return results;
511                     }
512                 }
513
514                 @Override
515                 @SuppressWarnings("unchecked")
516                 protected void publishResults(CharSequence constraint, FilterResults results) {
517                     synchronized (mLock) {
518                         mLastSearchString = constraint;
519                         mFilteredPrinters.clear();
520                         if (results == null) {
521                             mFilteredPrinters.addAll(mPrinters);
522                         } else {
523                             List<PrinterInfo> printers = (List<PrinterInfo>) results.values;
524                             mFilteredPrinters.addAll(printers);
525                         }
526                     }
527                     notifyDataSetChanged();
528                 }
529             };
530         }
531
532         @Override
533         public int getCount() {
534             synchronized (mLock) {
535                 return mFilteredPrinters.size();
536             }
537         }
538
539         @Override
540         public Object getItem(int position) {
541             synchronized (mLock) {
542                 return mFilteredPrinters.get(position);
543             }
544         }
545
546         @Override
547         public long getItemId(int position) {
548             return position;
549         }
550
551         @Override
552         public View getView(int position, View convertView, ViewGroup parent) {
553             if (convertView == null) {
554                 convertView = getActivity().getLayoutInflater().inflate(
555                         R.layout.printer_dropdown_item, parent, false);
556             }
557
558             PrinterInfo printer = (PrinterInfo) getItem(position);
559             CharSequence title = printer.getName();
560             CharSequence subtitle = null;
561             Drawable icon = null;
562             try {
563                 PackageInfo packageInfo = getPackageManager().getPackageInfo(
564                         printer.getId().getServiceName().getPackageName(), 0);
565                         subtitle = packageInfo.applicationInfo.loadLabel(getPackageManager());
566                         icon = packageInfo.applicationInfo.loadIcon(getPackageManager());
567             } catch (NameNotFoundException nnfe) {
568                 /* ignore */
569             }
570
571             TextView titleView = (TextView) convertView.findViewById(R.id.title);
572             titleView.setText(title);
573
574             TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle);
575             if (!TextUtils.isEmpty(subtitle)) {
576                 subtitleView.setText(subtitle);
577                 subtitleView.setVisibility(View.VISIBLE);
578             } else {
579                 subtitleView.setText(null);
580                 subtitleView.setVisibility(View.GONE);
581             }
582
583             ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
584             if (icon != null) {
585                 iconView.setImageDrawable(icon);
586                 iconView.setVisibility(View.VISIBLE);
587             } else {
588                 iconView.setVisibility(View.GONE);
589             }
590
591             return convertView;
592         }
593
594         @Override
595         public boolean isEnabled(int position) {
596             return false;
597         }
598
599         @Override
600         public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) {
601             if (id == LOADER_ID_PRINTERS_LOADER) {
602                 return new PrintersLoader(getActivity());
603             }
604             return null;
605         }
606
607         @Override
608         public void onLoadFinished(Loader<List<PrinterInfo>> loader,
609                 List<PrinterInfo> printers) {
610             synchronized (mLock) {
611                 mPrinters.clear();
612                 final int printerCount = printers.size();
613                 for (int i = 0; i < printerCount; i++) {
614                     PrinterInfo printer = printers.get(i);
615                     if (printer.getId().getServiceName().equals(mComponentName)) {
616                         mPrinters.add(printer);
617                     }
618                 }
619                 mFilteredPrinters.clear();
620                 mFilteredPrinters.addAll(mPrinters);
621                 if (!TextUtils.isEmpty(mLastSearchString)) {
622                     getFilter().filter(mLastSearchString);
623                 }
624             }
625             notifyDataSetChanged();
626         }
627
628         @Override
629         public void onLoaderReset(Loader<List<PrinterInfo>> loader) {
630             synchronized (mLock) {
631                 mPrinters.clear();
632                 mFilteredPrinters.clear();
633                 mLastSearchString = null;
634             }
635             notifyDataSetInvalidated();
636         }
637     }
638
639     private static class PrintersLoader extends Loader<List<PrinterInfo>> {
640
641         private static final String LOG_TAG = "PrintersLoader";
642
643         private static final boolean DEBUG = false;
644
645         private final Map<PrinterId, PrinterInfo> mPrinters =
646                 new LinkedHashMap<PrinterId, PrinterInfo>();
647
648         private PrinterDiscoverySession mDiscoverySession;
649
650         public PrintersLoader(Context context) {
651             super(context);
652         }
653
654         @Override
655         public void deliverResult(List<PrinterInfo> printers) {
656             if (isStarted()) {
657                 super.deliverResult(printers);
658             }
659         }
660
661         @Override
662         protected void onStartLoading() {
663             if (DEBUG) {
664                 Log.i(LOG_TAG, "onStartLoading()");
665             }
666             // The contract is that if we already have a valid,
667             // result the we have to deliver it immediately.
668             if (!mPrinters.isEmpty()) {
669                 deliverResult(new ArrayList<PrinterInfo>(mPrinters.values()));
670             }
671             // We want to start discovery at this point.
672             onForceLoad();
673         }
674
675         @Override
676         protected void onStopLoading() {
677             if (DEBUG) {
678                 Log.i(LOG_TAG, "onStopLoading()");
679             }
680             onCancelLoad();
681         }
682
683         @Override
684         protected void onForceLoad() {
685             if (DEBUG) {
686                 Log.i(LOG_TAG, "onForceLoad()");
687             }
688             loadInternal();
689         }
690
691         @Override
692         protected boolean onCancelLoad() {
693             if (DEBUG) {
694                 Log.i(LOG_TAG, "onCancelLoad()");
695             }
696             return cancelInternal();
697         }
698
699         @Override
700         protected void onReset() {
701             if (DEBUG) {
702                 Log.i(LOG_TAG, "onReset()");
703             }
704             onStopLoading();
705             mPrinters.clear();
706             if (mDiscoverySession != null) {
707                 mDiscoverySession.destroy();
708                 mDiscoverySession = null;
709             }
710         }
711
712         @Override
713         protected void onAbandon() {
714             if (DEBUG) {
715                 Log.i(LOG_TAG, "onAbandon()");
716             }
717             onStopLoading();
718         }
719
720         private boolean cancelInternal() {
721             if (mDiscoverySession != null
722                     && mDiscoverySession.isPrinterDiscoveryStarted()) {
723                 mDiscoverySession.stopPrinterDiscovery();
724                 return true;
725             }
726             return false;
727         }
728
729         private void loadInternal() {
730             if (mDiscoverySession == null) {
731                 PrintManager printManager = (PrintManager) getContext()
732                         .getSystemService(Context.PRINT_SERVICE);
733                 mDiscoverySession = printManager.createPrinterDiscoverySession();
734                 mDiscoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() {
735                     @Override
736                     public void onPrintersChanged() {
737                         deliverResult(new ArrayList<PrinterInfo>(
738                                 mDiscoverySession.getPrinters()));
739                     }
740                 });
741             }
742             mDiscoverySession.startPrinterDiscovery(null);
743         }
744     }
745 }
746