161 TInt pluginIndex = iPluginList->Count(); |
161 TInt pluginIndex = iPluginList->Count(); |
162 while (pluginIndex--) |
162 while (pluginIndex--) |
163 { |
163 { |
164 // Get the config for this plugin |
164 // Get the config for this plugin |
165 CGOomRunPluginConfig& pluginConfig = aConfig.GetPluginConfig(iPluginList->Uid(pluginIndex)); |
165 CGOomRunPluginConfig& pluginConfig = aConfig.GetPluginConfig(iPluginList->Uid(pluginIndex)); |
166 TInt priority = pluginConfig.CalculatePluginPriority(aWindowGroupList); |
|
167 |
|
168 TGOomSyncMode syncMode = pluginConfig.iSyncMode; |
|
169 TInt ramEstimate = pluginConfig.iRamEstimate; |
|
170 |
|
171 TActionRef::TActionType actionType; |
|
172 |
|
173 if (pluginConfig.PluginType() == EGOomAppPlugin) |
|
174 { |
|
175 actionType = TActionRef::EAppPlugin; |
|
176 } |
|
177 else |
|
178 actionType = TActionRef::ESystemPlugin; |
|
179 |
|
180 |
166 |
181 //get skip plugin config for foreground app |
167 //get skip plugin config for foreground app |
182 TUint foregroundUid = iMonitor.ForegroundAppUid(); |
168 TUint foregroundUid = iMonitor.ForegroundAppUid(); |
183 if(aConfig.GetApplicationConfig(foregroundUid).iSkipPluginId == iPluginList->Uid(pluginIndex)) |
169 if(aConfig.GetApplicationConfig(foregroundUid).iSkipPluginId == iPluginList->Uid(pluginIndex)) |
184 { |
170 { |
195 TRACES2("Skiping plugin %x, configured for app %x", iPluginList->Uid(pluginIndex), foregroundUid); |
181 TRACES2("Skiping plugin %x, configured for app %x", iPluginList->Uid(pluginIndex), foregroundUid); |
196 actionsIndex++; |
182 actionsIndex++; |
197 continue ; //skip this and continue with next plugin |
183 continue ; //skip this and continue with next plugin |
198 } |
184 } |
199 } |
185 } |
200 |
186 |
201 TActionRef ref = TActionRef(actionType, priority, syncMode, ramEstimate, *(iRunPluginActions[actionsIndex]), aWindowGroupList.GetIndexFromAppId(pluginConfig.TargetApp())); |
187 actionsIndex--; |
202 iAppsProtectedByPlugins.Append(pluginConfig.TargetApp()); |
188 CGOomRunPluginConfig * nextConfigForSamePlugin = &pluginConfig; |
203 TRACES2("Creating Plugin Action Item %x , TargetAppId %x", iPluginList->Uid(pluginIndex), pluginConfig.TargetApp()); |
189 while(nextConfigForSamePlugin) |
204 //It is valid to have plugins with equal priority |
190 { |
205 User::LeaveIfError(iActionRefs.InsertInOrderAllowRepeats(ref, ComparePriorities)); |
191 TInt priority = nextConfigForSamePlugin->CalculatePluginPriority(aWindowGroupList); |
|
192 TGOomSyncMode syncMode = nextConfigForSamePlugin->iSyncMode; |
|
193 TInt ramEstimate = nextConfigForSamePlugin->iRamEstimate; |
|
194 TActionRef::TActionType actionType; |
|
195 if (nextConfigForSamePlugin->PluginType() == EGOomAppPlugin) |
|
196 actionType = TActionRef::EAppPlugin; |
|
197 else |
|
198 actionType = TActionRef::ESystemPlugin; |
|
199 |
|
200 TActionRef ref = TActionRef(actionType, priority, syncMode, ramEstimate, *(iRunPluginActions[++actionsIndex]), aWindowGroupList.GetIndexFromAppId(nextConfigForSamePlugin->TargetApp())); |
|
201 iAppsProtectedByPlugins.Append(nextConfigForSamePlugin->TargetApp()); |
|
202 TRACES2("Creating Plugin Action Item %x , TargetAppId %x", iPluginList->Uid(pluginIndex), nextConfigForSamePlugin->TargetApp()); |
|
203 //It is valid to have plugins with equal priority |
|
204 User::LeaveIfError(iActionRefs.InsertInOrderAllowRepeats(ref, ComparePriorities)); |
|
205 nextConfigForSamePlugin = nextConfigForSamePlugin->iNextConfig; |
|
206 } |
206 |
207 |
207 actionsIndex++; |
208 actionsIndex++; |
208 } |
209 } |
209 |
210 |
210 TRACES1("BuildActionListL: Action list built with %d Plugin items",iActionRefs.Count()); |
211 TRACES1("BuildActionListL: Action list built with %d Plugin items",iActionRefs.Count()); |
227 iLowOnMemWgs.Append(aWindowGroupList.LowOnMemWgs(i)); |
228 iLowOnMemWgs.Append(aWindowGroupList.LowOnMemWgs(i)); |
228 } |
229 } |
229 } |
230 } |
230 */ |
231 */ |
231 iRunningKillAppActions = ETrue; |
232 iRunningKillAppActions = ETrue; |
|
233 |
|
234 TInt oldcount = iActionRefs.Count(); |
232 |
235 |
233 if (aWindowGroupList.Count()) |
236 if (aWindowGroupList.Count()) |
234 { |
237 { |
235 // Go through each item in the wglist, create an app close action for this application |
238 // Go through each item in the wglist, create an app close action for this application |
236 TInt wgIndex = aWindowGroupList.Count() - 1; |
239 TInt wgIndex = aWindowGroupList.Count() - 1; |
250 |
253 |
251 // Get the app ID for the wglist item |
254 // Get the app ID for the wglist item |
252 // This sets the window group name |
255 // This sets the window group name |
253 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue); |
256 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue); |
254 |
257 |
|
258 if(AppCloseActionAlreadyExists(aWindowGroupList, appId)) |
|
259 { |
|
260 wgIndex--; |
|
261 continue; |
|
262 } |
|
263 |
255 CApaWindowGroupName* wgName = aWindowGroupList.WgName(); |
264 CApaWindowGroupName* wgName = aWindowGroupList.WgName(); |
256 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName)); |
265 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName)); |
257 |
266 |
258 |
267 |
259 TBool skipped = EFalse; |
268 TBool skipped = EFalse; |
312 |
321 |
313 wgIndex--; |
322 wgIndex--; |
314 } |
323 } |
315 } |
324 } |
316 |
325 |
317 TRACES1("BuildActionListL: Action list built with %d items",iActionRefs.Count()); |
326 TRACES1("BuildActionListL: Action list built with %d new items",iActionRefs.Count()- oldcount); |
318 } |
327 } |
319 |
328 |
|
329 |
|
330 TBool CGOomActionList::AppCloseActionAlreadyExists(CGOomWindowGroupList& aWindowGroupList, TInt32 appId) |
|
331 { |
|
332 for(TInt i = 0 ; i < iActionRefs.Count() ; i++) |
|
333 { |
|
334 TActionRef ref = iActionRefs[i]; |
|
335 if(ref.Type() == TActionRef::EAppClose ) |
|
336 { |
|
337 if(aWindowGroupList.AppIdfromWgId(ref.WgId(), ETrue) == appId) |
|
338 return ETrue; |
|
339 } |
|
340 } |
|
341 return EFalse; |
|
342 } |
320 |
343 |
321 // Execute the OOM actions according to their priority |
344 // Execute the OOM actions according to their priority |
322 // Run batches of OOM actions according to their sync mode |
345 // Run batches of OOM actions according to their sync mode |
323 void CGOomActionList::FreeMemory(TInt aMaxPriority) |
346 void CGOomActionList::FreeMemory(TInt aMaxPriority) |
324 { |
347 { |
362 iAppIndex++; |
385 iAppIndex++; |
363 static_cast<CGOomCloseApp*>(action)->Reconfigure(ref); |
386 static_cast<CGOomCloseApp*>(action)->Reconfigure(ref); |
364 |
387 |
365 ref.iAppPlugin = action; |
388 ref.iAppPlugin = action; |
366 |
389 |
367 //Double checking again if this app is now in foreground, if yes then we dont kill |
390 TInt32 appId = iMonitor.GetWindowGroupList()->AppIdfromWgId(ref.WgId(), ETrue); |
368 CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, iWs.GetFocusWindowGroup()); |
|
369 |
391 |
370 TInt32 fgApp = wgName->AppUid().iUid; |
392 if(!IsOkToKillApp(appId)) |
371 TInt32 appId = iMonitor.GetWindowGroupList()->AppIdfromWgId(ref.WgId(), ETrue); |
|
372 |
|
373 if(appId == fgApp) |
|
374 { |
|
375 TRACES1("Foreground App wgid %x, spared by GOOM", appId); |
|
376 |
|
377 iCurrentActionIndex++; |
|
378 CleanupStack::PopAndDestroy(); |
|
379 continue; |
|
380 } |
|
381 |
|
382 //check if this is not parent of foreground app |
|
383 TBool spared = EFalse; |
|
384 TRACES1("CGOomActionList::FreeMemory - Going to kill Appid %x ",appId); |
|
385 TInt prevWgId = 0; |
|
386 while(prevWgId != KErrNotFound) |
|
387 { |
|
388 wgName->FindByAppUid(wgName->AppUid(), iWs, prevWgId); |
|
389 |
|
390 if(prevWgId == KErrNotFound) |
|
391 break; |
|
392 |
|
393 TInt parentId = 0; |
|
394 TRAPD(err, parentId = iMonitor.GetWindowGroupList()->FindParentIdL(prevWgId)); |
|
395 TRACES2("CGOomActionList::FreeMemory - Foreground App wgid %d, parent wgid %d",prevWgId, parentId); |
|
396 if( err == KErrNone && parentId != 0) |
|
397 { |
|
398 TInt32 parentAppId = iMonitor.GetWindowGroupList()->AppIdfromWgId(parentId, ETrue); |
|
399 if(parentAppId == appId) |
|
400 { |
|
401 TRACES3("Parent App %x (wgId %d), of Foreground App %x, spared by GOOM", parentAppId, parentId, fgApp); |
|
402 spared = ETrue; |
|
403 break; |
|
404 } |
|
405 } |
|
406 } |
|
407 CleanupStack::PopAndDestroy(); |
|
408 if(spared) |
|
409 { |
393 { |
410 iCurrentActionIndex++; |
394 iCurrentActionIndex++; |
411 if (iCurrentActionIndex >= iActionRefs.Count()) |
395 if (iCurrentActionIndex >= iActionRefs.Count()) |
412 { |
396 { |
413 StateChanged(); |
397 StateChanged(); |
425 iCurrentPluginRun = ref.RunPlugin().Id(); |
409 iCurrentPluginRun = ref.RunPlugin().Id(); |
426 } |
410 } |
427 |
411 |
428 iFreeingMemory = ETrue; |
412 iFreeingMemory = ETrue; |
429 TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority()); |
413 TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority()); |
|
414 iCurrentActionIndex++; |
430 action->FreeMemory(iCurrentTarget - memoryEstimate, iUseSwRendering); |
415 action->FreeMemory(iCurrentTarget - memoryEstimate, iUseSwRendering); |
431 iCurrentPluginRun = 0; |
416 iCurrentPluginRun = 0; |
432 memoryFreeingActionRun = ETrue; |
417 memoryFreeingActionRun = ETrue; |
433 |
418 |
434 // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions |
419 // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions |
447 } |
432 } |
448 |
433 |
449 if ((ref.SyncMode() == ECheckRam) |
434 if ((ref.SyncMode() == ECheckRam) |
450 || (numberOfRunningActions >= maxBatchSize) |
435 || (numberOfRunningActions >= maxBatchSize) |
451 || estimatedEnoughMemoryFreed |
436 || estimatedEnoughMemoryFreed |
452 || globalConfig.ForceCheckAtPriority(iActionRefs[iCurrentActionIndex].Priority())) |
437 || globalConfig.ForceCheckAtPriority(iActionRefs[iCurrentActionIndex-1].Priority())) |
453 // If this actions requires a RAM check then wait for it to complete |
438 // If this actions requires a RAM check then wait for it to complete |
454 // Also force a check if we've reached the maximum number of concurrent operations |
439 // Also force a check if we've reached the maximum number of concurrent operations |
455 // Also check if we estimate that we have already freed enough memory (assuming that the sync mode is "estimate" |
440 // Also check if we estimate that we have already freed enough memory (assuming that the sync mode is "estimate" |
456 { |
441 { |
457 // Return from the loop - we will be called back (in CGOomActionList::StateChanged()) when the running actions complete |
442 // Return from the loop - we will be called back (in CGOomActionList::StateChanged()) when the running actions complete |
458 iCurrentActionIndex++; |
|
459 TRACES("CGOomActionList::FreeMemory: Exiting run action loop"); |
443 TRACES("CGOomActionList::FreeMemory: Exiting run action loop"); |
460 return; |
444 return; |
461 } |
445 } |
462 // ... otherwise continue running actions, don't wait for any existing ones to complete |
446 // ... otherwise continue running actions, don't wait for any existing ones to complete |
463 iCurrentActionIndex++; |
|
464 |
447 |
465 if (iCurrentActionIndex >= iActionRefs.Count()) |
448 if (iCurrentActionIndex >= iActionRefs.Count()) |
466 { |
449 { |
467 StateChanged(); |
450 StateChanged(); |
468 return; |
451 return; |
489 iFreeingMemory = EFalse; |
472 iFreeingMemory = EFalse; |
490 iServer.CloseAppsFinished(freeMemory, EFalse); |
473 iServer.CloseAppsFinished(freeMemory, EFalse); |
491 iMonitor.WaitAndSynchroniseMemoryState(); |
474 iMonitor.WaitAndSynchroniseMemoryState(); |
492 } |
475 } |
493 } |
476 } |
|
477 } |
|
478 |
|
479 TBool CGOomActionList::IsOkToKillApp(TInt aAppId) |
|
480 { |
|
481 |
|
482 //Double checking again if this app is now in foreground, if yes then we dont kill |
|
483 TUid fgAppuid = TUid::Uid(iMonitor.ForegroundAppUid()); |
|
484 TInt32 fgApp = fgAppuid.iUid; |
|
485 TRACES1("Foreground Appuid %x", fgApp); |
|
486 |
|
487 if (aAppId == fgApp) |
|
488 { |
|
489 TRACES1("Foreground App wgid %x, spared by GOOM", aAppId); |
|
490 return EFalse; |
|
491 } |
|
492 |
|
493 //check if this is not parent of foreground app |
|
494 TBool spared = EFalse; |
|
495 TRACES2("CGOomActionList::FreeMemory - Going to kill Appid %x, Foreground app %x ", aAppId, fgApp); |
|
496 TInt prevWgId = 0; |
|
497 |
|
498 CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId); |
|
499 TInt i = 0; |
|
500 while ((prevWgId == KErrNotFound) && (i++ < 3)) //try 3 times before quiting. It takes time to get the wgid info when app is starting |
|
501 { |
|
502 TRACES1("Cannot find any more parent, trying again %d",i); |
|
503 User::After(200000); |
|
504 prevWgId = 0; |
|
505 CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId); |
|
506 } |
|
507 |
|
508 while (prevWgId != KErrNotFound) |
|
509 { |
|
510 TInt parentId = 0; |
|
511 TRAPD(err, parentId = iMonitor.GetWindowGroupList()->FindParentIdL(prevWgId)); |
|
512 TRACES3("CGOomActionList::FreeMemory - Foreground App AppId %x, wgid %d, parent wgid %d", fgApp, prevWgId, parentId); |
|
513 if (err == KErrNone && parentId > 0) |
|
514 { |
|
515 TInt32 parentAppId = iMonitor.GetWindowGroupList()->AppIdfromWgId(parentId, ETrue); |
|
516 if (parentAppId == aAppId) |
|
517 { |
|
518 TRACES3("Parent App %x (wgId %d), of Foreground App %x, spared by GOOM", parentAppId, parentId, fgApp); |
|
519 spared = ETrue; |
|
520 break; |
|
521 } |
|
522 } |
|
523 CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId); |
|
524 } |
|
525 return !spared; |
494 } |
526 } |
495 |
527 |
496 // Should be called when the memory situation is good |
528 // Should be called when the memory situation is good |
497 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request |
529 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request |
498 void CGOomActionList::MemoryGood() |
530 void CGOomActionList::MemoryGood() |
704 iMonitor.WaitAndSynchroniseMemoryState(); |
736 iMonitor.WaitAndSynchroniseMemoryState(); |
705 } |
737 } |
706 } |
738 } |
707 else |
739 else |
708 { |
740 { |
|
741 iMonitor.SwitchMemMode(CMemoryMonitor::EGOomLowMemMode); |
709 TRACES1("CGOomActionList::StateChanged: All current Plugin actions complete, below good threshold, Time to kill bad guys. freeMemory=%d", freeMemory); |
742 TRACES1("CGOomActionList::StateChanged: All current Plugin actions complete, below good threshold, Time to kill bad guys. freeMemory=%d", freeMemory); |
710 iRunningKillAppActions = ETrue; |
743 iRunningKillAppActions = ETrue; |
711 iMonitor.RunCloseAppActions(iMaxPriority); |
744 iMonitor.RunCloseAppActions(iMaxPriority); |
712 } |
745 } |
713 |
746 |
749 |
782 |
750 // Create an action acording to the config |
783 // Create an action acording to the config |
751 CGOomRunPlugin* action = CGOomRunPlugin::NewL(iPluginList->Uid(pluginIndex), pluginConfig, *this, iPluginList->Implementation(pluginIndex)); |
784 CGOomRunPlugin* action = CGOomRunPlugin::NewL(iPluginList->Uid(pluginIndex), pluginConfig, *this, iPluginList->Implementation(pluginIndex)); |
752 |
785 |
753 iRunPluginActions.AppendL(action); |
786 iRunPluginActions.AppendL(action); |
|
787 |
|
788 CGOomRunPluginConfig * nextConfigForSamePlugin = pluginConfig.iNextConfig; |
|
789 while(nextConfigForSamePlugin) |
|
790 { |
|
791 CGOomRunPlugin* action = CGOomRunPlugin::NewL(iPluginList->Uid(pluginIndex), *(nextConfigForSamePlugin), *this, iPluginList->Implementation(pluginIndex)); |
|
792 iRunPluginActions.AppendL(action); |
|
793 nextConfigForSamePlugin = nextConfigForSamePlugin->iNextConfig; |
|
794 } |
754 } |
795 } |
755 |
796 |
756 //references to v2 plugin types removed as these are not yet used by GOOM |
797 //references to v2 plugin types removed as these are not yet used by GOOM |
757 |
798 |
758 //allocate empty CGOomCloseApp objects |
799 //allocate empty CGOomCloseApp objects |