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