upload android base code part4

This commit is contained in:
August 2018-08-08 17:00:29 +08:00
parent b9e30e05b1
commit 78ea2404cd
23455 changed files with 5250148 additions and 0 deletions

View file

@ -0,0 +1,94 @@
// This file is autogenerated by hidl-gen. Do not edit manually.
filegroup {
name: "android.hardware.drm@1.0_hal",
srcs: [
"types.hal",
"ICryptoFactory.hal",
"ICryptoPlugin.hal",
"IDrmFactory.hal",
"IDrmPlugin.hal",
"IDrmPluginListener.hal",
],
}
genrule {
name: "android.hardware.drm@1.0_genc++",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0",
srcs: [
":android.hardware.drm@1.0_hal",
],
out: [
"android/hardware/drm/1.0/types.cpp",
"android/hardware/drm/1.0/CryptoFactoryAll.cpp",
"android/hardware/drm/1.0/CryptoPluginAll.cpp",
"android/hardware/drm/1.0/DrmFactoryAll.cpp",
"android/hardware/drm/1.0/DrmPluginAll.cpp",
"android/hardware/drm/1.0/DrmPluginListenerAll.cpp",
],
}
genrule {
name: "android.hardware.drm@1.0_genc++_headers",
tools: ["hidl-gen"],
cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.drm@1.0",
srcs: [
":android.hardware.drm@1.0_hal",
],
out: [
"android/hardware/drm/1.0/types.h",
"android/hardware/drm/1.0/hwtypes.h",
"android/hardware/drm/1.0/ICryptoFactory.h",
"android/hardware/drm/1.0/IHwCryptoFactory.h",
"android/hardware/drm/1.0/BnHwCryptoFactory.h",
"android/hardware/drm/1.0/BpHwCryptoFactory.h",
"android/hardware/drm/1.0/BsCryptoFactory.h",
"android/hardware/drm/1.0/ICryptoPlugin.h",
"android/hardware/drm/1.0/IHwCryptoPlugin.h",
"android/hardware/drm/1.0/BnHwCryptoPlugin.h",
"android/hardware/drm/1.0/BpHwCryptoPlugin.h",
"android/hardware/drm/1.0/BsCryptoPlugin.h",
"android/hardware/drm/1.0/IDrmFactory.h",
"android/hardware/drm/1.0/IHwDrmFactory.h",
"android/hardware/drm/1.0/BnHwDrmFactory.h",
"android/hardware/drm/1.0/BpHwDrmFactory.h",
"android/hardware/drm/1.0/BsDrmFactory.h",
"android/hardware/drm/1.0/IDrmPlugin.h",
"android/hardware/drm/1.0/IHwDrmPlugin.h",
"android/hardware/drm/1.0/BnHwDrmPlugin.h",
"android/hardware/drm/1.0/BpHwDrmPlugin.h",
"android/hardware/drm/1.0/BsDrmPlugin.h",
"android/hardware/drm/1.0/IDrmPluginListener.h",
"android/hardware/drm/1.0/IHwDrmPluginListener.h",
"android/hardware/drm/1.0/BnHwDrmPluginListener.h",
"android/hardware/drm/1.0/BpHwDrmPluginListener.h",
"android/hardware/drm/1.0/BsDrmPluginListener.h",
],
}
cc_library {
name: "android.hardware.drm@1.0",
defaults: ["hidl-module-defaults"],
generated_sources: ["android.hardware.drm@1.0_genc++"],
generated_headers: ["android.hardware.drm@1.0_genc++_headers"],
export_generated_headers: ["android.hardware.drm@1.0_genc++_headers"],
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"liblog",
"libutils",
"libcutils",
],
export_shared_lib_headers: [
"libhidlbase",
"libhidltransport",
"libhwbinder",
"libutils",
],
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
import ICryptoPlugin;
/**
* Ref: frameworks/native/include/media/hardware/CryptoAPI.h:CryptoFactory
*
* ICryptoFactory is the main entry point for interacting with a vendor's
* crypto HAL to create crypto plugins. Crypto plugins create crypto sessions
* which are used by a codec to decrypt protected video content.
*/
interface ICryptoFactory {
/**
* Determine if a crypto scheme is supported by this HAL
*
* @param uuid identifies the crypto scheme in question
* @return isSupported must be true only if the scheme is supported
*/
isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
/**
* Create a crypto plugin for the specified uuid and scheme-specific
* initialization data.
*
* @param uuid uniquely identifies the drm scheme. See
* http://dashif.org/identifiers/protection for uuid assignments
* @param initData scheme-specific init data.
* @return status the status of the call. The HAL implementation must return
* OK if the plugin is created and ERROR_DRM_CANNOT_HANDLE if the plugin
* cannot be created.
* @return cryptoPlugin the created ICryptoPlugin
*/
createPlugin(uint8_t[16] uuid, vec<uint8_t> initData)
generates (Status status, ICryptoPlugin cryptoPlugin);
};

View file

@ -0,0 +1,114 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
import android.hardware.drm@1.0::types;
/**
* Ref: frameworks/native/include/media/hardware/CryptoAPI.h:CryptoPlugin
*
* ICryptoPlugin is the HAL for vendor-provided crypto plugins.
* It allows crypto sessions to be opened and operated on, to
* load crypto keys for a codec to decrypt protected video content.
*/
interface ICryptoPlugin {
/**
* Check if the specified mime-type requires a secure decoder
* component.
*
* @param mime The content mime-type
* @return secureRequired must be true only if a secure decoder is required
* for the specified mime-type
*/
requiresSecureDecoderComponent(string mime)
generates(bool secureRequired);
/**
* Notify a plugin of the currently configured resolution
*
* @param width - the display resolutions's width
* @param height - the display resolution's height
*/
notifyResolution(uint32_t width, uint32_t height);
/**
* Associate a mediadrm session with this crypto session
*
* @param sessionId the MediaDrm session ID to associate with this crypto
* session
* @return status the status of the call, status must be
* ERROR_DRM_SESSION_NOT_OPENED if the session is not opened, or
* ERROR_DRM_CANNOT_HANDLE if the operation is not supported by the drm
* scheme.
*/
setMediaDrmSession(vec<uint8_t> sessionId) generates(Status status);
/**
* Set a shared memory base for subsequent decrypt operations. The buffer
* base is a hidl_memory which maps shared memory in the HAL module.
* After the shared buffer base is established, the decrypt() method
* receives SharedBuffer instances which specify the buffer address range
* for decrypt source and destination addresses.
*
* There can be multiple shared buffers per crypto plugin. The buffers
* are distinguished by the bufferId.
*
* @param base the base IMemory of the memory buffer identified by
* bufferId
* @param bufferId identifies the specific shared buffer for which
* the base is being set.
*/
setSharedBufferBase(memory base, uint32_t bufferId);
/**
* Decrypt an array of subsamples from the source memory buffer to the
* destination memory buffer.
*
* @param secure a flag to indicate if a secure decoder is being used. This
* enables the plugin to configure buffer modes to work consistently with
* a secure decoder.
* @param the keyId for the key that should be used to do the
* the decryption. The keyId refers to a key in the associated
* MediaDrm instance.
* @param iv the initialization vector to use
* @param mode the crypto mode to use
* @param pattern the crypto pattern to use
* @param subSamples a vector of subsamples indicating the number
* of clear and encrypted bytes to process. This allows the decrypt
* call to operate on a range of subsamples in a single call
* @param source the input buffer for the decryption
* @param offset the offset of the first byte of encrypted data from
* the base of the source buffer
* @param destination the output buffer for the decryption
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_NO_LICENSE if no license keys have been
* loaded, ERROR_DRM_LICENSE_EXPIRED if the license keys have expired,
* ERROR_DRM_RESOURCE_BUSY if the resources required to perform the
* decryption are not available, ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
* if required output protections are not active,
* ERROR_DRM_SESSION_NOT_OPENED if the decrypt session is not opened,
* ERROR_DRM_DECRYPT if the decrypt operation fails, and
* ERROR_DRM_CANNOT_HANDLE in other failure cases.
* @return bytesWritten the number of bytes output from the decryption
* @return detailedError if the error is a vendor-specific error, the
* vendor's crypto HAL may provide a detailed error string to help
* describe the error.
*/
decrypt(bool secure, uint8_t[16] keyId, uint8_t[16] iv, Mode mode,
Pattern pattern, vec<SubSample> subSamples,
SharedBuffer source, uint64_t offset, DestinationBuffer destination)
generates(Status status, uint32_t bytesWritten, string detailedError);
};

View file

@ -0,0 +1,61 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
import IDrmPlugin;
/**
* Ref: frameworks/native/include/media/drm/DrmAPI.h:DrmFactory
*
* IDrmFactory is the main entry point for interacting with a vendor's
* drm HAL to create drm plugin instances. A drm plugin instance
* creates drm sessions which are used to obtain keys for a crypto
* session so it can decrypt* protected video content.
*/
interface IDrmFactory {
/**
* Determine if a crypto scheme is supported by this HAL
*
* @param uuid identifies the crypto scheme in question
* @return isSupported must be true only if the scheme is supported
*/
isCryptoSchemeSupported(uint8_t[16] uuid) generates(bool isSupported);
/**
* Determine if the HAL factory is able to construct plugins that support a
* given media container format specified by mimeType
*
* @param mimeType identifies the mime type in question
* @return isSupported must be true only if the scheme is supported
*/
isContentTypeSupported(string mimeType) generates(bool isSupported);
/**
* Create a drm plugin instance for the specified uuid and scheme-specific
* initialization data.
*
* @param uuid uniquely identifies the drm scheme. See
* http://dashif.org/identifiers/protection for uuid assignments
* @param appPackageName identifies the package name of the calling
* application.
* @return status the status of the call. The HAL implementation must return
* OK if the plugin is created and ERROR_DRM_CANNOT_HANDLE if the plugin
* cannot be created.
*/
createPlugin(uint8_t[16] uuid, string appPackageName)
generates (Status status, IDrmPlugin drmPlugin);
};

View file

