• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <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>
29 #include <gtest/gtest.h>
30 #include <hidl/GtestPrinter.h>
31 #include <hidl/HidlSupport.h>
32 #include <hidl/HidlTransportSupport.h>
33 #include <hidl/ServiceManagement.h>
34 #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 
55 using android::Condition;
56 using android::IMemory;
57 using android::IMemoryHeap;
58 using android::MemoryDealer;
59 using android::Mutex;
60 using android::sp;
61 using android::hardware::fromHeap;
62 using android::hardware::hidl_string;
63 using android::hardware::hidl_vec;
64 using android::hardware::HidlMemory;
65 using android::hardware::Return;
66 using android::hardware::Void;
67 using android::hardware::cas::native::V1_0::BufferType;
68 using android::hardware::cas::native::V1_0::DestinationBuffer;
69 using android::hardware::cas::native::V1_0::IDescrambler;
70 using android::hardware::cas::native::V1_0::ScramblingControl;
71 using android::hardware::cas::native::V1_0::SharedBuffer;
72 using android::hardware::cas::native::V1_0::SubSample;
73 using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
74 using android::hardware::cas::V1_0::IDescramblerBase;
75 using android::hardware::cas::V1_0::Status;
76 using android::hardware::cas::V1_2::ICas;
77 using android::hardware::cas::V1_2::ICasListener;
78 using android::hardware::cas::V1_2::IMediaCasService;
79 using android::hardware::cas::V1_2::ScramblingMode;
80 using android::hardware::cas::V1_2::SessionIntent;
81 using android::hardware::cas::V1_2::StatusEvent;
82 
83 namespace {
84 
85 const 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 
94 const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
95 
96 const 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 
135 const 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 
174 class MediaCasListener : public ICasListener {
175   public:
onEvent(int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)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 
onSessionEvent(const hidl_vec<uint8_t> & sessionId,int32_t event,int32_t arg,const hidl_vec<uint8_t> & data)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 
onStatusUpdate(StatusEvent event,int32_t arg)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 
testEventEcho(sp<ICas> & mediaCas,int32_t & event,int32_t & eventArg,hidl_vec<uint8_t> & eventData)231 void 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 
testSessionEventEcho(sp<ICas> & mediaCas,const hidl_vec<uint8_t> & sessionId,int32_t & event,int32_t & eventArg,hidl_vec<uint8_t> & eventData)251 void 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 
testStatusUpdate(sp<ICas> & mediaCas,std::vector<uint8_t> * sessionId,SessionIntent intent,ScramblingMode mode)273 void 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 
297 class MediaCasHidlTest : public testing::TestWithParam<std::string> {
298   public:
SetUp()299     virtual void SetUp() override {
300         mService = IMediaCasService::getService(GetParam());
301         ASSERT_NE(mService, nullptr);
302     }
303 
304     sp<IMediaCasService> mService = nullptr;
305 
306   protected:
description(const std::string & description)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;
314     typedef struct _OobInputTestParams {
315         const SubSample* subSamples;
316         uint32_t numSubSamples;
317         size_t imemSizeActual;
318         uint64_t imemOffset;
319         uint64_t imemSize;
320         uint64_t srcOffset;
321         uint64_t dstOffset;
322     } OobInputTestParams;
323 
324     ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
325     ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
326     ::testing::AssertionResult openCasSession_1_2(std::vector<uint8_t>* sessionId,
327                                                   SessionIntent intent, ScramblingMode mode);
328     ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
329                                                          Status* descrambleStatus,
330                                                          sp<IMemory>* hidlInMemory);
331     ::testing::AssertionResult descrambleTestOobInput(const sp<IDescrambler>& descrambler,
332                                                       Status* descrambleStatus,
333                                                       const OobInputTestParams& params);
334 };
335 
createCasPlugin(int32_t caSystemId)336 ::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
337     auto status = mService->isSystemIdSupported(caSystemId);
338     if (!status.isOk() || !status) {
339         return ::testing::AssertionFailure();
340     }
341     status = mService->isDescramblerSupported(caSystemId);
342     if (!status.isOk() || !status) {
343         return ::testing::AssertionFailure();
344     }
345 
346     mCasListener = new MediaCasListener();
347     auto pluginStatus = mService->createPluginExt(caSystemId, mCasListener);
348     if (!pluginStatus.isOk()) {
349         return ::testing::AssertionFailure();
350     }
351     mMediaCas = ICas::castFrom(pluginStatus);
352     if (mMediaCas == nullptr) {
353         return ::testing::AssertionFailure();
354     }
355 
356     auto descramblerStatus = mService->createDescrambler(caSystemId);
357     if (!descramblerStatus.isOk()) {
358         return ::testing::AssertionFailure();
359     }
360     mDescramblerBase = descramblerStatus;
361     return ::testing::AssertionResult(mDescramblerBase != nullptr);
362 }
363 
openCasSession(std::vector<uint8_t> * sessionId)364 ::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
365     Status sessionStatus;
366     auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
367         sessionStatus = status;
368         *sessionId = id;
369     });
370     return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
371 }
372 
descrambleTestInputBuffer(const sp<IDescrambler> & descrambler,Status * descrambleStatus,sp<IMemory> * inMemory)373 ::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
374         const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
375     hidl_vec<SubSample> hidlSubSamples;
376     hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
377                                  (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
378 
379     sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
380     if (nullptr == dealer.get()) {
381         ALOGE("couldn't get MemoryDealer!");
382         return ::testing::AssertionFailure();
383     }
384 
385     sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
386     if (nullptr == mem.get()) {
387         ALOGE("couldn't allocate IMemory!");
388         return ::testing::AssertionFailure();
389     }
390     *inMemory = mem;
391 
392     // build HidlMemory from memory heap
393     ssize_t offset;
394     size_t size;
395     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
396     if (nullptr == heap.get()) {
397         ALOGE("couldn't get memory heap!");
398         return ::testing::AssertionFailure();
399     }
400 
401     uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->unsecurePointer()));
402     memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
403 
404     // hidlMemory is not to be passed out of scope!
405     sp<HidlMemory> hidlMemory = fromHeap(heap);
406 
407     SharedBuffer srcBuffer = {
408             .heapBase = *hidlMemory, .offset = (uint64_t)offset, .size = (uint64_t)size};
409 
410     DestinationBuffer dstBuffer;
411     dstBuffer.type = BufferType::SHARED_MEMORY;
412     dstBuffer.nonsecureMemory = srcBuffer;
413 
414     uint32_t outBytes;
415     hidl_string detailedError;
416     auto returnVoid = descrambler->descramble(
417             ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
418             [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
419                 *descrambleStatus = status;
420                 outBytes = bytesWritten;
421                 detailedError = detailedErr;
422             });
423     if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
424         ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
425               returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
426     }
427     return ::testing::AssertionResult(returnVoid.isOk());
428 }
429 
descrambleTestOobInput(const sp<IDescrambler> & descrambler,Status * descrambleStatus,const OobInputTestParams & params)430 ::testing::AssertionResult MediaCasHidlTest::descrambleTestOobInput(
431         const sp<IDescrambler>& descrambler, Status* descrambleStatus,
432         const OobInputTestParams& params) {
433     hidl_vec<SubSample> hidlSubSamples;
434     hidlSubSamples.setToExternal(const_cast<SubSample*>(params.subSamples), params.numSubSamples,
435                                  false /*own*/);
436 
437     sp<MemoryDealer> dealer = new MemoryDealer(params.imemSizeActual, "vts-cas");
438     if (nullptr == dealer.get()) {
439         ALOGE("couldn't get MemoryDealer!");
440         return ::testing::AssertionFailure();
441     }
442 
443     sp<IMemory> mem = dealer->allocate(params.imemSizeActual);
444     if (nullptr == mem.get()) {
445         ALOGE("couldn't allocate IMemory!");
446         return ::testing::AssertionFailure();
447     }
448 
449     // build HidlMemory from memory heap
450     ssize_t offset;
451     size_t size;
452     sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
453     if (nullptr == heap.get()) {
454         ALOGE("couldn't get memory heap!");
455         return ::testing::AssertionFailure();
456     }
457 
458     // hidlMemory is not to be passed out of scope!
459     sp<HidlMemory> hidlMemory = fromHeap(heap);
460 
461     SharedBuffer srcBuffer = {
462             .heapBase = *hidlMemory,
463             .offset = (uint64_t)offset + params.imemOffset,
464             .size = (uint64_t)params.imemSize,
465     };
466 
467     DestinationBuffer dstBuffer;
468     dstBuffer.type = BufferType::SHARED_MEMORY;
469     dstBuffer.nonsecureMemory = srcBuffer;
470 
471     uint32_t outBytes;
472     hidl_string detailedError;
473     auto returnVoid = descrambler->descramble(
474             ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, params.srcOffset,
475             dstBuffer, params.dstOffset,
476             [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
477                 *descrambleStatus = status;
478                 outBytes = bytesWritten;
479                 detailedError = detailedErr;
480             });
481     if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
482         ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
483               returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
484     }
485     return ::testing::AssertionResult(returnVoid.isOk());
486 }
487 
TEST_P(MediaCasHidlTest,TestClearKeyApisWithSession)488 TEST_P(MediaCasHidlTest, TestClearKeyApisWithSession) {
489     description("Test that valid call sequences with SessionEvent send and receive");
490 
491     ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
492 
493     auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
494     EXPECT_TRUE(returnStatus.isOk());
495     EXPECT_EQ(Status::OK, returnStatus);
496 
497     hidl_vec<uint8_t> hidlPvtData;
498     hidlPvtData.resize(256);
499     returnStatus = mMediaCas->setPrivateData(hidlPvtData);
500     EXPECT_TRUE(returnStatus.isOk());
501     EXPECT_EQ(Status::OK, returnStatus);
502 
503     std::vector<uint8_t> sessionId;
504     ASSERT_TRUE(openCasSession(&sessionId));
505     returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
506     EXPECT_TRUE(returnStatus.isOk());
507     EXPECT_EQ(Status::OK, returnStatus);
508 
509     std::vector<uint8_t> streamSessionId;
510     ASSERT_TRUE(openCasSession(&streamSessionId));
511     returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
512     EXPECT_TRUE(returnStatus.isOk());
513     EXPECT_EQ(Status::OK, returnStatus);
514 
515     returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
516     EXPECT_TRUE(returnStatus.isOk());
517     EXPECT_EQ(Status::OK, returnStatus);
518 
519     returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
520     EXPECT_TRUE(returnStatus.isOk());
521     EXPECT_EQ(Status::OK, returnStatus);
522 
523     hidl_vec<uint8_t> hidlNullPtr;
524     hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
525     returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
526     EXPECT_TRUE(returnStatus.isOk());
527     EXPECT_EQ(Status::OK, returnStatus);
528 
529     uint8_t refreshData[] = {0, 1, 2, 3};
530     hidl_vec<uint8_t> hidlRefreshData;
531     hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
532     returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
533     EXPECT_TRUE(returnStatus.isOk());
534     EXPECT_EQ(Status::OK, returnStatus);
535 
536     int32_t eventID = 1;
537     int32_t eventArg = 2;
538     mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
539     mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlNullPtr);
540 
541     eventID = 3;
542     eventArg = 4;
543     uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
544     hidl_vec<uint8_t> hidlEventData;
545     hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
546     mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
547     mCasListener->testSessionEventEcho(mMediaCas, sessionId, eventID, eventArg, hidlEventData);
548 
549     SessionIntent intent = SessionIntent::LIVE;
550     ScramblingMode mode = ScramblingMode::DVB_CSA1;
551     mCasListener->testStatusUpdate(mMediaCas, &sessionId, intent, mode);
552 
553     uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
554     hidl_vec<uint8_t> hidlClearKeyEmm;
555     hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
556     returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
557     EXPECT_TRUE(returnStatus.isOk());
558     EXPECT_EQ(Status::OK, returnStatus);
559 
560     hidl_vec<uint8_t> hidlEcm;
561     hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
562     returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
563     EXPECT_TRUE(returnStatus.isOk());
564     EXPECT_EQ(Status::OK, returnStatus);
565     returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
566     EXPECT_TRUE(returnStatus.isOk());
567     EXPECT_EQ(Status::OK, returnStatus);
568 
569     EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
570 
571     sp<IDescrambler> descrambler;
572     descrambler = IDescrambler::castFrom(mDescramblerBase);
573     ASSERT_NE(descrambler, nullptr);
574 
575     Status descrambleStatus = Status::OK;
576     sp<IMemory> dataMemory;
577 
578     ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
579     EXPECT_EQ(Status::OK, descrambleStatus);
580 
581     ASSERT_NE(nullptr, dataMemory.get());
582     uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->unsecurePointer()));
583 
584     int compareResult =
585             memcmp(static_cast<const void*>(opBuffer),
586                    static_cast<const void*>(kOutRefBinaryBuffer), sizeof(kOutRefBinaryBuffer));
587     EXPECT_EQ(0, compareResult);
588 
589     returnStatus = mDescramblerBase->release();
590     EXPECT_TRUE(returnStatus.isOk());
591     EXPECT_EQ(Status::OK, returnStatus);
592 
593     returnStatus = mMediaCas->release();
594     EXPECT_TRUE(returnStatus.isOk());
595     EXPECT_EQ(Status::OK, returnStatus);
596 }
597 
598 }  // anonymous namespace
599 
600 INSTANTIATE_TEST_SUITE_P(
601         PerInstance, MediaCasHidlTest,
602         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMediaCasService::descriptor)),
603         android::hardware::PrintInstanceNameToString);
604