uiacceltk/hitchcock/goommonitor/src/goomactionlist.cpp
changeset 48 7ced047fb7ae
parent 43 95d73125a086
child 56 93c3782a0a3b
equal deleted inserted replaced
43:95d73125a086 48:7ced047fb7ae
   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