@ -0,0 +1,542 @@
/**
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
import IDrmPluginListener;
/**
* Ref: frameworks/native/include/media/drm/DrmAPI.h:DrmPlugin
*
* IDrmPlugin is used to interact with a specific drm plugin that was
* created by IDrm::createPlugin. A drm plugin provides methods for
* obtaining drm keys that may be used by a codec to decrypt protected
* video content.
*/
interface IDrmPlugin {
/**
* Open a new session with the DrmPlugin object. A session ID is returned
* in the sessionId parameter.
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_NOT_PROVISIONED if the device requires
* provisioning before it can open a session, ERROR_DRM_RESOURCE_BUSY if
* there are insufficent resources available to open a session,
* ERROR_DRM_CANNOT_HANDLE, if openSession is not supported at the time of
* the call or ERROR_DRM_INVALID_STATE if the HAL is in a state where a
* session cannot be opened.
* @return sessionId the session ID for the newly opened session
*/
openSession() generates (Status status, SessionId sessionId);
/**
* Close a session on the DrmPlugin object
*
* @param sessionId the session id the call applies to
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the session cannot be closed.
*/
closeSession(SessionId sessionId) generates (Status status);
/**
* A key request/response exchange occurs between the app and a License
* Server to obtain the keys required to decrypt the content.
* getKeyRequest() is used to obtain an opaque key request blob that is
* delivered to the license server.
*
* @param scope may be a sessionId or a keySetId, depending on the
* specified keyType. When the keyType is OFFLINE or STREAMING,
* scope should be set to the sessionId the keys will be provided to.
* When the keyType is RELEASE, scope should be set to the keySetId
* of the keys being released.
* @param initData container-specific data, its meaning is interpreted
* based on the mime type provided in the mimeType parameter. It could
* contain, for example, the content ID, key ID or other data obtained
* from the content metadata that is required to generate the key request.
* initData may be empty when keyType is RELEASE.
* @param mimeType identifies the mime type of the content
* @param keyType specifies if the keys are to be used for streaming,
* offline or a release
* @param optionalParameters included in the key request message to
* allow a client application to provide additional message parameters to
* the server.
*
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
* before it can generate a key request, ERROR_DRM_CANNOT_HANDLE if
* getKeyRequest is not supported at the time of the call, BAD_VALUE if any
* parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL is in a state
* where a key request cannot be generated.
* @return request if successful, the opaque key request blob is returned
* @return requestType indicates type information about the returned
* request. The type may be one of INITIAL, RENEWAL or RELEASE. An
* INITIAL request is the first key request for a license. RENEWAL is a
* subsequent key request used to refresh the keys in a license. RELEASE
* corresponds to a keyType of RELEASE, which indicates keys are being
* released.
* @return defaultUrl the URL that the request may be sent to, if
* provided by the drm HAL. The app may choose to override this
* URL.
*/
getKeyRequest(vec<uint8_t> scope, vec<uint8_t> initData,
string mimeType, KeyType keyType, KeyedVector optionalParameters)
generates (Status status, vec<uint8_t> request,
KeyRequestType requestType, string defaultUrl);
/**
* After a key response is received by the app, it is provided to the
* Drm plugin using provideKeyResponse.
*
* @param scope may be a sessionId or a keySetId depending on the type
* of the response. Scope should be set to the sessionId when the response
* is for either streaming or offline key requests. Scope should be set to
* the keySetId when the response is for a release request.
* @param response the response from the key server that is being
* provided to the drm HAL.
*
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, ERROR_DRM_NOT_PROVISIONED if the device requires provisioning
* before it can handle the key response, ERROR_DRM_DEVICE_REVOKED if the
* device has been disabled by the license policy, ERROR_DRM_CANNOT_HANDLE
* if provideKeyResponse is not supported at the time of the call, BAD_VALUE
* if any parameters are invalid or ERROR_DRM_INVALID_STATE if the HAL is
* in a state where a key response cannot be handled.
* @return keySetId when the response is for an offline key request, a
* keySetId is returned in the keySetId vector parameter that can be used
* to later restore the keys to a new session with the method restoreKeys.
* When the response is for a streaming or release request, no keySetId is
* returned.
*/
provideKeyResponse(vec<uint8_t> scope, vec<uint8_t> response)
generates (Status status, vec<uint8_t> keySetId);
/**
* Remove the current keys from a session
*
* @param sessionId the session id the call applies to
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the keys cannot be removed.
*/
removeKeys(SessionId sessionId) generates (Status status);
/**
* Restore persisted offline keys into a new session
*
* @param sessionId the session id the call applies to
* @param keySetId identifies the keys to load, obtained from a prior
* call to provideKeyResponse().
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where keys cannot be restored.
*/
restoreKeys(SessionId sessionId,
vec<uint8_t> keySetId) generates (Status status);
/**
* Request an informative description of the license for the session. The
* status is in the form of {name, value} pairs. Since DRM license policies
* vary by vendor, the specific status field names are determined by each
* DRM vendor. Refer to your DRM provider documentation for definitions of
* the field names for a particular drm scheme.
*
* @param sessionId the session id the call applies to
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if the sessionId is invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where key status cannot be queried.
* @return infoList a list of name value pairs describing the license
*/
queryKeyStatus(SessionId sessionId)
generates (Status status, KeyedVector infoList);
/**
* A provision request/response exchange occurs between the app and a
* provisioning server to retrieve a device certificate. getProvisionRequest
* is used to obtain an opaque provisioning request blob that is delivered
* to the provisioning server.
*
* @param certificateType the type of certificate requested, e.g. "X.509"
* @param certificateAuthority identifies the certificate authority. A
* certificate authority (CA) is an entity which issues digital certificates
* for use by other parties. It is an example of a trusted third party.
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_CANNOT_HANDLE if the drm scheme does not
* require provisioning or ERROR_DRM_INVALID_STATE if the HAL is in a state
* where the provision request cannot be generated.
* @return request if successful the opaque certificate request blob
* is returned
* @return defaultUrl URL that the provisioning request should be
* sent to, if known by the HAL implementation. If the HAL implementation
* does not provide a defaultUrl, the returned string must be empty.
*/
getProvisionRequest(string certificateType, string certificateAuthority)
generates (Status status, vec<uint8_t> request, string defaultUrl);
/**
* After a provision response is received by the app from a provisioning
* server, it is provided to the Drm HAL using provideProvisionResponse.
* The HAL implementation must receive the provision request and
* store the provisioned credentials.
*
* @param response the opaque provisioning response received by the
* app from a provisioning server.
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_DEVICE_REVOKED if the device has been
* disabled by the license policy, BAD_VALUE if any parameters are invalid
* or ERROR_DRM_INVALID_STATE if the HAL is in a state where the provision
* response cannot be handled.
* @return certificate the public certificate resulting from the provisioning
* operation, if any. An empty vector indicates that no certificate was
* returned.
* @return wrappedKey an opaque object containing encrypted private key
* material to be used by signRSA when computing an RSA signature on a
* message, see the signRSA method.
*/
provideProvisionResponse(vec<uint8_t> response) generates (Status status,
vec<uint8_t> certificate, vec<uint8_t> wrappedKey);
/**
* SecureStop is a way of enforcing the concurrent stream limit per
* subscriber. It can securely monitor the lifetime of sessions across
* device reboots by periodically persisting the session lifetime
* status in secure storage.
*
* A signed version of the sessionID is written to persistent storage on the
* device when each MediaCrypto object is created and periodically during
* playback. The sessionID is signed by the device private key to prevent
* tampering.
*
* When playback is completed the session is destroyed, and the secure
* stops are queried by the app. The app then delivers the secure stop
* message to a server which verifies the signature to confirm that the
* session and its keys have been removed from the device. The persisted
* record on the device is removed after receiving and verifying the
* signed response from the server.
*/
/**
* Get all secure stops on the device
*
* @return status the status of the call. The status must be OK or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stops
* cannot be returned.
* @return secureStops a list of the secure stop opaque objects
*/
getSecureStops() generates
(Status status, vec<SecureStop> secureStops);
/**
* Get all secure stops by secure stop ID
*
* @param secureStopId the ID of the secure stop to return. The
* secure stop ID is delivered by the key server as part of the key
* response and must also be known by the app.
*
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the secureStopId is invalid or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stop
* cannot be returned.
* @return secureStop the secure stop opaque object
*/
getSecureStop(SecureStopId secureStopId)
generates (Status status, SecureStop secureStop);
/**
* Release all secure stops on the device
*
* @return status the status of the call. The status must be OK or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure
* stops cannot be released.
*/
releaseAllSecureStops() generates (Status status);
/**
* Release a secure stop by secure stop ID
*
* @param secureStopId the ID of the secure stop to release. The
* secure stop ID is delivered by the key server as part of the key
* response and must also be known by the app.
*
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the secureStopId is invalid or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the secure stop
* cannot be released.
*/
releaseSecureStop(vec<uint8_t> secureStopId) generates (Status status);
/**
* A drm scheme can have properties that are settable and readable
* by an app. There are a few forms of property access methods,
* depending on the data type of the property.
*
* Property values defined by the public API are:
* "vendor" [string] identifies the maker of the drm scheme
* "version" [string] identifies the version of the drm scheme
* "description" [string] describes the drm scheme
* 'deviceUniqueId' [byte array] The device unique identifier is
* established during device provisioning and provides a means of
* uniquely identifying each device.
*
* Since drm scheme properties may vary, additional field names may be
* defined by each DRM vendor. Refer to your DRM provider documentation
* for definitions of its additional field names.
*/
/**
* Read a string property value given the property name.
*
* @param propertyName the name of the property
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the property name is invalid,
* ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
* cannot be obtained.
* @return value the property value string
*/
getPropertyString(string propertyName)
generates (Status status, string value);
/**
* Read a byte array property value given the property name.
*
* @param propertyName the name of the property
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the property name is invalid,
* ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
* cannot be obtained.
* @return value the property value byte array
*/
getPropertyByteArray(string propertyName)
generates (Status status, vec<uint8_t> value);
/**
* Write a property string value given the property name
*
* @param propertyName the name of the property
* @param value the value to write
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the property name is invalid,
* ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
* cannot be set.
*/
setPropertyString(string propertyName, string value)
generates (Status status);
/**
* Write a property byte array value given the property name
*
* @param propertyName the name of the property
* @param value the value to write
* @return status the status of the call. The status must be OK or one of
* the following errors: BAD_VALUE if the property name is invalid,
* ERROR_DRM_CANNOT_HANDLE if the property is not supported, or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the property
* cannot be set.
*/
setPropertyByteArray(string propertyName, vec<uint8_t> value )
generates (Status status);
/**
* The following methods implement operations on a CryptoSession to support
* encrypt, decrypt, sign verify operations on operator-provided
* session keys.
*/
/**
* Set the cipher algorithm to be used for the specified session.
*
* @param sessionId the session id the call applies to
* @param algorithm the algorithm to use. The string conforms to JCA
* Standard Names for Cipher Transforms and is case insensitive. An
* example algorithm is "AES/CBC/PKCS5Padding".
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the algorithm cannot be set.
*/
setCipherAlgorithm(SessionId sessionId, string algorithm)
generates (Status status);
/**
* Set the MAC algorithm to be used for computing hashes in a session.
*
* @param sessionId the session id the call applies to
* @param algorithm the algorithm to use. The string conforms to JCA
* Standard Names for Mac Algorithms and is case insensitive. An example MAC
* algorithm string is "HmacSHA256".
* @return status the status of the call. The status must be OK or one of the
* following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the algorithm cannot be set.
*/
setMacAlgorithm(SessionId sessionId, string algorithm)
generates (Status status);
/**
* Encrypt the provided input buffer with the cipher algorithm specified by
* setCipherAlgorithm and the key selected by keyId, and return the
* encrypted data.
*
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for encryption
* @param input the input data to encrypt
* @param iv the initialization vector to use for encryption
* @return status the status of the call. The status must be OK or one of the
* following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not opened,
* BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the encrypt operation cannot be performed.
* @return output the decrypted data
*/
encrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
/**
* Decrypt the provided input buffer with the cipher algorithm
* specified by setCipherAlgorithm and the key selected by keyId,
* and return the decrypted data.
*
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for decryption
* @param input the input data to decrypt
* @param iv the initialization vector to use for decryption
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the decrypt operation cannot be
* performed.
* @return output the decrypted data
*/
decrypt(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> input,
vec<uint8_t> iv) generates (Status status, vec<uint8_t> output);
/**
* Compute a signature over the provided message using the mac algorithm
* specified by setMacAlgorithm and the key selected by keyId and return
* the signature.
*
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for decryption
* @param message the message to compute a signature over
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the sign operation cannot be
* performed.
* @return signature the computed signature
*/
sign(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message)
generates (Status status, vec<uint8_t> signature);
/**
* Compute a hash of the provided message using the mac algorithm specified
* by setMacAlgorithm and the key selected by keyId, and compare with the
* expected result.
*
* @param sessionId the session id the call applies to
* @param keyId the ID of the key to use for decryption
* @param message the message to compute a hash of
* @param signature the signature to verify
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is not
* opened, BAD_VALUE if any parameters are invalid or ERROR_DRM_INVALID_STATE
* if the HAL is in a state where the verify operation cannot be
* performed.
* @return match true if the signature is verified positively,
* false otherwise.
*/
verify(SessionId sessionId, vec<uint8_t> keyId, vec<uint8_t> message,
vec<uint8_t> signature) generates (Status status, bool match);
/**
* Compute an RSA signature on the provided message using the specified
* algorithm.
*
* @param sessionId the session id the call applies to
* @param algorithm the signing algorithm, such as "RSASSA-PSS-SHA1"
* or "PKCS1-BlockType1"
* @param message the message to compute the signature on
* @param wrappedKey the private key returned during provisioning as
* returned by provideProvisionResponse.
* @return status the status of the call. The status must be OK or one of
* the following errors: ERROR_DRM_SESSION_NOT_OPENED if the session is
* not opened, BAD_VALUE if any parameters are invalid or
* ERROR_DRM_INVALID_STATE if the HAL is in a state where the signRSA
* operation cannot be performed.
* @return signature the RSA signature computed over the message
*/
signRSA(SessionId sessionId, string algorithm, vec<uint8_t> message,
vec<uint8_t> wrappedkey)
generates (Status status, vec<uint8_t> signature);
/**
* Plugins call the following methods to deliver events to the
* java app.
*/
/**
* Set a listener for a drm session. This allows the drm HAL to
* make asynchronous calls back to the client of IDrm.
*
* @param listener instance of IDrmPluginListener to receive the events
*/
setListener(IDrmPluginListener listener);
/**
* Legacy event sending method, it sends events of various types using a
* single overloaded set of parameters. This form is deprecated.
*
* @param eventType the type of the event
* @param sessionId identifies the session the event originated from
* @param data event-specific data blob
*/
sendEvent(EventType eventType, SessionId sessionId, vec<uint8_t> data);
/**
* Send a license expiration update to the listener. The expiration
* update indicates how long the current license is valid before it
* needs to be renewed.
*
* @param sessionId identifies the session the event originated from
* @param expiryTimeInMS the time when the keys need to be renewed.
* The time is in milliseconds, relative to the Unix epoch. A time of 0
* indicates that the keys never expire.
*/
sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
/**
* Send a keys change event to the listener. The keys change event
* indicates the status of each key in the session. Keys can be
* indicated as being usable, expired, outputnotallowed or statuspending.
*
* @param sessionId identifies the session the event originated from
* @param keyStatusList indicates the status for each key ID in the
* session.
* @param hasNewUsableKey indicates if the event includes at least one
* key that has become usable.
*/
sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
bool hasNewUsableKey);
};

