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