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