View file

@ -0,0 +1,67 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
import android.hardware.drm@1.0::types;
/**
* Ref: frameworks/native/include/media/drm/DrmAPI.h:DrmPluginListener
*/
/**
* IDrmPluginListener is a listener interface for Drm events sent from an
* IDrmPlugin instance.
*/
interface IDrmPluginListener {
/**
* Legacy event sending method, it sends events of various types using a
* single overloaded set of parameters. This form is deprecated.
*
* @param eventType the type of the event
* @param sessionId identifies the session the event originated from
* @param data event-specific data blob
*/
oneway sendEvent(EventType eventType, SessionId sessionId,
vec<uint8_t> data);
/**
* Send a license expiration update to the listener. The expiration
* update indicates how long the current keys are valid before they
* need to be renewed.
*
* @param sessionId identifies the session the event originated from
* @param expiryTimeInMS the time when the keys need to be renewed.
* The time is in milliseconds, relative to the Unix epoch. A time
* of 0 indicates that the keys never expire.
*/
oneway sendExpirationUpdate(SessionId sessionId, int64_t expiryTimeInMS);
/**
* Send a keys change event to the listener. The keys change event
* indicates the status of each key in the session. Keys can be
* indicated as being usable, expired, outputnotallowed or statuspending.
*
* @param sessionId identifies the session the event originated from
* @param keyStatusList indicates the status for each key ID in the
* session.
* @param hasNewUsableKey indicates if the event includes at least one
* key that has become usable.
*/
oneway sendKeysChange(SessionId sessionId, vec<KeyStatus> keyStatusList,
bool hasNewUsableKey);
};

View file

@ -0,0 +1,23 @@
cc_library_static {
name: "android.hardware.drm@1.0-helper",
vendor_available: true,
defaults: ["hidl_defaults"],
srcs: [
"SharedLibrary.cpp",
],
cflags: [
"-Werror",
"-Wextra",
"-Wall",
],
shared_libs: [
"liblog",
],
header_libs: [
"libutils_headers",
],
export_header_lib_headers: [
"libutils_headers",
],
export_include_dirs : ["include"]
}

View file

@ -0,0 +1,98 @@
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
############# Build legacy drm service ############
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.drm@1.0-service
LOCAL_INIT_RC := android.hardware.drm@1.0-service.rc
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
service.cpp \
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hidl.memory@1.0 \
libhidlbase \
libhidltransport \
libhardware \
liblog \
libutils \
libbinder \
LOCAL_STATIC_LIBRARIES := \
android.hardware.drm@1.0-helper \
LOCAL_C_INCLUDES := \
hardware/interfaces/drm
LOCAL_HEADER_LIBRARIES := \
media_plugin_headers
# TODO(b/18948909) Some legacy DRM plugins only support 32-bit. They need to be
# migrated to 64-bit. Once all of a device's legacy DRM plugins support 64-bit,
# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this service as
# 64-bit.
ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
LOCAL_32_BIT_ONLY := true
endif
include $(BUILD_EXECUTABLE)
############# Build legacy drm impl library ############
include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.drm@1.0-impl
LOCAL_PROPRIETARY_MODULE := true
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SRC_FILES := \
DrmFactory.cpp \
DrmPlugin.cpp \
CryptoFactory.cpp \
CryptoPlugin.cpp \
LegacyPluginPath.cpp \
TypeConvert.cpp \
LOCAL_SHARED_LIBRARIES := \
android.hardware.drm@1.0 \
android.hidl.memory@1.0 \
libcutils \
libhidlbase \
libhidlmemory \
libhidltransport \
liblog \
libstagefright_foundation \
libutils \
LOCAL_STATIC_LIBRARIES := \
android.hardware.drm@1.0-helper \
LOCAL_C_INCLUDES := \
frameworks/native/include \
frameworks/av/include
# TODO: Some legacy DRM plugins only support 32-bit. They need to be migrated to
# 64-bit. (b/18948909) Once all of a device's legacy DRM plugins support 64-bit,
# that device can turn on TARGET_ENABLE_MEDIADRM_64 to build this impl as
# 64-bit.
ifneq ($(TARGET_ENABLE_MEDIADRM_64), true)
LOCAL_32_BIT_ONLY := true
endif
include $(BUILD_SHARED_LIBRARY)

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "CryptoFactory.h"
#include <log/log.h>
#include "CryptoPlugin.h"
#include "LegacyPluginPath.h"
#include "TypeConvert.h"
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
CryptoFactory::CryptoFactory() :
loader(getDrmPluginPath(), "createCryptoFactory") {
}
// Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
Return<bool> CryptoFactory::isCryptoSchemeSupported(
const hidl_array<uint8_t, 16>& uuid) {
for (size_t i = 0; i < loader.factoryCount(); i++) {
if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
return true;
}
}
return false;
}
Return<void> CryptoFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb) {
for (size_t i = 0; i < loader.factoryCount(); i++) {
if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
android::CryptoPlugin *legacyPlugin = NULL;
status_t status = loader.getFactory(i)->createPlugin(uuid.data(),
initData.data(), initData.size(), &legacyPlugin);
CryptoPlugin *newPlugin = NULL;
if (legacyPlugin == NULL) {
ALOGE("Crypto legacy HAL: failed to create crypto plugin");
} else {
newPlugin = new CryptoPlugin(legacyPlugin);
}
_hidl_cb(toStatus(status), newPlugin);
return Void();
}
}
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
return Void();
}
ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* /* name */) {
return new CryptoFactory();
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,68 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_DRM_V1_0__CRYPTOFACTORY_H
#define ANDROID_HARDWARE_DRM_V1_0__CRYPTOFACTORY_H
#include <android/hardware/drm/1.0/ICryptoFactory.h>
#include <hidl/Status.h>
#include <media/hardware/CryptoAPI.h>
#include <PluginLoader.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
using ::android::hardware::drm::V1_0::helper::PluginLoader;
using ::android::hardware::drm::V1_0::ICryptoFactory;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
struct CryptoFactory : public ICryptoFactory {
CryptoFactory();
virtual ~CryptoFactory() {}
// Methods from ::android::hardware::drm::V1_0::ICryptoFactory follow.
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
override;
Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
const hidl_vec<uint8_t>& initData, createPlugin_cb _hidl_cb)
override;
private:
PluginLoader<android::CryptoFactory> loader;
CryptoFactory(const CryptoFactory &) = delete;
void operator=(const CryptoFactory &) = delete;
};
extern "C" ICryptoFactory* HIDL_FETCH_ICryptoFactory(const char* name);
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_DRM_V1_0__CRYPTOFACTORY_H

View file

