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