uiacceltk/hitchcock/goommonitor/src/goomactionlist.cpp
branchRCL_3
changeset 17 c9d868f1e20c
parent 15 cd0ae4656946
child 18 1801340c26a2
equal deleted inserted replaced
15:cd0ae4656946 17:c9d868f1e20c
   217     // we can't reset action index here because plugins would miss memory good events
   217     // we can't reset action index here because plugins would miss memory good events
   218 
   218 
   219     iAppIndex = 0;
   219     iAppIndex = 0;
   220     
   220     
   221     aWindowGroupList.RefreshL(iTryOptional);
   221     aWindowGroupList.RefreshL(iTryOptional);
   222     
   222 /*    
   223     for (TInt i = 0; aWindowGroupList.LowOnMemWgs(i) != KErrNotFound ; i++ )
   223     for (TInt i = 0; aWindowGroupList.LowOnMemWgs(i) != KErrNotFound ; i++ )
   224         {
   224         {
   225         if ( iLowOnMemWgs.Find(aWindowGroupList.LowOnMemWgs(i)) == KErrNotFound)
   225         if ( iLowOnMemWgs.Find(aWindowGroupList.LowOnMemWgs(i)) == KErrNotFound)
   226             {
   226             {
   227             iLowOnMemWgs.Append(aWindowGroupList.LowOnMemWgs(i));    
   227             iLowOnMemWgs.Append(aWindowGroupList.LowOnMemWgs(i));    
   228             }
   228             }
   229         }
   229         }
   230         
   230 */        
   231     iRunningKillAppActions = ETrue;
   231     iRunningKillAppActions = ETrue;
       
   232     
       
   233     TInt oldcount = iActionRefs.Count();
   232     
   234     
   233     if (aWindowGroupList.Count())
   235     if (aWindowGroupList.Count())
   234             {
   236             {
   235             // Go through each item in the wglist, create an app close action for this application
   237             // Go through each item in the wglist, create an app close action for this application
   236             TInt wgIndex = aWindowGroupList.Count() - 1;
   238             TInt wgIndex = aWindowGroupList.Count() - 1;
   250     
   252     
   251                 // Get the app ID for the wglist item
   253                 // Get the app ID for the wglist item
   252                 // This sets the window group name
   254                 // This sets the window group name
   253                 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue);
   255                 TInt32 appId = aWindowGroupList.AppId(wgIndex, ETrue);
   254                 
   256                 
       
   257                 if(AppCloseActionAlreadyExists(aWindowGroupList, appId))
       
   258                     {
       
   259                     wgIndex--;
       
   260                     continue;
       
   261                     }
       
   262                     
   255                 CApaWindowGroupName* wgName = aWindowGroupList.WgName();
   263                 CApaWindowGroupName* wgName = aWindowGroupList.WgName();
   256                 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName));
   264                 __ASSERT_DEBUG(wgName, GOomMonitorPanic(KInvalidWgName));
   257 
   265 
   258                     
   266                     
   259                 TBool skipped = EFalse;
   267                 TBool skipped = EFalse;
   312     
   320     
   313                 wgIndex--;
   321                 wgIndex--;
   314                 }
   322                 }
   315             }
   323             }
   316             
   324             
   317         TRACES1("BuildActionListL: Action list built with %d items",iActionRefs.Count());
   325         TRACES1("BuildActionListL: Action list built with %d  new items",iActionRefs.Count()- oldcount);
   318     }    
   326     }    
   319 
   327 
       
   328 
       
   329 TBool CGOomActionList::AppCloseActionAlreadyExists(CGOomWindowGroupList& aWindowGroupList, TInt32 appId)
       
   330     {
       
   331     for(TInt i = 0 ; i < iActionRefs.Count() ; i++)
       
   332         {
       
   333         TActionRef ref = iActionRefs[i];
       
   334         if(ref.Type() == TActionRef::EAppClose )
       
   335             {
       
   336             if(aWindowGroupList.AppIdfromWgId(ref.WgId(), ETrue) == appId)
       
   337                 return ETrue;
       
   338             }
       
   339         }
       
   340         return EFalse;
       
   341     }
   320 
   342 
   321 // Execute the OOM actions according to their priority
   343 // Execute the OOM actions according to their priority
   322 // Run batches of OOM actions according to their sync mode
   344 // Run batches of OOM actions according to their sync mode
   323 void CGOomActionList::FreeMemory(TInt aMaxPriority)
   345 void CGOomActionList::FreeMemory(TInt aMaxPriority)
   324     {
   346     {
   362             iAppIndex++;
   384             iAppIndex++;
   363             static_cast<CGOomCloseApp*>(action)->Reconfigure(ref);
   385             static_cast<CGOomCloseApp*>(action)->Reconfigure(ref);
   364             
   386             
   365             ref.iAppPlugin = action;
   387             ref.iAppPlugin = action;
   366             
   388             
   367             //Double checking again if this app is now in foreground, if yes then we dont kill
   389             TInt32 appId = iMonitor.GetWindowGroupList()->AppIdfromWgId(ref.WgId(), ETrue);
   368             CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, iWs.GetFocusWindowGroup());
       
   369             
   390             
   370             TInt32 fgApp = wgName->AppUid().iUid;
   391             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                 {
   392                 {
   410                 iCurrentActionIndex++;
   393                 iCurrentActionIndex++;
   411                 if (iCurrentActionIndex >= iActionRefs.Count())
   394                 if (iCurrentActionIndex >= iActionRefs.Count())
   412                     {
   395                     {
   413                     StateChanged();
   396                     StateChanged();
   425             iCurrentPluginRun = ref.RunPlugin().Id();
   408             iCurrentPluginRun = ref.RunPlugin().Id();
   426             }
   409             }
   427 
   410 
   428         iFreeingMemory = ETrue;
   411         iFreeingMemory = ETrue;
   429         TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority());
   412         TRACES2("CGOomActionList::FreeMemory: Running action %d which has priority %d", iCurrentActionIndex,ref.Priority());
       
   413         iCurrentActionIndex++;
   430         action->FreeMemory(iCurrentTarget - memoryEstimate, iUseSwRendering);
   414         action->FreeMemory(iCurrentTarget - memoryEstimate, iUseSwRendering);
   431         iCurrentPluginRun = 0;
   415         iCurrentPluginRun = 0;
   432         memoryFreeingActionRun = ETrue;
   416         memoryFreeingActionRun = ETrue;
   433 
   417 
   434         // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions
   418         // Actions with EContinueIgnoreMaxBatchSize don't add to the tally of running actions
   447             }
   431             }
   448 
   432 
   449         if ((ref.SyncMode() == ECheckRam)
   433         if ((ref.SyncMode() == ECheckRam)
   450                 || (numberOfRunningActions >= maxBatchSize)
   434                 || (numberOfRunningActions >= maxBatchSize)
   451                 || estimatedEnoughMemoryFreed
   435                 || estimatedEnoughMemoryFreed
   452                 || globalConfig.ForceCheckAtPriority(iActionRefs[iCurrentActionIndex].Priority()))
   436                 || globalConfig.ForceCheckAtPriority(iActionRefs[iCurrentActionIndex-1].Priority()))
   453             // If this actions requires a RAM check then wait for it to complete
   437             // 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
   438             // 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"
   439             // Also check if we estimate that we have already freed enough memory (assuming that the sync mode is "estimate"
   456             {
   440             {
   457             // Return from the loop - we will be called back (in CGOomActionList::StateChanged()) when the running actions complete
   441             // 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");
   442             TRACES("CGOomActionList::FreeMemory: Exiting run action loop");
   460             return;
   443             return;
   461             }
   444             }
   462         // ... otherwise continue running actions, don't wait for any existing ones to complete
   445         // ... otherwise continue running actions, don't wait for any existing ones to complete
   463         iCurrentActionIndex++;
       
   464         
   446         
   465         if (iCurrentActionIndex >= iActionRefs.Count())
   447         if (iCurrentActionIndex >= iActionRefs.Count())
   466             {
   448             {
   467             StateChanged();
   449             StateChanged();
   468             return;
   450             return;
   484         else
   466         else
   485             {
   467             {
   486             iTryOptional = EFalse;
   468             iTryOptional = EFalse;
   487             iOptionalTried = EFalse;
   469             iOptionalTried = EFalse;
   488             TRACES("CGOomActionList::FreeMemory: No usable memory freeing action has been found");
   470             TRACES("CGOomActionList::FreeMemory: No usable memory freeing action has been found");
       
   471             iFreeingMemory = EFalse;
   489             iServer.CloseAppsFinished(freeMemory, EFalse);
   472             iServer.CloseAppsFinished(freeMemory, EFalse);
   490             iMonitor.WaitAndSynchroniseMemoryState();
   473             iMonitor.WaitAndSynchroniseMemoryState();
   491             }
   474             }
   492         }
   475         }
       
   476     }
       
   477 
       
   478 TBool CGOomActionList::IsOkToKillApp(TInt aAppId)
       
   479     {
       
   480     
       
   481     //Double checking again if this app is now in foreground, if yes then we dont kill
       
   482     TUid fgAppuid = TUid::Uid(iMonitor.ForegroundAppUid());
       
   483     TInt32 fgApp = fgAppuid.iUid;
       
   484     TRACES1("Foreground Appuid %x", fgApp);
       
   485         
       
   486     if (aAppId == fgApp)
       
   487         {
       
   488         TRACES1("Foreground App wgid %x, spared by GOOM", aAppId);
       
   489         return EFalse;
       
   490         }
       
   491 
       
   492     //check if this is not parent of foreground app
       
   493     TBool spared = EFalse;
       
   494     TRACES2("CGOomActionList::FreeMemory - Going to kill Appid %x, Foreground app %x ", aAppId, fgApp);
       
   495     TInt prevWgId = 0;
       
   496     
       
   497     CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId);
       
   498     TInt i = 0;
       
   499     while ((prevWgId == KErrNotFound) && (i++ < 3))   //try 3 times before quiting. It takes time to get the wgid info when app is starting
       
   500             {
       
   501             TRACES1("Cannot find any more parent, trying again %d",i);
       
   502             User::After(200000);
       
   503             prevWgId = 0;
       
   504             CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId);
       
   505             }
       
   506    
       
   507     while (prevWgId != KErrNotFound)
       
   508         {
       
   509         TInt parentId = 0;
       
   510         TRAPD(err, parentId = iMonitor.GetWindowGroupList()->FindParentIdL(prevWgId));
       
   511         TRACES3("CGOomActionList::FreeMemory - Foreground App AppId %x, wgid %d, parent wgid %d", fgApp, prevWgId, parentId);
       
   512         if (err == KErrNone && parentId > 0)
       
   513             {
       
   514             TInt32 parentAppId = iMonitor.GetWindowGroupList()->AppIdfromWgId(parentId, ETrue);
       
   515             if (parentAppId == aAppId)
       
   516                 {
       
   517                 TRACES3("Parent App %x (wgId %d), of Foreground App %x, spared by GOOM", parentAppId, parentId, fgApp);
       
   518                 spared = ETrue;
       
   519                 break;
       
   520                 }
       
   521             }
       
   522         CApaWindowGroupName::FindByAppUid(fgAppuid, iWs, prevWgId);
       
   523         }
       
   524     return !spared;
   493     }
   525     }
   494 
   526 
   495 // Should be called when the memory situation is good
   527 // Should be called when the memory situation is good
   496 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request
   528 // It results in notifications of the good memory state to all plugins with an outstanding FreeMemory request
   497 void CGOomActionList::MemoryGood()
   529 void CGOomActionList::MemoryGood()
   498     {
   530     {
   499     FUNC_LOG;
   531     FUNC_LOG;
   500 
   532     if(!ALWAYS_SW_REND)
       
   533         {
   501     TInt actionRefIndex = iActionRefs.Count();
   534     TInt actionRefIndex = iActionRefs.Count();
   502 
   535 
   503     // Go through each of the action references, if it's a plugin action then call MemoryGood on it
   536     // Go through each of the action references, if it's a plugin action then call MemoryGood on it
   504     // Note that this only results in a call to the plugin if FreeMemory has been called on this plugin since that last call to MemoryGood
   537     // Note that this only results in a call to the plugin if FreeMemory has been called on this plugin since that last call to MemoryGood
   505     while (actionRefIndex--)
   538     while (actionRefIndex--)
   508                 || (iActionRefs[actionRefIndex].Type() == TActionRef::ESystemPlugin))
   541                 || (iActionRefs[actionRefIndex].Type() == TActionRef::ESystemPlugin))
   509             {
   542             {
   510             iActionRefs[actionRefIndex].RunPlugin().MemoryGood();
   543             iActionRefs[actionRefIndex].RunPlugin().MemoryGood();
   511             }
   544             }
   512         }
   545         }
   513     // notify window groups which were triggered to low mem that 
   546     // notify window groups which were triggered to low mem that
       
   547     iMonitor.SwitchMemMode(CMemoryMonitor::EGOomGoodMemMode);
       
   548         }
       
   549 /*    
   514     TWsEvent event;
   550     TWsEvent event;
   515     event.SetType(KGoomMemoryGoodEvent); // naive
   551     event.SetType(KGoomMemoryGoodEvent); // naive
   516 
   552 
   517     for (TInt i = iLowOnMemWgs.Count()-1; i>=0; i--)
   553     for (TInt i = iLowOnMemWgs.Count()-1; i>=0; i--)
   518         {
   554         {
   519 #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
   555 #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
   520         iWs.SendEventToWindowGroup(iLowOnMemWgs[i], event);
   556         iWs.SendEventToWindowGroup(iLowOnMemWgs[i], event);
   521 #endif // #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
   557 #endif // #ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
   522         iLowOnMemWgs.Remove(i);
   558         iLowOnMemWgs.Remove(i);
   523 		}    
   559 		}
       
   560 */		    
   524     }
   561     }
   525 
   562 
   526 TBool CGOomActionList::FreeMemoryAboveTarget(TInt& aFreeMemory)
   563 TBool CGOomActionList::FreeMemoryAboveTarget(TInt& aFreeMemory)
   527     {
   564     {
   528     FUNC_LOG;
   565     FUNC_LOG;
   670         if (!freeMemoryAboveTarget)
   707         if (!freeMemoryAboveTarget)
   671             // If we are still below the good-memory-threshold then continue running actions
   708             // If we are still below the good-memory-threshold then continue running actions
   672             {            
   709             {            
   673             TRACES2("CGOomActionList::StateChanged: Finished Action %d out of %d",iCurrentActionIndex, iActionRefs.Count());
   710             TRACES2("CGOomActionList::StateChanged: Finished Action %d out of %d",iCurrentActionIndex, iActionRefs.Count());
   674 
   711 
   675             if (iCurrentActionIndex < iActionRefs.Count()-1)
   712             if (iCurrentActionIndex < iActionRefs.Count())
   676                 {
   713                 {
   677                 // launch more actions, potential recursion !!
   714                 // There are still more actions to try, so we continue
   678                 iCurrentActionIndex++;
   715                 TRACES1("CGOomActionList::StateChanged: All current actions complete, running more actions. freeMemory=%d", freeMemory);
   679                 return FreeMemory(iMaxPriority);
   716                 return FreeMemory(iMaxPriority);
   680                 } 
   717                 } 
   681                                    
   718                                    
   682             if(iRunningKillAppActions)
   719             if(iRunningKillAppActions)
   683 	            {
   720 	            {
   684                 iRunningKillAppActions = EFalse;
   721                 iRunningKillAppActions = EFalse;
   685                 // There are no more actions to try, so we give up
       
   686                 TRACES1("CGOomActionList::StateChanged: All current actions complete, below good threshold with no more actions available. freeMemory=%d", freeMemory);
       
   687 
   722 
   688                 if (!iTryOptional && !iOptionalTried && freeMemory < 25*1024*1024 ) // magic, should read this from config
   723                 if (!iTryOptional && !iOptionalTried && freeMemory < 25*1024*1024 ) // magic, should read this from config
   689                     { 
   724                     { 
   690                     iTryOptional = ETrue;
   725                     iTryOptional = ETrue;
   691                     iOptionalTried = ETrue;
   726                     iOptionalTried = ETrue;
   692                     iMonitor.RunCloseAppActions(iMaxPriority);
   727                     iMonitor.RunCloseAppActions(iMaxPriority);
   693                     }
   728                     }
   694                 else
   729                 else
   695                     {
   730                     {
       
   731                     // There are no more actions to try, so we give up
       
   732                     TRACES1("CGOomActionList::StateChanged: All current actions complete, below good threshold with no more actions available. freeMemory=%d", freeMemory);
   696                     iTryOptional = EFalse;       
   733                     iTryOptional = EFalse;       
   697                     iServer.CloseAppsFinished(freeMemory, EFalse);
   734                     iServer.CloseAppsFinished(freeMemory, EFalse);
   698                     iMonitor.WaitAndSynchroniseMemoryState();
   735                     iMonitor.WaitAndSynchroniseMemoryState();
   699                     }
   736                     }
   700                 }
   737                 }