@ -0,0 +1,172 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "CryptoPlugin.h"
#include "TypeConvert.h"
#include <android/hidl/memory/1.0/IMemory.h>
#include <hidlmemory/mapping.h>
#include <log/log.h>
#include <media/stagefright/foundation/AString.h>
using android::hardware::hidl_memory;
using android::hidl::memory::V1_0::IMemory;
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
// Methods from ::android::hardware::drm::V1_0::ICryptoPlugin follow
Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
const hidl_string& mime) {
return mLegacyPlugin->requiresSecureDecoderComponent(mime.c_str());
}
Return<void> CryptoPlugin::notifyResolution(uint32_t width,
uint32_t height) {
mLegacyPlugin->notifyResolution(width, height);
return Void();
}
Return<Status> CryptoPlugin::setMediaDrmSession(
const hidl_vec<uint8_t>& sessionId) {
return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
}
Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
uint32_t bufferId) {
sp<IMemory> hidlMemory = mapMemory(base);
ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr");
// allow mapMemory to return nullptr
mSharedBufferMap[bufferId] = hidlMemory;
return Void();
}
Return<void> CryptoPlugin::decrypt(bool secure,
const hidl_array<uint8_t, 16>& keyId,
const hidl_array<uint8_t, 16>& iv, Mode mode,
const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
const SharedBuffer& source, uint64_t offset,
const DestinationBuffer& destination,
decrypt_cb _hidl_cb) {
if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set");
return Void();
}
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& dest = destination.nonsecureMemory;
if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set");
return Void();
}
}
android::CryptoPlugin::Mode legacyMode;
switch(mode) {
case Mode::UNENCRYPTED:
legacyMode = android::CryptoPlugin::kMode_Unencrypted;
break;
case Mode::AES_CTR:
legacyMode = android::CryptoPlugin::kMode_AES_CTR;
break;
case Mode::AES_CBC_CTS:
legacyMode = android::CryptoPlugin::kMode_AES_WV;
break;
case Mode::AES_CBC:
legacyMode = android::CryptoPlugin::kMode_AES_CBC;
break;
}
android::CryptoPlugin::Pattern legacyPattern;
legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
legacyPattern.mSkipBlocks = pattern.skipBlocks;
android::CryptoPlugin::SubSample *legacySubSamples =
new android::CryptoPlugin::SubSample[subSamples.size()];
for (size_t i = 0; i < subSamples.size(); i++) {
legacySubSamples[i].mNumBytesOfClearData
= subSamples[i].numBytesOfClearData;
legacySubSamples[i].mNumBytesOfEncryptedData
= subSamples[i].numBytesOfEncryptedData;
}
AString detailMessage;
sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
if (sourceBase == nullptr) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
return Void();
}
if (source.offset + offset + source.size > sourceBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
uint8_t *base = static_cast<uint8_t *>
(static_cast<void *>(sourceBase->getPointer()));
void *srcPtr = static_cast<void *>(base + source.offset + offset);
void *destPtr = NULL;
if (destination.type == BufferType::SHARED_MEMORY) {
const SharedBuffer& destBuffer = destination.nonsecureMemory;
sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
if (destBase == nullptr) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
return Void();
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
} else if (destination.type == BufferType::NATIVE_HANDLE) {
native_handle_t *handle = const_cast<native_handle_t *>(
destination.secureMemory.getNativeHandle());
destPtr = static_cast<void *>(handle);
}
ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
legacyMode, legacyPattern, srcPtr, legacySubSamples,
subSamples.size(), destPtr, &detailMessage);
delete[] legacySubSamples;
uint32_t status;
uint32_t bytesWritten;
if (result >= 0) {
status = android::OK;
bytesWritten = result;
} else {
status = result;
bytesWritten = 0;
}
_hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
return Void();
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,84 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H
#define ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H
#include <android/hidl/memory/1.0/IMemory.h>
#include <android/hardware/drm/1.0/ICryptoPlugin.h>
#include <hidl/Status.h>
#include <media/hardware/CryptoAPI.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
using ::android::hardware::drm::V1_0::DestinationBuffer;
using ::android::hardware::drm::V1_0::ICryptoPlugin;
using ::android::hardware::drm::V1_0::Mode;
using ::android::hardware::drm::V1_0::Pattern;
using ::android::hardware::drm::V1_0::SubSample;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hidl::memory::V1_0::IMemory;
using ::android::sp;
struct CryptoPlugin : public ICryptoPlugin {
CryptoPlugin(android::CryptoPlugin *plugin) : mLegacyPlugin(plugin) {}
~CryptoPlugin() {delete mLegacyPlugin;}
// Methods from ::android::hardware::drm::V1_0::ICryptoPlugin
// follow.
Return<bool> requiresSecureDecoderComponent(const hidl_string& mime)
override;
Return<void> notifyResolution(uint32_t width, uint32_t height) override;
Return<Status> setMediaDrmSession(const hidl_vec<uint8_t>& sessionId)
override;
Return<void> setSharedBufferBase(const ::android::hardware::hidl_memory& base,
uint32_t bufferId) override;
Return<void> decrypt(bool secure, const hidl_array<uint8_t, 16>& keyId,
const hidl_array<uint8_t, 16>& iv, Mode mode, const Pattern& pattern,
const hidl_vec<SubSample>& subSamples, const SharedBuffer& source,
uint64_t offset, const DestinationBuffer& destination,
decrypt_cb _hidl_cb) override;
private:
android::CryptoPlugin *mLegacyPlugin;
std::map<uint32_t, sp<IMemory> > mSharedBufferMap;
CryptoPlugin() = delete;
CryptoPlugin(const CryptoPlugin &) = delete;
void operator=(const CryptoPlugin &) = delete;
};
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_DRM_V1_0__CRYPTOPLUGIN_H

View file

