public List<PrintJobInfo> getPrintJobInfos(ComponentName componentName, int state, int appId) {
   List<PrintJobInfo> foundPrintJobs = null;
   synchronized (mLock) {
     final int printJobCount = mPrintJobs.size();
     for (int i = 0; i < printJobCount; i++) {
       PrintJobInfo printJob = mPrintJobs.get(i);
       PrinterId printerId = printJob.getPrinterId();
       final boolean sameComponent =
           (componentName == null
               || (printerId != null && componentName.equals(printerId.getServiceName())));
       final boolean sameAppId = appId == PrintManager.APP_ID_ANY || printJob.getAppId() == appId;
       final boolean sameState =
           (state == printJob.getState())
               || (state == PrintJobInfo.STATE_ANY)
               || (state == PrintJobInfo.STATE_ANY_VISIBLE_TO_CLIENTS
                   && isStateVisibleToUser(printJob.getState()))
               || (state == PrintJobInfo.STATE_ANY_ACTIVE && isActiveState(printJob.getState()))
               || (state == PrintJobInfo.STATE_ANY_SCHEDULED
                   && isScheduledState(printJob.getState()));
       if (sameComponent && sameAppId && sameState) {
         if (foundPrintJobs == null) {
           foundPrintJobs = new ArrayList<>();
         }
         foundPrintJobs.add(printJob);
       }
     }
   }
   return foundPrintJobs;
 }
 public boolean hasActivePrintJobsForServiceLocked(ComponentName service) {
   final int printJobCount = mPrintJobs.size();
   for (int i = 0; i < printJobCount; i++) {
     PrintJobInfo printJob = mPrintJobs.get(i);
     if (isActiveState(printJob.getState())
         && printJob.getPrinterId() != null
         && printJob.getPrinterId().getServiceName().equals(service)) {
       return true;
     }
   }
   return false;
 }
 public void updatePrintJobUserConfigurableOptionsNoPersistence(PrintJobInfo printJob) {
   synchronized (mLock) {
     final int printJobCount = mPrintJobs.size();
     for (int i = 0; i < printJobCount; i++) {
       PrintJobInfo cachedPrintJob = mPrintJobs.get(i);
       if (cachedPrintJob.getId().equals(printJob.getId())) {
         cachedPrintJob.setPrinterId(printJob.getPrinterId());
         cachedPrintJob.setPrinterName(printJob.getPrinterName());
         cachedPrintJob.setCopies(printJob.getCopies());
         cachedPrintJob.setDocumentInfo(printJob.getDocumentInfo());
         cachedPrintJob.setPages(printJob.getPages());
         cachedPrintJob.setAttributes(printJob.getAttributes());
         cachedPrintJob.setAdvancedOptions(printJob.getAdvancedOptions());
         return;
       }
     }
     throw new IllegalArgumentException("No print job with id:" + printJob.getId());
   }
 }
    private void doWriteStateLocked() {
      if (DEBUG_PERSISTENCE) {
        Log.i(LOG_TAG, "[PERSIST START]");
      }
      FileOutputStream out = null;
      try {
        out = mStatePersistFile.startWrite();

        XmlSerializer serializer = new FastXmlSerializer();
        serializer.setOutput(out, "utf-8");
        serializer.startDocument(null, true);
        serializer.startTag(null, TAG_SPOOLER);

        List<PrintJobInfo> printJobs = mPrintJobs;

        final int printJobCount = printJobs.size();
        for (int j = 0; j < printJobCount; j++) {
          PrintJobInfo printJob = printJobs.get(j);

          if (!shouldPersistPrintJob(printJob)) {
            continue;
          }

          serializer.startTag(null, TAG_JOB);

          serializer.attribute(null, ATTR_ID, printJob.getId().flattenToString());
          serializer.attribute(null, ATTR_LABEL, printJob.getLabel().toString());
          serializer.attribute(null, ATTR_STATE, String.valueOf(printJob.getState()));
          serializer.attribute(null, ATTR_APP_ID, String.valueOf(printJob.getAppId()));
          String tag = printJob.getTag();
          if (tag != null) {
            serializer.attribute(null, ATTR_TAG, tag);
          }
          serializer.attribute(
              null, ATTR_CREATION_TIME, String.valueOf(printJob.getCreationTime()));
          serializer.attribute(null, ATTR_COPIES, String.valueOf(printJob.getCopies()));
          String printerName = printJob.getPrinterName();
          if (!TextUtils.isEmpty(printerName)) {
            serializer.attribute(null, ATTR_PRINTER_NAME, printerName);
          }
          String stateReason = printJob.getStateReason();
          if (!TextUtils.isEmpty(stateReason)) {
            serializer.attribute(null, ATTR_STATE_REASON, stateReason);
          }
          serializer.attribute(null, ATTR_CANCELLING, String.valueOf(printJob.isCancelling()));

          PrinterId printerId = printJob.getPrinterId();
          if (printerId != null) {
            serializer.startTag(null, TAG_PRINTER_ID);
            serializer.attribute(null, ATTR_LOCAL_ID, printerId.getLocalId());
            serializer.attribute(
                null, ATTR_SERVICE_NAME, printerId.getServiceName().flattenToString());
            serializer.endTag(null, TAG_PRINTER_ID);
          }

          PageRange[] pages = printJob.getPages();
          if (pages != null) {
            for (int i = 0; i < pages.length; i++) {
              serializer.startTag(null, TAG_PAGE_RANGE);
              serializer.attribute(null, ATTR_START, String.valueOf(pages[i].getStart()));
              serializer.attribute(null, ATTR_END, String.valueOf(pages[i].getEnd()));
              serializer.endTag(null, TAG_PAGE_RANGE);
            }
          }

          PrintAttributes attributes = printJob.getAttributes();
          if (attributes != null) {
            serializer.startTag(null, TAG_ATTRIBUTES);

            final int colorMode = attributes.getColorMode();
            serializer.attribute(null, ATTR_COLOR_MODE, String.valueOf(colorMode));

            MediaSize mediaSize = attributes.getMediaSize();
            if (mediaSize != null) {
              serializer.startTag(null, TAG_MEDIA_SIZE);
              serializer.attribute(null, ATTR_ID, mediaSize.getId());
              serializer.attribute(null, ATTR_WIDTH_MILS, String.valueOf(mediaSize.getWidthMils()));
              serializer.attribute(
                  null, ATTR_HEIGHT_MILS, String.valueOf(mediaSize.getHeightMils()));
              // We prefer to store only the package name and
              // resource id and fallback to the label.
              if (!TextUtils.isEmpty(mediaSize.mPackageName) && mediaSize.mLabelResId > 0) {
                serializer.attribute(null, ATTR_PACKAGE_NAME, mediaSize.mPackageName);
                serializer.attribute(
                    null, ATTR_LABEL_RES_ID, String.valueOf(mediaSize.mLabelResId));
              } else {
                serializer.attribute(null, ATTR_LABEL, mediaSize.getLabel(getPackageManager()));
              }
              serializer.endTag(null, TAG_MEDIA_SIZE);
            }

            Resolution resolution = attributes.getResolution();
            if (resolution != null) {
              serializer.startTag(null, TAG_RESOLUTION);
              serializer.attribute(null, ATTR_ID, resolution.getId());
              serializer.attribute(
                  null, ATTR_HORIZONTAL_DPI, String.valueOf(resolution.getHorizontalDpi()));
              serializer.attribute(
                  null, ATTR_VERTICAL_DPI, String.valueOf(resolution.getVerticalDpi()));
              serializer.attribute(null, ATTR_LABEL, resolution.getLabel());
              serializer.endTag(null, TAG_RESOLUTION);
            }

            Margins margins = attributes.getMinMargins();
            if (margins != null) {
              serializer.startTag(null, TAG_MARGINS);
              serializer.attribute(null, ATTR_LEFT_MILS, String.valueOf(margins.getLeftMils()));
              serializer.attribute(null, ATTR_TOP_MILS, String.valueOf(margins.getTopMils()));
              serializer.attribute(null, ATTR_RIGHT_MILS, String.valueOf(margins.getRightMils()));
              serializer.attribute(null, ATTR_BOTTOM_MILS, String.valueOf(margins.getBottomMils()));
              serializer.endTag(null, TAG_MARGINS);
            }

            serializer.endTag(null, TAG_ATTRIBUTES);
          }

          PrintDocumentInfo documentInfo = printJob.getDocumentInfo();
          if (documentInfo != null) {
            serializer.startTag(null, TAG_DOCUMENT_INFO);
            serializer.attribute(null, ATTR_NAME, documentInfo.getName());
            serializer.attribute(
                null, ATTR_CONTENT_TYPE, String.valueOf(documentInfo.getContentType()));
            serializer.attribute(
                null, ATTR_PAGE_COUNT, String.valueOf(documentInfo.getPageCount()));
            serializer.attribute(null, ATTR_DATA_SIZE, String.valueOf(documentInfo.getDataSize()));
            serializer.endTag(null, TAG_DOCUMENT_INFO);
          }

          Bundle advancedOptions = printJob.getAdvancedOptions();
          if (advancedOptions != null) {
            serializer.startTag(null, TAG_ADVANCED_OPTIONS);
            for (String key : advancedOptions.keySet()) {
              Object value = advancedOptions.get(key);
              if (value instanceof String) {
                String stringValue = (String) value;
                serializer.startTag(null, TAG_ADVANCED_OPTION);
                serializer.attribute(null, ATTR_KEY, key);
                serializer.attribute(null, ATTR_TYPE, TYPE_STRING);
                serializer.attribute(null, ATTR_VALUE, stringValue);
                serializer.endTag(null, TAG_ADVANCED_OPTION);
              } else if (value instanceof Integer) {
                String intValue = Integer.toString((Integer) value);
                serializer.startTag(null, TAG_ADVANCED_OPTION);
                serializer.attribute(null, ATTR_KEY, key);
                serializer.attribute(null, ATTR_TYPE, TYPE_INT);
                serializer.attribute(null, ATTR_VALUE, intValue);
                serializer.endTag(null, TAG_ADVANCED_OPTION);
              }
            }
            serializer.endTag(null, TAG_ADVANCED_OPTIONS);
          }

          serializer.endTag(null, TAG_JOB);

          if (DEBUG_PERSISTENCE) {
            Log.i(LOG_TAG, "[PERSISTED] " + printJob);
          }
        }

        serializer.endTag(null, TAG_SPOOLER);
        serializer.endDocument();
        mStatePersistFile.finishWrite(out);
        if (DEBUG_PERSISTENCE) {
          Log.i(LOG_TAG, "[PERSIST END]");
        }
      } catch (IOException e) {
        Slog.w(LOG_TAG, "Failed to write state, restoring backup.", e);
        mStatePersistFile.failWrite(out);
      } finally {
        IoUtils.closeQuietly(out);
      }
    }
  public boolean setPrintJobState(PrintJobId printJobId, int state, String error) {
    boolean success = false;

    synchronized (mLock) {
      PrintJobInfo printJob = getPrintJobInfo(printJobId, PrintManager.APP_ID_ANY);
      if (printJob != null) {
        final int oldState = printJob.getState();
        if (oldState == state) {
          return false;
        }

        success = true;

        printJob.setState(state);
        printJob.setStateReason(error);
        printJob.setCancelling(false);

        if (DEBUG_PRINT_JOB_LIFECYCLE) {
          Slog.i(LOG_TAG, "[STATE CHANGED] " + printJob);
        }

        switch (state) {
          case PrintJobInfo.STATE_COMPLETED:
          case PrintJobInfo.STATE_CANCELED:
            mPrintJobs.remove(printJob);
            removePrintJobFileLocked(printJob.getId());
            // $fall-through$

          case PrintJobInfo.STATE_FAILED:
            {
              PrinterId printerId = printJob.getPrinterId();
              if (printerId != null) {
                ComponentName service = printerId.getServiceName();
                if (!hasActivePrintJobsForServiceLocked(service)) {
                  sendOnAllPrintJobsForServiceHandled(service);
                }
              }
            }
            break;

          case PrintJobInfo.STATE_QUEUED:
            {
              sendOnPrintJobQueued(new PrintJobInfo(printJob));
            }
            break;
        }

        if (shouldPersistPrintJob(printJob)) {
          mPersistanceManager.writeStateLocked();
        }

        if (!hasActivePrintJobsLocked()) {
          notifyOnAllPrintJobsHandled();
        }

        Message message =
            mHandlerCaller.obtainMessageO(
                HandlerCallerCallback.MSG_ON_PRINT_JOB_STATE_CHANGED, printJob);
        mHandlerCaller.executeOrSendMessage(message);

        mNotificationController.onUpdateNotifications(mPrintJobs);
      }
    }

    return success;
  }