com.webos.service.pdm

API Summary

The Physical Device Manager (PDM) is a module that manages USB devices that are connected to the webOS system.

Main Functions:

  • Mount/unmount of Mass Storage Class (MSC) USB devices
  • Format, Fdisk, File system check (FSCK)
  • Detect USB device

Supported USB Devices

  • MSC USB device
    • Supported file system: Windows compatible file system (FAT, NTFS)
    • Supported device type: HDD, Memory Stick, SSD, Memory card
  • Still image device (Picture Transfer Protocol (PTP) Camera)
  • Camera
  • HID & XPAD
  • USB to Serial

Important Terms

  • Device - A device that is directly connected to a USB port or hub.
  • Drive - A device can have multiple drives, where each drive is a partition of a physical storage device.

Overview of the API

(click to expand)

NA


Open All


eject

Description

Unmounts all drives of the storage device for safe removal.

Prerequisite: The storage device must be connected.

Parameters

Name

Required

Type

Description

deviceNum RequiredNumber

Unique identifier of the device. It is auto-assigned when the device is connected.

Use the getAttachedDeviceStatus method to get a list of devices and their device numbers.

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/eject '{"deviceNum" : 2 }'

 

Response:

{
    "returnValue": true
}


format

Description

Formats the connected drive.

Parameters

Name

Required

Type

Description

driveName Requiredstring

Information that can identify the drive (e.g. sda1)

fsType Optionalstring

File system type (e.g. fat, ntfs)

Default value: fat

volumeLabelOptionalstring

Volume label for the drive.

Default value: volume label not set

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

Example

Example 1 : Formatting specific file system type and volume label:

# luna-send -n 1 -f luna://com.webos.service.pdm/format '{ "driveName" : "sda", "fsType" : "fat", "volumeLabel" : "test" }'

 

Response:

{
    "returnValue": true
}

 

Example 2 : Formatting using the default values of file system type and volume label:

# luna-send -n 1 -f luna://com.webos.service.pdm/format '{ "driveName" : "sda1"}'

 

Response:

{
    "returnValue": true
}


fsck

Description

Checks the file system by performing fsck (File System Check) of the corresponding connected drive.

Note: On connecting a USB device with a large number of files, the PDM service prompts for “Check & Repair” and “Open Now”. The fsck() API will do the file system checking when “Check & Repair” is selected.

Parameters

Name

Required

Type

Description

driveName Requiredstring

Information that can identify the drive (e.g. sda1)

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/fsck '{ "driveName" : "sda" }'

 

Response:

{
    "returnValue": true
}


getAttachedDeviceStatus

Description

Gets the status information of connected device(s).

Parameters

Name

Required

Type

Description

subscribeRequiredboolean

Subscribe to get notified when the device status information changes. Possible values are:

  • true - Subscribe for changes.
  • false - Not subscribed.

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

deviceStatusList RequiredObject: deviceStatusList

An array containing the status information of the device.

Subscription Returns

Name

Required

Type

Description

returnValueRequiredBoolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalString

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

deviceStatusList RequiredObject: deviceStatusList

An array containing the status information of the device.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/getAttachedDeviceStatus '{ "subscribe" : true }'

 

Response: 

{
   "deviceStatusList":[
      {
         "deviceNum":0,
         "deviceStatus":"NOTHING"
      },
      {
         "deviceNum":1,
         "deviceStatus":"EJECTED",
         "driveStatusList":[
            {
               "driveName":"apps",
               "driveStatus":"UMOUNT_OK"
            }
         ]
      },
      {
         "deviceNum":2,
         "deviceStatus":"NOTHING",
         "driveStatusList":[
            {
               "driveName":"sdb1",
               "driveStatus":"MOUNT_OK"
            }
         ]
      }
   ],
   "returnValue":true
}


getAttachedNonStorageDeviceList

Description

Gets the status information of connected non-storage device(s).

Parameters

Name

Required

Type

Description

subscribeRequiredboolean