@ -0,0 +1,85 @@
/*
* Copyright (C) 2016 The Android Open Source Project
` *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "DrmFactory.h"
#include <log/log.h>
#include "DrmPlugin.h"
#include "LegacyPluginPath.h"
#include "TypeConvert.h"
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
DrmFactory::DrmFactory() :
loader(getDrmPluginPath(), "createDrmFactory") {
}
// Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
Return<bool> DrmFactory::isCryptoSchemeSupported (
const hidl_array<uint8_t, 16>& uuid) {
for (size_t i = 0; i < loader.factoryCount(); i++) {
if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
return true;
}
}
return false;
}
Return<bool> DrmFactory::isContentTypeSupported (
const hidl_string& mimeType) {
for (size_t i = 0; i < loader.factoryCount(); i++) {
if (loader.getFactory(i)->isContentTypeSupported(String8(mimeType.c_str()))) {
return true;
}
}
return false;
}
Return<void> DrmFactory::createPlugin(const hidl_array<uint8_t, 16>& uuid,
const hidl_string& /* appPackageName */, createPlugin_cb _hidl_cb) {
for (size_t i = 0; i < loader.factoryCount(); i++) {
if (loader.getFactory(i)->isCryptoSchemeSupported(uuid.data())) {
android::DrmPlugin *legacyPlugin = NULL;
status_t status = loader.getFactory(i)->createDrmPlugin(
uuid.data(), &legacyPlugin);
DrmPlugin *newPlugin = NULL;
if (legacyPlugin == NULL) {
ALOGE("Drm legacy HAL: failed to create drm plugin");
} else {
newPlugin = new DrmPlugin(legacyPlugin);
}
_hidl_cb(toStatus(status), newPlugin);
return Void();
}
}
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, NULL);
return Void();
}
IDrmFactory* HIDL_FETCH_IDrmFactory(const char* /* name */) {
return new DrmFactory();
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,70 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_DRM_V1_0__DRMFACTORY_H
#define ANDROID_HARDWARE_DRM_V1_0__DRMFACTORY_H
#include <android/hardware/drm/1.0/IDrmFactory.h>
#include <hidl/Status.h>
#include <media/drm/DrmAPI.h>
#include <PluginLoader.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
using ::android::hardware::drm::V1_0::helper::PluginLoader;
using ::android::hardware::drm::V1_0::IDrmFactory;
using ::android::hardware::drm::V1_0::IDrmPlugin;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
struct DrmFactory : public IDrmFactory {
DrmFactory();
virtual ~DrmFactory() {}
// Methods from ::android::hardware::drm::V1_0::IDrmFactory follow.
Return<bool> isCryptoSchemeSupported(const hidl_array<uint8_t, 16>& uuid)
override;
Return<bool> isContentTypeSupported(const hidl_string &mimeType)
override;
Return<void> createPlugin(const hidl_array<uint8_t, 16>& uuid,
const hidl_string& appPackageName, createPlugin_cb _hidl_cb) override;
private:
PluginLoader<android::DrmFactory> loader;
DrmFactory(const DrmFactory &) = delete;
void operator=(const DrmFactory &) = delete;
};
extern "C" IDrmFactory* HIDL_FETCH_IDrmFactory(const char* name);
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_DRM_V1_0__DRMFACTORY_H

View file

@ -0,0 +1,435 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-impl"
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include "DrmPlugin.h"
#include "TypeConvert.h"
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
// Methods from ::android::hardware::drm::V1_0::IDrmPlugin follow.
Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
Vector<uint8_t> legacySessionId;
status_t status = mLegacyPlugin->openSession(legacySessionId);
_hidl_cb(toStatus(status), toHidlVec(legacySessionId));
return Void();
}
Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
return toStatus(mLegacyPlugin->closeSession(toVector(sessionId)));
}
Return<void> DrmPlugin::getKeyRequest(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) {
status_t status = android::OK;
android::DrmPlugin::KeyType legacyKeyType;
switch(keyType) {
case KeyType::OFFLINE:
legacyKeyType = android::DrmPlugin::kKeyType_Offline;
break;
case KeyType::STREAMING:
legacyKeyType = android::DrmPlugin::kKeyType_Streaming;
break;
case KeyType::RELEASE:
legacyKeyType = android::DrmPlugin::kKeyType_Release;
break;
default:
status = android::BAD_VALUE;
break;
}
Vector<uint8_t> legacyRequest;
KeyRequestType requestType = KeyRequestType::UNKNOWN;
String8 defaultUrl;
if (status == android::OK) {
android::KeyedVector<String8, String8> legacyOptionalParameters;
for (size_t i = 0; i < optionalParameters.size(); i++) {
legacyOptionalParameters.add(String8(optionalParameters[i].key.c_str()),
String8(optionalParameters[i].value.c_str()));
}
android::DrmPlugin::KeyRequestType legacyRequestType =
android::DrmPlugin::kKeyRequestType_Unknown;
status = mLegacyPlugin->getKeyRequest(toVector(scope),
toVector(initData), String8(mimeType.c_str()), legacyKeyType,
legacyOptionalParameters, legacyRequest, defaultUrl,
&legacyRequestType);
switch(legacyRequestType) {
case android::DrmPlugin::kKeyRequestType_Initial:
requestType = KeyRequestType::INITIAL;
break;
case android::DrmPlugin::kKeyRequestType_Renewal:
requestType = KeyRequestType::RENEWAL;
break;
case android::DrmPlugin::kKeyRequestType_Release:
requestType = KeyRequestType::RELEASE;
break;
case android::DrmPlugin::kKeyRequestType_Unknown:
requestType = KeyRequestType::UNKNOWN;
break;
}
}
_hidl_cb(toStatus(status), toHidlVec(legacyRequest), requestType,
defaultUrl.string());
return Void();
}
Return<void> DrmPlugin::provideKeyResponse(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb) {
Vector<uint8_t> keySetId;
status_t status = mLegacyPlugin->provideKeyResponse(toVector(scope),
toVector(response), keySetId);
_hidl_cb(toStatus(status), toHidlVec(keySetId));
return Void();
}
Return<Status> DrmPlugin::removeKeys(const hidl_vec<uint8_t>& sessionId) {
return toStatus(mLegacyPlugin->removeKeys(toVector(sessionId)));
}
Return<Status> DrmPlugin::restoreKeys(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keySetId) {
status_t legacyStatus = mLegacyPlugin->restoreKeys(toVector(sessionId),
toVector(keySetId));
return toStatus(legacyStatus);
}
Return<void> DrmPlugin::queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) {
android::KeyedVector<String8, String8> legacyInfoMap;
status_t status = mLegacyPlugin->queryKeyStatus(toVector(sessionId),
legacyInfoMap);
Vector<KeyValue> infoMapVec;
for (size_t i = 0; i < legacyInfoMap.size(); i++) {
KeyValue keyValuePair;
keyValuePair.key = String8(legacyInfoMap.keyAt(i));
keyValuePair.value = String8(legacyInfoMap.valueAt(i));
infoMapVec.push_back(keyValuePair);
}
_hidl_cb(toStatus(status), toHidlVec(infoMapVec));
return Void();
}
Return<void> DrmPlugin::getProvisionRequest(
const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) {
Vector<uint8_t> legacyRequest;
String8 legacyDefaultUrl;
status_t status = mLegacyPlugin->getProvisionRequest(
String8(certificateType.c_str()), String8(certificateAuthority.c_str()),
legacyRequest, legacyDefaultUrl);
_hidl_cb(toStatus(status), toHidlVec(legacyRequest),
hidl_string(legacyDefaultUrl));
return Void();
}
Return<void> DrmPlugin::provideProvisionResponse(
const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) {
Vector<uint8_t> certificate;
Vector<uint8_t> wrappedKey;
status_t legacyStatus = mLegacyPlugin->provideProvisionResponse(
toVector(response), certificate, wrappedKey);
_hidl_cb(toStatus(legacyStatus), toHidlVec(certificate),
toHidlVec(wrappedKey));
return Void();
}
Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
List<Vector<uint8_t> > legacySecureStops;
status_t status = mLegacyPlugin->getSecureStops(legacySecureStops);
Vector<SecureStop> secureStopsVec;
List<Vector<uint8_t> >::iterator iter = legacySecureStops.begin();
while (iter != legacySecureStops.end()) {
SecureStop secureStop;
secureStop.opaqueData = toHidlVec(*iter++);
secureStopsVec.push_back(secureStop);
}
_hidl_cb(toStatus(status), toHidlVec(secureStopsVec));
return Void();
}
Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
getSecureStop_cb _hidl_cb) {
Vector<uint8_t> legacySecureStop;
status_t status = mLegacyPlugin->getSecureStop(toVector(secureStopId),
legacySecureStop);
SecureStop secureStop;
secureStop.opaqueData = toHidlVec(legacySecureStop);
_hidl_cb(toStatus(status), secureStop);
return Void();
}
Return<Status> DrmPlugin::releaseAllSecureStops() {
return toStatus(mLegacyPlugin->releaseAllSecureStops());
}
Return<Status> DrmPlugin::releaseSecureStop(
const hidl_vec<uint8_t>& secureStopId) {
status_t legacyStatus =
mLegacyPlugin->releaseSecureStops(toVector(secureStopId));
return toStatus(legacyStatus);
}
Return<void> DrmPlugin::getPropertyString(const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) {
String8 legacyValue;
status_t status = mLegacyPlugin->getPropertyString(
String8(propertyName.c_str()), legacyValue);
_hidl_cb(toStatus(status), legacyValue.string());
return Void();
}
Return<void> DrmPlugin::getPropertyByteArray(const hidl_string& propertyName,
getPropertyByteArray_cb _hidl_cb) {
Vector<uint8_t> legacyValue;
status_t status = mLegacyPlugin->getPropertyByteArray(
String8(propertyName.c_str()), legacyValue);
_hidl_cb(toStatus(status), toHidlVec(legacyValue));
return Void();
}
Return<Status> DrmPlugin::setPropertyString(const hidl_string& propertyName,
const hidl_string& value) {
status_t legacyStatus =
mLegacyPlugin->setPropertyString(String8(propertyName.c_str()),
String8(value.c_str()));
return toStatus(legacyStatus);
}
Return<Status> DrmPlugin::setPropertyByteArray(
const hidl_string& propertyName, const hidl_vec<uint8_t>& value) {
status_t legacyStatus =
mLegacyPlugin->setPropertyByteArray(String8(propertyName.c_str()),
toVector(value));
return toStatus(legacyStatus);
}
Return<Status> DrmPlugin::setCipherAlgorithm(
const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
status_t legacyStatus =
mLegacyPlugin->setCipherAlgorithm(toVector(sessionId),
String8(algorithm.c_str()));
return toStatus(legacyStatus);
}
Return<Status> DrmPlugin::setMacAlgorithm(
const hidl_vec<uint8_t>& sessionId, const hidl_string& algorithm) {
status_t legacyStatus =
mLegacyPlugin->setMacAlgorithm(toVector(sessionId),
String8(algorithm.c_str()));
return toStatus(legacyStatus);
}
Return<void> DrmPlugin::encrypt(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) {
Vector<uint8_t> legacyOutput;
status_t status = mLegacyPlugin->encrypt(toVector(sessionId),
toVector(keyId), toVector(input), toVector(iv), legacyOutput);
_hidl_cb(toStatus(status), toHidlVec(legacyOutput));
return Void();
}
Return<void> DrmPlugin::decrypt(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) {
Vector<uint8_t> legacyOutput;
status_t status = mLegacyPlugin->decrypt(toVector(sessionId),
toVector(keyId), toVector(input), toVector(iv), legacyOutput);
_hidl_cb(toStatus(status), toHidlVec(legacyOutput));
return Void();
}
Return<void> DrmPlugin::sign(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
sign_cb _hidl_cb) {
Vector<uint8_t> legacySignature;
status_t status = mLegacyPlugin->sign(toVector(sessionId),
toVector(keyId), toVector(message), legacySignature);
_hidl_cb(toStatus(status), toHidlVec(legacySignature));
return Void();
}
Return<void> DrmPlugin::verify(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) {
bool match;
status_t status = mLegacyPlugin->verify(toVector(sessionId),
toVector(keyId), toVector(message), toVector(signature),
match);
_hidl_cb(toStatus(status), match);
return Void();
}
Return<void> DrmPlugin::signRSA(const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& wrappedKey, signRSA_cb _hidl_cb) {
Vector<uint8_t> legacySignature;
status_t status = mLegacyPlugin->signRSA(toVector(sessionId),
String8(algorithm.c_str()), toVector(message), toVector(wrappedKey),
legacySignature);
_hidl_cb(toStatus(status), toHidlVec(legacySignature));
return Void();
}
Return<void> DrmPlugin::setListener(const sp<IDrmPluginListener>& listener) {
mListener = listener;
mLegacyPlugin->setListener(listener == NULL ? NULL : this);
return Void();
}
Return<void> DrmPlugin::sendEvent(EventType eventType,
const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data) {
if (mListener != nullptr) {
mListener->sendEvent(eventType, sessionId, data);
}
return Void();
}
Return<void> DrmPlugin::sendExpirationUpdate(
const hidl_vec<uint8_t>& sessionId, int64_t expiryTimeInMS) {
if (mListener != nullptr) {
mListener->sendExpirationUpdate(sessionId, expiryTimeInMS);
}
return Void();
}
Return<void> DrmPlugin::sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) {
if (mListener != nullptr) {
mListener->sendKeysChange(sessionId, keyStatusList, hasNewUsableKey);
}
return Void();
}
// Methods from android::DrmPluginListener
void DrmPlugin::sendEvent(android::DrmPlugin::EventType legacyEventType,
int /*unused*/, Vector<uint8_t> const *sessionId,
Vector<uint8_t> const *data) {
EventType eventType;
bool sendEvent = true;
switch(legacyEventType) {
case android::DrmPlugin::kDrmPluginEventProvisionRequired:
eventType = EventType::PROVISION_REQUIRED;
break;
case android::DrmPlugin::kDrmPluginEventKeyNeeded:
eventType = EventType::KEY_NEEDED;
break;
case android::DrmPlugin::kDrmPluginEventKeyExpired:
eventType = EventType::KEY_EXPIRED;
break;
case android::DrmPlugin::kDrmPluginEventVendorDefined:
eventType = EventType::VENDOR_DEFINED;
break;
case android::DrmPlugin::kDrmPluginEventSessionReclaimed:
eventType = EventType::SESSION_RECLAIMED;
break;
default:
sendEvent = false;
break;
}
if (sendEvent) {
Vector<uint8_t> emptyVector;
mListener->sendEvent(eventType,
toHidlVec(sessionId == NULL ? emptyVector: *sessionId),
toHidlVec(data == NULL ? emptyVector: *data));
}
}
void DrmPlugin::sendExpirationUpdate(Vector<uint8_t> const *sessionId,
int64_t expiryTimeInMS) {
mListener->sendExpirationUpdate(toHidlVec(*sessionId), expiryTimeInMS);
}
void DrmPlugin::sendKeysChange(Vector<uint8_t> const *sessionId,
Vector<android::DrmPlugin::KeyStatus> const *legacyKeyStatusList,
bool hasNewUsableKey) {
Vector<KeyStatus> keyStatusVec;
for (size_t i = 0; i < legacyKeyStatusList->size(); i++) {
const android::DrmPlugin::KeyStatus &legacyKeyStatus =
legacyKeyStatusList->itemAt(i);
KeyStatus keyStatus;
switch(legacyKeyStatus.mType) {
case android::DrmPlugin::kKeyStatusType_Usable:
keyStatus.type = KeyStatusType::USABLE;
break;
case android::DrmPlugin::kKeyStatusType_Expired:
keyStatus.type = KeyStatusType::EXPIRED;
break;
case android::DrmPlugin::kKeyStatusType_OutputNotAllowed:
keyStatus.type = KeyStatusType::OUTPUTNOTALLOWED;
break;
case android::DrmPlugin::kKeyStatusType_StatusPending:
keyStatus.type = KeyStatusType::STATUSPENDING;
break;
case android::DrmPlugin::kKeyStatusType_InternalError:
default:
keyStatus.type = KeyStatusType::INTERNALERROR;
break;
}
keyStatus.keyId = toHidlVec(legacyKeyStatus.mKeyId);
keyStatusVec.push_back(keyStatus);
}
mListener->sendKeysChange(toHidlVec(*sessionId),
toHidlVec(keyStatusVec), hasNewUsableKey);
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,169 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_DRM_V1_0__DRMPLUGIN_H
#define ANDROID_HARDWARE_DRM_V1_0__DRMPLUGIN_H
#include <android/hardware/drm/1.0/IDrmPlugin.h>
#include <android/hardware/drm/1.0/IDrmPluginListener.h>
#include <hidl/Status.h>
#include <media/drm/DrmAPI.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
using ::android::hardware::drm::V1_0::EventType;
using ::android::hardware::drm::V1_0::IDrmPlugin;
using ::android::hardware::drm::V1_0::IDrmPluginListener;
using ::android::hardware::drm::V1_0::KeyRequestType;
using ::android::hardware::drm::V1_0::KeyStatus;
using ::android::hardware::drm::V1_0::KeyType;
using ::android::hardware::drm::V1_0::KeyValue;
using ::android::hardware::drm::V1_0::SecureStop;
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
struct DrmPlugin : public IDrmPlugin, android::DrmPluginListener {
DrmPlugin(android::DrmPlugin *plugin) : mLegacyPlugin(plugin) {}
~DrmPlugin() {delete mLegacyPlugin;}
// Methods from ::android::hardware::drm::V1_0::IDrmPlugin follow.
Return<void> openSession(openSession_cb _hidl_cb) override;
Return<Status> closeSession(const hidl_vec<uint8_t>& sessionId) override;
Return<void> getKeyRequest(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& initData, const hidl_string& mimeType,
KeyType keyType, const hidl_vec<KeyValue>& optionalParameters,
getKeyRequest_cb _hidl_cb) override;
Return<void> provideKeyResponse(const hidl_vec<uint8_t>& scope,
const hidl_vec<uint8_t>& response, provideKeyResponse_cb _hidl_cb)
override;
Return<Status> removeKeys(const hidl_vec<uint8_t>& sessionId) override;
Return<Status> restoreKeys(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keySetId) override;
Return<void> queryKeyStatus(const hidl_vec<uint8_t>& sessionId,
queryKeyStatus_cb _hidl_cb) override;
Return<void> getProvisionRequest(const hidl_string& certificateType,
const hidl_string& certificateAuthority,
getProvisionRequest_cb _hidl_cb) override;
Return<void> provideProvisionResponse(const hidl_vec<uint8_t>& response,
provideProvisionResponse_cb _hidl_cb) override;
Return<void> getSecureStops(getSecureStops_cb _hidl_cb) override;
Return<void> getSecureStop(const hidl_vec<uint8_t>& secureStopId,
getSecureStop_cb _hidl_cb) override;
Return<Status> releaseAllSecureStops() override;
Return<Status> releaseSecureStop(const hidl_vec<uint8_t>& secureStopId)
override;
Return<void> getPropertyString(const hidl_string& propertyName,
getPropertyString_cb _hidl_cb) override;
Return<void> getPropertyByteArray(const hidl_string& propertyName,
getPropertyByteArray_cb _hidl_cb) override;
Return<Status> setPropertyString(const hidl_string& propertyName,
const hidl_string& value) override;
Return<Status> setPropertyByteArray(const hidl_string& propertyName,
const hidl_vec<uint8_t>& value) override;
Return<Status> setCipherAlgorithm(const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<Status> setMacAlgorithm(const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm) override;
Return<void> encrypt(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv, encrypt_cb _hidl_cb) override;
Return<void> decrypt(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& input,
const hidl_vec<uint8_t>& iv, decrypt_cb _hidl_cb) override;
Return<void> sign(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
sign_cb _hidl_cb) override;
Return<void> verify(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<uint8_t>& keyId, const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& signature, verify_cb _hidl_cb) override;
Return<void> signRSA(const hidl_vec<uint8_t>& sessionId,
const hidl_string& algorithm, const hidl_vec<uint8_t>& message,
const hidl_vec<uint8_t>& wrappedkey, signRSA_cb _hidl_cb) override;
Return<void> setListener(const sp<IDrmPluginListener>& listener) override;
Return<void> sendEvent(EventType eventType,
const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& data)
override;
Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
int64_t expiryTimeInMS) override;
Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey)
override;
// Methods from android::DrmPluginListener follow
virtual void sendEvent(android::DrmPlugin::EventType eventType, int extra,
Vector<uint8_t> const *sessionId, Vector<uint8_t> const *data);
virtual void sendExpirationUpdate(Vector<uint8_t> const *sessionId,
int64_t expiryTimeInMS);
virtual void sendKeysChange(Vector<uint8_t> const *sessionId,
Vector<android::DrmPlugin::KeyStatus> const *keyStatusList,
bool hasNewUsableKey);
private:
android::DrmPlugin *mLegacyPlugin;
sp<IDrmPluginListener> mListener;
DrmPlugin() = delete;
DrmPlugin(const DrmPlugin &) = delete;
void operator=(const DrmPlugin &) = delete;
};
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_DRM_V1_0__DRMPLUGIN_H

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LegacyPluginPath.h"
#include <cutils/properties.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
const char* getDrmPluginPath() {
if (property_get_bool("drm.64bit.enabled", false)) {
return "/vendor/lib64/mediadrm";
} else {
return "/vendor/lib/mediadrm";
}
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LEGACY_PLUGIN_PATH_H_
#define LEGACY_PLUGIN_PATH_H_
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
const char* getDrmPluginPath();
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // LEGACY_PLUGIN_PATH_H_

View file

@ -0,0 +1,63 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SharedLibrary.h"
#include <dlfcn.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace helper {
SharedLibrary::SharedLibrary(const String8& path) {
mLibHandle = dlopen(path.string(), RTLD_NOW);
}
SharedLibrary::~SharedLibrary() {
if (mLibHandle != NULL) {
dlclose(mLibHandle);
mLibHandle = NULL;
}
}
bool SharedLibrary::operator!() const {
return mLibHandle == NULL;
}
void* SharedLibrary::lookup(const char* symbol) const {
if (!mLibHandle) {
return NULL;
}
// Clear last error before we load the symbol again,
// in case the caller didn't retrieve it.
(void)dlerror();
return dlsym(mLibHandle, symbol);
}
const char* SharedLibrary::lastError() const {
const char* error = dlerror();
return error ? error : "No errors or unknown error";
}
}
}
}
}
} // namespace android

