author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Wed, 13 Oct 2010 14:23:59 +0300 | |
branch | RCL_3 |
changeset 83 | 26b2b12093af |
parent 66 | 2455ef1f5bbc |
permissions | -rw-r--r-- |
66 | 1 |
/* |
2 |
* Copyright (c) 2009 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: A CoreUi Avkon implementation. |
|
15 |
* |
|
16 |
*/ |
|
17 |
||
18 |
#include <string.h> |
|
19 |
#include <apgwgnam.h> |
|
20 |
#include <akntitle.h> |
|
21 |
||
22 |
#include "logger.h" |
|
23 |
#include "coreuiavkonimpl.h" |
|
24 |
#include "javauiavkonimpl.h" |
|
25 |
#include "runtimeexception.h" |
|
26 |
#include "javacommonutils.h" |
|
27 |
||
28 |
using namespace java::ui; |
|
29 |
using namespace java::util; |
|
30 |
||
31 |
// ======== STATIC VARIABLES ======== |
|
32 |
||
33 |
/** |
|
34 |
* Singleton |
|
35 |
*/ |
|
36 |
||
37 |
NONSHARABLE_CLASS(CoreUiGlobals) |
|
38 |
{ |
|
39 |
public: |
|
40 |
CoreUiGlobals() : mUiCore(0) |
|
41 |
{ |
|
42 |
} |
|
43 |
||
44 |
public: |
|
45 |
java::ui::CoreUiAvkonImpl* mUiCore; |
|
46 |
}; |
|
47 |
||
48 |
||
49 |
#if defined(__WINSCW__) |
|
50 |
||
51 |
#include <pls.h> |
|
52 |
CoreUiGlobals* getCoreUiGlobals() |
|
53 |
{ |
|
54 |
// Access the PLS of this process |
|
55 |
CoreUiGlobals* globals = |
|
56 |
Pls<CoreUiGlobals>(TUid::Uid(0x2002703C)); |
|
57 |
return globals; |
|
58 |
} |
|
59 |
||
60 |
#else |
|
61 |
||
62 |
||
63 |
static CoreUiGlobals* sGlobals = 0; |
|
64 |
||
65 |
CoreUiGlobals* getCoreUiGlobals() |
|
66 |
{ |
|
67 |
if (sGlobals == 0) |
|
68 |
{ |
|
69 |
sGlobals = new CoreUiGlobals(); // codescanner::nonleavenew |
|
70 |
} |
|
71 |
return sGlobals; |
|
72 |
} |
|
73 |
#endif |
|
74 |
||
75 |
||
76 |
CoreUi& getUiInstance() |
|
77 |
{ |
|
78 |
JELOG2(EJavaUI); |
|
79 |
CoreUiGlobals* globals = getCoreUiGlobals(); |
|
80 |
if (globals->mUiCore == 0) |
|
81 |
{ |
|
82 |
globals->mUiCore = new CoreUiAvkonImpl(); // codescanner::nonleavenew |
|
83 |
} |
|
84 |
||
85 |
return *globals->mUiCore; |
|
86 |
} |
|
87 |
||
88 |
void releaseUi() |
|
89 |
{ |
|
90 |
JELOG2(EJavaUI); |
|
91 |
CoreUiGlobals* globals = getCoreUiGlobals(); |
|
92 |
if (globals->mUiCore) |
|
93 |
{ |
|
94 |
globals->mUiCore->dispose(); |
|
95 |
} |
|
96 |
} |
|
97 |
||
98 |
EXPORT_C FuncPtr findDllMethod(const char* funcName) |
|
99 |
{ |
|
100 |
JELOG2(EJavaUI); |
|
101 |
FuncPtr ptr = 0; |
|
102 |
if (strcmp(funcName, "getUiInstance") == 0) |
|
103 |
{ |
|
104 |
ptr = (FuncPtr)getUiInstance; |
|
105 |
} |
|
106 |
else if (strcmp(funcName, "releaseUi") == 0) |
|
107 |
{ |
|
108 |
ptr = (FuncPtr)releaseUi; |
|
109 |
} |
|
110 |
return ptr; |
|
111 |
} |
|
112 |
||
113 |
EXPORT_C bool CoreUiAvkon::isCoreUiCreated() |
|
114 |
{ |
|
115 |
JELOG2(EJavaUI); |
|
116 |
CoreUiGlobals* globals = getCoreUiGlobals(); |
|
117 |
return globals->mUiCore != 0; |
|
118 |
} |
|
119 |
||
120 |
EXPORT_C CoreUiAvkonLcdui& CoreUiAvkonLcdui::getInstance() |
|
121 |
{ |
|
122 |
JELOG2(EJavaUI); |
|
123 |
return static_cast<CoreUiAvkonLcdui&>( |
|
124 |
static_cast<CoreUiAvkonImpl&>(getUiInstance())); |
|
125 |
} |
|
126 |
||
127 |
EXPORT_C CoreUiAvkonEswt& CoreUiAvkonEswt::getInstance() |
|
128 |
{ |
|
129 |
JELOG2(EJavaUI); |
|
130 |
return static_cast<CoreUiAvkonEswt&>( |
|
131 |
static_cast<CoreUiAvkonImpl&>(getUiInstance())); |
|
132 |
} |
|
133 |
||
134 |
CoreUiAvkonImpl& CoreUiAvkonImpl::getInstanceImpl() |
|
135 |
{ |
|
136 |
JELOG2(EJavaUI); |
|
137 |
return static_cast<CoreUiAvkonImpl&>(::getUiInstance()); |
|
138 |
} |
|
139 |
||
140 |
CoreUiAvkonImpl::CoreUiAvkonImpl() : mJavaUiAvkonEnv(0), mWgName(0), |
|
141 |
mJavaUiAppUi(0), |
|
142 |
mState(Constructed), mShowStartScreen(true), |
|
143 |
mJavaVm(0), mShutDownPending(false), |
|
144 |
mShutdownTimer(0) |
|
145 |
{ |
|
146 |
JELOG2(EJavaUI); |
|
147 |
mLock.CreateLocal(); |
|
148 |
||
149 |
} |
|
150 |
||
151 |
||
152 |
CoreUiAvkonImpl::~CoreUiAvkonImpl() |
|
153 |
{ |
|
154 |
JELOG2(EJavaUI); |
|
155 |
delete mWgName; |
|
156 |
mWgName = 0; |
|
157 |
mLock.Close(); |
|
158 |
} |
|
159 |
||
160 |
void CoreUiAvkonImpl::ensureInitialized(const TUid& appUid, |
|
161 |
CoreUiParams* params) |
|
162 |
{ |
|
163 |
JELOG2(EJavaUI); |
|
164 |
if (mJavaUiAvkonEnv == 0) |
|
165 |
{ |
|
166 |
java::util::Uid uid; |
|
167 |
TUidToUid(appUid, uid); |
|
168 |
||
169 |
start(uid, params); |
|
170 |
} |
|
171 |
} |
|
172 |
||
173 |
||
174 |
CoreUiAvkonLcduiSupport& CoreUiAvkonImpl::getLcduiSupport() |
|
175 |
{ |
|
176 |
return mLcduiSupport; |
|
177 |
} |
|
178 |
||
179 |
CoreUiAvkonEswtSupport& CoreUiAvkonImpl::getEswtSupport() |
|
180 |
{ |
|
181 |
return mEswtSupport; |
|
182 |
} |
|
183 |
||
184 |
void CoreUiAvkonImpl::start(const java::util::Uid& midletUid, |
|
185 |
CoreUiParams* uiParams) |
|
186 |
{ |
|
187 |
mMidletUid = midletUid; |
|
188 |
if (uiParams != 0) |
|
189 |
{ |
|
190 |
mCoreUiParams = *uiParams; |
|
191 |
} |
|
192 |
mLcduiSupport.startUiThread(*this); |
|
193 |
} |
|
194 |
||
195 |
void CoreUiAvkonImpl::startScheduler() |
|
196 |
{ |
|
197 |
JELOG2(EJavaUI); |
|
198 |
if (mJavaUiAvkonEnv != 0) |
|
199 |
{ |
|
200 |
mState = CoreUiCreated; |
|
201 |
mJavaUiAvkonEnv->ExecuteD(); |
|
202 |
cancelShutdownTimer(); |
|
203 |
mEswtSupport.dispose(); |
|
204 |
mJavaUiAvkonEnv = 0; |
|
205 |
delete mWgName; |
|
206 |
mWgName = 0; |
|
207 |
} |
|
208 |
mState = Destroyed; |
|
209 |
} |
|
210 |
||
211 |
void CoreUiAvkonImpl::createUi() |
|
212 |
{ |
|
213 |
JELOG2(EJavaUI); |
|
214 |
// Construct the environment (EikonEnv + AppUi + server) |
|
215 |
||
216 |
// The cleanup stack is created here |
|
217 |
mJavaUiAvkonEnv = new CEikonEnv; // codescanner::nonleavenew |
|
218 |
||
219 |
if (mJavaUiAvkonEnv != 0) |
|
220 |
{ |
|
221 |
uidToTUid(mMidletUid, mMidletTUid); |
|
222 |
if (mMidletUid == Uid(L"[2001843a]") || // Is it installer. |
|
83
26b2b12093af
Revision: v2.2.17
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
66
diff
changeset
|
223 |
mMidletUid == Uid(L"[2002121e]")) // Is it TCK runner. |
66 | 224 |
{ |
225 |
mShowStartScreen = false; |
|
226 |
} |
|
227 |
TRAPD(status, initAvkonUiL()); |
|
228 |
if (status != KErrNone) |
|
229 |
{ |
|
230 |
// Deletes AS and CleanupTrap. No need to call 'delete env'. |
|
231 |
mJavaUiAvkonEnv->DestroyEnvironment(); |
|
232 |
std::string errorStr("Ui creation failed: "); |
|
233 |
errorStr.append(JavaCommonUtils::intToString(status)); |
|
234 |
throw java::runtime::RuntimeException(errorStr, __FILE__, __FUNCTION__, __LINE__); |
|
235 |
} |
|
236 |
mEswtSupport.uiThreadInit(); |
|
237 |
} |
|
238 |
} |
|
239 |
||
240 |
void CoreUiAvkonImpl::initAvkonUiL() |
|
241 |
{ |
|
242 |
JELOG2(EJavaUI); |
|
243 |
TApaApplicationFactory appFactory(newJavaApplication); |
|
244 |
||
245 |
CApaCommandLine* appCmdLine = CApaCommandLine::NewLC(); |
|
246 |
appCmdLine->SetExecutableNameL(KNullDesC); // None - app function provided by the app factory |
|
247 |
appCmdLine->SetDefaultScreenL(0); |
|
248 |
appCmdLine->SetServerNotRequiredL(); // |
|
249 |
if (mCoreUiParams.isBackgroundStart()) |
|
250 |
{ |
|
251 |
appCmdLine->SetCommandL(EApaCommandBackground); |
|
252 |
} |
|
253 |
mJavaUiAvkonEnv->DisableExitChecks(ETrue); |
|
254 |
mJavaUiAvkonEnv->ConstructAppFromCommandLineL(appFactory, *appCmdLine); |
|
255 |
||
256 |
CleanupStack::PopAndDestroy(appCmdLine); |
|
257 |
||
258 |
mJavaUiAvkonEnv->AppUiFactory()->StatusPane()->MakeVisible(EFalse); |
|
259 |
||
260 |
||
261 |
// Contruct the WindowsGroupName, used to change the displayed name in the tasklist |
|
262 |
mWgName = CApaWindowGroupName::NewL(mJavaUiAvkonEnv->WsSession()); |
|
263 |
mWgName->SetRespondsToSwitchFilesEvent(EFalse); |
|
264 |
mWgName->SetRespondsToShutdownEvent(ETrue); |
|
265 |
mWgName->SetHidden(EFalse); |
|
266 |
mWgName->SetAppUid(mMidletTUid); |
|
267 |
mWgName->SetWindowGroupName(mJavaUiAvkonEnv->RootWin()); |
|
268 |
||
269 |
mJavaUiAvkonEnv->RootWin().EnableReceiptOfFocus(ETrue); |
|
270 |
} |
|
271 |
||
272 |
||
273 |
void CoreUiAvkonImpl::dispose() |
|
274 |
{ |
|
275 |
JELOG2(EJavaUI); |
|
276 |
bool canBeDisposed = mJavaUiAppUi == 0 || |
|
277 |
(mJavaUiAppUi && mJavaUiAppUi->isClosingPossible()); |
|
278 |
if (canBeDisposed) |
|
279 |
{ |
|
280 |
if (mState != Destroyed) |
|
281 |
{ |
|
282 |
mLcduiSupport.closeUi(); |
|
283 |
} |
|
284 |
delete this; |
|
285 |
CoreUiGlobals* globals = getCoreUiGlobals(); |
|
286 |
globals->mUiCore = 0; |
|
287 |
} |
|
288 |
} |
|
289 |
||
290 |
CApaWindowGroupName* CoreUiAvkonImpl::getWindowGroupName() const |
|
291 |
{ |
|
292 |
JELOG2(EJavaUI); |
|
293 |
return mWgName; |
|
294 |
} |
|
295 |
||
296 |
bool CoreUiAvkonImpl::showStartScreen() const |
|
297 |
{ |
|
298 |
JELOG2(EJavaUI); |
|
299 |
return mShowStartScreen && mCoreUiParams.getScreenMode() != NO_START_SCREEN; |
|
300 |
} |
|
301 |
||
302 |
||
303 |
CoreUiAvkonAppUi* CoreUiAvkonImpl::getJavaUiAppUi() const |
|
304 |
{ |
|
305 |
JELOG2(EJavaUI); |
|
306 |
return mJavaUiAppUi; |
|
307 |
} |
|
308 |
||
309 |
CAknAppUi* CoreUiAvkonImpl::getJavaAknAppUi() const |
|
310 |
{ |
|
311 |
JELOG2(EJavaUI); |
|
312 |
return mJavaUiAppUi; |
|
313 |
} |
|
314 |
||
315 |
void CoreUiAvkonImpl::setJavaUiAppUi(JavaUiAvkonAppUi* appUi) |
|
316 |
{ |
|
317 |
JELOG2(EJavaUI); |
|
318 |
mJavaUiAppUi = appUi; |
|
319 |
} |
|
320 |
||
321 |
RHeap* CoreUiAvkonImpl::getProcessHeap() const |
|
322 |
{ |
|
323 |
JELOG2(EJavaUI); |
|
324 |
return mLcduiSupport.getProcessHeap(); |
|
325 |
} |
|
326 |
||
327 |
RHeap* CoreUiAvkonImpl::getUiThreadHeap() const |
|
328 |
{ |
|
329 |
JELOG2(EJavaUI); |
|
330 |
return mLcduiSupport.getUiThreadHeap(); |
|
331 |
} |
|
332 |
||
333 |
||
334 |
bool CoreUiAvkonImpl::setJavaVm(JNIEnv* env) |
|
335 |
{ |
|
336 |
JELOG2(EJavaUI); |
|
337 |
mLock.Wait(); |
|
338 |
bool result = false; // Meaning the starting of the MIDlet |
|
339 |
// should not be allowed. |
|
340 |
LOG(EJavaUI, EInfo, "Setting JavaVm"); |
|
341 |
if (!mShutDownPending) |
|
342 |
{ |
|
343 |
LOG(EJavaUI, EInfo, " No pending shutdown"); |
|
344 |
env->GetJavaVM(&mJavaVm); // Get pointer to VM |
|
345 |
if (mJavaVm) |
|
346 |
{ |
|
347 |
LOG(EJavaUI, EInfo, " Got the VM"); |
|
348 |
result = true; |
|
349 |
} |
|
350 |
else |
|
351 |
{ |
|
352 |
ELOG(EJavaUI, "JNI attachUiToVm(), GetJavaVM(() failed"); |
|
353 |
} |
|
354 |
} |
|
355 |
mLock.Signal(); |
|
356 |
LOG1(EJavaUI, EInfo, "CoreUiAvkonImpl::setJavaPeer result = %d", result); |
|
357 |
return result; |
|
358 |
} |
|
359 |
||
360 |
void CoreUiAvkonImpl::shutDownRequestFromWindowServer() |
|
361 |
{ |
|
362 |
JELOG2(EJavaUI); |
|
363 |
LOG(EJavaUI, EInfo, "shutDownRequestFromWindowServer"); |
|
364 |
mLock.Wait(); |
|
365 |
if (mState != ShuttingDown) |
|
366 |
{ |
|
367 |
mState = ShuttingDown; |
|
368 |
if (mShutdownTimer == 0) |
|
369 |
{ |
|
370 |
TRAP_IGNORE(setShutdownTimerL()); |
|
371 |
} |
|
372 |
LOG(EJavaUI, EInfo, " mState != SHUTTING_DOWN"); |
|
373 |
if (mJavaVm) // Check if the VM already running. |
|
374 |
{ |
|
375 |
LOG(EJavaUI, EInfo, " We have the VM"); |
|
376 |
||
377 |
bool success = |
|
378 |
callStaticVoidJavaMethod("com/nokia/mj/impl/coreui/CoreUi", |
|
379 |
"shutdownRequest", |
|
380 |
"()V"); |
|
381 |
||
382 |
if (!success) |
|
383 |
{ |
|
384 |
ELOG(EJavaUI, "Killing process forcefully"); |
|
385 |
RProcess().Kill(-1); |
|
386 |
} |
|
387 |
||
388 |
||
389 |
} |
|
390 |
else |
|
391 |
{ |
|
392 |
LOG(EJavaUI, EInfo, " Pending request"); |
|
393 |
// No, pend the request. |
|
394 |
mShutDownPending = true; |
|
395 |
} |
|
396 |
} |
|
397 |
mLock.Signal(); |
|
398 |
} |
|
399 |
||
400 |
bool CoreUiAvkonImpl::callStaticVoidJavaMethod(const char* className, |
|
401 |
const char* methodName, |
|
402 |
const char* methodSignature, |
|
403 |
...) |
|
404 |
{ |
|
405 |
JELOG2(EJavaUI); |
|
406 |
bool success = false; |
|
407 |
||
408 |
JNIEnv* env; |
|
409 |
#ifdef RD_JAVA_UITHREAD_OWN_HEAP |
|
410 |
User::SwitchHeap(getProcessHeap()); |
|
411 |
#endif // RD_JAVA_UITHREAD_OWN_HEAP |
|
412 |
int result = mJavaVm->AttachCurrentThread((void**)&env, 0); |
|
413 |
if (result == 0) |
|
414 |
{ |
|
415 |
LOG(EJavaUI, EInfo, " VM Attached"); |
|
416 |
jclass clz = env->FindClass(className); |
|
417 |
if (clz != 0) |
|
418 |
{ |
|
419 |
LOG(EJavaUI, EInfo, " jclass created"); |
|
420 |
jmethodID methodId = |
|
421 |
env->GetStaticMethodID(clz, methodName, methodSignature); |
|
422 |
if (methodId != 0) |
|
423 |
{ |
|
424 |
LOG(EJavaUI, EInfo, " methodId created"); |
|
425 |
va_list args; |
|
426 |
va_start(args, methodSignature); |
|
427 |
env->CallStaticVoidMethodV(clz, methodId, args); |
|
428 |
LOG(EJavaUI, EInfo, " CallStaticVoidMethodV done"); |
|
429 |
va_end(args); |
|
430 |
// Close message sent successfully to Java side. |
|
431 |
success = true; |
|
432 |
} |
|
433 |
else |
|
434 |
{ |
|
435 |
ELOG(EJavaUI, "callStaticVoidJavaMethod, " |
|
436 |
"GetMethodID(() failed"); |
|
437 |
} |
|
438 |
env->DeleteLocalRef(clz); |
|
439 |
} |
|
440 |
else |
|
441 |
{ |
|
442 |
ELOG(EJavaUI, "callStaticVoidJavaMethod, " |
|
443 |
"GetObjectClass() failed"); |
|
444 |
} |
|
445 |
result = mJavaVm->DetachCurrentThread(); |
|
446 |
LOG1(EJavaUI, EInfo, " DetachCurrentThread done, st = %d", result); |
|
447 |
} |
|
448 |
else |
|
449 |
{ |
|
450 |
ELOG(EJavaUI, "callStaticVoidJavaMethod, " |
|
451 |
"AttachCurrentThread() failed"); |
|
452 |
} |
|
453 |
#ifdef RD_JAVA_UITHREAD_OWN_HEAP |
|
454 |
User::SwitchHeap(getUiThreadHeap()); |
|
455 |
#endif // RD_JAVA_UITHREAD_OWN_HEAP |
|
456 |
return success; |
|
457 |
} |
|
458 |
||
459 |
void CoreUiAvkonImpl::setShutdownTimerL() |
|
460 |
{ |
|
461 |
JELOG2(EJavaUI); |
|
462 |
LOG(EJavaUI, EInfo, "setShutdownTimerL"); |
|
463 |
mShutdownTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
|
464 |
mShutdownTimer->Start(8000000, 1000000, |
|
465 |
TCallBack(shutdownTimerCallback, 0)); |
|
466 |
} |
|
467 |
||
468 |
void CoreUiAvkonImpl::cancelShutdownTimer() |
|
469 |
{ |
|
470 |
JELOG2(EJavaUI); |
|
471 |
LOG(EJavaUI, EInfo, "cancelShutdownTimer"); |
|
472 |
if (mShutdownTimer) |
|
473 |
{ |
|
474 |
if (mShutdownTimer->IsActive()) |
|
475 |
{ |
|
476 |
LOG(EJavaUI, EInfo, " It was active"); |
|
477 |
mShutdownTimer->Cancel(); |
|
478 |
} |
|
479 |
delete mShutdownTimer; |
|
480 |
mShutdownTimer = 0; |
|
481 |
} |
|
482 |
} |
|
483 |
||
484 |
TInt CoreUiAvkonImpl::shutdownTimerCallback(TAny*) |
|
485 |
{ |
|
486 |
JELOG2(EJavaUI); |
|
487 |
ELOG(EJavaUI, "Killing process forcefully due to timer"); |
|
488 |
RProcess().Kill(-1); |
|
489 |
return 0; |
|
490 |
} |