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.LoaderManager; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentSender.SendIntentException; 25 import android.content.Loader; 26 import android.content.pm.ResolveInfo; 27 import android.database.DataSetObserver; 28 import android.graphics.Color; 29 import android.graphics.drawable.ColorDrawable; 30 import android.graphics.drawable.Drawable; 31 import android.os.Bundle; 32 import android.print.PrintManager; 33 import android.print.PrintServicesLoader; 34 import android.print.PrinterDiscoverySession; 35 import android.print.PrinterDiscoverySession.OnPrintersChangeListener; 36 import android.print.PrinterId; 37 import android.print.PrinterInfo; 38 import android.printservice.PrintServiceInfo; 39 import android.text.TextUtils; 40 import android.util.Log; 41 import android.util.TypedValue; 42 import android.view.LayoutInflater; 43 import android.view.Menu; 44 import android.view.MenuInflater; 45 import android.view.MenuItem; 46 import android.view.View; 47 import android.view.ViewGroup; 48 import android.view.View.OnClickListener; 49 import android.view.accessibility.AccessibilityManager; 50 import android.widget.AdapterView; 51 import android.widget.BaseAdapter; 52 import android.widget.Filter; 53 import android.widget.Filterable; 54 import android.widget.ImageView; 55 import android.widget.LinearLayout; 56 import android.widget.ListView; 57 import android.widget.SearchView; 58 import android.widget.Switch; 59 import android.widget.TextView; 60 61 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 62 import com.android.settings.R; 63 import com.android.settings.SettingsActivity; 64 import com.android.settings.SettingsPreferenceFragment; 65 import com.android.settings.widget.SwitchBar; 66 import com.android.settings.widget.ToggleSwitch; 67 68 import java.util.ArrayList; 69 import java.util.LinkedHashMap; 70 import java.util.List; 71 import java.util.Map; 72 73 /** 74 * Fragment with print service settings. 75 */ 76 public class PrintServiceSettingsFragment extends SettingsPreferenceFragment 77 implements SwitchBar.OnSwitchChangeListener, 78 LoaderManager.LoaderCallbacks<List<PrintServiceInfo>> { 79 80 private static final String LOG_TAG = "PrintServiceSettingsFragment"; 81 82 private static final int LOADER_ID_PRINTERS_LOADER = 1; 83 private static final int LOADER_ID_PRINT_SERVICE_LOADER = 2; 84 85 private final DataSetObserver mDataObserver = new DataSetObserver() { 86 @Override 87 public void onChanged() { 88 invalidateOptionsMenuIfNeeded(); 89 updateEmptyView(); 90 } 91 92 @Override 93 public void onInvalidated() { 94 invalidateOptionsMenuIfNeeded(); 95 } 96 97 private void invalidateOptionsMenuIfNeeded() { 98 final int unfilteredItemCount = mPrintersAdapter.getUnfilteredCount(); 99 if ((mLastUnfilteredItemCount <= 0 && unfilteredItemCount > 0) 100 || mLastUnfilteredItemCount > 0 && unfilteredItemCount <= 0) { 101 getActivity().invalidateOptionsMenu(); 102 } 103 mLastUnfilteredItemCount = unfilteredItemCount; 104 } 105 }; 106 107 private SwitchBar mSwitchBar; 108 private ToggleSwitch mToggleSwitch; 109 110 private String mPreferenceKey; 111 112 private Intent mSettingsIntent; 113 114 private Intent mAddPrintersIntent; 115 116 private ComponentName mComponentName; 117 118 private PrintersAdapter mPrintersAdapter; 119 120 private int mLastUnfilteredItemCount; 121 122 private boolean mServiceEnabled; 123 124 private SearchView mSearchView; 125 126 @Override getMetricsCategory()127 public int getMetricsCategory() { 128 return MetricsEvent.PRINT_SERVICE_SETTINGS; 129 } 130 131 @Override onCreate(Bundle icicle)132 public void onCreate(Bundle icicle) { 133 super.onCreate(icicle); 134 135 String title = getArguments().getString(PrintSettingsFragment.EXTRA_TITLE); 136 if (!TextUtils.isEmpty(title)) { 137 getActivity().setTitle(title); 138 } 139 } 140 141 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)142 public View onCreateView(LayoutInflater inflater, ViewGroup container, 143 Bundle savedInstanceState) { 144 View root = super.onCreateView(inflater, container, savedInstanceState); 145 146 mServiceEnabled = getArguments().getBoolean(PrintSettingsFragment.EXTRA_CHECKED); 147 148 return root; 149 } 150 151 @Override onStart()152 public void onStart() { 153 super.onStart(); 154 updateEmptyView(); 155 updateUiForServiceState(); 156 } 157 158 @Override onPause()159 public void onPause() { 160 if (mSearchView != null) { 161 mSearchView.setOnQueryTextListener(null); 162 } 163 super.onPause(); 164 } 165 166 @Override onStop()167 public void onStop() { 168 super.onStop(); 169 } 170 171 @Override onViewCreated(View view, Bundle savedInstanceState)172 public void onViewCreated(View view, Bundle savedInstanceState) { 173 super.onViewCreated(view, savedInstanceState); 174 initComponents(); 175 updateUiForArguments(); 176 getListView().setVisibility(View.GONE); 177 getBackupListView().setVisibility(View.VISIBLE); 178 } 179 180 @Override onDestroyView()181 public void onDestroyView() { 182 super.onDestroyView(); 183 mSwitchBar.removeOnSwitchChangeListener(this); 184 mSwitchBar.hide(); 185 } 186 onPreferenceToggled(String preferenceKey, boolean enabled)187 private void onPreferenceToggled(String preferenceKey, boolean enabled) { 188 ((PrintManager)getContext().getSystemService(Context.PRINT_SERVICE)) 189 .setPrintServiceEnabled(mComponentName, enabled); 190 } 191 getBackupListView()192 private ListView getBackupListView() { 193 return (ListView) getView().findViewById(R.id.backup_list); 194 } 195 updateEmptyView()196 private void updateEmptyView() { 197 ViewGroup contentRoot = (ViewGroup) getListView().getParent(); 198 View emptyView = getBackupListView().getEmptyView(); 199 if (!mToggleSwitch.isChecked()) { 200 if (emptyView != null && emptyView.getId() != R.id.empty_print_state) { 201 contentRoot.removeView(emptyView); 202 emptyView = null; 203 } 204 if (emptyView == null) { 205 emptyView = getActivity().getLayoutInflater().inflate( 206 R.layout.empty_print_state, contentRoot, false); 207 ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon); 208 iconView.setContentDescription(getString(R.string.print_service_disabled)); 209 TextView textView = (TextView) emptyView.findViewById(R.id.message); 210 textView.setText(R.string.print_service_disabled); 211 contentRoot.addView(emptyView); 212 getBackupListView().setEmptyView(emptyView); 213 } 214 } else if (mPrintersAdapter.getUnfilteredCount() <= 0) { 215 if (emptyView != null 216 && emptyView.getId() != R.id.empty_printers_list_service_enabled) { 217 contentRoot.removeView(emptyView); 218 emptyView = null; 219 } 220 if (emptyView == null) { 221 emptyView = getActivity().getLayoutInflater().inflate( 222 R.layout.empty_printers_list_service_enabled, contentRoot, false); 223 contentRoot.addView(emptyView); 224 getBackupListView().setEmptyView(emptyView); 225 } 226 } else if (mPrintersAdapter.getCount() <= 0) { 227 if (emptyView != null && emptyView.getId() != R.id.empty_print_state) { 228 contentRoot.removeView(emptyView); 229 emptyView = null; 230 } 231 if (emptyView == null) { 232 emptyView = getActivity().getLayoutInflater().inflate( 233 R.layout.empty_print_state, contentRoot, false); 234 ImageView iconView = (ImageView) emptyView.findViewById(R.id.icon); 235 iconView.setContentDescription(getString(R.string.print_no_printers_found)); 236 TextView textView = (TextView) emptyView.findViewById(R.id.message); 237 textView.setText(R.string.print_no_printers_found); 238 contentRoot.addView(emptyView); 239 getBackupListView().setEmptyView(emptyView); 240 } 241 } 242 } 243 updateUiForServiceState()244 private void updateUiForServiceState() { 245 if (mServiceEnabled) { 246 mSwitchBar.setCheckedInternal(true); 247 mPrintersAdapter.enable(); 248 } else { 249 mSwitchBar.setCheckedInternal(false); 250 mPrintersAdapter.disable(); 251 } 252 getActivity().invalidateOptionsMenu(); 253 } 254 initComponents()255 private void initComponents() { 256 mPrintersAdapter = new PrintersAdapter(); 257 mPrintersAdapter.registerDataSetObserver(mDataObserver); 258 259 final SettingsActivity activity = (SettingsActivity) getActivity(); 260 261 mSwitchBar = activity.getSwitchBar(); 262 mSwitchBar.addOnSwitchChangeListener(this); 263 mSwitchBar.show(); 264 265 mToggleSwitch = mSwitchBar.getSwitch(); 266 mToggleSwitch.setOnBeforeCheckedChangeListener(new ToggleSwitch.OnBeforeCheckedChangeListener() { 267 @Override 268 public boolean onBeforeCheckedChanged(ToggleSwitch toggleSwitch, boolean checked) { 269 onPreferenceToggled(mPreferenceKey, checked); 270 return false; 271 } 272 }); 273 274 getBackupListView().setSelector(new ColorDrawable(Color.TRANSPARENT)); 275 getBackupListView().setAdapter(mPrintersAdapter); 276 getBackupListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { 277 @Override 278 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 279 PrinterInfo printer = (PrinterInfo) mPrintersAdapter.getItem(position); 280 281 if (printer.getInfoIntent() != null) { 282 try { 283 getActivity().startIntentSender(printer.getInfoIntent().getIntentSender(), 284 null, 0, 0, 0); 285 } catch (SendIntentException e) { 286 Log.e(LOG_TAG, "Could not execute info intent: %s", e); 287 } 288 } 289 } 290 }); 291 } 292 293 294 @Override onSwitchChanged(Switch switchView, boolean isChecked)295 public void onSwitchChanged(Switch switchView, boolean isChecked) { 296 updateEmptyView(); 297 } 298 updateUiForArguments()299 private void updateUiForArguments() { 300 Bundle arguments = getArguments(); 301 302 // Component name. 303 mComponentName = ComponentName.unflattenFromString(arguments 304 .getString(PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME)); 305 306 // Key. 307 mPreferenceKey = mComponentName.flattenToString(); 308 309 // Enabled. 310 final boolean enabled = arguments.getBoolean(PrintSettingsFragment.EXTRA_CHECKED); 311 mSwitchBar.setCheckedInternal(enabled); 312 313 getLoaderManager().initLoader(LOADER_ID_PRINT_SERVICE_LOADER, null, this); 314 setHasOptionsMenu(true); 315 } 316 317 @Override onCreateLoader(int id, Bundle args)318 public Loader<List<PrintServiceInfo>> onCreateLoader(int id, Bundle args) { 319 return new PrintServicesLoader( 320 (PrintManager) getContext().getSystemService(Context.PRINT_SERVICE), getContext(), 321 PrintManager.ALL_SERVICES); 322 } 323 324 @Override onLoadFinished(Loader<List<PrintServiceInfo>> loader, List<PrintServiceInfo> services)325 public void onLoadFinished(Loader<List<PrintServiceInfo>> loader, 326 List<PrintServiceInfo> services) { 327 PrintServiceInfo service = null; 328 329 if (services != null) { 330 final int numServices = services.size(); 331 for (int i = 0; i < numServices; i++) { 332 if (services.get(i).getComponentName().equals(mComponentName)) { 333 service = services.get(i); 334 break; 335 } 336 } 337 } 338 339 if (service == null) { 340 // The print service was uninstalled 341 finishFragment(); 342 } 343 344 mServiceEnabled = service.isEnabled(); 345 346 if (service.getSettingsActivityName() != null) { 347 Intent settingsIntent = new Intent(Intent.ACTION_MAIN); 348 349 settingsIntent.setComponent( 350 new ComponentName(service.getComponentName().getPackageName(), 351 service.getSettingsActivityName())); 352 353 List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities( 354 settingsIntent, 0); 355 if (!resolvedActivities.isEmpty()) { 356 // The activity is a component name, therefore it is one or none. 357 if (resolvedActivities.get(0).activityInfo.exported) { 358 mSettingsIntent = settingsIntent; 359 } 360 } 361 } else { 362 mSettingsIntent = null; 363 } 364 365 if (service.getAddPrintersActivityName() != null) { 366 Intent addPrintersIntent = new Intent(Intent.ACTION_MAIN); 367 368 addPrintersIntent.setComponent( 369 new ComponentName(service.getComponentName().getPackageName(), 370 service.getAddPrintersActivityName())); 371 372 List<ResolveInfo> resolvedActivities = getPackageManager().queryIntentActivities( 373 addPrintersIntent, 0); 374 if (!resolvedActivities.isEmpty()) { 375 // The activity is a component name, therefore it is one or none. 376 if (resolvedActivities.get(0).activityInfo.exported) { 377 mAddPrintersIntent = addPrintersIntent; 378 } 379 } 380 } else { 381 mAddPrintersIntent = null; 382 } 383 384 updateUiForServiceState(); 385 } 386 387 @Override onLoaderReset(Loader<List<PrintServiceInfo>> loader)388 public void onLoaderReset(Loader<List<PrintServiceInfo>> loader) { 389 updateUiForServiceState(); 390 } 391 392 @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)393 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 394 super.onCreateOptionsMenu(menu, inflater); 395 inflater.inflate(R.menu.print_service_settings, menu); 396 397 MenuItem addPrinters = menu.findItem(R.id.print_menu_item_add_printer); 398 if (mServiceEnabled && mAddPrintersIntent != null) { 399 addPrinters.setIntent(mAddPrintersIntent); 400 } else { 401 menu.removeItem(R.id.print_menu_item_add_printer); 402 } 403 404 MenuItem settings = menu.findItem(R.id.print_menu_item_settings); 405 if (mServiceEnabled && mSettingsIntent != null) { 406 settings.setIntent(mSettingsIntent); 407 } else { 408 menu.removeItem(R.id.print_menu_item_settings); 409 } 410 411 MenuItem searchItem = menu.findItem(R.id.print_menu_item_search); 412 if (mServiceEnabled && mPrintersAdapter.getUnfilteredCount() > 0) { 413 mSearchView = (SearchView) searchItem.getActionView(); 414 mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 415 @Override 416 public boolean onQueryTextSubmit(String query) { 417 return true; 418 } 419 420 @Override 421 public boolean onQueryTextChange(String searchString) { 422 mPrintersAdapter.getFilter().filter(searchString); 423 return true; 424 } 425 }); 426 mSearchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { 427 @Override 428 public void onViewAttachedToWindow(View view) { 429 if (AccessibilityManager.getInstance(getActivity()).isEnabled()) { 430 view.announceForAccessibility(getString( 431 R.string.print_search_box_shown_utterance)); 432 } 433 } 434 @Override 435 public void onViewDetachedFromWindow(View view) { 436 Activity activity = getActivity(); 437 if (activity != null && !activity.isFinishing() 438 && AccessibilityManager.getInstance(activity).isEnabled()) { 439 view.announceForAccessibility(getString( 440 R.string.print_search_box_hidden_utterance)); 441 } 442 } 443 }); 444 } else { 445 menu.removeItem(R.id.print_menu_item_search); 446 } 447 } 448 449 private final class PrintersAdapter extends BaseAdapter 450 implements LoaderManager.LoaderCallbacks<List<PrinterInfo>>, Filterable { 451 private final Object mLock = new Object(); 452 453 private final List<PrinterInfo> mPrinters = new ArrayList<PrinterInfo>(); 454 455 private final List<PrinterInfo> mFilteredPrinters = new ArrayList<PrinterInfo>(); 456 457 private CharSequence mLastSearchString; 458 enable()459 public void enable() { 460 getLoaderManager().initLoader(LOADER_ID_PRINTERS_LOADER, null, this); 461 } 462 disable()463 public void disable() { 464 getLoaderManager().destroyLoader(LOADER_ID_PRINTERS_LOADER); 465 mPrinters.clear(); 466 } 467 getUnfilteredCount()468 public int getUnfilteredCount() { 469 return mPrinters.size(); 470 } 471 472 @Override getFilter()473 public Filter getFilter() { 474 return new Filter() { 475 @Override 476 protected FilterResults performFiltering(CharSequence constraint) { 477 synchronized (mLock) { 478 if (TextUtils.isEmpty(constraint)) { 479 return null; 480 } 481 FilterResults results = new FilterResults(); 482 List<PrinterInfo> filteredPrinters = new ArrayList<PrinterInfo>(); 483 String constraintLowerCase = constraint.toString().toLowerCase(); 484 final int printerCount = mPrinters.size(); 485 for (int i = 0; i < printerCount; i++) { 486 PrinterInfo printer = mPrinters.get(i); 487 String name = printer.getName(); 488 if (name != null && name.toLowerCase().contains(constraintLowerCase)) { 489 filteredPrinters.add(printer); 490 } 491 } 492 results.values = filteredPrinters; 493 results.count = filteredPrinters.size(); 494 return results; 495 } 496 } 497 498 @Override 499 @SuppressWarnings("unchecked") 500 protected void publishResults(CharSequence constraint, FilterResults results) { 501 synchronized (mLock) { 502 mLastSearchString = constraint; 503 mFilteredPrinters.clear(); 504 if (results == null) { 505 mFilteredPrinters.addAll(mPrinters); 506 } else { 507 List<PrinterInfo> printers = (List<PrinterInfo>) results.values; 508 mFilteredPrinters.addAll(printers); 509 } 510 } 511 notifyDataSetChanged(); 512 } 513 }; 514 } 515 516 @Override 517 public int getCount() { 518 synchronized (mLock) { 519 return mFilteredPrinters.size(); 520 } 521 } 522 523 @Override 524 public Object getItem(int position) { 525 synchronized (mLock) { 526 return mFilteredPrinters.get(position); 527 } 528 } 529 530 @Override 531 public long getItemId(int position) { 532 return position; 533 } 534 535 /** 536 * Checks if a printer can be used for printing 537 * 538 * @param position The position of the printer in the list 539 * @return true iff the printer can be used for printing. 540 */ 541 public boolean isActionable(int position) { 542 PrinterInfo printer = (PrinterInfo) getItem(position); 543 return printer.getStatus() != PrinterInfo.STATUS_UNAVAILABLE; 544 } 545 546 @Override 547 public View getView(int position, View convertView, ViewGroup parent) { 548 if (convertView == null) { 549 convertView = getActivity().getLayoutInflater().inflate( 550 R.layout.printer_dropdown_item, parent, false); 551 } 552 553 convertView.setEnabled(isActionable(position)); 554 555 final PrinterInfo printer = (PrinterInfo) getItem(position); 556 CharSequence title = printer.getName(); 557 CharSequence subtitle = printer.getDescription(); 558 Drawable icon = printer.loadIcon(getActivity()); 559 560 TextView titleView = (TextView) convertView.findViewById(R.id.title); 561 titleView.setText(title); 562 563 TextView subtitleView = (TextView) convertView.findViewById(R.id.subtitle); 564 if (!TextUtils.isEmpty(subtitle)) { 565 subtitleView.setText(subtitle); 566 subtitleView.setVisibility(View.VISIBLE); 567 } else { 568 subtitleView.setText(null); 569 subtitleView.setVisibility(View.GONE); 570 } 571 572 LinearLayout moreInfoView = (LinearLayout) convertView.findViewById(R.id.more_info); 573 if (printer.getInfoIntent() != null) { 574 moreInfoView.setVisibility(View.VISIBLE); 575 moreInfoView.setOnClickListener(new OnClickListener() { 576 @Override 577 public void onClick(View v) { 578 try { 579 getActivity().startIntentSender( 580 printer.getInfoIntent().getIntentSender(), null, 0, 0, 0); 581 } catch (SendIntentException e) { 582 Log.e(LOG_TAG, "Could not execute pending info intent: %s", e); 583 } 584 } 585 }); 586 } else { 587 moreInfoView.setVisibility(View.GONE); 588 } 589 590 ImageView iconView = (ImageView) convertView.findViewById(R.id.icon); 591 if (icon != null) { 592 iconView.setVisibility(View.VISIBLE); 593 if (!isActionable(position)) { 594 icon.mutate(); 595 596 TypedValue value = new TypedValue(); 597 getActivity().getTheme().resolveAttribute(android.R.attr.disabledAlpha, value, 598 true); 599 icon.setAlpha((int)(value.getFloat() * 255)); 600 } 601 iconView.setImageDrawable(icon); 602 } else { 603 iconView.setVisibility(View.GONE); 604 } 605 606 return convertView; 607 } 608 609 @Override 610 public Loader<List<PrinterInfo>> onCreateLoader(int id, Bundle args) { 611 if (id == LOADER_ID_PRINTERS_LOADER) { 612 return new PrintersLoader(getContext()); 613 } 614 return null; 615 } 616 617 @Override 618 public void onLoadFinished(Loader<List<PrinterInfo>> loader, 619 List<PrinterInfo> printers) { 620 synchronized (mLock) { 621 mPrinters.clear(); 622 final int printerCount = printers.size(); 623 for (int i = 0; i < printerCount; i++) { 624 PrinterInfo printer = printers.get(i); 625 if (printer.getId().getServiceName().equals(mComponentName)) { 626 mPrinters.add(printer); 627 } 628 } 629 mFilteredPrinters.clear(); 630 mFilteredPrinters.addAll(mPrinters); 631 if (!TextUtils.isEmpty(mLastSearchString)) { 632 getFilter().filter(mLastSearchString); 633 } 634 } 635 notifyDataSetChanged(); 636 } 637 638 @Override 639 public void onLoaderReset(Loader<List<PrinterInfo>> loader) { 640 synchronized (mLock) { 641 mPrinters.clear(); 642 mFilteredPrinters.clear(); 643 mLastSearchString = null; 644 } 645 notifyDataSetInvalidated(); 646 } 647 } 648 649 private static class PrintersLoader extends Loader<List<PrinterInfo>> { 650 651 private static final String LOG_TAG = "PrintersLoader"; 652 653 private static final boolean DEBUG = false; 654 655 private final Map<PrinterId, PrinterInfo> mPrinters = 656 new LinkedHashMap<PrinterId, PrinterInfo>(); 657 658 private PrinterDiscoverySession mDiscoverySession; 659 660 public PrintersLoader(Context context) { 661 super(context); 662 } 663 664 @Override 665 public void deliverResult(List<PrinterInfo> printers) { 666 if (isStarted()) { 667 super.deliverResult(printers); 668 } 669 } 670 671 @Override 672 protected void onStartLoading() { 673 if (DEBUG) { 674 Log.i(LOG_TAG, "onStartLoading()"); 675 } 676 // The contract is that if we already have a valid, 677 // result the we have to deliver it immediately. 678 if (!mPrinters.isEmpty()) { 679 deliverResult(new ArrayList<PrinterInfo>(mPrinters.values())); 680 } 681 // We want to start discovery at this point. 682 onForceLoad(); 683 } 684 685 @Override 686 protected void onStopLoading() { 687 if (DEBUG) { 688 Log.i(LOG_TAG, "onStopLoading()"); 689 } 690 onCancelLoad(); 691 } 692 693 @Override 694 protected void onForceLoad() { 695 if (DEBUG) { 696 Log.i(LOG_TAG, "onForceLoad()"); 697 } 698 loadInternal(); 699 } 700 701 @Override 702 protected boolean onCancelLoad() { 703 if (DEBUG) { 704 Log.i(LOG_TAG, "onCancelLoad()"); 705 } 706 return cancelInternal(); 707 } 708 709 @Override 710 protected void onReset() { 711 if (DEBUG) { 712 Log.i(LOG_TAG, "onReset()"); 713 } 714 onStopLoading(); 715 mPrinters.clear(); 716 if (mDiscoverySession != null) { 717 mDiscoverySession.destroy(); 718 mDiscoverySession = null; 719 } 720 } 721 722 @Override 723 protected void onAbandon() { 724 if (DEBUG) { 725 Log.i(LOG_TAG, "onAbandon()"); 726 } 727 onStopLoading(); 728 } 729 730 private boolean cancelInternal() { 731 if (mDiscoverySession != null 732 && mDiscoverySession.isPrinterDiscoveryStarted()) { 733 mDiscoverySession.stopPrinterDiscovery(); 734 return true; 735 } 736 return false; 737 } 738 739 private void loadInternal() { 740 if (mDiscoverySession == null) { 741 PrintManager printManager = (PrintManager) getContext() 742 .getSystemService(Context.PRINT_SERVICE); 743 mDiscoverySession = printManager.createPrinterDiscoverySession(); 744 mDiscoverySession.setOnPrintersChangeListener(new OnPrintersChangeListener() { 745 @Override 746 public void onPrintersChanged() { 747 deliverResult(new ArrayList<PrinterInfo>( 748 mDiscoverySession.getPrinters())); 749 } 750 }); 751 } 752 mDiscoverySession.startPrinterDiscovery(null); 753 } 754 } 755 } 756