blob: acb3daef51da6d0f2ea2751be221f75f35c7c0f7 [file] [log] [blame]
/*
* Copyright 2022 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 CRYPTO_ASYNC_H_
#define CRYPTO_ASYNC_H_
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/foundation/Mutexed.h>
namespace android {
class CryptoAsync: public AHandler {
public:
class CryptoAsyncCallback {
public:
virtual ~CryptoAsyncCallback() = default;
/*
* Callback with result for queuing the decrypted buffer to the
* underlying codec. Cannot block this function
*/
virtual void onDecryptComplete(const sp<AMessage>& result) = 0;
/*
* Callback with error information while decryption. Cannot block
* this call. The return should contain the error information
* and the buffer the caused the error.
*/
virtual void onDecryptError(const std::list<sp<AMessage>>& errorMsg) = 0;
};
// Ideally we should be returning the output of the decryption in
// onDecryptComple() calback and let the next module take over the
// rest of the processing. In the current state, the next step will
// be to queue the output the codec which is done using BufferChannel
// In order to prevent thread hop to just do that, we have created
// a dependency on BufferChannel here to queue the buffer to the codec
// immediately after decryption.
CryptoAsync(std::weak_ptr<BufferChannelBase> bufferChannel)
:mState(kCryptoAsyncActive) {
mBufferChannel = std::move(bufferChannel);
}
// Destructor
virtual ~CryptoAsync();
inline void setCallback(std::unique_ptr<CryptoAsyncCallback>&& callback) {
mCallback = std::move(callback);
}
// Call this function to decrypt the buffer in the message.
status_t decrypt(sp<AMessage>& msg);
// This function stops further processing in the thread and returns
// with any unprocessed buffers from the queue.
// We can use this method in case of flush or clearing the queue
// upon error. When the processing hits an error, the self processing
// in this looper stops and in-fact., there is a need to clear (call stop())
// for the queue to become operational again. Also acts like a rest.
void stop(std::list<sp<AMessage>> * const buffers = nullptr);
// Describes two actions for decrypt();
// kActionDecrypt - decrypts the buffer and queues to codec
// kActionAttachEncryptedBuffer - decrypts and attaches the buffer
// and queues to the codec.
// TODO: kActionAttachEncryptedBuffer is meant to work with
// BLOCK_MODEL which is not yet implemented.
enum : uint32_t {
// decryption types
kActionDecrypt = (1 << 0),
kActionAttachEncryptedBuffer = (1 << 1)
};
// This struct is meant to copy the mapped contents from the original info.
struct CryptoAsyncInfo : public CodecCryptoInfo {
public:
explicit CryptoAsyncInfo(const std::unique_ptr<CodecCryptoInfo> &info);
virtual ~CryptoAsyncInfo() = default;
protected:
// all backup buffers for the base object.
sp<ABuffer> mKeyBuffer;
sp<ABuffer> mIvBuffer;
sp<ABuffer> mSubSamplesBuffer;
};
protected:
// Message types for the looper
enum : uint32_t {
// used with decrypt()
// Exact decryption type as described by the above enum
// decides what "action" to take. The "action" should be
// part of this message
kWhatDecrypt = 1,
// used with stop()
kWhatStop = 2,
// place holder
kWhatDoNothing = 10
};
// Defines the staste of this thread.
typedef enum : uint32_t {
// kCryptoAsyncActive as long as we have not encountered
// any errors during processing. Any errors will
// put the state to error and the thread now refuses to
// do further processing until the error state is cleared
// with a call to stop()
kCryptoAsyncActive = (0 << 0),
// state of the looper when encountered with error during
// processing
kCryptoAsyncError = (1 << 8)
} CryptoAsyncState;
// Implements kActionDecrypt
status_t decryptAndQueue(sp<AMessage>& msg);
// Implements kActionAttachEncryptedBuffer
status_t attachEncryptedBufferAndQueue(sp<AMessage>& msg);
// Implements the Looper
void onMessageReceived(const sp<AMessage>& msg) override;
std::unique_ptr<CryptoAsyncCallback> mCallback;
private:
CryptoAsyncState mState;
// Queue holding any pending buffers
Mutexed<std::list<sp<AMessage>>> mPendingBuffers;
std::weak_ptr<BufferChannelBase> mBufferChannel;
};
} // namespace android
#endif // CRYPTO_ASYNC_H_