View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-impl"
#include "TypeConvert.h"
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
Status toStatus(status_t legacyStatus) {
Status status;
switch(legacyStatus) {
case android::OK:
status = Status::OK;
break;
case android::ERROR_DRM_NO_LICENSE:
status = Status::ERROR_DRM_NO_LICENSE;
break;
case android::ERROR_DRM_LICENSE_EXPIRED:
status = Status::ERROR_DRM_LICENSE_EXPIRED;
break;
case android::ERROR_DRM_SESSION_NOT_OPENED:
status = Status::ERROR_DRM_SESSION_NOT_OPENED;
break;
case android::ERROR_DRM_CANNOT_HANDLE:
status = Status::ERROR_DRM_CANNOT_HANDLE;
break;
case android::ERROR_DRM_TAMPER_DETECTED:
status = Status::ERROR_DRM_INVALID_STATE;
break;
case android::BAD_VALUE:
status = Status::BAD_VALUE;
break;
case android::ERROR_DRM_NOT_PROVISIONED:
status = Status::ERROR_DRM_NOT_PROVISIONED;
break;
case android::ERROR_DRM_RESOURCE_BUSY:
status = Status::ERROR_DRM_RESOURCE_BUSY;
break;
case android::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
status = Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
break;
case android::ERROR_DRM_DEVICE_REVOKED:
status = Status::ERROR_DRM_DEVICE_REVOKED;
break;
case android::ERROR_DRM_DECRYPT:
status = Status::ERROR_DRM_DECRYPT;
break;
default:
ALOGW("Unable to convert legacy status: %d, defaulting to UNKNOWN",
legacyStatus);
status = Status::ERROR_DRM_UNKNOWN;
break;
}
return status;
}
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android

View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_HARDWARE_DRM_V1_0_TYPECONVERT
#define ANDROID_HARDWARE_DRM_V1_0_TYPECONVERT
#include <android/hardware/drm/1.0/types.h>
#include <media/stagefright/MediaErrors.h>
#include <utils/Vector.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_vec;
template<typename T> const hidl_vec<T> toHidlVec(const Vector<T> &Vector) {
hidl_vec<T> vec;
vec.setToExternal(const_cast<T *>(Vector.array()), Vector.size());
return vec;
}
template<typename T> hidl_vec<T> toHidlVec(Vector<T> &Vector) {
hidl_vec<T> vec;
vec.setToExternal(Vector.editArray(), Vector.size());
return vec;
}
template<typename T> const Vector<T> toVector(const hidl_vec<T> &vec) {
Vector<T> vector;
vector.appendArray(vec.data(), vec.size());
return *const_cast<const Vector<T> *>(&vector);
}
template<typename T> Vector<T> toVector(hidl_vec<T> &vec) {
Vector<T> vector;
vector.appendArray(vec.data(), vec.size());
return vector;
}
template<typename T, size_t SIZE> const Vector<T> toVector(
const hidl_array<T, SIZE> &array) {
Vector<T> vector;
vector.appendArray(array.data(), array.size());
return vector;
}
template<typename T, size_t SIZE> Vector<T> toVector(
hidl_array<T, SIZE> &array) {
Vector<T> vector;
vector.appendArray(array.data(), array.size());
return vector;
}
Status toStatus(status_t legacyStatus);
} // namespace implementation
} // namespace V1_0
} // namespace drm
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_DRM_V1_0_TYPECONVERT

View file

@ -0,0 +1,6 @@
service drm-hal-1-0 /vendor/bin/hw/android.hardware.drm@1.0-service
class hal
user media
group mediadrm drmrpc
ioprio rt 4
writepid /dev/cpuset/foreground/tasks

View file

