|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Handles DRM File IO Operations |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <errno.h> |
|
19 #include <unistd.h> |
|
20 #include <string> |
|
21 |
|
22 #include "s60commonutils.h" |
|
23 #include "javacommonutils.h" |
|
24 #include "jniarrayutils.h" |
|
25 #include "logger.h" |
|
26 #include "functionserver.h" |
|
27 #include "fs_methodcall.h" |
|
28 |
|
29 #include "filedrmcontenthandler.h" |
|
30 #include "s60filesystemutilities.h" |
|
31 #include "com_nokia_mj_impl_fileutils_FileDRMContentHandler.h" |
|
32 |
|
33 using namespace std; |
|
34 using namespace java::util; |
|
35 using namespace java::fileutils; |
|
36 |
|
37 TBool FileDRMContentHandler::isDRMProtectedFile(const TDesC& aFullName) |
|
38 { |
|
39 JELOG2(EJavaFile); |
|
40 LOG(EJavaFile, EInfo, "+FileDRMContentHandler::isDRMProtectedFile{}"); |
|
41 TInt value = 0; |
|
42 HBufC* fileName = 0; |
|
43 |
|
44 TRAPD(err, fileName = HBufC::NewL(aFullName.Length())); |
|
45 if (KErrNone == err) |
|
46 { |
|
47 TPtr fileNamePtr(fileName->Des()); |
|
48 fileNamePtr = aFullName; |
|
49 S60FileSystemUtilities::ReplaceCharacters(fileNamePtr, '/', '\\'); |
|
50 |
|
51 ContentAccess::CContent* content = 0; |
|
52 // Use CAF to check whether the content is protected |
|
53 TRAP(err, content = ContentAccess::CContent::NewL(fileNamePtr)); |
|
54 |
|
55 if (KErrNone == err) |
|
56 { |
|
57 LOG(EJavaFile, EInfo, |
|
58 " FileDRMContentHandler::isDRMProtectedFile: " \ |
|
59 "Getting attribute."); |
|
60 err = content->GetAttribute(ContentAccess::EIsProtected, value); |
|
61 if (err != KErrNone) |
|
62 { |
|
63 return EFalse; |
|
64 } |
|
65 delete content; //Cleanup after NewL |
|
66 } |
|
67 } |
|
68 LOG1(EJavaFile, EInfo, |
|
69 "-FileDRMContentHandler::isDRMProtectedFile: returns %d", |
|
70 value); |
|
71 delete fileName; |
|
72 return value ? ETrue : EFalse; |
|
73 } |
|
74 |
|
75 ContentAccess::TIntent FileDRMContentHandler::mapIntentToCAF(TInt aIntent) |
|
76 { |
|
77 JELOG2(EJavaFile); |
|
78 ContentAccess::TIntent intent; |
|
79 switch (aIntent) |
|
80 { |
|
81 case com_nokia_mj_impl_fileutils_FileDRMContentHandler_Peek: |
|
82 intent = ContentAccess::EPeek; |
|
83 break; |
|
84 case com_nokia_mj_impl_fileutils_FileDRMContentHandler_Play: |
|
85 intent = ContentAccess::EPlay; |
|
86 break; |
|
87 case com_nokia_mj_impl_fileutils_FileDRMContentHandler_View: |
|
88 intent = ContentAccess::EView; |
|
89 break; |
|
90 case com_nokia_mj_impl_fileutils_FileDRMContentHandler_Execute: |
|
91 intent = ContentAccess::EExecute; |
|
92 break; |
|
93 case com_nokia_mj_impl_fileutils_FileDRMContentHandler_Print: |
|
94 intent = ContentAccess::EPrint; |
|
95 break; |
|
96 default: |
|
97 intent = ContentAccess::EUnknown; |
|
98 } |
|
99 return intent; |
|
100 |
|
101 } |
|
102 |
|
103 void FileDRMContentHandler::setDrmArguments(TInt aIntent, TBool aExecuteIntent) |
|
104 { |
|
105 LOG2(EJavaFile, EInfo, "FileDRMContentHandler::setDrmArguments(): " |
|
106 " Intent to %d and Set Intent?", aIntent, aExecuteIntent); |
|
107 |
|
108 mExecuteIntent = aExecuteIntent; |
|
109 mDrmIntent = mapIntentToCAF(aIntent); |
|
110 } |
|
111 |
|
112 FileDRMContentHandler::FileDRMContentHandler(const std::wstring aName) : |
|
113 NativeFileIOHandler(aName), mContent(0), mData(0), mReadPosition(0) |
|
114 { |
|
115 // CContent and CData both use RFile internally. |
|
116 // Calling in different thread context will result in a panic. |
|
117 // Hence we need to use Function Server to maintain a single thread context. |
|
118 LOG(EJavaFile, EInfo, "FileDRMContentHandler: Creating new FunctionServer"); |
|
119 mFunctionServer = new FunctionServer("FileDRMContentHandler"); |
|
120 mFunctionServer->createServerToNewThread(); |
|
121 } |
|
122 |
|
123 FileDRMContentHandler::~FileDRMContentHandler() |
|
124 { |
|
125 JELOG2(EJavaFile); |
|
126 CallMethod(this, &FileDRMContentHandler::clearContent, mFunctionServer); |
|
127 delete mFunctionServer; |
|
128 } |
|
129 |
|
130 void FileDRMContentHandler::clearContent() |
|
131 { |
|
132 if (mContent) |
|
133 { |
|
134 delete mContent; |
|
135 mContent = 0; |
|
136 } |
|
137 |
|
138 if (mData) |
|
139 { |
|
140 delete mData; |
|
141 mData = 0; |
|
142 } |
|
143 } |
|
144 |
|
145 long FileDRMContentHandler::skip(const long aOffset) |
|
146 { |
|
147 long result = 0; |
|
148 CallMethod(result, this, &FileDRMContentHandler::skipFs, aOffset, |
|
149 mFunctionServer); |
|
150 return result; |
|
151 } |
|
152 |
|
153 long FileDRMContentHandler::skipFs(const long aOffset) |
|
154 { |
|
155 JELOG2(EJavaFile); |
|
156 handleReopenCase(); |
|
157 |
|
158 TInt pos = aOffset; |
|
159 TInt currentOffset = mReadPosition; |
|
160 |
|
161 LOG1(EJavaFile, EInfo, "FileDRMContentHandler::skip: trying to skip: %d", |
|
162 aOffset); |
|
163 |
|
164 TInt error = mData->Seek(ESeekCurrent, pos); |
|
165 TInt skipped = 0; |
|
166 |
|
167 if (KErrNone == error) |
|
168 { |
|
169 mReadPosition = pos; |
|
170 LOG1(EJavaFile, EInfo, |
|
171 "FileDRMContentHandler::skip: setting read pos to: %d", |
|
172 mReadPosition); |
|
173 skipped = (mReadPosition - currentOffset); |
|
174 } |
|
175 |
|
176 LOG1(EJavaFile, EInfo, "FileDRMContentHandler::skip: skipped: %d", skipped); |
|
177 return skipped; |
|
178 } |
|
179 |
|
180 int FileDRMContentHandler::readBytes(char* aBuffer, int aLength) |
|
181 { |
|
182 int result = 0; |
|
183 CallMethod(result, this, &FileDRMContentHandler::readBytesFs, aBuffer, |
|
184 aLength, mFunctionServer); |
|
185 return result; |
|
186 } |
|
187 |
|
188 int FileDRMContentHandler::readBytesFs(char* aBuffer, int aLength) |
|
189 { |
|
190 JELOG2(EJavaFile); |
|
191 handleReopenCase(); |
|
192 |
|
193 HBufC8* data = HBufC8::New(aLength + 1); |
|
194 TPtr8 buffer(data->Des()); |
|
195 LOG(EJavaFile, EInfo, "FileDRMContentHandler::readBytes() Reading data..."); |
|
196 |
|
197 TInt error = mData->Read(buffer, aLength); |
|
198 TInt bytesRead = buffer.Size(); |
|
199 |
|
200 memcpy(aBuffer, buffer.Ptr(), bytesRead); |
|
201 aBuffer[bytesRead] = 0; |
|
202 |
|
203 mReadPosition += bytesRead; |
|
204 delete data; |
|
205 |
|
206 LOG1(EJavaFile, EInfo, "FileDRMContentHandler::readBytes: returning: %d", |
|
207 bytesRead); |
|
208 return bytesRead; |
|
209 } |
|
210 |
|
211 int FileDRMContentHandler::writeBytes(char* /*aBuffer*/, int /*aLength*/) |
|
212 { |
|
213 JELOG2(EJavaFile); |
|
214 // There is no write for DRM protected content. We should not be here. |
|
215 return 0; |
|
216 } |
|
217 |
|
218 void FileDRMContentHandler::stopReading() |
|
219 { |
|
220 JELOG2(EJavaFile); |
|
221 mReadPosition = 0; |
|
222 } |
|
223 |
|
224 void FileDRMContentHandler::stopWriting() |
|
225 { |
|
226 JELOG2(EJavaFile); |
|
227 ELOG(EJavaFile, "FileDRMContentHandler::stopWriting() " |
|
228 " WE SHOULD NEVER BE HERE. SOMETHING WRONG."); |
|
229 // NOTE: There is no write for DRM protected content. We should not be here. |
|
230 } |
|
231 |
|
232 void FileDRMContentHandler::initializeAndOpenL() |
|
233 { |
|
234 JELOG2(EJavaFile); |
|
235 |
|
236 LOG(EJavaFile, EInfo, "+FileDRMContentHandler::initializeAndOpenL() "); |
|
237 |
|
238 // Check and initialize DRM content here. |
|
239 HBufC* fileName = S60CommonUtils::wstringToDes(mFileName.c_str()); |
|
240 TPtr fileNameDes(fileName->Des()); |
|
241 S60FileSystemUtilities::ReplaceCharacters(fileNameDes, '/', '\\'); |
|
242 |
|
243 CleanupStack::PushL(fileName); |
|
244 |
|
245 mContent = ContentAccess::CContent::NewL(fileNameDes); |
|
246 mData = mContent->OpenContentL(mDrmIntent); |
|
247 LOG(EJavaFile, EInfo, |
|
248 " FileDRMContentHandler::initializeAndOpenL(): Content opened."); |
|
249 |
|
250 int error = mData->EvaluateIntent(mDrmIntent); |
|
251 User::LeaveIfError(error); |
|
252 |
|
253 LOG(EJavaFile, EInfo, |
|
254 " FileDRMContentHandler::initializeAndOpenL(): Intent evaluated"); |
|
255 |
|
256 if (mExecuteIntent) |
|
257 { |
|
258 LOG(EJavaFile, EInfo, |
|
259 " FileDRMContentHandler::initializeAndOpenL(): Executing intent"); |
|
260 |
|
261 // Initialize and open should be called only once until the file is not closed. |
|
262 error = mData->ExecuteIntent(mDrmIntent); |
|
263 User::LeaveIfError(error); |
|
264 } |
|
265 |
|
266 CleanupStack::PopAndDestroy(fileName); |
|
267 LOG(EJavaFile, EInfo, "-FileDRMContentHandler::initializeAndOpenL() "); |
|
268 } |
|
269 |
|
270 void FileDRMContentHandler::openForReading() |
|
271 { |
|
272 JELOG2(EJavaFile); |
|
273 LOG1(EJavaFile, EInfo, "FileDRMContentHandler::openForReading(): " |
|
274 " Opening: %S", mFileName.c_str()); |
|
275 |
|
276 TRAPD(error, CallMethodL(this, |
|
277 &java::fileutils::FileDRMContentHandler::initializeAndOpenL, |
|
278 mFunctionServer)); |
|
279 |
|
280 if ((KErrCANoPermission == error) || (KErrCANoRights == error) |
|
281 || (KErrCAPendingRights == error)) |
|
282 { |
|
283 ELOG1(EJavaFile, "FileDRMContentHandler::openForReading() Open failed." |
|
284 " Error: %d", error); |
|
285 throw EPERM; |
|
286 } |
|
287 |
|
288 if (KErrNone != error) |
|
289 { |
|
290 ELOG1(EJavaFile, "FileDRMContentHandler::openForReading() Open failed." |
|
291 " Error: %d", error); |
|
292 throw EIO; |
|
293 } |
|
294 |
|
295 mReadPosition = 0; |
|
296 } |
|
297 |
|
298 void FileDRMContentHandler::openForWriting(const long /*aOffset*/) |
|
299 { |
|
300 JELOG2(EJavaFile); |
|
301 // NOTE: There is no write for DRM protected content. We should not be here. |
|
302 ELOG(EJavaFile, "FileDRMContentHandler::openForWriting(): " |
|
303 " Trying to write into DRM file. Throwing exception EPERM."); |
|
304 throw EPERM; |
|
305 } |
|
306 |
|
307 void FileDRMContentHandler::closeFileToReopen() |
|
308 { |
|
309 JELOG2(EJavaFile); |
|
310 // We never close file to re-open again. |
|
311 } |
|
312 |
|
313 void FileDRMContentHandler::handleReopenCase() |
|
314 { |
|
315 JELOG2(EJavaFile); |
|
316 // File is never closed temporarily in case of DRM files. |
|
317 // Kept for future use. |
|
318 } |
|
319 |
|
320 long FileDRMContentHandler::available() |
|
321 { |
|
322 JELOG2(EJavaFile); |
|
323 TInt fileLength = 0; |
|
324 TRAPD(error, CallMethodL(mData, &ContentAccess::CData::DataSizeL, |
|
325 fileLength, mFunctionServer)); |
|
326 |
|
327 TInt total = 0; |
|
328 if (KErrNone == error) |
|
329 { |
|
330 total = fileLength - mReadPosition; |
|
331 } |
|
332 |
|
333 LOG1(EJavaFile, EInfo, "FileDRMContentHandler::available: Returning: %d", |
|
334 total); |
|
335 return total; |
|
336 } |
|
337 |