blob: 1218307918372bbf1e44f11bd65173a2675dc869 [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>
Zhuoyao Zhanga5e67072018-02-08 20:43:55 -080020#include <VtsHalHidlTargetTestEnvBase.h>
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053021#include <android-base/logging.h>
22#include <android/hardware/cas/1.0/ICas.h>
23#include <android/hardware/cas/1.0/ICasListener.h>
24#include <android/hardware/cas/1.0/IDescramblerBase.h>
25#include <android/hardware/cas/1.0/IMediaCasService.h>
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053026#include <android/hardware/cas/1.0/types.h>
27#include <android/hardware/cas/native/1.0/IDescrambler.h>
28#include <android/hardware/cas/native/1.0/types.h>
Chong Zhang704d5862017-10-10 13:03:18 -070029#include <binder/MemoryDealer.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>
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053033#include <utils/Condition.h>
34#include <utils/Mutex.h>
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053035
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053036#define CLEAR_KEY_SYSTEM_ID 0xF6D8
37#define INVALID_SYSTEM_ID 0
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053038#define WAIT_TIMEOUT 3000000000
39
40#define PROVISION_STR \
41 "{ " \
42 " \"id\": 21140844, " \
43 " \"name\": \"Test Title\", " \
44 " \"lowercase_organization_name\": \"Android\", " \
45 " \"asset_key\": { " \
46 " \"encryption_key\": \"nezAr3CHFrmBR9R8Tedotw==\" " \
47 " }, " \
48 " \"cas_type\": 1, " \
49 " \"track_types\": [ ] " \
50 "} "
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053051
52using android::Condition;
53using android::hardware::cas::V1_0::ICas;
54using android::hardware::cas::V1_0::ICasListener;
55using android::hardware::cas::V1_0::IDescramblerBase;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053056using android::hardware::cas::native::V1_0::IDescrambler;
57using android::hardware::cas::native::V1_0::SubSample;
58using android::hardware::cas::native::V1_0::SharedBuffer;
59using android::hardware::cas::native::V1_0::DestinationBuffer;
60using android::hardware::cas::native::V1_0::BufferType;
61using android::hardware::cas::native::V1_0::ScramblingControl;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053062using android::hardware::cas::V1_0::IMediaCasService;
63using android::hardware::cas::V1_0::HidlCasPluginDescriptor;
64using android::hardware::Void;
65using android::hardware::hidl_vec;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053066using android::hardware::hidl_string;
67using android::hardware::hidl_handle;
68using android::hardware::hidl_memory;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053069using android::hardware::Return;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053070using android::hardware::cas::V1_0::Status;
Chong Zhang704d5862017-10-10 13:03:18 -070071using android::IMemory;
72using android::IMemoryHeap;
73using android::MemoryDealer;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +053074using android::Mutex;
75using android::sp;
76
77namespace {
78
Suresh Sivaraman0645aec2017-09-21 18:44:24 +053079const uint8_t kEcmBinaryBuffer[] = {
80 0x00, 0x00, 0x01, 0xf0, 0x00, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, 0x00,
81 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x27, 0x10, 0x02, 0x00,
82 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0x0e, 0xe3, 0x91, 0xbc, 0xfd, 0x05, 0xb1, 0x60, 0x4f,
83 0x17, 0x82, 0xa4, 0x86, 0x9b, 0x23, 0x56, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
84 0x27, 0x10, 0x02, 0x00, 0x01, 0x77, 0x01, 0x42, 0x95, 0x6c, 0xd7, 0x43, 0x62, 0xf8, 0x1c,
85 0x62, 0x19, 0x05, 0xc7, 0x3a, 0x42, 0xcd, 0xfd, 0xd9, 0x13, 0x48,
86};
87
88const SubSample kSubSamples[] = {{162, 0}, {0, 184}, {0, 184}};
89
90const uint8_t kInBinaryBuffer[] = {
91 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
92 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
93 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
94 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
95 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
96 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
97 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
98 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
99 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
100 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
101 0x6d, 0x6c, 0x6e, 0x45, 0x21, 0x82, 0x38, 0xf0, 0x9d, 0x7d, 0x96, 0xe6, 0x94, 0xae, 0xe2, 0x87,
102 0x8f, 0x04, 0x49, 0xe5, 0xf6, 0x8c, 0x8b, 0x9a, 0x10, 0x18, 0xba, 0x94, 0xe9, 0x22, 0x31, 0x04,
103 0x7e, 0x60, 0x5b, 0xc4, 0x24, 0x00, 0x90, 0x62, 0x0d, 0xdc, 0x85, 0x74, 0x75, 0x78, 0xd0, 0x14,
104 0x08, 0xcb, 0x02, 0x1d, 0x7d, 0x9d, 0x34, 0xe8, 0x81, 0xb9, 0xf7, 0x09, 0x28, 0x79, 0x29, 0x8d,
105 0xe3, 0x14, 0xed, 0x5f, 0xca, 0xaf, 0xf4, 0x1c, 0x49, 0x15, 0xe1, 0x80, 0x29, 0x61, 0x76, 0x80,
106 0x43, 0xf8, 0x58, 0x53, 0x40, 0xd7, 0x31, 0x6d, 0x61, 0x81, 0x41, 0xe9, 0x77, 0x9f, 0x9c, 0xe1,
107 0x6d, 0xf2, 0xee, 0xd9, 0xc8, 0x67, 0xd2, 0x5f, 0x48, 0x73, 0xe3, 0x5c, 0xcd, 0xa7, 0x45, 0x58,
108 0xbb, 0xdd, 0x28, 0x1d, 0x68, 0xfc, 0xb4, 0xc6, 0xf6, 0x92, 0xf6, 0x30, 0x03, 0xaa, 0xe4, 0x32,
109 0xf6, 0x34, 0x51, 0x4b, 0x0f, 0x8c, 0xf9, 0xac, 0x98, 0x22, 0xfb, 0x49, 0xc8, 0xbf, 0xca, 0x8c,
110 0x80, 0x86, 0x5d, 0xd7, 0xa4, 0x52, 0xb1, 0xd9, 0xa6, 0x04, 0x4e, 0xb3, 0x2d, 0x1f, 0xb8, 0x35,
111 0xcc, 0x45, 0x6d, 0x9c, 0x20, 0xa7, 0xa4, 0x34, 0x59, 0x72, 0xe3, 0xae, 0xba, 0x49, 0xde, 0xd1,
112 0xaa, 0xee, 0x3d, 0x77, 0xfc, 0x5d, 0xc6, 0x1f, 0x9d, 0xac, 0xc2, 0x15, 0x66, 0xb8, 0xe1, 0x54,
113 0x4e, 0x74, 0x93, 0xdb, 0x9a, 0x24, 0x15, 0x6e, 0x20, 0xa3, 0x67, 0x3e, 0x5a, 0x24, 0x41, 0x5e,
114 0xb0, 0xe6, 0x35, 0x87, 0x1b, 0xc8, 0x7a, 0xf9, 0x77, 0x65, 0xe0, 0x01, 0xf2, 0x4c, 0xe4, 0x2b,
115 0xa9, 0x64, 0x96, 0x96, 0x0b, 0x46, 0xca, 0xea, 0x79, 0x0e, 0x78, 0xa3, 0x5f, 0x43, 0xfc, 0x47,
116 0x6a, 0x12, 0xfa, 0xc4, 0x33, 0x0e, 0x88, 0x1c, 0x19, 0x3a, 0x00, 0xc3, 0x4e, 0xb5, 0xd8, 0xfa,
117 0x8e, 0xf1, 0xbc, 0x3d, 0xb2, 0x7e, 0x50, 0x8d, 0x67, 0xc3, 0x6b, 0xed, 0xe2, 0xea, 0xa6, 0x1f,
118 0x25, 0x24, 0x7c, 0x94, 0x74, 0x50, 0x49, 0xe3, 0xc6, 0x58, 0x2e, 0xfd, 0x28, 0xb4, 0xc6, 0x73,
119 0xb1, 0x53, 0x74, 0x27, 0x94, 0x5c, 0xdf, 0x69, 0xb7, 0xa1, 0xd7, 0xf5, 0xd3, 0x8a, 0x2c, 0x2d,
120 0xb4, 0x5e, 0x8a, 0x16, 0x14, 0x54, 0x64, 0x6e, 0x00, 0x6b, 0x11, 0x59, 0x8a, 0x63, 0x38, 0x80,
121 0x76, 0xc3, 0xd5, 0x59, 0xf7, 0x3f, 0xd2, 0xfa, 0xa5, 0xca, 0x82, 0xff, 0x4a, 0x62, 0xf0, 0xe3,
122 0x42, 0xf9, 0x3b, 0x38, 0x27, 0x8a, 0x89, 0xaa, 0x50, 0x55, 0x4b, 0x29, 0xf1, 0x46, 0x7c, 0x75,
123 0xef, 0x65, 0xaf, 0x9b, 0x0d, 0x6d, 0xda, 0x25, 0x94, 0x14, 0xc1, 0x1b, 0xf0, 0xc5, 0x4c, 0x24,
124 0x0e, 0x65,
125};
126
127const uint8_t kOutRefBinaryBuffer[] = {
128 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb, 0x01,
129 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03, 0xc5, 0x8b,
130 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06, 0x05, 0xff, 0xff,
131 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8, 0x20, 0xd9, 0x23, 0xee,
132 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x31, 0x34, 0x32,
133 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d, 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20,
134 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63, 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79,
135 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d,
136 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65,
137 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74,
138 0x6d, 0x6c, 0x20, 0x2d, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61,
139 0x62, 0x61, 0x63, 0x3d, 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c,
140 0x6f, 0x63, 0x6b, 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73,
141 0x65, 0x3d, 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68,
142 0x65, 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
143 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e, 0x30,
144 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20, 0x6d, 0x65,
145 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61,
146 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69, 0x73, 0x3d, 0x31, 0x20,
147 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71, 0x6d, 0x3d, 0x30, 0x20, 0x64,
148 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31, 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61,
149 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d, 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d,
150 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74,
151 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68,
152 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c,
153 0x69, 0x63, 0x65, 0x64, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e,
154 0x72, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69,
155 0x6e, 0x74, 0x65, 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72,
156 0x61, 0x79, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73,
157 0x74, 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
158 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74,
159 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30, 0x20, 0x6b,
160 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20, 0x73, 0x63, 0x65,
161 0x6e, 0x65,
162};
163
164class MediaCasListener : public ICasListener {
165 public:
166 virtual Return<void> onEvent(int32_t event, int32_t arg,
167 const hidl_vec<uint8_t>& data) override {
168 android::Mutex::Autolock autoLock(mMsgLock);
169 mEvent = event;
170 mEventArg = arg;
171 mEventData = data;
172
173 mEventReceived = true;
174 mMsgCondition.signal();
175 return Void();
176 }
177
178 void testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
179 hidl_vec<uint8_t>& eventData);
180
181 private:
182 int32_t mEvent = -1;
183 int32_t mEventArg = -1;
184 bool mEventReceived = false;
185 hidl_vec<uint8_t> mEventData;
186 android::Mutex mMsgLock;
187 android::Condition mMsgCondition;
188};
189
190void MediaCasListener::testEventEcho(sp<ICas>& mediaCas, int32_t& event, int32_t& eventArg,
191 hidl_vec<uint8_t>& eventData) {
192 mEventReceived = false;
193 auto returnStatus = mediaCas->sendEvent(event, eventArg, eventData);
194 EXPECT_TRUE(returnStatus.isOk());
195 EXPECT_EQ(Status::OK, returnStatus);
196
197 android::Mutex::Autolock autoLock(mMsgLock);
198 while (!mEventReceived) {
199 if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
200 EXPECT_TRUE(false) << "event not received within timeout";
201 return;
202 }
203 }
204
205 EXPECT_EQ(mEvent, event);
206 EXPECT_EQ(mEventArg, eventArg);
207 EXPECT_TRUE(mEventData == eventData);
208}
209
Zhuoyao Zhanga5e67072018-02-08 20:43:55 -0800210// Test environment for Cas HIDL HAL.
211class CasHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
212 public:
213 // get the test environment singleton
214 static CasHidlEnvironment* Instance() {
215 static CasHidlEnvironment* instance = new CasHidlEnvironment;
216 return instance;
217 }
218
219 virtual void registerTestServices() override { registerTestService<IMediaCasService>(); }
220};
221
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530222class MediaCasHidlTest : public ::testing::VtsHalHidlTargetTestBase {
223 public:
224 virtual void SetUp() override {
Zhuoyao Zhanga5e67072018-02-08 20:43:55 -0800225 mService = ::testing::VtsHalHidlTargetTestBase::getService<IMediaCasService>(
226 CasHidlEnvironment::Instance()->getServiceName<IMediaCasService>());
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530227 ASSERT_NE(mService, nullptr);
228 }
229
230 sp<IMediaCasService> mService;
231
232 protected:
233 static void description(const std::string& description) {
234 RecordProperty("description", description);
235 }
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530236
237 sp<ICas> mMediaCas;
238 sp<IDescramblerBase> mDescramblerBase;
239 sp<MediaCasListener> mCasListener;
240
241 ::testing::AssertionResult createCasPlugin(int32_t caSystemId);
242 ::testing::AssertionResult openCasSession(std::vector<uint8_t>* sessionId);
243 ::testing::AssertionResult descrambleTestInputBuffer(const sp<IDescrambler>& descrambler,
244 Status* descrambleStatus,
Chong Zhang704d5862017-10-10 13:03:18 -0700245 sp<IMemory>* hidlInMemory);
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530246};
247
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530248::testing::AssertionResult MediaCasHidlTest::createCasPlugin(int32_t caSystemId) {
249 auto status = mService->isSystemIdSupported(caSystemId);
250 if (!status.isOk() || !status) {
251 return ::testing::AssertionFailure();
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530252 }
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530253 status = mService->isDescramblerSupported(caSystemId);
254 if (!status.isOk() || !status) {
255 return ::testing::AssertionFailure();
256 }
257
258 mCasListener = new MediaCasListener();
259 auto pluginStatus = mService->createPlugin(caSystemId, mCasListener);
260 if (!pluginStatus.isOk()) {
261 return ::testing::AssertionFailure();
262 }
263 mMediaCas = pluginStatus;
264 if (mMediaCas == nullptr) {
265 return ::testing::AssertionFailure();
266 }
267
268 auto descramblerStatus = mService->createDescrambler(caSystemId);
269 if (!descramblerStatus.isOk()) {
270 return ::testing::AssertionFailure();
271 }
272 mDescramblerBase = descramblerStatus;
273 return ::testing::AssertionResult(mDescramblerBase != nullptr);
274}
275
276::testing::AssertionResult MediaCasHidlTest::openCasSession(std::vector<uint8_t>* sessionId) {
277 Status sessionStatus;
278 auto returnVoid = mMediaCas->openSession([&](Status status, const hidl_vec<uint8_t>& id) {
279 sessionStatus = status;
280 *sessionId = id;
281 });
282 return ::testing::AssertionResult(returnVoid.isOk() && (Status::OK == sessionStatus));
283}
284
285::testing::AssertionResult MediaCasHidlTest::descrambleTestInputBuffer(
Chong Zhang704d5862017-10-10 13:03:18 -0700286 const sp<IDescrambler>& descrambler, Status* descrambleStatus, sp<IMemory>* inMemory) {
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530287 hidl_vec<SubSample> hidlSubSamples;
288 hidlSubSamples.setToExternal(const_cast<SubSample*>(kSubSamples),
289 (sizeof(kSubSamples) / sizeof(SubSample)), false /*own*/);
Chong Zhang704d5862017-10-10 13:03:18 -0700290
291 sp<MemoryDealer> dealer = new MemoryDealer(sizeof(kInBinaryBuffer), "vts-cas");
292 if (nullptr == dealer.get()) {
293 ALOGE("couldn't get MemoryDealer!");
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530294 return ::testing::AssertionFailure();
295 }
296
Chong Zhang704d5862017-10-10 13:03:18 -0700297 sp<IMemory> mem = dealer->allocate(sizeof(kInBinaryBuffer));
298 if (nullptr == mem.get()) {
299 ALOGE("couldn't allocate IMemory!");
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530300 return ::testing::AssertionFailure();
301 }
Chong Zhang704d5862017-10-10 13:03:18 -0700302 *inMemory = mem;
303
304 // build hidl_memory from memory heap
305 ssize_t offset;
306 size_t size;
307 sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
308 if (nullptr == heap.get()) {
309 ALOGE("couldn't get memory heap!");
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530310 return ::testing::AssertionFailure();
311 }
312
Chong Zhang704d5862017-10-10 13:03:18 -0700313 native_handle_t* nativeHandle = native_handle_create(1, 0);
314 if (!nativeHandle) {
315 ALOGE("failed to create native handle!");
316 return ::testing::AssertionFailure();
317 }
318 nativeHandle->data[0] = heap->getHeapID();
319
320 uint8_t* ipBuffer = static_cast<uint8_t*>(static_cast<void*>(mem->pointer()));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530321 memcpy(ipBuffer, kInBinaryBuffer, sizeof(kInBinaryBuffer));
322
323 SharedBuffer srcBuffer = {
Chong Zhang704d5862017-10-10 13:03:18 -0700324 .heapBase = hidl_memory("ashmem", hidl_handle(nativeHandle), heap->getSize()),
325 .offset = (uint64_t) offset,
326 .size = (uint64_t) size
327 };
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530328
329 DestinationBuffer dstBuffer;
330 dstBuffer.type = BufferType::SHARED_MEMORY;
331 dstBuffer.nonsecureMemory = srcBuffer;
332
333 uint32_t outBytes;
334 hidl_string detailedError;
335 auto returnVoid = descrambler->descramble(
336 ScramblingControl::EVENKEY /*2*/, hidlSubSamples, srcBuffer, 0, dstBuffer, 0,
337 [&](Status status, uint32_t bytesWritten, const hidl_string& detailedErr) {
338 *descrambleStatus = status;
339 outBytes = bytesWritten;
340 detailedError = detailedErr;
341 });
342 if (!returnVoid.isOk() || *descrambleStatus != Status::OK) {
343 ALOGI("descramble failed, trans=%s, status=%d, outBytes=%u, error=%s",
344 returnVoid.description().c_str(), *descrambleStatus, outBytes, detailedError.c_str());
345 }
346 return ::testing::AssertionResult(returnVoid.isOk());
347}
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530348
349TEST_F(MediaCasHidlTest, EnumeratePlugins) {
350 description("Test enumerate plugins");
351 hidl_vec<HidlCasPluginDescriptor> descriptors;
352 EXPECT_TRUE(mService
353 ->enumeratePlugins([&descriptors](
354 hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
355 .isOk());
356
357 if (descriptors.size() == 0) {
358 ALOGW("[ WARN ] enumeratePlugins list empty");
359 return;
360 }
361
362 sp<MediaCasListener> casListener = new MediaCasListener();
363 for (size_t i = 0; i < descriptors.size(); i++) {
364 int32_t caSystemId = descriptors[i].caSystemId;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530365
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530366 ASSERT_TRUE(createCasPlugin(caSystemId));
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530367 }
368}
369
370TEST_F(MediaCasHidlTest, TestInvalidSystemIdFails) {
371 description("Test failure for invalid system ID");
372 sp<MediaCasListener> casListener = new MediaCasListener();
373
374 ASSERT_FALSE(mService->isSystemIdSupported(INVALID_SYSTEM_ID));
375 ASSERT_FALSE(mService->isDescramblerSupported(INVALID_SYSTEM_ID));
376
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530377 auto pluginStatus = mService->createPlugin(INVALID_SYSTEM_ID, casListener);
378 ASSERT_TRUE(pluginStatus.isOk());
379 sp<ICas> mediaCas = pluginStatus;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530380 EXPECT_EQ(mediaCas, nullptr);
381
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530382 auto descramblerStatus = mService->createDescrambler(INVALID_SYSTEM_ID);
383 ASSERT_TRUE(descramblerStatus.isOk());
384 sp<IDescramblerBase> descramblerBase = descramblerStatus;
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530385 EXPECT_EQ(descramblerBase, nullptr);
386}
387
388TEST_F(MediaCasHidlTest, TestClearKeyPluginInstalled) {
389 description("Test if ClearKey plugin is installed");
390 hidl_vec<HidlCasPluginDescriptor> descriptors;
391 EXPECT_TRUE(mService
392 ->enumeratePlugins([&descriptors](
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530393 hidl_vec<HidlCasPluginDescriptor> const& desc) { descriptors = desc; })
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530394 .isOk());
395
396 if (descriptors.size() == 0) {
397 ALOGW("[ WARN ] enumeratePlugins list empty");
398 }
399
400 for (size_t i = 0; i < descriptors.size(); i++) {
401 int32_t caSystemId = descriptors[i].caSystemId;
402 if (CLEAR_KEY_SYSTEM_ID == caSystemId) {
403 return;
404 }
405 }
406
407 ASSERT_TRUE(false) << "ClearKey plugin not installed";
408}
409
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530410TEST_F(MediaCasHidlTest, TestClearKeyApis) {
411 description("Test that valid call sequences succeed");
412
413 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
414
415 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
416 EXPECT_TRUE(returnStatus.isOk());
417 EXPECT_EQ(Status::OK, returnStatus);
418
419 hidl_vec<uint8_t> hidlPvtData;
420 hidlPvtData.resize(256);
421 returnStatus = mMediaCas->setPrivateData(hidlPvtData);
422 EXPECT_TRUE(returnStatus.isOk());
423 EXPECT_EQ(Status::OK, returnStatus);
424
425 std::vector<uint8_t> sessionId;
426 ASSERT_TRUE(openCasSession(&sessionId));
427 returnStatus = mMediaCas->setSessionPrivateData(sessionId, hidlPvtData);
428 EXPECT_TRUE(returnStatus.isOk());
429 EXPECT_EQ(Status::OK, returnStatus);
430
431 std::vector<uint8_t> streamSessionId;
432 ASSERT_TRUE(openCasSession(&streamSessionId));
433 returnStatus = mMediaCas->setSessionPrivateData(streamSessionId, hidlPvtData);
434 EXPECT_TRUE(returnStatus.isOk());
435 EXPECT_EQ(Status::OK, returnStatus);
436
437 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
438 EXPECT_TRUE(returnStatus.isOk());
439 EXPECT_EQ(Status::OK, returnStatus);
440
441 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
442 EXPECT_TRUE(returnStatus.isOk());
443 EXPECT_EQ(Status::OK, returnStatus);
444
445 hidl_vec<uint8_t> hidlNullPtr;
446 hidlNullPtr.setToExternal(static_cast<uint8_t*>(nullptr), 0);
447 returnStatus = mMediaCas->refreshEntitlements(3, hidlNullPtr);
448 EXPECT_TRUE(returnStatus.isOk());
449 EXPECT_EQ(Status::OK, returnStatus);
450
451 uint8_t refreshData[] = {0, 1, 2, 3};
452 hidl_vec<uint8_t> hidlRefreshData;
453 hidlRefreshData.setToExternal(static_cast<uint8_t*>(refreshData), sizeof(refreshData));
454 returnStatus = mMediaCas->refreshEntitlements(10, hidlRefreshData);
455 EXPECT_TRUE(returnStatus.isOk());
456 EXPECT_EQ(Status::OK, returnStatus);
457
458 int32_t eventID = 1;
459 int32_t eventArg = 2;
460 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlNullPtr);
461
462 eventID = 3;
463 eventArg = 4;
464 uint8_t eventData[] = {'e', 'v', 'e', 'n', 't', 'd', 'a', 't', 'a'};
465 hidl_vec<uint8_t> hidlEventData;
466 hidlEventData.setToExternal(static_cast<uint8_t*>(eventData), sizeof(eventData));
467 mCasListener->testEventEcho(mMediaCas, eventID, eventArg, hidlEventData);
468
469 uint8_t clearKeyEmmData[] = {'c', 'l', 'e', 'a', 'r', 'k', 'e', 'y', 'e', 'm', 'm'};
470 hidl_vec<uint8_t> hidlClearKeyEmm;
471 hidlClearKeyEmm.setToExternal(static_cast<uint8_t*>(clearKeyEmmData), sizeof(clearKeyEmmData));
472 returnStatus = mMediaCas->processEmm(hidlClearKeyEmm);
473 EXPECT_TRUE(returnStatus.isOk());
474 EXPECT_EQ(Status::OK, returnStatus);
475
476 hidl_vec<uint8_t> hidlEcm;
477 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
478 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
479 EXPECT_TRUE(returnStatus.isOk());
480 EXPECT_EQ(Status::OK, returnStatus);
481 returnStatus = mMediaCas->processEcm(streamSessionId, hidlEcm);
482 EXPECT_TRUE(returnStatus.isOk());
483 EXPECT_EQ(Status::OK, returnStatus);
484
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530485 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("video/avc"));
486
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530487 sp<IDescrambler> descrambler;
488 descrambler = IDescrambler::castFrom(mDescramblerBase);
489 ASSERT_NE(descrambler, nullptr);
490
491 Status descrambleStatus = Status::OK;
Chong Zhang704d5862017-10-10 13:03:18 -0700492 sp<IMemory> dataMemory;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530493
Chong Zhang704d5862017-10-10 13:03:18 -0700494 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530495 EXPECT_EQ(Status::OK, descrambleStatus);
496
Chong Zhang704d5862017-10-10 13:03:18 -0700497 ASSERT_NE(nullptr, dataMemory.get());
498 uint8_t* opBuffer = static_cast<uint8_t*>(static_cast<void*>(dataMemory->pointer()));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530499
500 int compareResult =
501 memcmp(static_cast<const void*>(opBuffer), static_cast<const void*>(kOutRefBinaryBuffer),
502 sizeof(kOutRefBinaryBuffer));
503 EXPECT_EQ(0, compareResult);
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530504
505 returnStatus = mDescramblerBase->release();
506 EXPECT_TRUE(returnStatus.isOk());
507 EXPECT_EQ(Status::OK, returnStatus);
508
509 returnStatus = mMediaCas->release();
510 EXPECT_TRUE(returnStatus.isOk());
511 EXPECT_EQ(Status::OK, returnStatus);
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530512}
513
514TEST_F(MediaCasHidlTest, TestClearKeySessionClosedAfterRelease) {
515 description("Test that all sessions are closed after a MediaCas object is released");
516
517 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
518
519 auto returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
520 EXPECT_TRUE(returnStatus.isOk());
521 EXPECT_EQ(Status::OK, returnStatus);
522
523 std::vector<uint8_t> sessionId;
524 ASSERT_TRUE(openCasSession(&sessionId));
525 std::vector<uint8_t> streamSessionId;
526 ASSERT_TRUE(openCasSession(&streamSessionId));
527
528 returnStatus = mMediaCas->release();
529 EXPECT_TRUE(returnStatus.isOk());
530 EXPECT_EQ(Status::OK, returnStatus);
531
532 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
533 EXPECT_TRUE(returnStatus.isOk());
534 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
535
536 returnStatus = mDescramblerBase->setMediaCasSession(streamSessionId);
537 EXPECT_TRUE(returnStatus.isOk());
538 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
539}
540
541TEST_F(MediaCasHidlTest, TestClearKeyErrors) {
542 description("Test that invalid call sequences fail with expected error codes");
543
544 ASSERT_TRUE(createCasPlugin(CLEAR_KEY_SYSTEM_ID));
545
546 /*
547 * Test MediaCas error codes
548 */
549 // Provision should fail with an invalid asset string
550 auto returnStatus = mMediaCas->provision(hidl_string("invalid asset string"));
551 EXPECT_TRUE(returnStatus.isOk());
552 EXPECT_EQ(Status::ERROR_CAS_NO_LICENSE, returnStatus);
553
554 // Open a session, then close it so that it should become invalid
555 std::vector<uint8_t> invalidSessionId;
556 ASSERT_TRUE(openCasSession(&invalidSessionId));
557 returnStatus = mMediaCas->closeSession(invalidSessionId);
558 EXPECT_TRUE(returnStatus.isOk());
559 EXPECT_EQ(Status::OK, returnStatus);
560
561 // processEcm should fail with an invalid session id
562 hidl_vec<uint8_t> hidlEcm;
563 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
564 returnStatus = mMediaCas->processEcm(invalidSessionId, hidlEcm);
565 EXPECT_TRUE(returnStatus.isOk());
566 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
567
568 std::vector<uint8_t> sessionId;
569 ASSERT_TRUE(openCasSession(&sessionId));
570
571 // processEcm should fail without provisioning
572 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), sizeof(kEcmBinaryBuffer));
573 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
574 EXPECT_TRUE(returnStatus.isOk());
575 EXPECT_EQ(Status::ERROR_CAS_NOT_PROVISIONED, returnStatus);
576
577 returnStatus = mMediaCas->provision(hidl_string(PROVISION_STR));
578 EXPECT_TRUE(returnStatus.isOk());
579 EXPECT_EQ(Status::OK, returnStatus);
580
581 // processEcm should fail with ecm buffer that's too short
582 hidlEcm.setToExternal(const_cast<uint8_t*>(kEcmBinaryBuffer), 8);
583 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
584 EXPECT_TRUE(returnStatus.isOk());
585 EXPECT_EQ(Status::BAD_VALUE, returnStatus);
586
587 // processEcm should fail with ecm with bad descriptor count
588 uint8_t badDescriptor[sizeof(kEcmBinaryBuffer)];
589 memcpy(badDescriptor, kEcmBinaryBuffer, sizeof(kEcmBinaryBuffer));
590 badDescriptor[17] = 0x03; // change the descriptor count field to 3 (invalid)
591 hidlEcm.setToExternal(static_cast<uint8_t*>(badDescriptor), sizeof(badDescriptor));
592 returnStatus = mMediaCas->processEcm(sessionId, hidlEcm);
593 EXPECT_TRUE(returnStatus.isOk());
594 EXPECT_EQ(Status::ERROR_CAS_UNKNOWN, returnStatus);
595
596 /*
597 * Test MediaDescrambler error codes
598 */
599 // setMediaCasSession should fail with an invalid session id
600 returnStatus = mDescramblerBase->setMediaCasSession(invalidSessionId);
601 EXPECT_TRUE(returnStatus.isOk());
602 EXPECT_EQ(Status::ERROR_CAS_SESSION_NOT_OPENED, returnStatus);
603
604 // descramble should fail without a valid session
605 sp<IDescrambler> descrambler;
606 descrambler = IDescrambler::castFrom(mDescramblerBase);
607 ASSERT_NE(descrambler, nullptr);
608
609 Status descrambleStatus = Status::OK;
Chong Zhang704d5862017-10-10 13:03:18 -0700610 sp<IMemory> dataMemory;
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530611
Chong Zhang704d5862017-10-10 13:03:18 -0700612 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530613 EXPECT_EQ(Status::ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED, descrambleStatus);
614
615 // Now set a valid session, should still fail because no valid ecm is processed
616 returnStatus = mDescramblerBase->setMediaCasSession(sessionId);
617 EXPECT_TRUE(returnStatus.isOk());
618 EXPECT_EQ(Status::OK, returnStatus);
619
Chong Zhang704d5862017-10-10 13:03:18 -0700620 ASSERT_TRUE(descrambleTestInputBuffer(descrambler, &descrambleStatus, &dataMemory));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530621 EXPECT_EQ(Status::ERROR_CAS_DECRYPT, descrambleStatus);
Suresh Sivaraman6d176aa2017-10-04 14:37:36 +0530622
623 // Verify that requiresSecureDecoderComponent handles empty mime
624 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent(""));
625
626 // Verify that requiresSecureDecoderComponent handles invalid mime
627 EXPECT_FALSE(mDescramblerBase->requiresSecureDecoderComponent("bad"));
Suresh Sivaraman0645aec2017-09-21 18:44:24 +0530628}
629
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530630} // anonymous namespace
631
632int main(int argc, char** argv) {
Zhuoyao Zhanga5e67072018-02-08 20:43:55 -0800633 ::testing::AddGlobalTestEnvironment(CasHidlEnvironment::Instance());
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530634 ::testing::InitGoogleTest(&argc, argv);
Zhuoyao Zhanga5e67072018-02-08 20:43:55 -0800635 CasHidlEnvironment::Instance()->init(&argc, argv);
Suresh Sivaramanf1fbb442017-09-15 11:51:15 +0530636 int status = RUN_ALL_TESTS();
637 LOG(INFO) << "Test result = " << status;
638 return status;
639}