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 protected: 89 90 // Message types for the looper 91 enum : uint32_t { 92 // used with decrypt() 93 // Exact decryption type as described by the above enum 94 // decides what "action" to take. The "action" should be 95 // part of this message 96 kWhatDecrypt = 1, 97 // used with stop() 98 kWhatStop = 2, 99 // place holder 100 kWhatDoNothing = 10 101 }; 102 103 // Defines the staste of this thread. 104 typedef enum : uint32_t { 105 // kCryptoAsyncActive as long as we have not encountered 106 // any errors during processing. Any errors will 107 // put the state to error and the thread now refuses to 108 // do further processing until the error state is cleared 109 // with a call to stop() 110 111 kCryptoAsyncActive = (0 << 0), 112 // state of the looper when encountered with error during 113 // processing 114 kCryptoAsyncError = (1 << 8) 115 } CryptoAsyncState; 116 117 // Implements kActionDecrypt 118 status_t decryptAndQueue(sp<AMessage>& msg); 119 120 // Implements kActionAttachEncryptedBuffer 121 status_t attachEncryptedBufferAndQueue(sp<AMessage>& msg); 122 123 // Implements the Looper 124 void onMessageReceived(const sp<AMessage>& msg) override; 125 126 std::unique_ptr<CryptoAsyncCallback> mCallback; 127 private: 128 129 CryptoAsyncState mState; 130 131 // Queue holding any pending buffers 132 Mutexed<std::list<sp<AMessage>>> mPendingBuffers; 133 134 std::weak_ptr<BufferChannelBase> mBufferChannel; 135 }; 136 137 } // namespace android 138 139 #endif // CRYPTO_ASYNC_H_ 140