blob: 8a19e2c08c712c119adc57b61ce0f1470f625345 [file] [log] [blame]
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +05301/*
2 * Copyright (C) 2017 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 <android-base/logging.h>
21#include <android/hardware/cas/1.0/ICas.h>
22#include <android/hardware/cas/1.0/ICasListener.h>
23#include <android/hardware/cas/1.0/IDescramblerBase.h>
24#include <android/hardware/cas/1.0/IMediaCasService.h>
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053025#include <android/hardware/cas/1.0/types.h>
26#include <android/hardware/cas/native/1.0/IDescrambler.h>
27#include <android/hardware/cas/native/1.0/types.h>
28#include <android/hidl/allocator/1.0/IAllocator.h>
29#include <android/hidl/memory/1.0/IMapper.h>
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053030#include <hidl/HidlSupport.h>
31#include <hidl/HidlTransportSupport.h>
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053032#include <hidl/Status.h>
33#include <hidlmemory/mapping.h>
34#include <utils/Condition.h>
35#include <utils/Mutex.h>
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053036
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053037#define CLEAR_KEY_SYSTEM_ID 0xF6D8
38#define INVALID_SYSTEM_ID 0
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053039#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 "} "
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053052
53using android::Condition;
54using android::hardware::cas::V1_0::ICas;
55using android::hardware::cas::V1_0::ICasListener;
56using android::hardware::cas::V1_0::IDescramblerBase;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053057using android::hardware::cas::native::V1_0::IDescrambler;
58using android::hardware::cas::native::V1_0::SubSample;
59using android::hardware::cas::native::V1_0::SharedBuffer;
60using android::hardware::cas::native::V1_0::DestinationBuffer;
61using android::hardware::cas::native::V1_0::BufferType;
62using android::hardware::cas::native::V1_0::ScramblingControl;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053063using android::hardware::cas::V1_0::IMediaCasService;
64using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
65using android::hardware::Void;
66using android::hardware::hidl_vec;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053067using android::hardware::hidl_string;
68using android::hardware::hidl_handle;
69using android::hardware::hidl_memory;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053070using android::hardware::Return;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053071using android::hardware::cas::V1_0::Status;
72using android::hidl::allocator::V1_0::IAllocator;
73using android::hidl::memory::V1_0::IMemory;
74using android::hidl::memory::V1_0::IMapper;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053075using android::Mutex;
76using android::sp;
77
78namespace {
79
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053080const 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
89const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
90
91const uint8_t kInBinaryBuffer[] = {
92 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
93 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
94 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
95 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
96 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
97 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
98 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
99 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
100 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
101 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
102 0x6d, 0x6c, 0x6e, 0x45, 0x21, 0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87,
103 0x8f, 0x04, 0x49, 0xe5, 0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04,
104 0x7e, 0x60, 0x5b, 0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14,
105 0x08, 0xcb, 0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d,
106 0xe3, 0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
107 0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c, 0xe1,
108 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7, 0x45, 0x58,
109 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03, 0xaa, 0xe4, 0x32,
110 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49, 0xc8, 0xbf, 0xca, 0x8c,
111 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e, 0xb3, 0x2d, 0x1f, 0xb8, 0x35,
112 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72, 0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1,
113 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d, 0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54,
114 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e, 0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e,
115 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a, 0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b,
116 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46, 0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47,
117 0x6a, 0x12, 0xfa, 0xc4, 0x33, 0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa,
118 0x8e, 0xf1, 0xbc, 0x3d, 0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f,
119 0x25, 0x24, 0x7c, 0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73,
120 0xb1, 0x53, 0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d,
121 0xb4, 0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
122 0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0, 0xe3,
123 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46, 0x7c, 0x75,
124 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0, 0xc5, 0x4c, 0x24,
125 0x0e, 0x65,
126};
127
128const uint8_t kOutRefBinaryBuffer[] = {
129 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
130 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
131 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
132 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
133 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
134 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
135 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
136 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
137 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
138 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
139 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61,
140 0x62, 0x61, 0x63, 0x3d, 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c,
141 0x6f, 0x63, 0x6b, 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73,
142 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68,
143 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
144 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e, 0x30,
145 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x6d, 0x65,
146 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
147 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69, 0x73, 0x3d, 0x31, 0x20,
148 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64,
149 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61,
150 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d, 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d,
151 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74,
152 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68,
153 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c,
154 0x69, 0x63, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e,
155 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69,
156 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72,
157 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73,
158 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
159 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
160 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30, 0x20, 0x6b,
161 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20, 0x73, 0x63, 0x65,
162 0x6e, 0x65,
163};
164
165class MediaCasListener : public ICasListener {
166 public:
167 virtual Return<void> onEvent(int32_t event, int32_t arg,
168 const hidl_vec<uint8_t>& data) override {
169 android::Mutex::Autolock autoLock(mMsgLock);
170 mEvent = event;
171 mEventArg = arg;
172 mEventData = data;
173
174 mEventReceived = true;
175 mMsgCondition.signal();
176 return Void();
177 }
178
179 void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
180 hidl_vec<uint8_t>& eventData);
181
182 private:
183 int32_t mEvent = -1;
184 int32_t mEventArg = -1;
185 bool mEventReceived = false;
186 hidl_vec<uint8_t> mEventData;
187 android::Mutex mMsgLock;
188 android::Condition mMsgCondition;
189};
190
191void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
192 hidl_vec<uint8_t>& eventData) {
193 mEventReceived = false;
194 auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
195 EXPECT_TRUE(returnStatus.isOk());
196 EXPECT_EQ(Status::OK, returnStatus);
197
198 android::Mutex::Autolock autoLock(mMsgLock);
199 while (!mEventReceived) {
200 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
201 EXPECT_TRUE(false) << "event not received within timeout";
202 return;
203 }
204 }
205
206 EXPECT_EQ(mEvent, event);
207 EXPECT_EQ(mEventArg, eventArg);
208 EXPECT_TRUE(mEventData == eventData);
209}
210
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530211class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
212 public:
213 virtual void SetUp() override {
214 mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>();
215 ASSERT_NE(mService, nullptr);
216 }
217
218 sp<IMediaCasService> mService;
219
220 protected:
221 static void description(const std::string& description) {
222 RecordProperty("description", description);
223 }
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530224
225 sp<ICas> mMediaCas;
226 sp<IDescramblerBase> mDescramblerBase;
227 sp<MediaCasListener> mCasListener;
228
229 ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
230 ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
231 ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
232 Status* descrambleStatus,
233 hidl_memory* hidlInMemory);
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530234};
235
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530236::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
237 auto status = mService->isSystemIdSupported(caSystemId);
238 if (!status.isOk() || !status) {
239 return ::testing::AssertionFailure();
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530240 }
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530241 status = mService->isDescramblerSupported(caSystemId);
242 if (!status.isOk() || !status) {
243 return ::testing::AssertionFailure();
244 }
245
246 mCasListener = new MediaCasListener();
247 auto pluginStatus = mService->createPlugin(caSystemId, mCasListener);
248 if (!pluginStatus.isOk()) {
249 return ::testing::AssertionFailure();
250 }
251 mMediaCas = pluginStatus;
252 if (mMediaCas == nullptr) {
253 return ::testing::AssertionFailure();
254 }
255
256 auto descramblerStatus = mService->createDescrambler(caSystemId);
257 if (!descramblerStatus.isOk()) {
258 return ::testing::AssertionFailure();
259 }
260 mDescramblerBase = descramblerStatus;
261 return ::testing::AssertionResult(mDescramblerBase != nullptr);
262}
263
264::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
265 Status sessionStatus;
266 auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
267 sessionStatus = status;
268 *sessionId = id;
269 });
270 return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
271}
272
273::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
274 const sp<IDescrambler>& descrambler, Status* descrambleStatus, hidl_memory* hidlInMemory) {
275 hidl_vec<SubSample> hidlSubSamples;
276 hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
277 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
278 sp<IAllocator> allocator = IAllocator::getService("ashmem");
279 if (nullptr == allocator.get()) {
280 return ::testing::AssertionFailure();
281 }
282
283 bool allocateStatus;
284 auto returnStatus =
285 allocator->allocate(sizeof(kInBinaryBuffer), [&](bool status, hidl_memory const& mem) {
286 allocateStatus = status;
287 *hidlInMemory = mem;
288 });
289 if (!returnStatus.isOk() || !allocateStatus) {
290 return ::testing::AssertionFailure();
291 }
292 android::sp<IMemory> inMemory = mapMemory(*hidlInMemory);
293 if (nullptr == inMemory.get()) {
294 return ::testing::AssertionFailure();
295 }
296
297 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(inMemory->getPointer()));
298 memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
299
300 SharedBuffer srcBuffer = {
301 .heapBase = *hidlInMemory, .offset = (uint64_t)0, .size = sizeof(kInBinaryBuffer)};
302
303 DestinationBuffer dstBuffer;
304 dstBuffer.type = BufferType::SHARED_MEMORY;
305 dstBuffer.nonsecureMemory = srcBuffer;
306
307 uint32_t outBytes;
308 hidl_string detailedError;
309 auto returnVoid = descrambler->descramble(
310 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
311 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
312 *descrambleStatus = status;
313 outBytes = bytesWritten;
314 detailedError = detailedErr;
315 });
316 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
317 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
318 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
319 }
320 return ::testing::AssertionResult(returnVoid.isOk());
321}
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530322
323TEST_F(MediaCasHidlTest, EnumeratePlugins) {
324 description("Test enumerate plugins");
325 hidl_vec<HidlCasPluginDescriptor> descriptors;
326 EXPECT_TRUE(mService
327 ->enumeratePlugins([&descriptors](
328 hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
329 .isOk());
330
331 if (descriptors.size() == 0) {
332 ALOGW("[ WARN ] enumeratePlugins list empty");
333 return;
334 }
335
336 sp<MediaCasListener> casListener = new MediaCasListener();
337 for (size_t i = 0; i < descriptors.size(); i++) {
338 int32_t caSystemId = descriptors[i].caSystemId;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530339
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530340 ASSERT_TRUE(createCasPlugin(caSystemId));
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530341 }
342}
343
344TEST_F(MediaCasHidlTest, TestInvalidSystemIdFails) {
345 description("Test failure for invalid system ID");
346 sp<MediaCasListener> casListener = new MediaCasListener();
347
348 ASSERT_FALSE(mService->isSystemIdSupported(INVALID_SYSTEM_ID));
349 ASSERT_FALSE(mService->isDescramblerSupported(INVALID_SYSTEM_ID));
350
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530351 auto pluginStatus = mService->createPlugin(INVALID_SYSTEM_ID, casListener);
352 ASSERT_TRUE(pluginStatus.isOk());
353 sp<ICas> mediaCas = pluginStatus;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530354 EXPECT_EQ(mediaCas, nullptr);
355
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530356 auto descramblerStatus = mService->createDescrambler(INVALID_SYSTEM_ID);
357 ASSERT_TRUE(descramblerStatus.isOk());
358 sp<IDescramblerBase> descramblerBase = descramblerStatus;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530359 EXPECT_EQ(descramblerBase, nullptr);
360}
361
362TEST_F(MediaCasHidlTest, TestClearKeyPluginInstalled) {
363 description("Test if ClearKey plugin is installed");
364 hidl_vec<HidlCasPluginDescriptor> descriptors;
365 EXPECT_TRUE(mService
366 ->enumeratePlugins([&descriptors](
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530367 hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530368 .isOk());
369
370 if (descriptors.size() == 0) {
371 ALOGW("[ WARN ] enumeratePlugins list empty");
372 }
373
374 for (size_t i = 0; i < descriptors.size(); i++) {
375 int32_t caSystemId = descriptors[i].caSystemId;
376 if (CLEAR_KEY_SYSTEM_ID == caSystemId) {
377 return;
378 }
379 }
380
381 ASSERT_TRUE(false) << "ClearKey plugin not installed";
382}
383
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530384TEST_F(MediaCasHidlTest, TestClearKeyApis) {
385 description("Test that valid call sequences succeed");
386
387 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
388
389 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
390 EXPECT_TRUE(returnStatus.isOk());
391 EXPECT_EQ(Status::OK, returnStatus);
392
393 hidl_vec<uint8_t> hidlPvtData;
394 hidlPvtData.resize(256);
395 returnStatus = mMediaCas->setPrivateData(hidlPvtData);
396 EXPECT_TRUE(returnStatus.isOk());
397 EXPECT_EQ(Status::OK, returnStatus);
398
399 std::vector<uint8_t> sessionId;
400 ASSERT_TRUE(openCasSession(&sessionId));
401 returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
402 EXPECT_TRUE(returnStatus.isOk());
403 EXPECT_EQ(Status::OK, returnStatus);
404
405 std::vector<uint8_t> streamSessionId;
406 ASSERT_TRUE(openCasSession(&streamSessionId));
407 returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
408 EXPECT_TRUE(returnStatus.isOk());
409 EXPECT_EQ(Status::OK, returnStatus);
410
411 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
412 EXPECT_TRUE(returnStatus.isOk());
413 EXPECT_EQ(Status::OK, returnStatus);
414
415 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
416 EXPECT_TRUE(returnStatus.isOk());
417 EXPECT_EQ(Status::OK, returnStatus);
418
419 hidl_vec<uint8_t> hidlNullPtr;
420 hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
421 returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
422 EXPECT_TRUE(returnStatus.isOk());
423 EXPECT_EQ(Status::OK, returnStatus);
424
425 uint8_t refreshData[] = {0, 1, 2, 3};
426 hidl_vec<uint8_t> hidlRefreshData;
427 hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
428 returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
429 EXPECT_TRUE(returnStatus.isOk());
430 EXPECT_EQ(Status::OK, returnStatus);
431
432 int32_t eventID = 1;
433 int32_t eventArg = 2;
434 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
435
436 eventID = 3;
437 eventArg = 4;
438 uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
439 hidl_vec<uint8_t> hidlEventData;
440 hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
441 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
442
443 uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
444 hidl_vec<uint8_t> hidlClearKeyEmm;
445 hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
446 returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
447 EXPECT_TRUE(returnStatus.isOk());
448 EXPECT_EQ(Status::OK, returnStatus);
449
450 hidl_vec<uint8_t> hidlEcm;
451 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
452 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
453 EXPECT_TRUE(returnStatus.isOk());
454 EXPECT_EQ(Status::OK, returnStatus);
455 returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
456 EXPECT_TRUE(returnStatus.isOk());
457 EXPECT_EQ(Status::OK, returnStatus);
458
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530459 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
460
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530461 sp<IDescrambler> descrambler;
462 descrambler = IDescrambler::castFrom(mDescramblerBase);
463 ASSERT_NE(descrambler, nullptr);
464
465 Status descrambleStatus = Status::OK;
466 hidl_memory hidlDataMemory;
467
468 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlDataMemory));
469 EXPECT_EQ(Status::OK, descrambleStatus);
470
471 android::sp<IMemory> outMemory = mapMemory(hidlDataMemory);
472 ASSERT_NE(nullptr, outMemory.get());
473 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(outMemory->getPointer()));
474
475 int compareResult =
476 memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
477 sizeof(kOutRefBinaryBuffer));
478 EXPECT_EQ(0, compareResult);
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530479
480 returnStatus = mDescramblerBase->release();
481 EXPECT_TRUE(returnStatus.isOk());
482 EXPECT_EQ(Status::OK, returnStatus);
483
484 returnStatus = mMediaCas->release();
485 EXPECT_TRUE(returnStatus.isOk());
486 EXPECT_EQ(Status::OK, returnStatus);
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530487}
488
489TEST_F(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) {
490 description("Test that all sessions are closed after a MediaCas object is released");
491
492 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
493
494 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
495 EXPECT_TRUE(returnStatus.isOk());
496 EXPECT_EQ(Status::OK, returnStatus);
497
498 std::vector<uint8_t> sessionId;
499 ASSERT_TRUE(openCasSession(&sessionId));
500 std::vector<uint8_t> streamSessionId;
501 ASSERT_TRUE(openCasSession(&streamSessionId));
502
503 returnStatus = mMediaCas->release();
504 EXPECT_TRUE(returnStatus.isOk());
505 EXPECT_EQ(Status::OK, returnStatus);
506
507 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
508 EXPECT_TRUE(returnStatus.isOk());
509 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
510
511 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
512 EXPECT_TRUE(returnStatus.isOk());
513 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
514}
515
516TEST_F(MediaCasHidlTest, TestClearKeyErrors) {
517 description("Test that invalid call sequences fail with expected error codes");
518
519 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
520
521 /*
522 * Test MediaCas error codes
523 */
524 // Provision should fail with an invalid asset string
525 auto returnStatus = mMediaCas->provision(hidl_string("invalid asset string"));
526 EXPECT_TRUE(returnStatus.isOk());
527 EXPECT_EQ(Status::ERROR_CAS_NO_LICENSE, returnStatus);
528
529 // Open a session, then close it so that it should become invalid
530 std::vector<uint8_t> invalidSessionId;
531 ASSERT_TRUE(openCasSession(&invalidSessionId));
532 returnStatus = mMediaCas->closeSession(invalidSessionId);
533 EXPECT_TRUE(returnStatus.isOk());
534 EXPECT_EQ(Status::OK, returnStatus);
535
536 // processEcm should fail with an invalid session id
537 hidl_vec<uint8_t> hidlEcm;
538 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
539 returnStatus = mMediaCas->processEcm(invalidSessionId, hidlEcm);
540 EXPECT_TRUE(returnStatus.isOk());
541 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
542
543 std::vector<uint8_t> sessionId;
544 ASSERT_TRUE(openCasSession(&sessionId));
545
546 // processEcm should fail without provisioning
547 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
548 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
549 EXPECT_TRUE(returnStatus.isOk());
550 EXPECT_EQ(Status::ERROR_CAS_NOT_PROVISIONED, returnStatus);
551
552 returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
553 EXPECT_TRUE(returnStatus.isOk());
554 EXPECT_EQ(Status::OK, returnStatus);
555
556 // processEcm should fail with ecm buffer that's too short
557 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), 8);
558 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
559 EXPECT_TRUE(returnStatus.isOk());
560 EXPECT_EQ(Status::BAD_VALUE, returnStatus);
561
562 // processEcm should fail with ecm with bad descriptor count
563 uint8_t badDescriptor[sizeof(kEcmBinaryBuffer)];
564 memcpy(badDescriptor, kEcmBinaryBuffer, sizeof(kEcmBinaryBuffer));
565 badDescriptor[17] = 0x03; // change the descriptor count field to 3 (invalid)
566 hidlEcm.setToExternal(static_cast<uint8_t*>(badDescriptor), sizeof(badDescriptor));
567 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
568 EXPECT_TRUE(returnStatus.isOk());
569 EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus);
570
571 /*
572 * Test MediaDescrambler error codes
573 */
574 // setMediaCasSession should fail with an invalid session id
575 returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
576 EXPECT_TRUE(returnStatus.isOk());
577 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
578
579 // descramble should fail without a valid session
580 sp<IDescrambler> descrambler;
581 descrambler = IDescrambler::castFrom(mDescramblerBase);
582 ASSERT_NE(descrambler, nullptr);
583
584 Status descrambleStatus = Status::OK;
585 hidl_memory hidlInMemory;
586
587 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlInMemory));
588 EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
589
590 // Now set a valid session, should still fail because no valid ecm is processed
591 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
592 EXPECT_TRUE(returnStatus.isOk());
593 EXPECT_EQ(Status::OK, returnStatus);
594
595 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlInMemory));
596 EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530597
598 // Verify that requiresSecureDecoderComponent handles empty mime
599 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent(""));
600
601 // Verify that requiresSecureDecoderComponent handles invalid mime
602 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad"));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530603}
604
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530605} // anonymous namespace
606
607int main(int argc, char** argv) {
608 ::testing::InitGoogleTest(&argc, argv);
609 int status = RUN_ALL_TESTS();
610 LOG(INFO) << "Test result = " << status;
611 return status;
612}