docs: @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
      public ScanRecord parseFromBytes(byte[] scanRecord) {
          if (scanRecord == null) {
              return null;
          }
  
          int currentPos = 0;
          int advertiseFlag = -1;
          List<ParcelUuid> serviceUuids = new ArrayList<ParcelUuid>();
          String localName = null;
          int txPowerLevel = Integer.MIN_VALUE;
  
          SparseArray<byte[]> manufacturerData = new SparseArray<>();
          Map<ParcelUuid, byte[]> serviceData = new HashMap<>();
  
          try {
              while (currentPos < scanRecord.length) {
                  // length is unsigned int.
                  int length = scanRecord[currentPos++] & 0xFF;
                  if (length == 0) {
                      break;
                  }
                  // Note the length includes the length of the field type itself.
                  int dataLength = length - 1;
                  // fieldType is unsigned int.
                  int fieldType = scanRecord[currentPos++] & 0xFF;
                  switch (fieldType) {
                      case DATA_TYPE_FLAGS:
                          advertiseFlag = scanRecord[currentPos] & 0xFF;
                          break;
                      case DATA_TYPE_SERVICE_UUIDS_16_BIT_PARTIAL:
                      case DATA_TYPE_SERVICE_UUIDS_16_BIT_COMPLETE:
                          parseServiceUuid(scanRecord, currentPos,
                                  dataLength, UUID_BYTES_16_BIT, serviceUuids);
                          break;
                      case DATA_TYPE_SERVICE_UUIDS_32_BIT_PARTIAL:
                      case DATA_TYPE_SERVICE_UUIDS_32_BIT_COMPLETE:
                          parseServiceUuid(scanRecord, currentPos, dataLength,
                                  UUID_BYTES_32_BIT, serviceUuids);
                          break;
                      case DATA_TYPE_SERVICE_UUIDS_128_BIT_PARTIAL:
                      case DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE:
                          parseServiceUuid(scanRecord, currentPos, dataLength,
                                  UUID_BYTES_128_BIT, serviceUuids);
                          break;
                      case DATA_TYPE_LOCAL_NAME_SHORT:
                      case DATA_TYPE_LOCAL_NAME_COMPLETE:
                          localName = new String(
                                  extractBytes(scanRecord, currentPos, dataLength));
                          break;
                      case DATA_TYPE_TX_POWER_LEVEL:
                          txPowerLevel = scanRecord[currentPos];
                          break;
                      case DATA_TYPE_SERVICE_DATA:
                          // The first two bytes of the service data are service data UUID in little
                          // endian. The rest bytes are service data.
                          int serviceUuidLength = UUID_BYTES_16_BIT;
                          byte[] serviceDataUuidBytes = extractBytes(scanRecord, currentPos,
                                  serviceUuidLength);
                          ParcelUuid serviceDataUuid = parseUuidFrom(serviceDataUuidBytes);
                          byte[] serviceDataArray = extractBytes(scanRecord,
                                  currentPos + serviceUuidLength, dataLength - serviceUuidLength);
                          serviceData.put(serviceDataUuid, serviceDataArray);
                          break;
                      case DATA_TYPE_MANUFACTURER_SPECIFIC_DATA:
                          // The first two bytes of the manufacturer specific data are
                          // manufacturer ids in little endian.
                          int manufacturerId = ((scanRecord[currentPos + 1] & 0xFF) << 8)
                                  + (scanRecord[currentPos] & 0xFF);
                          byte[] manufacturerDataBytes = extractBytes(scanRecord, currentPos + 2,
                                  dataLength - 2);
                          manufacturerData.put(manufacturerId, manufacturerDataBytes);
                          break;
                      default:
                          // Just ignore, we don't handle such data type.
                          break;
                  }
                  currentPos += dataLength;
              }
  
              if (serviceUuids.isEmpty()) {
                  serviceUuids = null;
              }
              return new ScanRecordImplCompat(serviceUuids, manufacturerData, serviceData,
                      advertiseFlag, txPowerLevel, localName, scanRecord);
          } catch (Exception e) {
              RxBleLog.e(e, "Unable to parse scan record: %s", LoggerUtil.bytesToHex(scanRecord));
              // As the record is invalid, ignore all the parsed results for this packet
              // and return an empty record with raw scanRecord bytes in results
              return new ScanRecordImplCompat(null, null, null, -1, Integer.MIN_VALUE, null, scanRecord);
          }
      }