tstaskmonitor/server/src/tsdatalist.cpp
changeset 104 9b022b1f357c
equal deleted inserted replaced
103:b99b84bcd2d1 104:9b022b1f357c
       
     1 /*
       
     2  * Copyright (c) 2008 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:  File containing application list classes
       
    15  *
       
    16  */
       
    17 
       
    18 //INCLUDES:
       
    19 
       
    20 #include "tsdatalist.h"
       
    21 #include "tsentrykeygenerator.h"
       
    22 #include <mmf/common/mmfcontrollerpluginresolver.h> // for CleanupResetAndDestroyPushL
       
    23 #include <apgwgnam.h>
       
    24 #include <bitstd.h>
       
    25 #include <AknIconUtils.h> // avkon
       
    26 #include <apgicnfl.h> // fbsbitmap
       
    27 #include <AknIconSrvClient.h> 
       
    28 #include <fbs.h>
       
    29 #include <apgwgnam.h>
       
    30 
       
    31 
       
    32 // size for the created app icons
       
    33 const TInt KAppIconWidth = 128;
       
    34 const TInt KAppIconHeight = 128;
       
    35 
       
    36 //uids to be hidden
       
    37 const TUid KHsApplicationUid = { 0x20022F35 };
       
    38 
       
    39 const TInt KMaxLookupSize(75);
       
    40 
       
    41 // ================= MEMBER FUNCTIONS =======================
       
    42 
       
    43 // --------------------------------------------------------------------------
       
    44 /**
       
    45  * Two-phased constructor.
       
    46  */
       
    47 CTsDataList* CTsDataList::NewL(MTsResourceManager& resources,
       
    48                                      MTsWindowGroupsMonitor &monitor, 
       
    49                                      MHsDataObserver& observer)
       
    50 {
       
    51     CTsDataList* self = new (ELeave) CTsDataList(resources, monitor, observer);
       
    52     CleanupStack::PushL(self);
       
    53     self->ConstructL();
       
    54     CleanupStack::Pop(self);
       
    55     return self;
       
    56 }
       
    57 
       
    58 // --------------------------------------------------------------------------
       
    59 /**
       
    60  * Constructor.
       
    61  */
       
    62 CTsDataList::CTsDataList(MTsResourceManager& resources,
       
    63                          MTsWindowGroupsMonitor &monitor, 
       
    64                          MHsDataObserver& observer) 
       
    65 :
       
    66     CTsWindowGroupsObserver(monitor),
       
    67     mResources(resources),
       
    68     mObserver(observer)
       
    69 {
       
    70 }
       
    71 
       
    72 // --------------------------------------------------------------------------
       
    73 /*
       
    74  * Destructor
       
    75  */
       
    76 CTsDataList::~CTsDataList()
       
    77 {
       
    78     mData.ResetAndDestroy();
       
    79     mHiddenUids.Close();
       
    80     mAllowedUids.Close();
       
    81     RFbsSession::Disconnect();
       
    82     RAknIconSrvClient::Disconnect();
       
    83 }
       
    84 
       
    85 // --------------------------------------------------------------------------
       
    86 /**
       
    87  * Performs 2nd phase construction.
       
    88  */
       
    89 void CTsDataList::ConstructL()
       
    90 {
       
    91     BaseConstructL();
       
    92     mHiddenUids.AppendL(KHsApplicationUid);
       
    93     User::LeaveIfError(RFbsSession::Connect());
       
    94     RAknIconSrvClient::Connect();
       
    95 }
       
    96 
       
    97 // --------------------------------------------------------------------------
       
    98 /**
       
    99  * Returns a reference to the current content.
       
   100  * Also performs sanity checks, e.g. associates application icons
       
   101  * when no screenshot has been received.
       
   102  * @return  ref to content array
       
   103  */
       
   104 const RTsFswArray& CTsDataList::Data() const
       
   105 {
       
   106     return mData;
       
   107 }
       
   108 
       
   109 // --------------------------------------------------------------------------
       
   110 /**
       
   111  * Interface implementation
       
   112  * @see MTsWindowGroupsObserver HandleWindowGroupChanged
       
   113  */
       
   114 void CTsDataList::HandleWindowGroupChanged(MTsResourceManager &, 
       
   115                                               const TArray<RWsSession::TWindowGroupChainInfo> &wgList)
       
   116 {
       
   117     TRAP_IGNORE(RTsFswArray newAppsList;
       
   118                 CleanupResetAndDestroyPushL(newAppsList);
       
   119                 CollectAppsL(newAppsList, wgList);
       
   120                 FitDataToList(newAppsList);
       
   121                 CleanupStack::PopAndDestroy(&newAppsList));
       
   122     
       
   123 }
       
   124 
       
   125 // --------------------------------------------------------------------------
       
   126 /**
       
   127  * Adds running apps to the list.
       
   128  * @param   appsList    array to add to
       
   129  */
       
   130 void CTsDataList::CollectAppsL(RTsFswArray& appsList, 
       
   131                                const TArray<RWsSession::TWindowGroupChainInfo> &wgList)
       
   132 {
       
   133     TInt offset(KErrNotFound);
       
   134     for (TInt i = 0; i < wgList.Count(); ++i) {
       
   135         TTsEntryKey key = TsEntryKeyGeneraror::GenerateL(wgList[i].iId, wgList);
       
   136         //skip this entry if it is already on list
       
   137         if (FindEntry(appsList, key) >= 0) {
       
   138             continue;
       
   139         }
       
   140 
       
   141         // get window group name
       
   142         CApaWindowGroupName* windowName = CApaWindowGroupName::NewLC(mResources.WsSession(), key.WindowGroupId());
       
   143         TUid appUid = windowName->AppUid();
       
   144         
       
   145         //Check hidden applications
       
   146         if (KErrNotFound != (offset = mHiddenUids.Find(appUid))) {
       
   147             UpdateLookupTableL(mHiddenUids, offset);
       
   148         } else if (KErrNotFound != (offset = mAllowedUids.Find(appUid))) {
       
   149             UpdateLookupTableL(mAllowedUids, offset);
       
   150             AddEntryL(key, appUid, windowName, appsList);
       
   151         } else if(VerifyApplicationL(appUid)) {
       
   152             AddEntryL(key, appUid, windowName, appsList);
       
   153         }
       
   154         CleanupStack::PopAndDestroy(windowName);
       
   155     }
       
   156     CompressLookupTable(mHiddenUids);
       
   157     CompressLookupTable(mAllowedUids);
       
   158 }
       
   159 
       
   160 // --------------------------------------------------------------------------
       
   161 /**
       
   162  * Called from CollectTasksL for each entry in the task list.
       
   163  * @param   key       entry key
       
   164  * @param   appUid     application uid
       
   165  * @param   wgName     window group name or NULL
       
   166  * @param   newList    list to add to
       
   167  */
       
   168 void CTsDataList::AddEntryL(const TTsEntryKey& key, const TUid& appUid,
       
   169     CApaWindowGroupName* wgName, RTsFswArray& newList)
       
   170 {
       
   171     CTsEntry* entry = CTsEntry::NewLC(key, &mObserver);
       
   172 
       
   173     // check if present in old list and if yes then take some of the old data
       
   174     TBool found = ConsiderOldDataL(key);
       
   175 
       
   176     // if not present previously then find out app name
       
   177     // and check if screenshot is already available
       
   178     if (!found) {
       
   179         entry->SetAppUid(appUid);
       
   180         HBufC* name = FindAppNameLC(wgName, appUid, key.WindowGroupId());
       
   181         if (name) {
       
   182             entry->SetAppNameL(*name);
       
   183         }
       
   184         CleanupStack::PopAndDestroy(name);
       
   185 
       
   186         if (wgName) {
       
   187             entry->SetCloseableApp(!wgName->IsSystem());
       
   188         }
       
   189         CFbsBitmap* iconBitmap = NULL;
       
   190         CFbsBitmap* iconMask = NULL;
       
   191         GetAppIconL(appUid, iconBitmap, iconMask);
       
   192         //transfer ownership to entry
       
   193         entry->SetAppIcon(iconBitmap, iconMask);
       
   194     }
       
   195 
       
   196     // add to new list, ownership is transferred
       
   197     newList.AppendL(entry);
       
   198     CleanupStack::Pop(entry);
       
   199 }
       
   200 
       
   201 // --------------------------------------------------------------------------
       
   202 /**
       
   203  * Checks if there is an entry for same app in the content list.
       
   204  * If yes then it takes some of the data for the entry that
       
   205  * will correspond to the same app in the refreshed content list.
       
   206  * @param   key      new key in content list
       
   207  * @return  ETrue if app was found
       
   208  */
       
   209 TBool CTsDataList::ConsiderOldDataL(const TTsEntryKey& key)
       
   210 {
       
   211     for (TInt entryIdx = 0, oldCount = mData.Count(); entryIdx < oldCount; ++entryIdx) {
       
   212         if (mData[entryIdx]->Key() == key) {
       
   213             return ETrue;
       
   214         }
       
   215     }
       
   216     return EFalse;
       
   217 }
       
   218 
       
   219 // --------------------------------------------------------------------------
       
   220 /**
       
   221  * Finds out the application name.
       
   222  * @param   windowName window group name or NULL
       
   223  * @param   appUId     application uid
       
   224  * @param   wgId       window group id
       
   225  * @return  application name, ownership transferred to caller
       
   226  */
       
   227 HBufC* CTsDataList::FindAppNameLC(CApaWindowGroupName* windowName, const TUid& appUid, TInt wgId)
       
   228 {
       
   229     //Retrieve the app name
       
   230     TApaAppInfo info;
       
   231     mResources.ApaSession().GetAppInfo(info, appUid);
       
   232     TPtrC caption = info.iShortCaption;
       
   233 
       
   234     HBufC* tempName = 0;
       
   235     if (!caption.Length() && windowName) // if not set - use thread name instead
       
   236     {
       
   237         if (windowName->Caption().Length()) {
       
   238             tempName = windowName->Caption().AllocL();
       
   239             //put on cleanupstack after the if
       
   240         }
       
   241         else {
       
   242             TThreadId threadId;
       
   243             TInt err = mResources.WsSession().GetWindowGroupClientThreadId(wgId, threadId);
       
   244             if (err == KErrNone) {
       
   245                 RThread thread;
       
   246                 CleanupClosePushL(thread);
       
   247                 err = thread.Open(threadId);
       
   248                 if (err == KErrNone) {
       
   249                     tempName = thread.Name().AllocL(); // codescanner::forgottoputptroncleanupstack
       
   250                     // tempName put on cleanupstack after the if
       
   251                 }
       
   252                 CleanupStack::PopAndDestroy(&thread);
       
   253             }
       
   254         }
       
   255     }
       
   256     else {
       
   257         tempName = caption.AllocL();
       
   258         //put on cleanupstack after the if
       
   259     }
       
   260     CleanupStack::PushL(tempName);
       
   261     return tempName;
       
   262 }
       
   263 
       
   264 // --------------------------------------------------------------------------
       
   265 /**
       
   266  * Fit existing class contained data list into give one.
       
   267  * Data is being changed with application type consideration that is based 
       
   268  * on aConsiderWidgets param. 
       
   269  * Function removes or add entries into data depend on given list.
       
   270  * @param   listToFit          list with actual data  
       
   271  */
       
   272 void CTsDataList::FitDataToList(RTsFswArray& listToFit)
       
   273 {
       
   274     TBool changed = EFalse;
       
   275     TInt listCount = listToFit.Count();
       
   276     TInt dataCount = mData.Count();
       
   277 
       
   278     //remove items that dont't exists in newly collected list      
       
   279     for (TInt i = dataCount - 1; i >= 0; --i) {
       
   280         if (!CheckIfExists(*mData[i], listToFit)) {
       
   281             delete mData[i];
       
   282             mData.Remove(i);
       
   283             changed = ETrue;
       
   284         }
       
   285     }
       
   286     RArray<TTsEntryKey> allKeys;
       
   287 
       
   288     //add new item at start
       
   289     for (TInt i = listToFit.Count() - 1; i >= 0; --i) {
       
   290         allKeys.Insert(listToFit[i]->Key(), 0);
       
   291         if (!CheckIfExists(*listToFit[i], mData)) {
       
   292             mData.Insert(listToFit[i], 0);
       
   293             listToFit[i] = 0;
       
   294             changed = ETrue;
       
   295         }
       
   296     }
       
   297     //establish order
       
   298     TBool orderChanged = EstablishOrder(allKeys);
       
   299     if (changed || orderChanged) {
       
   300         mObserver.DataChanged();
       
   301     }
       
   302     allKeys.Close();
       
   303 }
       
   304 
       
   305 // --------------------------------------------------------------------------
       
   306 /**
       
   307  * Checks if there is an entry for same app in the given list.
       
   308  * @param   entry      entry
       
   309  * @param   newList    ref to list
       
   310  * @return  ETrue if app was found
       
   311  */
       
   312 
       
   313 TBool CTsDataList::CheckIfExists(const CTsEntry& entry, const RTsFswArray& list) const
       
   314 {
       
   315     TBool exists(EFalse);
       
   316     TInt pos = FindEntry(list, entry.Key());
       
   317     if (pos >= 0) {
       
   318         exists = ETrue;
       
   319     }
       
   320     return exists;
       
   321 }
       
   322 
       
   323 // --------------------------------------------------------------------------
       
   324 /**
       
   325  * Retrieves the bitmap/mask for the icon of the given app.
       
   326  * @param   appUid application uid
       
   327  * @param   bitmapArg bitmap ptr, ownership transferred to caller, or NULL
       
   328  * @param   maskArg   mask ptr, ownership transferred to caller, or NULL
       
   329  */
       
   330 void CTsDataList::GetAppIconL(const TUid& aAppUid, CFbsBitmap*& bitmapArg, CFbsBitmap*& maskArg)
       
   331 {
       
   332     bitmapArg = maskArg = NULL;
       
   333 
       
   334     TSize size(KAppIconWidth, KAppIconHeight);
       
   335     CApaMaskedBitmap* apaMaskedBitmap = CApaMaskedBitmap::NewLC();
       
   336     TInt err = mResources.ApaSession().GetAppIcon(aAppUid, size, *apaMaskedBitmap);
       
   337     TInt iconsCount(0);
       
   338     if (err == KErrNone) {
       
   339         err = mResources.ApaSession().NumberOfOwnDefinedIcons(aAppUid, iconsCount);
       
   340     }
       
   341 
       
   342     if ((err == KErrNone) && (iconsCount > 0)) {
       
   343         bitmapArg = static_cast<CFbsBitmap*> (apaMaskedBitmap);
       
   344         TInt maskHandle = apaMaskedBitmap->Mask()->Handle();
       
   345         maskArg = new (ELeave) CFbsBitmap;
       
   346         maskArg->Duplicate(maskHandle);
       
   347         CleanupStack::Pop(apaMaskedBitmap);
       
   348     }
       
   349     else {
       
   350         CleanupStack::PopAndDestroy(apaMaskedBitmap);
       
   351         HBufC* fileNameFromApparc = NULL;
       
   352         TInt err = mResources.ApaSession().GetAppIcon(aAppUid, fileNameFromApparc);
       
   353         if (err == KErrNone) {
       
   354             CleanupStack::PushL(fileNameFromApparc);
       
   355             CFbsBitmap *bitamp(0);
       
   356             CFbsBitmap *mask(0);
       
   357             TInt bitmapIndex = 0;
       
   358             TInt maskIndex = 1;
       
   359             // it will change bitmap ids if it is mif (checking inside)
       
   360             AknIconUtils::ValidateLogicalAppIconId(*fileNameFromApparc, bitmapIndex, maskIndex);
       
   361             AknIconUtils::CreateIconLC(bitamp, mask, fileNameFromApparc->Des(), bitmapIndex,
       
   362                 maskIndex);
       
   363 
       
   364             if (AknIconUtils::IsMifFile(*fileNameFromApparc)) {
       
   365                 AknIconUtils::DisableCompression(bitamp);
       
   366                 AknIconUtils::SetSize(bitamp, TSize(KAppIconWidth, KAppIconHeight),
       
   367                     EAspectRatioPreservedAndUnusedSpaceRemoved);
       
   368                 // bitmap and icon, AknsUtils::CreateIconLC doesn't specify the order
       
   369                 CleanupStack::Pop(2);
       
   370                 bitmapArg = bitamp;
       
   371                 maskArg = mask;
       
   372             }
       
   373             else {
       
   374                 CleanupStack::PopAndDestroy(2);
       
   375             }
       
   376             CleanupStack::PopAndDestroy(fileNameFromApparc);
       
   377         }
       
   378     }
       
   379 }
       
   380 
       
   381 // --------------------------------------------------------------------------
       
   382 /**
       
   383  * Checks if given uid is on hidden list
       
   384  * @param   aUid uid to be checked
       
   385  * @return  ETrue if uid is on hidden list
       
   386  */
       
   387 TBool CTsDataList::IsHiddenUid(TUid uid)
       
   388 {
       
   389     return mHiddenUids.Find(uid) >= 0 ? ETrue : EFalse;
       
   390 }
       
   391 
       
   392 // --------------------------------------------------------------------------
       
   393 /**
       
   394  * Finds entry in array
       
   395  * @param   list list to find
       
   396  * @param   key finding key
       
   397  * @return   position or KErrNotFound
       
   398  */
       
   399 TInt CTsDataList::FindEntry(const RTsFswArray& list, const TTsEntryKey& key) const
       
   400 {
       
   401     TInt pos(KErrNotFound);
       
   402     for (TInt entryIdx = 0; entryIdx < list.Count(); ++entryIdx) {
       
   403         if (list[entryIdx]->Key() == key) {
       
   404             pos = entryIdx;
       
   405             break;
       
   406         }
       
   407     }
       
   408     return pos;
       
   409 }
       
   410 // --------------------------------------------------------------------------
       
   411 /**
       
   412  * Set screenshot 
       
   413  */
       
   414 void CTsDataList::UpdateL(TInt key, const CFbsBitmap& data, TInt /*param*/, TInt priority)
       
   415 {
       
   416     const TInt pos = FindEntry(mData, GenerateKeyL(key));
       
   417     User::LeaveIfError(pos);
       
   418     mData[pos]->SetScreenshotL(data, static_cast<UpdatePriority>(priority));
       
   419 }
       
   420 
       
   421 // --------------------------------------------------------------------------
       
   422 /**
       
   423  * Change visibility status 
       
   424  */
       
   425 void CTsDataList::UpdateL(TInt key, const Visibility& data, TInt /*param*/)
       
   426 {
       
   427     const TInt pos = FindEntry(mData, GenerateKeyL(key));
       
   428     User::LeaveIfError(pos);
       
   429     data == mData[pos]->GetVisibility() ? User::Leave(KErrInUse) : 
       
   430                                           mData[pos]->SetVisibility(data);
       
   431     mObserver.DataChanged();
       
   432 }
       
   433 
       
   434 // --------------------------------------------------------------------------
       
   435 /**
       
   436  * Removes screenshot 
       
   437  */
       
   438 void CTsDataList::RemoveL(TInt key, TInt /*param*/)
       
   439 {
       
   440     TInt pos = FindEntry(mData, GenerateKeyL(key));
       
   441     User::LeaveIfError(pos);
       
   442     mData[pos]->RemoveScreenshotL();
       
   443 }
       
   444 
       
   445 // --------------------------------------------------------------------------
       
   446 /**
       
   447  * Establish entry order accridung to aKeyList, all keys MUST be in iData
       
   448  * @param   keyList reference key list
       
   449  * @return   ETrue if changes occured
       
   450  */
       
   451 TBool CTsDataList::EstablishOrder(const RArray<TTsEntryKey>& keyList)
       
   452 {
       
   453     TBool changed(EFalse);
       
   454     __ASSERT_ALWAYS(mData.Count() == keyList.Count(), User::Panic(_L("EstablishOrder 1"), KErrBadHandle) );
       
   455     for (TInt i = 0; i < keyList.Count(); i++) {
       
   456         const TTsEntryKey& currentdataKey = mData[i]->Key();
       
   457         const TTsEntryKey& referenceKey = keyList[i];
       
   458         if (!(currentdataKey == referenceKey)) {
       
   459             TInt foundPos = FindEntry(mData, referenceKey);
       
   460             __ASSERT_ALWAYS(foundPos>=0, User::Panic(_L("EstablishOrder 2"), KErrBadHandle) );
       
   461             CTsEntry* entry = mData[foundPos];
       
   462             mData.Remove(foundPos);
       
   463             mData.Insert(entry, i);
       
   464             changed = ETrue;
       
   465         }
       
   466     }
       
   467     return changed;
       
   468 }
       
   469 
       
   470 // --------------------------------------------------------------------------
       
   471 /**
       
   472  * Gets allowed uids, tries to filter non GUI application 
       
   473  */
       
   474 TBool CTsDataList::VerifyApplicationL(TUid uid)
       
   475 {
       
   476     TBool retVal(EFalse);
       
   477     TApaAppInfo appInfo;
       
   478     TApaAppCapabilityBuf appCap;
       
   479 
       
   480     User::LeaveIfError(mResources.ApaSession().GetAllApps(0));
       
   481     // for every application get uid, hidden and missing attribute
       
   482     // and add to aArray.
       
   483     while (KErrNone == mResources.ApaSession().GetNextApp(appInfo)) {
       
   484         User::LeaveIfError(mResources.ApaSession().GetAppCapability(appCap, appInfo.iUid));
       
   485         if(!appCap().iAppIsHidden) {
       
   486             if (uid == appInfo.iUid) {
       
   487                 retVal = ETrue;
       
   488                 mAllowedUids.InsertL(appInfo.iUid, mAllowedUids.Count());
       
   489             }
       
   490         } else if(KErrNotFound == mHiddenUids.Find(appInfo.iUid)) {
       
   491             mHiddenUids.InsertL(appInfo.iUid, mHiddenUids.Count());
       
   492         }
       
   493     }
       
   494     if (EFalse == retVal && KErrNotFound == mHiddenUids.Find(uid)) {
       
   495         mHiddenUids.InsertL(uid, mHiddenUids.Count());
       
   496     }
       
   497     return retVal;
       
   498 }
       
   499 
       
   500 // --------------------------------------------------------------------------
       
   501 /**
       
   502  * Function generate task key using window group id
       
   503  * @param wgId - window group id of running application
       
   504  * @param entry key 
       
   505  */
       
   506 TTsEntryKey CTsDataList::GenerateKeyL(TInt wgId)
       
   507 {
       
   508     RArray<RWsSession::TWindowGroupChainInfo> allWgIds;
       
   509    CleanupClosePushL(allWgIds);
       
   510    User::LeaveIfError(mResources.WsSession().WindowGroupList(0, &allWgIds));
       
   511    const TTsEntryKey key(TsEntryKeyGeneraror::GenerateL(wgId, allWgIds.Array()));
       
   512    CleanupStack::PopAndDestroy(&allWgIds);
       
   513    return key;
       
   514 }
       
   515 
       
   516 // --------------------------------------------------------------------------
       
   517 /**
       
   518  * Analyse and compress lookup table id needed
       
   519  * @param array - lookup table that has to be checked
       
   520  * 
       
   521  */
       
   522 void CTsDataList::CompressLookupTable(RArray<TUid> &array)
       
   523 {
       
   524     while(KMaxLookupSize < array.Count()) {
       
   525         array.Remove(0);
       
   526     }
       
   527 }
       
   528 
       
   529 // --------------------------------------------------------------------------
       
   530 /**
       
   531  * Change priority of an item in the lookup table
       
   532  * @param array - look up table
       
   533  * @param offset - index of an item in the table
       
   534  */
       
   535 void CTsDataList::UpdateLookupTableL(RArray<TUid> &array, TInt offset)
       
   536 {
       
   537     const TUid uid(array[offset]);
       
   538     array.Remove(offset);
       
   539     array.InsertL(uid, array.Count());
       
   540 }
       
   541 // end of file