@ -0,0 +1,107 @@
/**
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PLUGIN_LOADER_H_
#define PLUGIN_LOADER_H_
#include "SharedLibrary.h"
#include <utils/Log.h>
#include <utils/String8.h>
#include <utils/Vector.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace helper {
template <class T>
class PluginLoader {
public:
PluginLoader(const char *dir, const char *entry) {
/**
* scan all plugins in the plugin directory and add them to the
* factories list.
*/
String8 pluginDir(dir);
DIR* pDir = opendir(pluginDir.string());
if (pDir == NULL) {
ALOGE("Failed to find plugin directory %s", pluginDir.string());
} else {
struct dirent* pEntry;
while ((pEntry = readdir(pDir))) {
String8 file(pEntry->d_name);
if (file.getPathExtension() == ".so") {
String8 path = pluginDir + "/" + pEntry->d_name;
T *plugin = loadOne(path, entry);
if (plugin) {
factories.push(plugin);
}
}
}
closedir(pDir);
}
}
~PluginLoader() {
for (size_t i = 0; i < factories.size(); i++) {
delete factories[i];
}
}
T *getFactory(size_t i) const {
return factories[i];
}
size_t factoryCount() const {return factories.size();}
private:
T* loadOne(const char *path, const char *entry) {
sp<SharedLibrary> library = new SharedLibrary(String8(path));
if (!library.get()) {
ALOGE("Failed to open plugin library %s: %s", path,
library->lastError());
} else {
typedef T *(*CreateFactoryFunc)();
CreateFactoryFunc createFactoryFunc =
(CreateFactoryFunc)library->lookup(entry);
if (createFactoryFunc) {
ALOGV("Found plugin factory entry %s in %s", entry, path);
libraries.push(library);
T* result = createFactoryFunc();
return result;
}
}
return NULL;
}
Vector<T *> factories;
Vector<sp<SharedLibrary> > libraries;
PluginLoader(const PluginLoader &) = delete;
void operator=(const PluginLoader &) = delete;
};
}
}
}
}
} // namespace android
#endif // PLUGIN_LOADER_H_

View file

@ -0,0 +1,51 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SHARED_LIBRARY_H_
#define SHARED_LIBRARY_H_
#include <utils/RefBase.h>
#include <utils/String8.h>
namespace android {
namespace hardware {
namespace drm {
namespace V1_0 {
namespace helper {
class SharedLibrary : public RefBase {
public:
explicit SharedLibrary(const String8& path);
~SharedLibrary();
bool operator!() const;
void* lookup(const char* symbol) const;
const char* lastError() const;
private:
void* mLibHandle;
SharedLibrary(const SharedLibrary&) = delete;
void operator=(const SharedLibrary&) = delete;
};
}
}
}
}
}
#endif // SHARED_LIBRARY_H_

View file

@ -0,0 +1,51 @@
/*
* Copyright 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "android.hardware.drm@1.0-service"
#include <1.0/default/CryptoFactory.h>
#include <1.0/default/DrmFactory.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/LegacySupport.h>
#include <binder/ProcessState.h>
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::registerPassthroughServiceImplementation;
using android::hardware::drm::V1_0::ICryptoFactory;
using android::hardware::drm::V1_0::IDrmFactory;
int main() {
ALOGD("android.hardware.drm@1.0-service starting...");
// The DRM HAL may communicate to other vendor components via
// /dev/vndbinder
android::ProcessState::initWithDriver("/dev/vndbinder");
configureRpcThreadpool(8, true /* callerWillJoin */);
android::status_t status =
registerPassthroughServiceImplementation<IDrmFactory>();
LOG_ALWAYS_FATAL_IF(
status != android::OK,
"Error while registering drm service: %d", status);
status = registerPassthroughServiceImplementation<ICryptoFactory>();
LOG_ALWAYS_FATAL_IF(
status != android::OK,
"Error while registering crypto service: %d", status);
joinRpcThreadpool();
}

View file

@ -0,0 +1,348 @@
/**
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.drm@1.0;
enum Status : uint32_t {
/**
* The DRM plugin must return OK when an operation completes without any
* errors.
*/
OK,
/**
* The DRM plugin must return ERROR_DRM_NO_LICENSE, when decryption is
* attempted and no license keys have been provided.
*/
ERROR_DRM_NO_LICENSE,
/**
* ERROR_DRM_LICENSE_EXPIRED must be returned when an attempt is made
* to use a license and the keys in that license have expired.
*/
ERROR_DRM_LICENSE_EXPIRED,
/**
* The DRM plugin must return ERROR_DRM_SESSION_NOT_OPENED when an
* attempt is made to use a session that has not been opened.
*/
ERROR_DRM_SESSION_NOT_OPENED,
/**
* The DRM plugin must return ERROR_DRM_CANNOT_HANDLE when an unsupported
* data format or operation is attempted.
*/
ERROR_DRM_CANNOT_HANDLE,
/**
* ERROR_DRM_INVALID_STATE must be returned when the device is in a state
* where it is not able to perform decryption.
*/
ERROR_DRM_INVALID_STATE,
/**
* The DRM plugin must return BAD_VALUE whenever an illegal parameter is
* passed to one of the interface functions.
*/
BAD_VALUE,
/**
* The DRM plugin must return ERROR_DRM_NOT_PROVISIONED from getKeyRequest,
* openSession or provideKeyResponse when the device has not yet been
* provisioned.
*/
ERROR_DRM_NOT_PROVISIONED,
/**
* ERROR_DRM_RESOURCE_BUSY must be returned when resources, such as drm
* sessions or secure buffers are not available to perform a requested
* operation because they are already in use.
*/
ERROR_DRM_RESOURCE_BUSY,
/**
* The DRM Plugin must return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION
* when the output protection level enabled on the device is not
* sufficient to meet the requirements in the license policy. HDCP is an
* example of a form of output protection.
*/
ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION,
/**
* The DRM Plugin must return ERROR_DRM_DEVICE_REVOKED from
* provideProvisionResponse and provideKeyResponse if the response indicates
* that the device has been revoked. Device revocation means that the device
* is no longer permitted to play content.
*/
ERROR_DRM_DEVICE_REVOKED,
/**
* The DRM Plugin must return ERROR_DRM_DECRYPT if the CryptoPlugin
* decrypt operation fails.
*/
ERROR_DRM_DECRYPT,
/**
* ERROR_DRM_UNKNOWN must be returned when a fatal failure occurs and no
* other defined error is appropriate.
*/
ERROR_DRM_UNKNOWN,
};
/**
* EventType enumerates the events that can be delivered by sendEvent
*/
enum EventType : uint32_t {
/**
* This event type indicates that the app needs to request a certificate
* from the provisioning server. The request message data is obtained using
* getProvisionRequest().
*/
PROVISION_REQUIRED,
/**
* This event type indicates that the app needs to request keys from a
* license server. The request message data is obtained using getKeyRequest.
*/
KEY_NEEDED,
/**
* This event type indicates that the licensed usage duration for keys in a
* session has expired. The keys are no longer valid.
*/
KEY_EXPIRED,
/**
* This event may indicate some specific vendor-defined condition, see your
* DRM provider documentation for details.
*/
VENDOR_DEFINED,
/**
* This event indicates that a session opened by the app has been reclaimed
* by the resource manager.
*/
SESSION_RECLAIMED,
};
enum KeyType : uint32_t {
/**
* Drm keys can be for offline content or for online streaming.
* Offline keys are persisted on the device and may be used when the device
* is disconnected from the network.
*/
OFFLINE,
/**
* Keys for streaming are not persisted and require the device to be
* connected to the network for periodic renewal.
*/
STREAMING,
/**
* The Release type is used to request that offline keys be no longer
* restricted to offline use.
*/
RELEASE,
};
/**
* Enumerate KeyRequestTypes to allow an app to determine the type of a key
* request returned from getKeyRequest.
*/
enum KeyRequestType : uint32_t {
/**
* Key request type is for an initial license request
*/
INITIAL,
/**
* Key request type is for license renewal. Renewal requests are used
* to extend the validity period for streaming keys.
*/
RENEWAL,
/**
* Key request type is a release. A key release causes offline keys
* to become available for streaming.
*/
RELEASE,
/**
* Key request type is unknown due to some error condition.
*/
UNKNOWN,
};
/**
* Enumerate KeyStatusTypes which indicate the state of a key
*/
enum KeyStatusType : uint32_t {
/**
* The key is currently usable to decrypt media data.
*/
USABLE,
/**
* The key is no longer usable to decrypt media data because its expiration
* time has passed.
*/
EXPIRED,
/**
* The key is not currently usable to decrypt media data because its output
* requirements cannot currently be met.
*/
OUTPUTNOTALLOWED,
/**
* The status of the key is not yet known and is being determined.
*/
STATUSPENDING,
/**
* The key is not currently usable to decrypt media data because of an
* internal error in processing unrelated to input parameters.
*/
INTERNALERROR,
};
typedef vec<uint8_t> SessionId;
/**
* Used by sendKeysChange to report the usability status of each key to the
* app.
*/
struct KeyStatus
{
vec<uint8_t> keyId;
KeyStatusType type;
};
/**
* Simulates a KeyedVector<String8, String8>
*/
struct KeyValue {
string key;
string value;
};
typedef vec<KeyValue> KeyedVector;
/**
* Encapsulates a secure stop opaque object
*/
struct SecureStop {
vec<uint8_t> opaqueData;
};
typedef vec<uint8_t> SecureStopId;
/**
* Enumerate the supported crypto modes
*/
enum Mode : uint32_t {
UNENCRYPTED = 0, // Samples are unencrypted
AES_CTR = 1, // Samples are encrypted with AES CTR mode
AES_CBC_CTS = 2, // Samples are encrypted with AES CBC CTS mode
AES_CBC = 3, // Samples are encrypted with AES CBC mode
};
/**
* A subsample consists of some number of bytes of clear (unencrypted)
* data followed by a number of bytes of encrypted data.
*/
struct SubSample {
uint32_t numBytesOfClearData;
uint32_t numBytesOfEncryptedData;
};
/**
* A crypto Pattern is a repeating sequence of encrypted and clear blocks
* occuring within the bytes indicated by mNumBytesOfEncryptedDatad bytes
* of a subsample. Patterns are used to reduce the CPU overhead of
* decrypting samples. As an example, HLS uses 1:9 patterns where every
* 10th block is encrypted.
*/
struct Pattern {
/**
* The number of blocks to be encrypted in the pattern. If zero,
* pattern encryption is inoperative.
*/
uint32_t encryptBlocks;
/**
* The number of blocks to be skipped (left clear) in the pattern. If
* zero, pattern encryption is inoperative.
*/
uint32_t skipBlocks;
};
enum BufferType : uint32_t {
SHARED_MEMORY = 0,
NATIVE_HANDLE = 1,
};
/**
* SharedBuffer describes a decrypt buffer which is defined by a bufferId, an
* offset and a size. The offset is relative to the shared memory base for the
* memory region identified by bufferId, which is established by
* setSharedMemoryBase().
*/
struct SharedBuffer {
/**
* The unique buffer identifier
*/
uint32_t bufferId;
/**
* The offset from the shared memory base
*/
uint64_t offset;
/**
* The size of the shared buffer in bytes
*/
uint64_t size;
};
/**
* A decrypt destination buffer can be either normal user-space shared
* memory for the non-secure decrypt case, or it can be a secure buffer
* which is referenced by a native-handle. The native handle is allocated
* by the vendor's buffer allocator.
*/
struct DestinationBuffer {
/**
* The type of the buffer
*/
BufferType type;
/**
* If type == SHARED_MEMORY, the decrypted data must be written
* to user-space non-secure shared memory.
*/
SharedBuffer nonsecureMemory;
/**
* If type == NATIVE_HANDLE, the decrypted data must be written
* to secure memory referenced by the vendor's buffer allocator.
*/
handle secureMemory;
};

