private String getDocIdForFile(File file) throws FileNotFoundException {
    String path = file.getAbsolutePath();

    // Find the most-specific root path
    String mostSpecificId = null;
    String mostSpecificPath = null;
    synchronized (mRootsLock) {
      for (int i = 0; i < mRoots.size(); i++) {
        final String rootId = mRoots.keyAt(i);
        final String rootPath = mRoots.valueAt(i).path.getAbsolutePath();
        if (path.startsWith(rootPath)
            && (mostSpecificPath == null || rootPath.length() > mostSpecificPath.length())) {
          mostSpecificId = rootId;
          mostSpecificPath = rootPath;
        }
      }
    }

    if (mostSpecificPath == null) {
      throw new FileNotFoundException("Failed to find root that contains " + path);
    }

    // Start at first char of path under root
    final String rootPath = mostSpecificPath;
    if (rootPath.equals(path)) {
      path = "";
    } else if (rootPath.endsWith("/")) {
      path = path.substring(rootPath.length());
    } else {
      path = path.substring(rootPath.length() + 1);
    }

    return mostSpecificId + ':' + path;
  }
 public UsbPort[] getPorts() {
   synchronized (mLock) {
     final int count = mPorts.size();
     final UsbPort[] result = new UsbPort[count];
     for (int i = 0; i < count; i++) {
       result[i] = mPorts.valueAt(i).mUsbPort;
     }
     return result;
   }
 }
 public boolean getAppsWithPermissionsCount(Context context, int[] counts) {
   ArraySet<String> launcherPkgs = Utils.getLauncherPackages(context);
   // Indexed by uid.
   ArrayMap<String, Boolean> grantedApps = new ArrayMap<>();
   ArrayMap<String, Boolean> allApps = new ArrayMap<>();
   for (String group : Utils.MODERN_PERMISSION_GROUPS) {
     PermissionApps permissionApps = new PermissionApps(context, group, null);
     permissionApps.loadNowWithoutUi();
     for (PermissionApp app : permissionApps.getApps()) {
       String key = app.getKey();
       if (Utils.isSystem(app, launcherPkgs)) {
         // We default to not showing system apps, so hide them from count.
         continue;
       }
       if (app.areRuntimePermissionsGranted()) {
         grantedApps.put(key, true);
       }
       allApps.put(key, true);
     }
   }
   counts[0] = grantedApps.size();
   counts[1] = allApps.size();
   return true;
 }
 @Override
 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
   final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ", 160);
   synchronized (mRootsLock) {
     for (int i = 0; i < mRoots.size(); i++) {
       final RootInfo root = mRoots.valueAt(i);
       pw.println("Root{" + root.rootId + "}:");
       pw.increaseIndent();
       pw.printPair("flags", DebugUtils.flagsToString(Root.class, "FLAG_", root.flags));
       pw.println();
       pw.printPair("title", root.title);
       pw.printPair("docId", root.docId);
       pw.println();
       pw.printPair("path", root.path);
       pw.printPair("visiblePath", root.visiblePath);
       pw.decreaseIndent();
       pw.println();
     }
   }
 }
  private void updatePortsLocked(IndentingPrintWriter pw) {
    // Assume all ports are gone unless informed otherwise.
    // Kind of pessimistic but simple.
    for (int i = mPorts.size(); i-- > 0; ) {
      mPorts.valueAt(i).mDisposition = PortInfo.DISPOSITION_REMOVED;
    }

    // Enumerate all extant ports.
    if (!mSimulatedPorts.isEmpty()) {
      final int count = mSimulatedPorts.size();
      for (int i = 0; i < count; i++) {
        final SimulatedPortInfo portInfo = mSimulatedPorts.valueAt(i);
        addOrUpdatePortLocked(
            portInfo.mPortId,
            portInfo.mSupportedModes,
            portInfo.mCurrentMode,
            portInfo.mCanChangeMode,
            portInfo.mCurrentPowerRole,
            portInfo.mCanChangePowerRole,
            portInfo.mCurrentDataRole,
            portInfo.mCanChangeDataRole,
            pw);
      }
    } else if (mHaveKernelSupport) {
      final File[] portDirs = new File(SYSFS_CLASS).listFiles();
      if (portDirs != null) {
        for (File portDir : portDirs) {
          if (!portDir.isDirectory()) {
            continue;
          }

          // Parse the sysfs file contents.
          final String portId = portDir.getName();
          final int supportedModes = readSupportedModes(portDir);
          final int currentMode = readCurrentMode(portDir);
          final boolean canChangeMode = canChangeMode(portDir);
          final int currentPowerRole = readCurrentPowerRole(portDir);
          final boolean canChangePowerRole = canChangePowerRole(portDir);
          final int currentDataRole = readCurrentDataRole(portDir);
          final boolean canChangeDataRole = canChangeDataRole(portDir);
          addOrUpdatePortLocked(
              portId,
              supportedModes,
              currentMode,
              canChangeMode,
              currentPowerRole,
              canChangePowerRole,
              currentDataRole,
              canChangeDataRole,
              pw);
        }
      }
    }

    // Process the updates.
    // Once finished, the list of ports will only contain ports in DISPOSITION_READY.
    for (int i = mPorts.size(); i-- > 0; ) {
      final PortInfo portInfo = mPorts.valueAt(i);
      switch (portInfo.mDisposition) {
        case PortInfo.DISPOSITION_ADDED:
          handlePortAddedLocked(portInfo, pw);
          portInfo.mDisposition = PortInfo.DISPOSITION_READY;
          break;
        case PortInfo.DISPOSITION_CHANGED:
          handlePortChangedLocked(portInfo, pw);
          portInfo.mDisposition = PortInfo.DISPOSITION_READY;
          break;
        case PortInfo.DISPOSITION_REMOVED:
          mPorts.removeAt(i);
          portInfo.mUsbPortStatus = null; // must do this early
          handlePortRemovedLocked(portInfo, pw);
          break;
      }
    }
  }
 boolean dumpMap(
     PrintWriter out,
     String titlePrefix,
     String title,
     String prefix,
     ArrayMap<String, F[]> map,
     String packageName,
     boolean printFilter,
     boolean collapseDuplicates) {
   final String eprefix = prefix + "  ";
   final String fprefix = prefix + "    ";
   final ArrayMap<Object, MutableInt> found = new ArrayMap<>();
   boolean printedSomething = false;
   Printer printer = null;
   for (int mapi = 0; mapi < map.size(); mapi++) {
     F[] a = map.valueAt(mapi);
     final int N = a.length;
     boolean printedHeader = false;
     F filter;
     if (collapseDuplicates && !printFilter) {
       found.clear();
       for (int i = 0; i < N && (filter = a[i]) != null; i++) {
         if (packageName != null && !isPackageForFilter(packageName, filter)) {
           continue;
         }
         Object label = filterToLabel(filter);
         int index = found.indexOfKey(label);
         if (index < 0) {
           found.put(label, new MutableInt(1));
         } else {
           found.valueAt(index).value++;
         }
       }
       for (int i = 0; i < found.size(); i++) {
         if (title != null) {
           out.print(titlePrefix);
           out.println(title);
           title = null;
         }
         if (!printedHeader) {
           out.print(eprefix);
           out.print(map.keyAt(mapi));
           out.println(":");
           printedHeader = true;
         }
         printedSomething = true;
         dumpFilterLabel(out, fprefix, found.keyAt(i), found.valueAt(i).value);
       }
     } else {
       for (int i = 0; i < N && (filter = a[i]) != null; i++) {
         if (packageName != null && !isPackageForFilter(packageName, filter)) {
           continue;
         }
         if (title != null) {
           out.print(titlePrefix);
           out.println(title);
           title = null;
         }
         if (!printedHeader) {
           out.print(eprefix);
           out.print(map.keyAt(mapi));
           out.println(":");
           printedHeader = true;
         }
         printedSomething = true;
         dumpFilter(out, fprefix, filter);
         if (printFilter) {
           if (printer == null) {
             printer = new PrintWriterPrinter(out);
           }
           filter.dump(printer, fprefix + "  ");
         }
       }
     }
   }
   return printedSomething;
 }