Subscribe to get notified when a device is connected and the list of non-storage device changes. Possible values are:

  • true - Subscribe for changes.
  • false - Not subscribed.
categoryOptionalString

Category of non-storage device. Possible values are:

  • Audio
  • Video
  • Net

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

powerStatusRequiredString

Power-on status of the device.

Note: This value always defaults to "normal".

nonStorageDeviceListOptionalObject: nonStorageDeviceList

An array containing the information about the non-storage device that is currently connected.

videoDeviceListOptionalObject: videoDeviceList

An array of video device lists connected.

Note: Returned only when "category" is "Video".

audioDeviceListOptionalObject: audioDeviceList

An array of audio device list connected.

Note: Returned only when "category" is "Audio".

netDeviceListOptionalObject: netDeviceList

An array of net device list connected.

Note: Returned only when "category" is "Net".

Subscription Returns

Name

Required

Type

Description

returnValueRequiredBoolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalString

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

powerStatusRequiredString

Power-on status of the device.

Note: This value always defaults to "normal".

nonStorageDeviceListRequiredObject: nonStorageDeviceList

An array containing the information about the non-storage device that is currently connected.

videoDeviceListOptionalObject: videoDeviceList

An array of video devices connected.

Note: Returned only when "category" is "Video".

audioDeviceListOptionalObject: audioDeviceList

An array of audio devices connected.

Note: Returned only when "category" is "Audio".

netDeviceListOptionalObject: netDeviceList

An array of net devices connected.

Note: Returned only when "category" is "Net".

Example

Example 1: To view all non-storage devices attached

# luna-send -n 1 -f luna://com.webos.service.pdm/getAttachedNonStorageDeviceList '{ "subscribe" : true }'

 

Response:
{
    "powerStatus": "normal",
    "nonStorageDeviceList": [
        {
            "usbPortNum": 255,
            "serialNumber": "",
            "isPowerOnConnect": false,
            "deviceNum": 52,
            "deviceSubtype": "usbhid",
            "vendorName": "DELL",
            "deviceType": "HID",
            "productName": "Dell USB Entry Keyboard",
            "devSpeed": "LOW"
        },
        {
            "usbPortNum": 2,
            "serialNumber": "",
            "isPowerOnConnect": false,
            "deviceNum": 62,
            "deviceSubtype": "usbhid",
            "vendorName": "17ef",
            "deviceType": "HID",
            "productName": "Lenovo Optical USB Mouse",
            "devSpeed": "LOW"
        }
    ],
    "returnValue": true
}

 

Example 2: To view all non-storage (video) devices attached

# luna-send -n 1 -f luna://com.webos.service.pdm/getAttachedNonStorageDeviceList '{ "subscribe" : true, "category" : "Video" }'

 

Response:
{
    "powerStatus": "normal",
    "videoDeviceList": [
        {
            "KERNEL": "video0",
            "SUBSYSTEM": "video4linux",
            "vendorName": "Logitech, Inc.",
            "productName": "081b",
            "devSpeed": "HIGH"
        }
    ],
    "returnValue": true
}

 

Example 3: To view all non-storage (audio) devices attached

# luna://com.webos.service.pdm/getAttachedNonStorageDeviceList '{ "subscribe" : true, "category" : "Audio" }'

 

Response:
{
    "powerStatus": "normal",
    "audioDeviceList": [
        {
            "cardNumber": 1,
            "cardName": "card1",
            "cardId": "Wireless",
            "usbPortNum": 3,
            "devSpeed": "HIGH"
        }
    ],
    "returnValue": true
}

 

Example 4: To view all non-storage (net) devices attached

# luna-send -n 1 -f luna://com.webos.service.pdm/getAttachedNonStorageDeviceList '{ "subscribe" : true, "category" : "Net" }'

 

Response:
{
    "netDeviceList": [
        {
            "duplex": "",
            "ifindex": "4",
            "linkmode": "0",
            "address": "50:3e:aa:6d:65:e5",
            "vendorName": "TP-LINK",
            "productName": "USB 10 100 1000 LAN",
            "devSpeed": "HIGH",
            "operstate": "down"
        }
    ],
    "powerStatus": "normal",
    "returnValue": true
}


