175 actionType = TActionRef::EAppPlugin; |
175 actionType = TActionRef::EAppPlugin; |
176 } |
176 } |
177 else |
177 else |
178 actionType = TActionRef::ESystemPlugin; |
178 actionType = TActionRef::ESystemPlugin; |
179 |
179 |
|
180 |
|
181 //get skip plugin config for foreground app |
|
182 TUint foregroundUid = iMonitor.ForegroundAppUid(); |
|
183 if(aConfig.GetApplicationConfig(foregroundUid).iSkipPluginId == iPluginList->Uid(pluginIndex)) |
|
184 { |
|
185 TRACES2("Skiping plugin %x, configured for app %x", iPluginList->Uid(pluginIndex), foregroundUid); |
|
186 actionsIndex++; |
|
187 continue ; //skip this and continue with next plugin |
|
188 } |
|
189 |
|
190 TUint activeClientId = iMonitor.ActiveClientId(); |
|
191 if(activeClientId!=0 && activeClientId!=foregroundUid) |
|
192 { |
|
193 if(aConfig.GetApplicationConfig(activeClientId).iSkipPluginId == iPluginList->Uid(pluginIndex)) |
|
194 { |
|
195 TRACES2("Skiping plugin %x, configured for app %x", iPluginList->Uid(pluginIndex), foregroundUid); |
|
196 actionsIndex++; |
|
197 continue ; //skip this and continue with next plugin |
|
198 } |
|
199 } |
|
200 |
180 TActionRef ref = TActionRef(actionType, priority, syncMode, ramEstimate, *(iRunPluginActions[actionsIndex]), aWindowGroupList.GetIndexFromAppId(pluginConfig.TargetApp())); |
201 TActionRef ref = TActionRef(actionType, priority, syncMode, ramEstimate, *(iRunPluginActions[actionsIndex]), aWindowGroupList.GetIndexFromAppId(pluginConfig.TargetApp())); |
181 iAppsProtectedByPlugins.Append(pluginConfig.TargetApp()); |
202 iAppsProtectedByPlugins.Append(pluginConfig.TargetApp()); |
182 TRACES1("Creating Plugin Action Item TargetAppId %x", pluginConfig.TargetApp()); |
203 TRACES2("Creating Plugin Action Item %x , TargetAppId %x", iPluginList->Uid(pluginIndex), pluginConfig.TargetApp()); |
183 //It is valid to have plugins with equal priority |
204 //It is valid to have plugins with equal priority |
184 User::LeaveIfError(iActionRefs.InsertInOrderAllowRepeats(ref, ComparePriorities)); |
205 User::LeaveIfError(iActionRefs.InsertInOrderAllowRepeats(ref, ComparePriorities)); |
185 |
206 |
186 actionsIndex++; |
207 actionsIndex++; |
187 } |
208 } |
191 |
212 |
192 void CGOomActionList::BuildKillAppActionListL(CGOomWindowGroupList& aWindowGroupList, CGOomConfig& aConfig) |
213 void CGOomActionList::BuildKillAppActionListL(CGOomWindowGroupList& aWindowGroupList, CGOomConfig& aConfig) |
193 { |
214 { |
194 FUNC_LOG; |
215 FUNC_LOG; |
195 |
216 |
196 iActionRefs.Reset(); |
217 // iActionRefs.Reset(); |
197 iCurrentActionIndex = 0; |
218 // iCurrentActionIndex = 0; |
198 |
219 |
199 aWindowGroupList.RefreshL(); |
220 aWindowGroupList.RefreshL(); |
200 |
221 |
201 iRunningKillAppActions = ETrue; |
222 iRunningKillAppActions = ETrue; |
202 |
223 |
216 |
237 |
217 while (wgIndex >= 0) |
238 while (wgIndex >= 0) |
218 { |
239 { |
219 CGOomCloseAppConfig* appCloseConfig = NULL; |
240 CGOomCloseAppConfig* appCloseConfig = NULL; |
220 |
241 |
221 CApaWindowGroupName* wgName = aWindowGroupList.WgName(); |
|
222 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName)); |
|
223 |
|
224 // Get the app ID for the wglist item |
242 // Get the app ID for the wglist item |
225 // This sets the window group name |
243 // This sets the window group name |
226 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue); |
244 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue); |
227 |
245 |
228 if ( !appId || foregroundUid.iUid ==appId || wgName->IsSystem() || wgName->Hidden() || (iAppsProtectedByPlugins.Find(appId) != KErrNotFound)) |
246 CApaWindowGroupName* wgName = aWindowGroupList.WgName(); |
|
247 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName)); |
|
248 |
|
249 |
|
250 TBool skipped = EFalse; |
|
251 if ( !appId || foregroundUid.iUid ==appId || (iAppsProtectedByPlugins.Find(appId) != KErrNotFound)) |
229 { |
252 { |
230 //If the UID is NULL at this point, we assume the process is not an application |
253 //If the UID is NULL at this point, we assume the process is not an application |
231 //and therefore is not a suitable candidate for closure. |
254 //and therefore is not a suitable candidate for closure. |
232 //We also do not close system or hidden apps. |
255 //We also do not close system or hidden apps. |
233 TRACES3("BuildActionListL: Not adding process to action list; UID = %x, wgIndex = %d, wgid = %d", appId, wgIndex, aWindowGroupList.WgId(wgIndex).iId); |
256 TRACES3("BuildActionListL: Not adding process to action list; UID = %x, wgIndex = %d, wgid = %d", appId, wgIndex, aWindowGroupList.WgId(wgIndex).iId); |
234 TRACES3("BuildActionListL: IsSystem = %d, Hidden = %d, Foregroundapp %x", wgName->IsSystem() ? 1 : 0, wgName->Hidden() ? 1 : 0, foregroundUid); |
257 TRACES1("BuildActionListL: Foregroundapp %x", foregroundUid); |
|
258 skipped = ETrue; |
235 } |
259 } |
236 |
260 |
237 else if (aWindowGroupList.IsBusy(wgIndex) || wgName->IsBusy()) |
261 else if (aWindowGroupList.IsBusy(wgIndex) || wgName->IsBusy()) |
238 // If the application has been flagged as busy then look up the configuration for busy apps in the config file |
262 // If the application has been flagged as busy then look up the configuration for busy apps in the config file |
239 { |
263 { |
249 else |
273 else |
250 // If the application hasn't been flagged as busy or high priority then look up the priority according to the config |
274 // If the application hasn't been flagged as busy or high priority then look up the priority according to the config |
251 { |
275 { |
252 // Find the app close config for this app ID |
276 // Find the app close config for this app ID |
253 appCloseConfig = aConfig.GetApplicationConfig(appId).GetAppCloseConfig(); |
277 appCloseConfig = aConfig.GetApplicationConfig(appId).GetAppCloseConfig(); |
|
278 } |
|
279 |
|
280 if(!appCloseConfig && !skipped) |
|
281 { |
|
282 appCloseConfig = aConfig.GetApplicationConfig(KGOomDefaultAppId).GetAppCloseConfig(); |
254 } |
283 } |
255 |
284 |
256 // Create the app close action and add it to the action list |
285 // Create the app close action and add it to the action list |
257 if (appCloseConfig) |
286 if (appCloseConfig) |
258 { |
287 { |
259 TUint priority = appCloseConfig->CalculateCloseAppPriority(aWindowGroupList, wgIndex); |
288 TUint priority = appCloseConfig->CalculateCloseAppPriority(aWindowGroupList, wgIndex); |
260 TInt wgId = aWindowGroupList.WgId(wgIndex).iId; |
289 TInt wgId = aWindowGroupList.WgId(wgIndex).iId; |
261 TGOomSyncMode syncMode = appCloseConfig->iSyncMode; |
290 TGOomSyncMode syncMode = appCloseConfig->iSyncMode; |
262 TInt ramEstimate = appCloseConfig->iRamEstimate; |
291 TInt ramEstimate = appCloseConfig->iRamEstimate; |
263 TActionRef ref = TActionRef(TActionRef::EAppClose, priority, syncMode, ramEstimate, wgId, wgIndex); |
292 TActionRef ref = TActionRef(TActionRef::EAppClose, priority, syncMode, ramEstimate, wgId, wgIndex, appCloseConfig->iCloseTimeout, appCloseConfig->iWaitAfterClose); |
264 |
293 |
265 //AppClose Actions should always have a unique prioirity determined by the application's z order. |
294 //AppClose Actions should always have a unique prioirity determined by the application's z order. |
266 TInt err = iActionRefs.InsertInOrder(ref, ComparePriorities); |
295 TInt err = iActionRefs.InsertInOrder(ref, ComparePriorities); |
267 if ((err != KErrNone) && (err != KErrAlreadyExists)) |
296 if ((err != KErrNone) && (err != KErrAlreadyExists)) |
268 { |
297 { |
318 action = iCloseAppActions[numberOfRunningActions]; |
347 action = iCloseAppActions[numberOfRunningActions]; |
319 static_cast<CGOomCloseApp*>(action)->Reconfigure(ref); |
348 static_cast<CGOomCloseApp*>(action)->Reconfigure(ref); |
320 |
349 |
321 //Double checking again if this app is now in foreground, if yes then we dont kill |
350 //Double checking again if this app is now in foreground, if yes then we dont kill |
322 CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, iWs.GetFocusWindowGroup()); |
351 CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, iWs.GetFocusWindowGroup()); |
323 RDebug::Print(wgName->WindowGroupName()); |
352 |
324 TInt32 fgApp = wgName->AppUid().iUid; |
353 TInt32 fgApp = wgName->AppUid().iUid; |
325 TInt32 appId = iMonitor.GetWindowGroupList()->AppIdfromWgId(ref.WgId(), ETrue); |
354 TInt32 appId = iMonitor.GetWindowGroupList()->AppIdfromWgId(ref.WgId(), ETrue); |
326 if(appId == fgApp) |
355 if(appId == fgApp) |
327 { |
356 { |
328 TRACES1("Foreground App wgid %x, spared by GOOM", appId); |
357 TRACES1("Foreground App wgid %x, spared by GOOM", appId); |
332 } |
361 } |
333 } |
362 } |
334 else |
363 else |
335 { |
364 { |
336 action = &(ref.RunPlugin()); |
365 action = &(ref.RunPlugin()); |
|
366 iCurrentPluginRun = ref.RunPlugin().Id(); |
337 } |
367 } |
338 |
368 |
339 iFreeingMemory = ETrue; |
369 iFreeingMemory = ETrue; |
340 TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority()); |
370 TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority()); |
341 action->FreeMemory(iCurrentTarget - memoryEstimate); |
371 action->FreeMemory(iCurrentTarget - memoryEstimate); |
|
372 iCurrentPluginRun = 0; |
342 memoryFreeingActionRun = ETrue; |
373 memoryFreeingActionRun = ETrue; |
343 |
374 |
344 // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions |
375 // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions |
345 if (ref.SyncMode() != EContinueIgnoreMaxBatchSize) |
376 if (ref.SyncMode() != EContinueIgnoreMaxBatchSize) |
346 numberOfRunningActions++; |
377 numberOfRunningActions++; |
375 |
406 |
376 if (!memoryFreeingActionRun) |
407 if (!memoryFreeingActionRun) |
377 { |
408 { |
378 // No usable memory freeing action has been found, so we give up |
409 // No usable memory freeing action has been found, so we give up |
379 TRACES("CGOomActionList::FreeMemory: No usable memory freeing action has been found"); |
410 TRACES("CGOomActionList::FreeMemory: No usable memory freeing action has been found"); |
380 iMonitor.ResetTargets(); |
|
381 TInt freeMemory; |
411 TInt freeMemory; |
382 if (FreeMemoryAboveTarget(freeMemory) && !iMonitor.NeedToPostponeMemGood()) |
412 FreeMemoryAboveTarget(freeMemory); |
383 { |
|
384 MemoryGood(); |
|
385 } |
|
386 iServer.CloseAppsFinished(freeMemory, EFalse); |
413 iServer.CloseAppsFinished(freeMemory, EFalse); |
|
414 iMonitor.WaitAndSynchroniseMemoryState(); |
387 } |
415 } |
388 } |
416 } |
389 |
417 |
390 // Should be called when the memory situation is good |
418 // Should be called when the memory situation is good |
391 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request |
419 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request |
411 { |
439 { |
412 FUNC_LOG; |
440 FUNC_LOG; |
413 |
441 |
414 aFreeMemory = iMonitor.GetFreeMemory(); |
442 aFreeMemory = iMonitor.GetFreeMemory(); |
415 |
443 |
416 TRACES1("CGOomActionList::FreeMemoryAboveTarget: Free RAM now %d",aFreeMemory); |
444 TRACES2("CGOomActionList::FreeMemoryAboveTarget: Free RAM now %d, currentTarget %d",aFreeMemory, iCurrentTarget); |
417 |
445 |
418 return (aFreeMemory >= iCurrentTarget); |
446 return (aFreeMemory >= iCurrentTarget); |
419 } |
447 } |
420 |
448 |
421 TInt CGOomActionList::ComparePriorities(const TActionRef& aPos1, const TActionRef& aPos2 ) |
449 TInt CGOomActionList::ComparePriorities(const TActionRef& aPos1, const TActionRef& aPos2 ) |
570 if(iRunningKillAppActions) |
598 if(iRunningKillAppActions) |
571 { |
599 { |
572 iRunningKillAppActions = EFalse; |
600 iRunningKillAppActions = EFalse; |
573 // There are no more actions to try, so we give up |
601 // There are no more actions to try, so we give up |
574 TRACES1("CGOomActionList::StateChanged: All current actions complete, below good threshold with no more actions available. freeMemory=%d", freeMemory); |
602 TRACES1("CGOomActionList::StateChanged: All current actions complete, below good threshold with no more actions available. freeMemory=%d", freeMemory); |
575 iMonitor.ResetTargets(); |
603 |
576 /* Do not call memory good immidiately after freeing memory for some app |
604 /* Do not call memory good immidiately after freeing memory for some app |
577 if (freeMemory >= iCurrentTarget && !iMonitor.NeedToPostponeMemGood()) |
605 if (freeMemory >= iCurrentTarget && !iMonitor.NeedToPostponeMemGood()) |
578 { |
606 { |
579 MemoryGood(); |
607 MemoryGood(); |
580 } |
608 } |
581 */ |
609 */ |
582 iServer.CloseAppsFinished(freeMemory, EFalse); |
610 iServer.CloseAppsFinished(freeMemory, EFalse); |
|
611 iMonitor.WaitAndSynchroniseMemoryState(); |
583 } |
612 } |
584 else |
613 else |
585 { |
614 { |
586 TRACES1("CGOomActionList::StateChanged: All current Plugin actions complete, below good threshold, Time to kill bad guys. freeMemory=%d", freeMemory); |
615 TRACES1("CGOomActionList::StateChanged: All current Plugin actions complete, below good threshold, Time to kill bad guys. freeMemory=%d", freeMemory); |
587 iRunningKillAppActions = ETrue; |
616 iRunningKillAppActions = ETrue; |
588 iMonitor.RunCloseAppActions(iMaxPriority); |
617 iMonitor.RunCloseAppActions(iMaxPriority); |
589 } |
618 } |
|
619 |
590 } |
620 } |
591 else |
621 else |
592 { |
622 { |
593 // There are still more actions to try, so we continue |
623 // There are still more actions to try, so we continue |
594 TRACES1("CGOomActionList::StateChanged: All current actions complete, running more actions. freeMemory=%d", freeMemory); |
624 TRACES1("CGOomActionList::StateChanged: All current actions complete, running more actions. freeMemory=%d", freeMemory); |
603 { |
633 { |
604 MemoryGood(); |
634 MemoryGood(); |
605 } |
635 } |
606 */ |
636 */ |
607 iRunningKillAppActions = EFalse; |
637 iRunningKillAppActions = EFalse; |
608 iMonitor.ResetTargets(); |
|
609 iServer.CloseAppsFinished(freeMemory, ETrue); |
638 iServer.CloseAppsFinished(freeMemory, ETrue); |
|
639 iMonitor.WaitAndSynchroniseMemoryState(); |
610 } |
640 } |
611 } |
641 } |
612 |
642 |
613 // If some actions are not yet in the idle state then we must continue to wait for them (they will notify us of a state change via a callback) |
643 // If some actions are not yet in the idle state then we must continue to wait for them (they will notify us of a state change via a callback) |
614 } |
644 } |
651 CGOomCloseApp* action = CGOomCloseApp::NewL(*this, iWs); |
681 CGOomCloseApp* action = CGOomCloseApp::NewL(*this, iWs); |
652 iCloseAppActions.AppendL(action); |
682 iCloseAppActions.AppendL(action); |
653 } |
683 } |
654 } |
684 } |
655 |
685 |
656 void CGOomActionList::SetPriority(TInt aWgIndex, TInt aPriority) |
686 |
|
687 void CGOomActionList::SetPriority(TInt aWgId, TInt aPriority) |
657 { |
688 { |
658 FUNC_LOG; |
689 FUNC_LOG; |
659 |
690 |
660 TInt idx = iActionRefs.Count()-1; |
691 TInt idx = iActionRefs.Count()-1; |
661 while(idx >= 0) |
692 while(idx >= 0) |
662 { |
693 { |
663 if(iActionRefs[idx].WgIndex() == aWgIndex) |
694 if(iActionRefs[idx].WgId() == aWgId) |
664 { |
695 { |
665 break; |
696 break; |
666 } |
697 } |
667 idx--; |
698 idx--; |
668 } |
699 } |
669 |
700 |
670 if(idx >= 0) |
701 if(idx >= 0) |
671 { |
702 { |
672 TRACES2("CGOomActionList::SetPriority Setting app wgindex %d, index %d as busy", aWgIndex, idx); |
703 TRACES2("CGOomActionList::SetPriority Setting app wgid %d, index %d as busy", aWgId, idx); |
673 iActionRefs[idx].SetPriority(aPriority); |
704 iActionRefs[idx].SetPriority(aPriority); |
674 if (!iFreeingMemory) |
|
675 { |
|
676 iActionRefs.Sort(ComparePriorities); |
|
677 } |
|
678 } |
705 } |
679 else |
706 else |
680 { |
707 { |
681 TRACES1("CGOomActionList::SetPriority wgindex %d not in the hitlist", aWgIndex); |
708 TRACES1("CGOomActionList::SetPriority wgd %d not in the hitlist", aWgId); |
682 } |
709 } |
683 } |
710 } |
|
711 |
|
712 |
|
713 TUint CGOomActionList::CurrentPluginRun() |
|
714 { |
|
715 return iCurrentPluginRun; |
|
716 } |
|
717 |
|
718 TBool CGOomActionList::IsRunningKillAppActions() |
|
719 { |
|
720 return iRunningKillAppActions; |
|
721 } |