1 /* 2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef CRYPTO_ASYNC_H_ 18 #define CRYPTO_ASYNC_H_ 19 20 #include <media/stagefright/CodecBase.h> 21 #include <media/stagefright/foundation/Mutexed.h> 22 namespace android { 23 24 class CryptoAsync: public AHandler { 25 public: 26 27 class CryptoAsyncCallback { 28 public: 29 30 virtual ~CryptoAsyncCallback() = default; 31 32 /* 33 * Callback with result for queuing the decrypted buffer to the 34 * underlying codec. Cannot block this function 35 */ 36 virtual void onDecryptComplete(const sp<AMessage>& result) = 0; 37 38 /* 39 * Callback with error information while decryption. Cannot block 40 * this call. The return should contain the error information 41 * and the buffer the caused the error. 42 */ 43 virtual void onDecryptError(const std::list<sp<AMessage>>& errorMsg) = 0; 44 }; 45 46 // Ideally we should be returning the output of the decryption in 47 // onDecryptComple() calback and let the next module take over the 48 // rest of the processing. In the current state, the next step will 49 // be to queue the output the codec which is done using BufferChannel 50 51 // In order to prevent thread hop to just do that, we have created 52 // a dependency on BufferChannel here to queue the buffer to the codec 53 // immediately after decryption. CryptoAsync(std::weak_ptr<BufferChannelBase> bufferChannel)54 CryptoAsync(std::weak_ptr<BufferChannelBase> bufferChannel) 55 :mState(kCryptoAsyncActive) { 56 mBufferChannel = std::move(bufferChannel); 57 } 58 59 // Destructor 60 virtual ~CryptoAsync(); 61 setCallback(std::unique_ptr<CryptoAsyncCallback> && callback)62 inline void setCallback(std::unique_ptr<CryptoAsyncCallback>&& callback) { 63 mCallback = std::move(callback); 64 } 65 66 // Call this function to decrypt the buffer in the message. 67 status_t decrypt(sp<AMessage>& msg); 68 69 // This function stops further processing in the thread and returns 70 // with any unprocessed buffers from the queue. 71 // We can use this method in case of flush or clearing the queue 72 // upon error. When the processing hits an error, the self processing 73 // in this looper stops and in-fact., there is a need to clear (call stop()) 74 // for the queue to become operational again. Also acts like a rest. 75 void stop(std::list<sp<AMessage>> * const buffers = nullptr); 76 77 // Describes two actions for decrypt(); 78 // kActionDecrypt - decrypts the buffer and queues to codec 79 // kActionAttachEncryptedBuffer - decrypts and attaches the buffer 80 // and queues to the codec. 81 // TODO: kActionAttachEncryptedBuffer is meant to work with 82 // BLOCK_MODEL which is not yet implemented. 83 enum : uint32_t { 84 // decryption types 85 kActionDecrypt = (1 << 0), 86 kActionAttachEncryptedBuffer = (1 << 1) 87 }; 88 89 // This struct is meant to copy the mapped contents from the original info. 90 struct CryptoAsyncInfo : public CodecCryptoInfo { 91 public: 92 explicit CryptoAsyncInfo(const std::unique_ptr<CodecCryptoInfo> &info); 93 virtual ~CryptoAsyncInfo() = default; 94 protected: 95 // all backup buffers for the base object. 96 sp<ABuffer> mKeyBuffer; 97 sp<ABuffer> mIvBuffer; 98 sp<ABuffer> mSubSamplesBuffer; 99 }; 100 protected: 101 102 // Message types for the looper 103 enum : uint32_t { 104 // used with decrypt() 105 // Exact decryption type as described by the above enum 106 // decides what "action" to take. The "action" should be 107 // part of this message 108 kWhatDecrypt = 1, 109 // used with stop() 110 kWhatStop = 2, 111 // place holder 112 kWhatDoNothing = 10 113 }; 114 115 // Defines the staste of this thread. 116 typedef enum : uint32_t { 117 // kCryptoAsyncActive as long as we have not encountered 118 // any errors during processing. Any errors will 119 // put the state to error and the thread now refuses to 120 // do further processing until the error state is cleared 121 // with a call to stop() 122 123 kCryptoAsyncActive = (0 << 0), 124 // state of the looper when encountered with error during 125 // processing 126 kCryptoAsyncError = (1 << 8) 127 } CryptoAsyncState; 128 129 // Implements kActionDecrypt 130 status_t decryptAndQueue(sp<AMessage>& msg); 131 132 // Implements kActionAttachEncryptedBuffer 133 status_t attachEncryptedBufferAndQueue(sp<AMessage>& msg); 134 135 // Implements the Looper 136 void onMessageReceived(const sp<AMessage>& msg) override; 137 138 std::unique_ptr<CryptoAsyncCallback> mCallback; 139 private: 140 141 CryptoAsyncState mState; 142 143 // Queue holding any pending buffers 144 Mutexed<std::list<sp<AMessage>>> mPendingBuffers; 145 146 std::weak_ptr<BufferChannelBase> mBufferChannel; 147 }; 148 149 } // namespace android 150 151 #endif // CRYPTO_ASYNC_H_ 152