getAttachedStorageDeviceList

Description

Gets status information of connected storage device(s).

Parameters

Name

Required

Type

Description

subscribeRequiredboolean

Subscribe to get notified when a device is connected and the list of storage device changes. Possible values are:

  • true - Subscribe for changes.
  • false - Not subscribed.

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

powerStatusRequiredString

Power-on status of the device.

Note: This value always defaults to "normal".

storageDeviceListRequiredObject: storageDeviceList

An array containing information about the currently connected storage device(s).

Subscription Returns

Name

Required

Type

Description

returnValueRequiredBoolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalString

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

powerStatusRequiredString

Power-on status of the device.

Note: This value always defaults to "normal".

storageDeviceListRequiredObject: storageDeviceList

An array containing information about the currently connected storage device(s).

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/getAttachedStorageDeviceList '{ "subscribe" : true }'

 

Response: 

{
   "powerStatus":"normal",
   "returnValue":true,
   "storageDeviceList":[
     {
         "usbPortNum":2,
         "rootPath":"/tmp/usb/sdb",
         "storageDriveList":[
            {
               "isMounted":true,
               "volumeLabel":"MX-ES",
               "uuid":"1209-3C50",
               "driveName":"sdb1",
               "driveSize":31190064,
               "fsType":"fat",
               "mountName":"/tmp/usb/sdb/sdb1"
            }
         ],
         "serialNumber":"000000000000000236",
         "isPowerOnConnect":false,
         "deviceNum":2,
         "vendorName":"MX",
         "storageType":"FLASH",
         "deviceType":"USB_STORAGE",
         "productName":"Mass Storage Device",
         "devSpeed":"HIGH",
         "errorReason":"NOTHING"
      }
   ]
}


getIoPerformance

Description

Measures the IO performance of the drive. This method is applicable only for writable USB stick. 

Note: The drive must be mounted.

Parameters

Name

Required

Type

Description

driveName Requiredstring

Information that can identify the drive (e.g. sda1)

chunkSizeOptionalNumber

IO performance measurement unit buffer size (KB) to read / write.

Possible values range from 4 ~ 65536 and should be a power of 2 (of the form 2n), such as 4, 8, 16, 32, 64 etc.  

Default value: 256

countOptionalNumber

Number of chunks for max writes/reads.

mountNameOptionalString

Absolute path where the device is mounted.

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

ioPerformanceRequiredObject: ioPerformance

Drive I/O performance information

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/getIoPerformance '{ "driveName" : "sda1", "chunkSize" : 256}'

 

Response:

{
    "ioPerformance": {
        "seqWriteAverage": 8.2411526076037,
        "seqReadMinimum": 27.027027027027,
        "randReadMinimum": 4.4305031279352,
        "seqReadAverage": 57.856977551493,
        "seqWriteMinimum": 2.0088711751093,
        "randReadAverage": 17.251864279584
    },
    "returnValue": true
}

 

# luna-send -n 1 -f luna://com.webos.service.pdm/getIoPerformance '{ "driveName" : "", "mountName" : "/tmp/usb/sda/sda1/test" , "chunkSize" : 512}'

 

Response:

{
   "ioPerformance":{
      "seqWriteAverage":32.972694,
      "seqReadMinimum":18.726592,
      "randReadMinimum":13.839681,
      "seqReadAverage":87.412587,
      "seqWriteMinimum":27.044569,
      "randReadAverage":25.132259
   },
   "returnValue":true
}


getSpaceInfo

Description

Gets the space information of the connected drive.

Note: The drive must be mounted.

Parameters

Name

Required

Type

Description

driveName Requiredstring

Information that can identify the drive (e.g. sda1)

directCheckOptionalboolean

Indicates if PDM needs to newly measure the drive space information at the time of API call. Possible values are:

  • true - Newly measures the information
  • false - Returns periodically measured information

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

spaceInfoRequiredObject: spaceInfo

