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