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