Information about the drive space.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/getSpaceInfo '{ "driveName" : "sda" , "directCheck" : true }'

Response:

{
   "spaceInfo":{
      "usedRate":0,
      "freeSize":31116080.000000,
      "totalSize":31190064.000000,
      "usedSize":73984.000000
   },
   "returnValue":true
}


isWritableDrive

Description

Checks the file system attribute of the drive and returns whether it is writable. 

Parameters

Name

Required

Type

Description

driveNameRequiredString

Information that can identify the drive (e.g. sda1)

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

isWritableRequiredboolean

Indicates if data can be written on the drive. Possible values are: 

  • true - Writable drive
  • false - Cannot be written

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/isWritableDrive '{ "driveName" : "sda" }'

Response:

{
   "returnValue":true,
   "isWritable":true
}


setVolumeLabel

Description

Sets the volume label of the drive. It is supported only when file system type is FAT.

Parameters

Name

Required

Type

Description

driveName Requiredstring

Information that can identify the drive (e.g. sda1)

volumeLabelRequiredstring

Volume label for the drive.

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/setVolumeLabel '{ "driveName" : "sda", "volumeLabel" : "webos" }'

 

Response:

{  
   "returnValue":true
}


umountAllDrive

Description

Unmounts all drives. 

Parameters

None

Call Returns

Name

Required

Type

Description

returnValueRequiredboolean

Indicates the status of operation. Possible values are:

  • true - Indicates that the operation was successful.
  • false - Indicates that the operation failed. Check the "errorCode" and "errorText" fields for details.
errorCodeOptionalNumber

The error code for the failed operation.

errorTextOptionalstring

Indicates the reason for the failure of the operation. See the "API Error Codes Reference" section for details.

Example

# luna-send -n 1 -f luna://com.webos.service.pdm/umountAllDrive '{}'

 

Response:

{  
   "returnValue":true
}


Objects

ioPerformance

I/O performance information of the drive.

Name

Required

Type

Description

seqReadAverageRequiredNumber (double)

Sequential I / O read performance average value (MB / sec)

seqReadMinimumRequiredNumber (double)

Sequential I / O read performance Minimum value of measurement result (MB / sec)

seqWriteAverageRequiredNumber (double)

Sequential I / O write performance average value (MB / sec)

seqWriteMinimumRequiredNumber (double)

Sequential I / O write performance Minimum value of measurement result (MB / sec)

randReadAverageRequiredNumber (double)

Random I / O read performance average value (MB / sec)

randReadMinimumRequiredNumber (double)

Random I / O read performance Minimum value of measurement result (MB / sec)

spaceInfo

Information about the drive space. 

Name

Required

Type

Description

totalSizeRequiredNumber (double)

Total Drive Size (KB)

usedSizeRequiredNumber (double)

Drive size currently in use (KB)

freeSizeRequiredNumber (double)

Currently Available Drive Size (KB)

usedRateRequiredNumber (int32_t)

Current Drive Utilization (%)

deviceStatusList

List of the storage and non-storage devices connected and their statuses.

Name

Required

Type

Description

deviceNumRequiredNumber

Device number

deviceStatusRequiredString

Status of the device

driveStatusListOptionalObject: driveStatusList

List of statuses of the drives in the device

driveStatusList

List of the drives in the connected storage devices and their statuses.

Name

Required

Type

Description

driveNameRequiredString

Name of the drive

driveStatusRequiredString

Mount status of the drive

nonStorageDeviceList

List of information about the non-storage devices that are currently connected.

Name

Required

Type

Description

usbPortNumRequiredNumber

Port number to which the device is connected

serialNumberRequiredString

Serial number of the device product

isPowerOnConnectRequiredBoolean

Indicates whether the device was connected during power on. Possible values are:

  • true - Connected during power on
  • false - Connected after powering on
deviceNumRequiredNumber

Number assigned to the connected device

deviceSubtypeRequiredString

Sub-type of the device connected.

For example: If deviceType is "usb", then deviceSubtype can be "usbhid" etc.

