lib/helpers.js
function (dumpsysOutput, groupNames, grantedState = null) {
  const groupPatternByName = (groupName) => new RegExp(`^(\\s*${_.escapeRegExp(groupName)} permissions:[\\s\\S]+)`, 'm');
  const indentPattern = /\S|$/;
  const permissionNamePattern = /android\.permission\.\w+/;
  const grantedStatePattern = /\bgranted=(\w+)/;
  const result = [];
  for (const groupName of groupNames) {
    const groupMatch = groupPatternByName(groupName).exec(dumpsysOutput);
    if (!groupMatch) {
      continue;
    }

    const lines = groupMatch[1].split('\n');
    if (lines.length < 2) {
      continue;
    }

    const titleIndent = lines[0].search(indentPattern);
    for (const line of lines.slice(1)) {
      const currentIndent = line.search(indentPattern);
      if (currentIndent <= titleIndent) {
        break;
      }

      const permissionNameMatch = permissionNamePattern.exec(line);
      if (!permissionNameMatch) {
        continue;
      }
      const item = {
        permission: permissionNameMatch[0],
      };
      const grantedStateMatch = grantedStatePattern.exec(line);
      if (grantedStateMatch) {
        item.granted = grantedStateMatch[1] === 'true';
      }
      result.push(item);
    }
  }

  const filteredResult = result
    .filter((item) => !_.isBoolean(grantedState) || item.granted === grantedState)
    .map((item) => item.permission);
  log.debug(`Retrieved ${filteredResult.length} permission(s) from ${JSON.stringify(groupNames)} group(s)`);
  return filteredResult;
}
function (dumpsysOutput, groupNames, grantedState = null) {
  const groupPatternByName = (groupName) => new RegExp(`^(\\s*${_.escapeRegExp(groupName)} permissions:[\\s\\S]+)`, 'm');
  const indentPattern = /\S|$/;
  const permissionNamePattern = /android\.permission\.\w+/;
  const grantedStatePattern = /\bgranted=(\w+)/;
  const result = [];
  for (const groupName of groupNames) {
    const groupMatch = groupPatternByName(groupName).exec(dumpsysOutput);
    if (!groupMatch) {
      continue;
    }

    const lines = groupMatch[1].split('\n');
    if (lines.length < 2) {
      continue;
    }

    const titleIndent = lines[0].search(indentPattern);
    for (const line of lines.slice(1)) {
      const currentIndent = line.search(indentPattern);
      if (currentIndent <= titleIndent) {
        break;
      }

      const permissionNameMatch = permissionNamePattern.exec(line);
      if (!permissionNameMatch) {
        continue;
      }
      const item = {
        permission: permissionNameMatch[0],
      };
      const grantedStateMatch = grantedStatePattern.exec(line);
      if (grantedStateMatch) {
        item.granted = grantedStateMatch[1] === 'true';
      }
      result.push(item);
    }
  }

  const filteredResult = result
    .filter((item) => !_.isBoolean(grantedState) || item.granted === grantedState)
    .map((item) => item.permission);
  log.debug(`Retrieved ${filteredResult.length} permission(s) from ${JSON.stringify(groupNames)} group(s)`);
  return filteredResult;
}
function ( dumpsysOutput , groupNames , grantedState = null ) { const groupPatternByName = ( groupName ) => new RegExp ( ` \\ ${ _ . escapeRegExp ( groupName ) } \\ \\ ` , 'm' ) ; const indentPattern = / \S|$ / ; const permissionNamePattern = / android\.permission\.\w+ / ; const grantedStatePattern = / \bgranted=(\w+) / ; const result = [ ] ; for ( const groupName of groupNames ) { const groupMatch = groupPatternByName ( groupName ) . exec ( dumpsysOutput ) ; if ( ! groupMatch ) { continue ; } const lines = groupMatch [ 1 ] . split ( '\n' ) ; if ( lines . length < 2 ) { continue ; } const titleIndent = lines [ 0 ] . search ( indentPattern ) ; for ( const line of lines . slice ( 1 ) ) { const currentIndent = line . search ( indentPattern ) ; if ( currentIndent <= titleIndent ) { break ; } const permissionNameMatch = permissionNamePattern . exec ( line ) ; if ( ! permissionNameMatch ) { continue ; } const item = { permission : permissionNameMatch [ 0 ] , } ; const grantedStateMatch = grantedStatePattern . exec ( line ) ; if ( grantedStateMatch ) { item . granted = grantedStateMatch [ 1 ] === 'true' ; } result . push ( item ) ; } } const filteredResult = result . filter ( ( item ) => ! _ . isBoolean ( grantedState ) || item . granted === grantedState ) . map ( ( item ) => item . permission ) ; log . debug ( ` ${ filteredResult . length } ${ JSON . stringify ( groupNames ) } ` ) ; return filteredResult ; }
Retrieves the list of permission names encoded in `dumpsys package` command output.

@param {string} dumpsysOutput - The actual command output.
@param {Array<string>} groupNames - The list of group names to list permissions for.
@param {?boolean} grantedState - The expected state of `granted` attribute to filter with.
No filtering is done if the parameter is not set.
@returns {Array<string>} The list of matched permission names or an empty list if no matches were found.
Retrieves the list of permission names encoded in dumpsys package command output .