blob: 333dea61db92a0399e140c2dc176442a5152011c [file] [log] [blame]
Henry Fang9bed3dc2019-10-11 17:30:15 -07001/*
2 * Copyright (C) 2019 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#define LOG_TAG "mediacas_hidl_hal_test"
18
Henry Fang9bed3dc2019-10-11 17:30:15 -070019#include <android-base/logging.h>
20#include <android/hardware/cas/1.0/IDescramblerBase.h>
21#include <android/hardware/cas/1.0/types.h>
22#include <android/hardware/cas/1.2/ICas.h>
23#include <android/hardware/cas/1.2/ICasListener.h>
24#include <android/hardware/cas/1.2/IMediaCasService.h>
25#include <android/hardware/cas/1.2/types.h>
26#include <android/hardware/cas/native/1.0/IDescrambler.h>
27#include <android/hardware/cas/native/1.0/types.h>
28#include <binder/MemoryDealer.h>
Henry Fang93470542020-03-10 14:29:36 -070029#include <gtest/gtest.h>
30#include <hidl/GtestPrinter.h>
Henry Fang9bed3dc2019-10-11 17:30:15 -070031#include <hidl/HidlSupport.h>
32#include <hidl/HidlTransportSupport.h>
Henry Fang93470542020-03-10 14:29:36 -070033#include <hidl/ServiceManagement.h>
Henry Fang9bed3dc2019-10-11 17:30:15 -070034#include <hidl/Status.h>
35#include <hidlmemory/FrameworkUtils.h>
36#include <utils/Condition.h>
37#include <utils/Mutex.h>
38
39#define CLEAR_KEY_SYSTEM_ID 0xF6D8
40#define INVALID_SYSTEM_ID 0
41#define WAIT_TIMEOUT 3000000000
42
43#define PROVISION_STR \
44 "{ " \
45 " \"id\": 21140844, " \
46 " \"name\": \"Test Title\", " \
47 " \"lowercase_organization_name\": \"Android\", " \
48 " \"asset_key\": { " \
49 " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \
50 " }, " \
51 " \"cas_type\": 1, " \
52 " \"track_types\": [ ] " \
53 "} "
54
55using android::Condition;
56using android::IMemory;
57using android::IMemoryHeap;
58using android::MemoryDealer;
59using android::Mutex;
60using android::sp;
61using android::hardware::fromHeap;
62using android::hardware::hidl_string;
63using android::hardware::hidl_vec;
64using android::hardware::HidlMemory;
65using android::hardware::Return;
66using android::hardware::Void;
67using android::hardware::cas::native::V1_0::BufferType;
68using android::hardware::cas::native::V1_0::DestinationBuffer;
69using android::hardware::cas::native::V1_0::IDescrambler;
70using android::hardware::cas::native::V1_0::ScramblingControl;
71using android::hardware::cas::native::V1_0::SharedBuffer;
72using android::hardware::cas::native::V1_0::SubSample;
73using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
74using android::hardware::cas::V1_0::IDescramblerBase;
75using android::hardware::cas::V1_0::Status;
76using android::hardware::cas::V1_2::ICas;
77using android::hardware::cas::V1_2::ICasListener;
78using android::hardware::cas::V1_2::IMediaCasService;
79using android::hardware::cas::V1_2::ScramblingMode;
80using android::hardware::cas::V1_2::SessionIntent;
81using android::hardware::cas::V1_2::StatusEvent;
82
83namespace {
84
85const uint8_t kEcmBinaryBuffer[] = {
86 0x00, 0x00, 0x01, 0xf0, 0x00, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00,
87 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00,
88 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0x0e, 0xe3, 0x91, 0xbc, 0xfd, 0x05, 0xb1, 0x60, 0x4f,
89 0x17, 0x82, 0xa4, 0x86, 0x9b, 0x23, 0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
90 0x27, 0x10, 0x02, 0x00, 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0xd7, 0x43, 0x62, 0xf8, 0x1c,
91 0x62, 0x19, 0x05, 0xc7, 0x3a, 0x42, 0xcd, 0xfd, 0xd9, 0x13, 0x48,
92};
93
94const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
95
96const uint8_t kInBinaryBuffer[] = {
97 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
98 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
99 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
100 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
101 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
102 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
103 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
104 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
105 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
106 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
107 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x6e, 0x45, 0x21,
108 0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87, 0x8f, 0x04, 0x49, 0xe5,
109 0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04, 0x7e, 0x60, 0x5b,
110 0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14, 0x08, 0xcb,
111 0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d, 0xe3,
112 0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
113 0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c,
114 0xe1, 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7,
115 0x45, 0x58, 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03,
116 0xaa, 0xe4, 0x32, 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49,
117 0xc8, 0xbf, 0xca, 0x8c, 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e,
118 0xb3, 0x2d, 0x1f, 0xb8, 0x35, 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72,
119 0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1, 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d,
120 0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54, 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e,
121 0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e, 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a,
122 0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b, 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46,
123 0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47, 0x6a, 0x12, 0xfa, 0xc4, 0x33,
124 0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa, 0x8e, 0xf1, 0xbc, 0x3d,
125 0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f, 0x25, 0x24, 0x7c,
126 0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73, 0xb1, 0x53,
127 0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d, 0xb4,
128 0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
129 0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0,
130 0xe3, 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46,
131 0x7c, 0x75, 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0,
132 0xc5, 0x4c, 0x24, 0x0e, 0x65,
133};
134
135const uint8_t kOutRefBinaryBuffer[] = {
136 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
137 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
138 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
139 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
140 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
141 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
142 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
143 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
144 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
145 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
146 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
147 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
148 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
149 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
150 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
151 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
152 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
153 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
154 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
155 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
156 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
157 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
158 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
159 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
160 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
161 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
162 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
163 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
164 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
165 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
166 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
167 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
168 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
169 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
170 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
171 0x73, 0x63, 0x65, 0x6e, 0x65,
172};
173
174class MediaCasListener : public ICasListener {
175 public:
176 virtual Return<void> onEvent(int32_t event, int32_t arg,
177 const hidl_vec<uint8_t>& data) override {
178 android::Mutex::Autolock autoLock(mMsgLock);
179 mEvent = event;
180 mEventArg = arg;
181 mEventData = data;
182
183 mEventReceived = true;
184 mMsgCondition.signal();
185 return Void();
186 }
187
188 virtual Return<void> onSessionEvent(const hidl_vec<uint8_t>& sessionId, int32_t event,
189 int32_t arg, const hidl_vec<uint8_t>& data) override {
190 android::Mutex::Autolock autoLock(mMsgLock);
191 mSessionId = sessionId;
192 mEvent = event;
193 mEventArg = arg;
194 mEventData = data;
195
196 mEventReceived = true;
197 mMsgCondition.signal();
198 return Void();
199 }
200
201 virtual Return<void> onStatusUpdate(StatusEvent event, int32_t arg) override {
202 android::Mutex::Autolock autoLock(mMsgLock);
203 mStatusEvent = event;
204 mEventArg = arg;
205
206 mEventReceived = true;
207 mMsgCondition.signal();
208 return Void();
209 }
210
211 void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
212 hidl_vec<uint8_t>& eventData);
213
214 void testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
215 int32_t& event, int32_t& eventArg, hidl_vec<uint8_t>& eventData);
216
217 void testStatusUpdate(sp<ICas>& mediaCas, std::vector<uint8_t>* sessionId, SessionIntent intent,
218 ScramblingMode mode);
219
220 private:
221 int32_t mEvent = -1;
222 int32_t mEventArg = -1;
223 StatusEvent mStatusEvent;
224 bool mEventReceived = false;
225 hidl_vec<uint8_t> mEventData;
226 hidl_vec<uint8_t> mSessionId;
227 android::Mutex mMsgLock;
228 android::Condition mMsgCondition;
229};
230
231void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
232 hidl_vec<uint8_t>& eventData) {
233 mEventReceived = false;
234 auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
235 EXPECT_TRUE(returnStatus.isOk());
236 EXPECT_EQ(Status::OK, returnStatus);
237
238 android::Mutex::Autolock autoLock(mMsgLock);
239 while (!mEventReceived) {
240 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
241 EXPECT_TRUE(false) << "event not received within timeout";
242 return;
243 }
244 }
245
246 EXPECT_EQ(mEvent, event);
247 EXPECT_EQ(mEventArg, eventArg);
248 EXPECT_TRUE(mEventData == eventData);
249}
250
251void MediaCasListener::testSessionEventEcho(sp<ICas>& mediaCas, const hidl_vec<uint8_t>& sessionId,
252 int32_t& event, int32_t& eventArg,
253 hidl_vec<uint8_t>& eventData) {
254 mEventReceived = false;
255 auto returnStatus = mediaCas->sendSessionEvent(sessionId, event, eventArg, eventData);
256 EXPECT_TRUE(returnStatus.isOk());
257 EXPECT_EQ(Status::OK, returnStatus);
258
259 android::Mutex::Autolock autoLock(mMsgLock);
260 while (!mEventReceived) {
261 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
262 EXPECT_TRUE(false) << "event not received within timeout";
263 return;
264 }
265 }
266
267 EXPECT_TRUE(mSessionId == sessionId);
268 EXPECT_EQ(mEvent, event);
269 EXPECT_EQ(mEventArg, eventArg);
270 EXPECT_TRUE(mEventData == eventData);
271}
272
273void MediaCasListener::testStatusUpdate(sp<ICas>& mediaCas, std::vector<uint8_t>* sessionId,
274 SessionIntent intent, ScramblingMode mode) {
275 mEventReceived = false;
276 android::hardware::cas::V1_2::Status sessionStatus;
277 auto returnVoid = mediaCas->openSession_1_2(
278 intent, mode,
279 [&](android::hardware::cas::V1_2::Status status, const hidl_vec<uint8_t>& id) {
280 sessionStatus = status;
281 *sessionId = id;
282 });
283 EXPECT_TRUE(returnVoid.isOk());
284 EXPECT_EQ(android::hardware::cas::V1_2::Status::OK, sessionStatus);
285
286 android::Mutex::Autolock autoLock(mMsgLock);
287 while (!mEventReceived) {
288 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
289 EXPECT_TRUE(false) << "event not received within timeout";
290 return;
291 }
292 }
293 EXPECT_EQ(mStatusEvent, static_cast<StatusEvent>(intent));
294 EXPECT_EQ(mEventArg, static_cast<int32_t>(mode));
295}
296
Henry Fang93470542020-03-10 14:29:36 -0700297class MediaCasHidlTest : public testing::TestWithParam<std::string> {
Henry Fang9bed3dc2019-10-11 17:30:15 -0700298 public:
299 virtual void SetUp() override {
Henry Fang93470542020-03-10 14:29:36 -0700300 mService = IMediaCasService::getService(GetParam());
Henry Fang9bed3dc2019-10-11 17:30:15 -0700301 ASSERT_NE(mService, nullptr);
302 }
303
Henry Fang93470542020-03-10 14:29:36 -0700304 sp<IMediaCasService> mService = nullptr;
Henry Fang9bed3dc2019-10-11 17:30:15 -0700305
306 protected:
307 static void description(const std::string& description) {
308 RecordProperty("description", description);
309 }
310
311 sp<ICas> mMediaCas;
312 sp<IDescramblerBase> mDescramblerBase;
313 sp<MediaCasListener> mCasListener;
Henry Fang8964b852021-01-08 16:09:08 -0800314 bool mIsTestDescrambler = false;
Henry Fang9bed3dc2019-10-11 17:30:15 -0700315 typedef struct _OobInputTestParams {
316 const SubSample* subSamples;
317 uint32_t numSubSamples;
318 size_t imemSizeActual;
319 uint64_t imemOffset;
320 uint64_t imemSize;
321 uint64_t srcOffset;
322 uint64_t dstOffset;
323 } OobInputTestParams;
324
325 ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
326 ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
327 ::testing::AssertionResult openCasSession_1_2(std::vector<uint8_t>* sessionId,
328 SessionIntent intent, ScramblingMode mode);
329 ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
330 Status* descrambleStatus,
331 sp<IMemory>* hidlInMemory);
332 ::testing::AssertionResult descrambleTestOobInput(const sp<IDescrambler>& descrambler,
333 Status* descrambleStatus,
334 const OobInputTestParams& params);
335};
336
337::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
338 auto status = mService->isSystemIdSupported(caSystemId);
339 if (!status.isOk() || !status) {
340 return ::testing::AssertionFailure();
341 }
342 status = mService->isDescramblerSupported(caSystemId);
343 if (!status.isOk() || !status) {
344 return ::testing::AssertionFailure();
345 }
346
347 mCasListener = new MediaCasListener();
348 auto pluginStatus = mService->createPluginExt(caSystemId, mCasListener);
349 if (!pluginStatus.isOk()) {
350 return ::testing::AssertionFailure();
351 }
352 mMediaCas = ICas::castFrom(pluginStatus);
353 if (mMediaCas == nullptr) {
354 return ::testing::AssertionFailure();
355 }
356
357 auto descramblerStatus = mService->createDescrambler(caSystemId);
358 if (!descramblerStatus.isOk()) {
Henry Fang8964b852021-01-08 16:09:08 -0800359 ALOGI("Skip Descrambler test since it's not required in cas@1.2.");
360 return ::testing::AssertionSuccess();
Henry Fang9bed3dc2019-10-11 17:30:15 -0700361 }
Henry Fang8964b852021-01-08 16:09:08 -0800362 mIsTestDescrambler = true;
363
Henry Fang9bed3dc2019-10-11 17:30:15 -0700364 mDescramblerBase = descramblerStatus;
365 return ::testing::AssertionResult(mDescramblerBase != nullptr);
366}
367
368::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
369 Status sessionStatus;
370 auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
371 sessionStatus = status;
372 *sessionId = id;
373 });
374 return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
375}
376
377::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
378 const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
379 hidl_vec<SubSample> hidlSubSamples;
380 hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
381 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
382
383 sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
384 if (nullptr == dealer.get()) {
385 ALOGE("couldn't get MemoryDealer!");
386 return ::testing::AssertionFailure();
387 }
388
389 sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
390 if (nullptr == mem.get()) {
391 ALOGE("couldn't allocate IMemory!");
392 return ::testing::AssertionFailure();
393 }
394 *inMemory = mem;
395
396 // build HidlMemory from memory heap
397 ssize_t offset;
398 size_t size;
399 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
400 if (nullptr == heap.get()) {
401 ALOGE("couldn't get memory heap!");
402 return ::testing::AssertionFailure();
403 }
404
405 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->unsecurePointer()));
406 memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
407
408 // hidlMemory is not to be passed out of scope!
409 sp<HidlMemory> hidlMemory = fromHeap(heap);
410
411 SharedBuffer srcBuffer = {
412 .heapBase = *hidlMemory, .offset = (uint64_t)offset, .size = (uint64_t)size};
413
414 DestinationBuffer dstBuffer;
415 dstBuffer.type = BufferType::SHARED_MEMORY;
416 dstBuffer.nonsecureMemory = srcBuffer;
417
418 uint32_t outBytes;
419 hidl_string detailedError;
420 auto returnVoid = descrambler->descramble(
421 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
422 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
423 *descrambleStatus = status;
424 outBytes = bytesWritten;
425 detailedError = detailedErr;
426 });
427 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
428 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
429 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
430 }
431 return ::testing::AssertionResult(returnVoid.isOk());
432}
433
434::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
435 const sp<IDescrambler>& descrambler, Status* descrambleStatus,
436 const OobInputTestParams& params) {
437 hidl_vec<SubSample> hidlSubSamples;
438 hidlSubSamples.setToExternal(const_cast<SubSample*>(params.subSamples), params.numSubSamples,
439 false /*own*/);
440
441 sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
442 if (nullptr == dealer.get()) {
443 ALOGE("couldn't get MemoryDealer!");
444 return ::testing::AssertionFailure();
445 }
446
447 sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
448 if (nullptr == mem.get()) {
449 ALOGE("couldn't allocate IMemory!");
450 return ::testing::AssertionFailure();
451 }
452
453 // build HidlMemory from memory heap
454 ssize_t offset;
455 size_t size;
456 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
457 if (nullptr == heap.get()) {
458 ALOGE("couldn't get memory heap!");
459 return ::testing::AssertionFailure();
460 }
461
462 // hidlMemory is not to be passed out of scope!
463 sp<HidlMemory> hidlMemory = fromHeap(heap);
464
465 SharedBuffer srcBuffer = {
466 .heapBase = *hidlMemory,
467 .offset = (uint64_t)offset + params.imemOffset,
468 .size = (uint64_t)params.imemSize,
469 };
470
471 DestinationBuffer dstBuffer;
472 dstBuffer.type = BufferType::SHARED_MEMORY;
473 dstBuffer.nonsecureMemory = srcBuffer;
474
475 uint32_t outBytes;
476 hidl_string detailedError;
477 auto returnVoid = descrambler->descramble(
478 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, params.srcOffset,
479 dstBuffer, params.dstOffset,
480 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
481 *descrambleStatus = status;
482 outBytes = bytesWritten;
483 detailedError = detailedErr;
484 });
485 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
486 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
487 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
488 }
489 return ::testing::AssertionResult(returnVoid.isOk());
490}
491
Henry Fang93470542020-03-10 14:29:36 -0700492TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) {
Henry Fang9bed3dc2019-10-11 17:30:15 -0700493 description("Test that valid call sequences with SessionEvent send and receive");
494
495 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
496
497 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
498 EXPECT_TRUE(returnStatus.isOk());
499 EXPECT_EQ(Status::OK, returnStatus);
500
501 hidl_vec<uint8_t> hidlPvtData;
502 hidlPvtData.resize(256);
503 returnStatus = mMediaCas->setPrivateData(hidlPvtData);
504 EXPECT_TRUE(returnStatus.isOk());
505 EXPECT_EQ(Status::OK, returnStatus);
506
507 std::vector<uint8_t> sessionId;
508 ASSERT_TRUE(openCasSession(&sessionId));
509 returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
510 EXPECT_TRUE(returnStatus.isOk());
511 EXPECT_EQ(Status::OK, returnStatus);
512
513 std::vector<uint8_t> streamSessionId;
514 ASSERT_TRUE(openCasSession(&streamSessionId));
515 returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
516 EXPECT_TRUE(returnStatus.isOk());
517 EXPECT_EQ(Status::OK, returnStatus);
518
Henry Fang8964b852021-01-08 16:09:08 -0800519 if (mIsTestDescrambler) {
520 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
521 EXPECT_TRUE(returnStatus.isOk());
522 EXPECT_EQ(Status::OK, returnStatus);
Henry Fang9bed3dc2019-10-11 17:30:15 -0700523
Henry Fang8964b852021-01-08 16:09:08 -0800524 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
525 EXPECT_TRUE(returnStatus.isOk());
526 EXPECT_EQ(Status::OK, returnStatus);
527 }
Henry Fang9bed3dc2019-10-11 17:30:15 -0700528 hidl_vec<uint8_t> hidlNullPtr;
529 hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
530 returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
531 EXPECT_TRUE(returnStatus.isOk());
532 EXPECT_EQ(Status::OK, returnStatus);
533
534 uint8_t refreshData[] = {0, 1, 2, 3};
535 hidl_vec<uint8_t> hidlRefreshData;
536 hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
537 returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
538 EXPECT_TRUE(returnStatus.isOk());
539 EXPECT_EQ(Status::OK, returnStatus);
540
541 int32_t eventID = 1;
542 int32_t eventArg = 2;
543 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
544 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlNullPtr);
545
546 eventID = 3;
547 eventArg = 4;
548 uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
549 hidl_vec<uint8_t> hidlEventData;
550 hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
551 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
552 mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlEventData);
553
554 SessionIntent intent = SessionIntent::LIVE;
555 ScramblingMode mode = ScramblingMode::DVB_CSA1;
556 mCasListener->testStatusUpdate(mMediaCas, &sessionId, intent, mode);
557
558 uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
559 hidl_vec<uint8_t> hidlClearKeyEmm;
560 hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
561 returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
562 EXPECT_TRUE(returnStatus.isOk());
563 EXPECT_EQ(Status::OK, returnStatus);
564
565 hidl_vec<uint8_t> hidlEcm;
566 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
567 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
568 EXPECT_TRUE(returnStatus.isOk());
569 EXPECT_EQ(Status::OK, returnStatus);
570 returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
571 EXPECT_TRUE(returnStatus.isOk());
572 EXPECT_EQ(Status::OK, returnStatus);
573
Henry Fang8964b852021-01-08 16:09:08 -0800574 if (mIsTestDescrambler) {
575 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
Henry Fang9bed3dc2019-10-11 17:30:15 -0700576
Henry Fang8964b852021-01-08 16:09:08 -0800577 sp<IDescrambler> descrambler;
578 descrambler = IDescrambler::castFrom(mDescramblerBase);
579 ASSERT_NE(descrambler, nullptr);
Henry Fang9bed3dc2019-10-11 17:30:15 -0700580
Henry Fang8964b852021-01-08 16:09:08 -0800581 Status descrambleStatus = Status::OK;
582 sp<IMemory> dataMemory;
Henry Fang9bed3dc2019-10-11 17:30:15 -0700583
Henry Fang8964b852021-01-08 16:09:08 -0800584 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
585 EXPECT_EQ(Status::OK, descrambleStatus);
Henry Fang9bed3dc2019-10-11 17:30:15 -0700586
Henry Fang8964b852021-01-08 16:09:08 -0800587 ASSERT_NE(nullptr, dataMemory.get());
588 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
Henry Fang9bed3dc2019-10-11 17:30:15 -0700589
Henry Fang8964b852021-01-08 16:09:08 -0800590 int compareResult =
591 memcmp(static_cast<const void*>(opBuffer),
592 static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
593 EXPECT_EQ(0, compareResult);
Henry Fang9bed3dc2019-10-11 17:30:15 -0700594
Henry Fang8964b852021-01-08 16:09:08 -0800595 returnStatus = mDescramblerBase->release();
596 EXPECT_TRUE(returnStatus.isOk());
597 EXPECT_EQ(Status::OK, returnStatus);
598 }
Henry Fang9bed3dc2019-10-11 17:30:15 -0700599
600 returnStatus = mMediaCas->release();
601 EXPECT_TRUE(returnStatus.isOk());
602 EXPECT_EQ(Status::OK, returnStatus);
603}
604
605} // anonymous namespace
606
Dan Shiff985a82020-07-29 09:45:03 -0700607GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MediaCasHidlTest);
Henry Fang93470542020-03-10 14:29:36 -0700608INSTANTIATE_TEST_SUITE_P(
609 PerInstance, MediaCasHidlTest,
610 testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)),
611 android::hardware::PrintInstanceNameToString);