blob: 062ee2038ea5f027e45c86e01d080823f65831bd [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
459 sp<IDescrambler> descrambler;
460 descrambler = IDescrambler::castFrom(mDescramblerBase);
461 ASSERT_NE(descrambler, nullptr);
462
463 Status descrambleStatus = Status::OK;
464 hidl_memory hidlDataMemory;
465
466 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlDataMemory));
467 EXPECT_EQ(Status::OK, descrambleStatus);
468
469 android::sp<IMemory> outMemory = mapMemory(hidlDataMemory);
470 ASSERT_NE(nullptr, outMemory.get());
471 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(outMemory->getPointer()));
472
473 int compareResult =
474 memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
475 sizeof(kOutRefBinaryBuffer));
476 EXPECT_EQ(0, compareResult);
477}
478
479TEST_F(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) {
480 description("Test that all sessions are closed after a MediaCas object is released");
481
482 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
483
484 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
485 EXPECT_TRUE(returnStatus.isOk());
486 EXPECT_EQ(Status::OK, returnStatus);
487
488 std::vector<uint8_t> sessionId;
489 ASSERT_TRUE(openCasSession(&sessionId));
490 std::vector<uint8_t> streamSessionId;
491 ASSERT_TRUE(openCasSession(&streamSessionId));
492
493 returnStatus = mMediaCas->release();
494 EXPECT_TRUE(returnStatus.isOk());
495 EXPECT_EQ(Status::OK, returnStatus);
496
497 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
498 EXPECT_TRUE(returnStatus.isOk());
499 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
500
501 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
502 EXPECT_TRUE(returnStatus.isOk());
503 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
504}
505
506TEST_F(MediaCasHidlTest, TestClearKeyErrors) {
507 description("Test that invalid call sequences fail with expected error codes");
508
509 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
510
511 /*
512 * Test MediaCas error codes
513 */
514 // Provision should fail with an invalid asset string
515 auto returnStatus = mMediaCas->provision(hidl_string("invalid asset string"));
516 EXPECT_TRUE(returnStatus.isOk());
517 EXPECT_EQ(Status::ERROR_CAS_NO_LICENSE, returnStatus);
518
519 // Open a session, then close it so that it should become invalid
520 std::vector<uint8_t> invalidSessionId;
521 ASSERT_TRUE(openCasSession(&invalidSessionId));
522 returnStatus = mMediaCas->closeSession(invalidSessionId);
523 EXPECT_TRUE(returnStatus.isOk());
524 EXPECT_EQ(Status::OK, returnStatus);
525
526 // processEcm should fail with an invalid session id
527 hidl_vec<uint8_t> hidlEcm;
528 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
529 returnStatus = mMediaCas->processEcm(invalidSessionId, hidlEcm);
530 EXPECT_TRUE(returnStatus.isOk());
531 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
532
533 std::vector<uint8_t> sessionId;
534 ASSERT_TRUE(openCasSession(&sessionId));
535
536 // processEcm should fail without provisioning
537 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
538 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
539 EXPECT_TRUE(returnStatus.isOk());
540 EXPECT_EQ(Status::ERROR_CAS_NOT_PROVISIONED, returnStatus);
541
542 returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
543 EXPECT_TRUE(returnStatus.isOk());
544 EXPECT_EQ(Status::OK, returnStatus);
545
546 // processEcm should fail with ecm buffer that's too short
547 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), 8);
548 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
549 EXPECT_TRUE(returnStatus.isOk());
550 EXPECT_EQ(Status::BAD_VALUE, returnStatus);
551
552 // processEcm should fail with ecm with bad descriptor count
553 uint8_t badDescriptor[sizeof(kEcmBinaryBuffer)];
554 memcpy(badDescriptor, kEcmBinaryBuffer, sizeof(kEcmBinaryBuffer));
555 badDescriptor[17] = 0x03; // change the descriptor count field to 3 (invalid)
556 hidlEcm.setToExternal(static_cast<uint8_t*>(badDescriptor), sizeof(badDescriptor));
557 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
558 EXPECT_TRUE(returnStatus.isOk());
559 EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus);
560
561 /*
562 * Test MediaDescrambler error codes
563 */
564 // setMediaCasSession should fail with an invalid session id
565 returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
566 EXPECT_TRUE(returnStatus.isOk());
567 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
568
569 // descramble should fail without a valid session
570 sp<IDescrambler> descrambler;
571 descrambler = IDescrambler::castFrom(mDescramblerBase);
572 ASSERT_NE(descrambler, nullptr);
573
574 Status descrambleStatus = Status::OK;
575 hidl_memory hidlInMemory;
576
577 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlInMemory));
578 EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
579
580 // Now set a valid session, should still fail because no valid ecm is processed
581 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
582 EXPECT_TRUE(returnStatus.isOk());
583 EXPECT_EQ(Status::OK, returnStatus);
584
585 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &hidlInMemory));
586 EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
587}
588
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530589} // anonymous namespace
590
591int main(int argc, char** argv) {
592 ::testing::InitGoogleTest(&argc, argv);
593 int status = RUN_ALL_TESTS();
594 LOG(INFO) << "Test result = " << status;
595 return status;
596}