vendorNameRequiredString

Name of the device vendor

deviceTypeRequiredString

Type of the device

productNameRequiredString

Name of the device product

devSpeedRequiredString

Speed of the device. Possible values are:

  • LOW
  • HIGH
  • SUPER

videoDeviceList

List of video device(s) connected.

Name

Required

Type

Description

KERNELRequiredString

Device name

SUBSYSTEMRequiredString

Device driver

vendorNameRequiredString

Name of the vendor

productNameRequiredString

Name of the product

devSpeedRequiredString

Speed of the device. Possible values are:

  • LOW
  • HIGH
  • SUPER

audioDeviceList

List of audio device(s) connected.

Name

Required

Type

Description

cardNumberRequiredNumber

Card number of the audio device

cardNameRequiredString

Name of the audio device card

cardIdRequiredString

Type of the audio device card

usbPortNumRequiredNumber

Port number where the sound device is connected

devSpeedRequiredString

Speed of the sound device. Possible values are:

  • LOW
  • HIGH
  • SUPER

netDeviceList

List of Communication Device Class (CDC) device(s) connected.

Name

Required

Type

Description

operstateRequiredString

State of the device operation

ifindexRequiredString

Network interface index

linkmodeRequiredString

Tells whether specified interface is managed and configured by systemd network manager. Possible values are:

  • 0 - LINK_AUTO
  • 1 - LINK_MANUAL
  • 2 - LINK_MODE_UNKNOWN
duplexRequiredString

Bandwidth of the device. Possible values are:

  • uni-directional
  • bi-directional
addressRequiredString

Ethernet address of the device connected

vendorNameRequiredString

Name of the vendor

productNameRequiredString

Name of the product

devSpeedRequiredString

Speed of the device. Possible values are:

  • LOW
  • HIGH
  • SUPER

storageDeviceList

List of information about the storage devices that are currently connected.

Name

Required

Type

Description

usbPortNumRequiredNumber

Port number to which the device is connected.

rootPathRequiredString

Root directory path of the device.

storageDriveListRequiredObject: storageDriveList

List of storage drives in the connected storage device.

serialNumberRequiredString

Serial number of the device.

isPowerOnConnectRequiredBoolean

Indicates whether the device was connected during power on. Possible values are:

  • true - Connected during power on.
  • false - Connected after powering on.
deviceNumRequiredNumber

Number assigned to the device.

vendorNameRequiredString

Name of the vendor.

storageTypeRequiredString

Type of the storage device.

deviceTypeRequiredString

Type of the USB device.

productNameRequiredString

Name of the product.

devSpeedRequiredString

Speed of the device.

errorReasonRequiredString

Describes the status of device mounting. Possible values are:

  • NOTHING - Mount successful
  • NOMOUNTED - Mount unsuccessful
  • UNSUPPORT_FILESYSTEM - File system of the device is unsupported
  • EJECTED - Device ejected
  • NEED_FSCK -Device needs file system checking

storageDriveList

List of the drives in storage devices connected.

Name

Required

Type

Description

isMountedRequiredBoolean

Indicates whether the device is mounted or not. Possible values are:

  • true - Device is mounted
  • false - Device is not mounted
volumeLabelRequiredString

Label set for the drive in the device

uuidRequiredString

Unique SCSI device ID

driveNameRequiredString

Name of the drive where mounted

driveSizeRequiredNumber

Size of the drive

fsTypeRequiredString

Type of the file system in the drive

mountNameRequiredString

Absolute path of the drive in the device where mounted


API Error Codes Reference

Error Code

Error Text

Error Description

1Parameter error

Parameter error

2Interface function error

Interface function error

3Subscribe Error

Subscribe Error

4SubscriptionAdd Fail

SubscriptionAdd Fail

5LSSubscriptionAcquire Fail

LSSubscriptionAcquire Fail

6Json parse error

Json parse error


Except as noted, this content is licensed under Creative Commons Attribution 4.0 and sample code is licensed under Apache License 2.0.