View file

@ -0,0 +1,35 @@
//
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
cc_test {
name: "VtsHalDrmV1_0TargetTest",
defaults: ["VtsHalTargetTestDefaults"],
srcs: [
"drm_hal_clearkey_test.cpp",
"drm_hal_vendor_test.cpp",
"vendor_modules.cpp"
],
static_libs: [
"android.hardware.drm@1.0",
"android.hardware.drm@1.0-helper",
"android.hidl.allocator@1.0",
"android.hidl.memory@1.0",
"libhidlmemory",
"libnativehelper",
"libssl",
"libcrypto",
],
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,234 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DRM_HAL_VENDOR_MODULE_API_H
#define DRM_HAL_VENDOR_MODULE_API_H
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
/**
* The DRM and Crypto HALs interact with vendor-provided HAL implementations
* that have DRM-specific capabilities. Since the VTS tests cannot contain
* DRM-specific functionality, supporting modules are required to enable VTS
* to validate HAL implementations in a generic way. If the vendor-specific
* VTS module is not provided for a given drm HAL implementation, only very
* small subset of functionality can be verified.
*
* As an example, a DRM HAL implementation interacts with a DRM-specific
* license server to obtain licenses for decrypting content. The DRM HAL
* implementation generates a key request message, delivers it to the server
* and receives a key response message which is then loaded into the HAL. Once
* the keys are loaded, the Crypto HAL decryption functionality and performance
* and other associated APIs can be tested by the common VTS test suite.
*
* Vendor-specific VTS modules are shared libraries used by the DRM VTS test.
* They provide a set of functions to support VTS testing of the DRM HAL module.
*
* The modules are placed in a common location on the file system. The VTS test
* scans through all vendor-provided support libraries and runs the VTS test
* suite on each library that is found.
*
* The vendor-specific module exposes an extern C vendorModuleFactory()
* function that returns a DrmHalVTSVendorModule instance. DrmHalVTSVendorModule
* instances are versioned, where each version is represented by subclass of
* DrmHalVTSVendorModule that corresponds to the API version. For example, a
* vendor-specific module that implements version 1 of the API would return a
* DrmHalVTSVendorModule_V1 from the vendorModuleFactory() function.
*/
class DrmHalVTSVendorModule;
extern "C" {
/**
* The factory method for creating DrmHalVTSVendorModule instances. The returned
* instance will be a subclass of DrmHalVTSVendorModule that corresponds to the
* supported API version.
*/
DrmHalVTSVendorModule* vendorModuleFactory();
};
class DrmHalVTSVendorModule {
public:
DrmHalVTSVendorModule() : installed(true) {}
virtual ~DrmHalVTSVendorModule() {}
/**
* Return the vendor-specific module API version. The version is an integer
* value with initial version 1. The API version indicates which subclass
* version DrmHalVTSVendorModule this instance is.
*/
virtual uint32_t getAPIVersion() const = 0;
/**
* Return the UUID for the DRM HAL implementation. Protection System
* Specific
* UUID (see http://dashif.org/identifiers/protection/)
*/
virtual std::vector<uint8_t> getUUID() const = 0;
/**
* Return the service name for the DRM HAL implementation. If the hal is a
* legacy
* drm plugin, i.e. not running as a HIDL service, return the empty string.
*/
virtual std::string getServiceName() const = 0;
/**
* Set a flag in the vendor module to indicate whether or not the drm
* scheme corresponding to this module is installed on the device.
*/
void setInstalled(bool flag) {installed = flag;}
bool isInstalled() const {return installed;}
private:
bool installed;
DrmHalVTSVendorModule(const DrmHalVTSVendorModule&) = delete;
void operator=(const DrmHalVTSVendorModule&) = delete;
};
/**
* API Version 1. This is the baseline version that supports a minimal set
* of VTS tests.
*/
class DrmHalVTSVendorModule_V1 : public DrmHalVTSVendorModule {
public:
DrmHalVTSVendorModule_V1() {}
virtual ~DrmHalVTSVendorModule_V1() {}
virtual uint32_t getAPIVersion() const { return 1; }
/**
* Handle a provisioning request. This function will be called if the HAL
* module's getProvisionRequest returns a provision request. The vendor
* module should process the provisioning request, either by sending it
* to a provisioning server, or generating a mock response. The resulting
* provisioning response is returned to the VTS test.
*
* @param provisioningRequest the provisioning request recieved from
* the DRM HAL
* @param url the default url the HAL implementation provided with the
* provisioning request
* @return the generated provisioning response
*/
virtual std::vector<uint8_t> handleProvisioningRequest(
const std::vector<uint8_t>& provisioningRequest,
const std::string& url) = 0;
/**
* Content configuration specifies content-specific parameters associated
* with a key request/response transaction. It allows the VTS test to
* request keys and use them to perform decryption.
*/
struct ContentConfiguration {
/**
* Assign a name for this configuration that will be referred to
* in log messages.
*/
const std::string name;
/**
* Server to use when requesting a key response. This url will be
* passed as a parameter to the vendor vts module along with the
* key request to perform the key request transaction.
*/
const std::string serverUrl;
/**
* Initialization data provided to getKeyRequest, e.g. PSSH for CENC
* content
*/
const std::vector<uint8_t> initData;
/**
* Mime type provided to getKeyRequest, e.g. "video/mp4", or "cenc"
*/
const std::string mimeType;
/**
* Optional parameters to be associated with the key request
*/
const std::map<std::string, std::string> optionalParameters;
/**
* Define license policy attributes for the content configuration.
* These attributes can affect which tests are able to be applied.
*/
struct Policy {
/**
* Indicate if the license policy allows offline playback.
* Content configurated with this policy supports KeyType::OFFLINE
* key requests/responses. A vendor module should provide at least
* one content configuration where allowOffline is true if the drm
* scheme supports offline content.
*/
bool allowOffline;
} policy;
/**
* The keys that will be available once the keys are loaded
*/
struct Key {
/**
* Indicate if the key content is configured to require secure
* buffers, where the output buffers are protected and cannot be
* accessed by the non-secure cpu. A vendor module should provide
* at least one content configurations where isSecure is false, to
* allow decrypt result verification tests to be run.
*/
bool isSecure;
/**
* A key ID identifies a key to use for decryption
*/
const std::vector<uint8_t> keyId;
/**
* The clear content key is provided to generate expected values for
* validating decryption.
*/
const std::vector<uint8_t> clearContentKey;
};
std::vector<Key> keys;
};
/**
* Return a list of content configurations that can be exercised by the
* VTS test.
*/
virtual std::vector<ContentConfiguration>
getContentConfigurations() const = 0;
/**
* Handle a key request. This function will be called if the HAL
* module's getKeyRequest returns a key request. The vendor
* module should process the key request, either by sending it
* to a license server, or by generating a mock response. The resulting
* key response is returned to the VTS test.
*
* @param keyRequest the key request recieved from the DRM HAL
* @param serverUrl the url of the key server that was supplied
* by the ContentConfiguration
* @return the generated key response
*/
virtual std::vector<uint8_t> handleKeyRequest(
const std::vector<uint8_t>& keyRequest,
const std::string& serverUrl) = 0;
};
#endif // DRM_HAL_VENDOR_MODULE_API_H

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "drm-vts-vendor-modules"
#include <dirent.h>
#include <dlfcn.h>
#include <log/log.h>
#include <memory>
#include <utils/String8.h>
#include <SharedLibrary.h>
#include "vendor_modules.h"
using std::string;
using std::vector;
using std::unique_ptr;
using ::android::String8;
using ::android::hardware::drm::V1_0::helper::SharedLibrary;
namespace drm_vts {
void VendorModules::scanModules(const std::string &directory) {
DIR* dir = opendir(directory.c_str());
if (dir == NULL) {
ALOGE("Unable to open drm VTS vendor directory %s", directory.c_str());
} else {
struct dirent* entry;
while ((entry = readdir(dir))) {
ALOGD("checking file %s", entry->d_name);
string fullpath = directory + "/" + entry->d_name;
if (endsWith(fullpath, ".so")) {
mPathList.push_back(fullpath);
}
}
closedir(dir);
}
}
DrmHalVTSVendorModule* VendorModules::getModule(const string& path) {
if (mOpenLibraries.find(path) == mOpenLibraries.end()) {
auto library = std::make_unique<SharedLibrary>(String8(path.c_str()));
if (!library) {
ALOGE("failed to map shared library %s", path.c_str());
return NULL;
}
mOpenLibraries[path] = std::move(library);
}
const unique_ptr<SharedLibrary>& library = mOpenLibraries[path];
void* symbol = library->lookup("vendorModuleFactory");
if (symbol == NULL) {
ALOGE("getVendorModule failed to lookup 'vendorModuleFactory' in %s: "
"%s", path.c_str(), library->lastError());
return NULL;
}
typedef DrmHalVTSVendorModule* (*ModuleFactory)();
ModuleFactory moduleFactory = reinterpret_cast<ModuleFactory>(symbol);
return (*moduleFactory)();
}
};

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef VENDOR_MODULES_H
#define VENDOR_MODULES_H
#include <map>
#include <vector>
#include <string>
#include <SharedLibrary.h>
using ::android::hardware::drm::V1_0::helper::SharedLibrary;
class DrmHalVTSVendorModule;
namespace drm_vts {
class VendorModules {
public:
/**
* Initialize with a file system path where the shared libraries
* are to be found.
*/
explicit VendorModules(const std::string& dir) {
scanModules(dir);
}
~VendorModules() {}
/**
* Retrieve a DrmHalVTSVendorModule given its full path. The
* getAPIVersion method can be used to determine the versioned
* subclass type.
*/
DrmHalVTSVendorModule* getModule(const std::string& path);
/**
* Return the list of paths to available vendor modules.
*/
std::vector<std::string> getPathList() const {return mPathList;}
private:
std::vector<std::string> mPathList;
std::map<std::string, std::unique_ptr<SharedLibrary>> mOpenLibraries;
/**
* Scan the list of paths to available vendor modules.
*/
void scanModules(const std::string& dir);
inline bool endsWith(const std::string& str, const std::string& suffix) const {
if (suffix.size() > str.size()) return false;
return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());
}
VendorModules(const VendorModules&) = delete;
void operator=(const VendorModules&) = delete;
};
};
#endif // VENDOR_MODULES_H