Пример #7
0
  private void handleReadPrintJobsLocked() {
    // Make a map with the files for a print job since we may have
    // to delete some. One example of getting orphan files if the
    // spooler crashes while constructing a print job. We do not
    // persist partially populated print jobs under construction to
    // avoid special handling for various attributes missing.
    ArrayMap<PrintJobId, File> fileForJobMap = null;
    File[] files = getFilesDir().listFiles();
    if (files != null) {
      final int fileCount = files.length;
      for (int i = 0; i < fileCount; i++) {
        File file = files[i];
        if (file.isFile() && file.getName().startsWith(PRINT_JOB_FILE_PREFIX)) {
          if (fileForJobMap == null) {
            fileForJobMap = new ArrayMap<PrintJobId, File>();
          }
          String printJobIdString =
              file.getName().substring(PRINT_JOB_FILE_PREFIX.length(), file.getName().indexOf('.'));
          PrintJobId printJobId = PrintJobId.unflattenFromString(printJobIdString);
          fileForJobMap.put(printJobId, file);
        }
      }
    }

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

      // We want to have only the orphan files at the end.
      if (fileForJobMap != null) {
        fileForJobMap.remove(printJob.getId());
      }

      switch (printJob.getState()) {
        case PrintJobInfo.STATE_QUEUED:
        case PrintJobInfo.STATE_STARTED:
        case PrintJobInfo.STATE_BLOCKED:
          {
            // We have a print job that was queued or started or blocked in
            // the past but the device battery died or a crash occurred. In
            // this case we assume the print job failed and let the user
            // decide whether to restart the job or just cancel it.
            setPrintJobState(
                printJob.getId(),
                PrintJobInfo.STATE_FAILED,
                getString(R.string.no_connection_to_printer));
          }
          break;
      }
    }

    if (!mPrintJobs.isEmpty()) {
      // Update the notification.
      mNotificationController.onUpdateNotifications(mPrintJobs);
    }

    // Delete the orphan files.
    if (fileForJobMap != null) {
      final int orphanFileCount = fileForJobMap.size();
      for (int i = 0; i < orphanFileCount; i++) {
        File file = fileForJobMap.valueAt(i);
        file.delete();
      }
    }
  }
  private void updateVolumesLocked() {
    mRoots.clear();

    final int userId = UserHandle.myUserId();
    final List<VolumeInfo> volumes = mStorageManager.getVolumes();
    for (VolumeInfo volume : volumes) {
      if (!volume.isMountedReadable()) continue;

      final String rootId;
      final String title;
      if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
        // We currently only support a single emulated volume mounted at
        // a time, and it's always considered the primary
        rootId = ROOT_ID_PRIMARY_EMULATED;
        if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
          title = getContext().getString(R.string.root_internal_storage);
        } else {
          final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
          title = mStorageManager.getBestVolumeDescription(privateVol);
        }
      } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
        rootId = volume.getFsUuid();
        title = mStorageManager.getBestVolumeDescription(volume);
      } else {
        // Unsupported volume; ignore
        continue;
      }

      if (TextUtils.isEmpty(rootId)) {
        Log.d(TAG, "Missing UUID for " + volume.getId() + "; skipping");
        continue;
      }
      if (mRoots.containsKey(rootId)) {
        Log.w(TAG, "Duplicate UUID " + rootId + " for " + volume.getId() + "; skipping");
        continue;
      }

      try {
        final RootInfo root = new RootInfo();
        mRoots.put(rootId, root);

        root.rootId = rootId;
        root.flags =
            Root.FLAG_SUPPORTS_CREATE
                | Root.FLAG_LOCAL_ONLY
                | Root.FLAG_ADVANCED
                | Root.FLAG_SUPPORTS_SEARCH
                | Root.FLAG_SUPPORTS_IS_CHILD;
        root.title = title;
        if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
          root.flags |= Root.FLAG_HAS_SETTINGS;
        }
        if (volume.isVisibleForRead(userId)) {
          root.visiblePath = volume.getPathForUser(userId);
        } else {
          root.visiblePath = null;
        }
        root.path = volume.getInternalPathForUser(userId);
        root.docId = getDocIdForFile(root.path);

      } catch (FileNotFoundException e) {
        throw new IllegalStateException(e);
      }
    }

    Log.d(TAG, "After updating volumes, found " + mRoots.size() + " active roots");

    // Note this affects content://com.android.externalstorage.documents/root/39BD-07C5
    // as well as content://com.android.externalstorage.documents/document/*/children,
    // so just notify on content://com.android.externalstorage.documents/.
    getContext().getContentResolver().notifyChange(BASE_URI, null, false);
  }