921 This propagates the change to all of its dependents. |
920 This propagates the change to all of its dependents. |
922 This function takes Originator name and id as parameter as this needs to be passed for custom sense function. |
921 This function takes Originator name and id as parameter as this needs to be passed for custom sense function. |
923 */ |
922 */ |
924 TInt DStaticPowerResourceD::HandleChangePropagation(TPowerRequest aRequest, TPropagation aProp, TUint aOriginatorId, const TDesC8& aOriginatorName) |
923 TInt DStaticPowerResourceD::HandleChangePropagation(TPowerRequest aRequest, TPropagation aProp, TUint aOriginatorId, const TDesC8& aOriginatorName) |
925 { |
924 { |
|
925 TInt result = KErrNone; |
|
926 result = PowerResourceController->HandleResourceChange(aRequest, aProp, aOriginatorId, aOriginatorName, this); |
|
927 return result; |
|
928 } |
|
929 //Function to change the resource state of dependency resource. |
|
930 TInt DPowerResourceController::HandleResourceChange(TPowerRequest &aRequest, TPropagation aProp, TUint aOriginatorId, |
|
931 const TDesC8& aOriginatorName, DStaticPowerResourceD* aResource) |
|
932 { |
926 static TUint16 clientLevelCount = 0; |
933 static TUint16 clientLevelCount = 0; |
927 DStaticPowerResourceD* pDR = (DStaticPowerResourceD*)aRequest.Resource(); |
934 DStaticPowerResourceD* pDR = (DStaticPowerResourceD*)aRequest.Resource(); |
|
935 DStaticPowerResourceD* pDepRes = NULL; |
|
936 SNode* dependencyList = NULL; |
|
937 TPowerRequest depRequest; |
928 TInt result = KErrNone; |
938 TInt result = KErrNone; |
929 TInt resState; |
939 TInt resState; |
930 TPowerRequest depRequest; |
|
931 depRequest.ReqType() = TPowerRequest::EChange; |
940 depRequest.ReqType() = TPowerRequest::EChange; |
932 depRequest.ResourceCb() = NULL; |
941 depRequest.ResourceCb() = NULL; |
933 depRequest.ReturnCode() = KErrNone; |
942 depRequest.ReturnCode() = KErrNone; |
934 depRequest.RequiresChange() = EFalse; |
943 depRequest.RequiresChange() = EFalse; |
935 DStaticPowerResourceD* pDepRes = NULL; |
944 |
936 TBool traceEnabled = EFalse; |
945 if(pDR->iResourceId & KIdMaskDynamic) |
|
946 dependencyList = ((DDynamicPowerResourceD*)pDR)->iDependencyList; |
|
947 else |
|
948 dependencyList = pDR->iDependencyList; |
|
949 switch(aProp) |
|
950 { |
|
951 case EChangeStart: |
|
952 { |
|
953 if(!dependencyList) /*No dependents so change state of the resource*/ |
|
954 { |
|
955 aRequest.ReturnCode() = pDR->DoRequest(aRequest); |
|
956 if(aRequest.ReturnCode() == KErrNone) |
|
957 { |
|
958 aResource->iCachedLevel = aRequest.Level(); |
|
959 aResource->iLevelOwnerId = aRequest.ClientId(); |
|
960 if(aResource->iIdleListEntry) |
|
961 { |
|
962 aResource->iIdleListEntry->iCurrentLevel = aRequest.Level(); |
|
963 aResource->iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); |
|
964 } |
|
965 CompleteNotifications(aRequest.ClientId(), pDR, |
|
966 aRequest.Level(), aRequest.ReturnCode(), aRequest.ClientId()); |
|
967 } |
|
968 break; |
|
969 } |
|
970 depRequest.ResourceId() = aRequest.ResourceId(); |
|
971 depRequest.ClientId() = aRequest.ResourceId(); |
|
972 depRequest.Level() = aRequest.Level(); |
|
973 depRequest.Resource() = pDR; |
|
974 result = pDR->HandleChangePropagation(depRequest, ECheckChangeAllowed, aOriginatorId, aOriginatorName); |
|
975 if(result != KErrNone) |
|
976 return result; |
|
977 /*Adjust resource client level*/ |
|
978 if(clientLevelCount) |
|
979 { |
|
980 result = ReserveClientLevelPoolCount(clientLevelCount); |
|
981 if(result != KErrNone) |
|
982 return result; |
|
983 } |
|
984 /*Resource change of dependents */ |
|
985 pDR->HandleChangePropagation(aRequest, ERequestStateChange, aOriginatorId, aOriginatorName); |
|
986 /*Notification to dependents */ |
|
987 pDR->HandleChangePropagation(aRequest, EIssueNotifications, aOriginatorId, aOriginatorName); |
|
988 break; |
|
989 } |
|
990 case ECheckChangeAllowed: |
|
991 { |
|
992 TChangePropagationStatus status; |
|
993 for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext) |
|
994 { |
|
995 pDepRes = depNode->iResource; |
|
996 if((aRequest.ClientId() & KIdMaskResourceWithDependencies) && |
|
997 (pDepRes->iResourceId == (TUint)aRequest.ClientId())) |
|
998 continue; |
|
999 /*Resource need not change if it is already in that state, so continue with |
|
1000 another dependent state.*/ |
|
1001 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1002 status = ((DDynamicPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), |
|
1003 aRequest.Level(), resState); |
|
1004 else |
|
1005 status = ((DStaticPowerResourceD*)pDepRes)->TranslateDependentState(aRequest.ResourceId(), |
|
1006 aRequest.Level(), resState); |
|
1007 if((status == ENoChange) || (pDepRes->iCachedLevel == resState)) |
|
1008 { |
|
1009 depNode->iRequiresChange = EFalse; |
|
1010 continue; |
|
1011 } |
|
1012 if(status == EChangeNotAccepted) |
|
1013 return KErrPermissionDenied; |
|
1014 depRequest.ResourceId() = pDepRes->iResourceId; |
|
1015 depRequest.ClientId() = aRequest.ResourceId(); /*ID of the dependent resource */ |
|
1016 depRequest.Level() = resState; |
|
1017 depRequest.Resource() = pDepRes; |
|
1018 /*Check resource client list and resource list to see whether change is allowed.*/ |
|
1019 if(pDepRes->Sense() == DStaticPowerResource::ECustom) |
|
1020 { |
|
1021 /*Call custom function to check whether change is allowed.*/ |
|
1022 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1023 depRequest.RequiresChange() = ((DDynamicPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), |
|
1024 aOriginatorName, depRequest.ResourceId(), EClientRequestLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, |
|
1025 (TAny*)&((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, NULL); |
|
1026 else |
|
1027 depRequest.RequiresChange() = ((DStaticPowerResourceD*)pDepRes)->iDepCustomFunction(depRequest.ClientId(), |
|
1028 aOriginatorName, depRequest.ResourceId(), EClientRequestLevel, depRequest.Level(), (TAny*)&pDepRes->iClientList, |
|
1029 (TAny*)&((DStaticPowerResourceD*)pDepRes)->iResourceClientList, NULL); |
|
1030 if(!depRequest.RequiresChange()) |
|
1031 return KErrPermissionDenied; |
|
1032 } |
|
1033 SPowerResourceClientLevel*pN=NULL; |
|
1034 for(SDblQueLink* pNL=pDepRes->iClientList.First();pNL!=&pDepRes->iClientList.iA; pNL=pNL->iNext) |
|
1035 { |
|
1036 pN = (SPowerResourceClientLevel*)pNL; |
|
1037 if(pDepRes->Sense() == DStaticPowerResource::EPositive) |
|
1038 { |
|
1039 if(pN->iLevel > depRequest.Level()) |
|
1040 return KErrPermissionDenied; |
|
1041 } |
|
1042 else if(pDepRes->Sense() == DStaticPowerResource::ENegative) |
|
1043 { |
|
1044 if(pN->iLevel < depRequest.Level()) |
|
1045 return KErrPermissionDenied; |
|
1046 } |
|
1047 } |
|
1048 /*check through the resource client level */ |
|
1049 SPowerResourceClientLevel*pCL = NULL; |
|
1050 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1051 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; |
|
1052 else |
|
1053 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; |
|
1054 for(; pCL != NULL; pCL = pCL->iNextInList) |
|
1055 { |
|
1056 if(pCL->iClientId == pDR->iResourceId) |
|
1057 break; |
|
1058 } |
|
1059 if(!pCL) |
|
1060 clientLevelCount++; |
|
1061 /*check dependent resource client list & resource list to see whether change is allowed */ |
|
1062 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1063 result = ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, |
|
1064 ECheckChangeAllowed, aOriginatorId, aOriginatorName); |
|
1065 else |
|
1066 result = ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, |
|
1067 ECheckChangeAllowed, aOriginatorId, aOriginatorName); |
|
1068 if(result != KErrNone) |
|
1069 return result; |
|
1070 depNode->iPropagatedLevel = resState; |
|
1071 depNode->iRequiresChange = ETrue; |
|
1072 } |
|
1073 break; |
|
1074 } |
|
1075 case ERequestStateChange: |
|
1076 { |
|
1077 SPowerResourceClientLevel* pCL = NULL; |
|
1078 for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext) |
|
1079 { |
|
1080 pDepRes = depNode->iResource; |
|
1081 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) |
|
1082 continue; |
|
1083 depRequest.ResourceId() = pDepRes->iResourceId; |
|
1084 depRequest.ClientId() = aRequest.ResourceId(); |
|
1085 depRequest.Level() = depNode->iPropagatedLevel; |
|
1086 depRequest.Resource() = pDepRes; |
|
1087 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1088 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, |
|
1089 aOriginatorId, aOriginatorName); |
|
1090 else |
|
1091 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, ERequestStateChange, |
|
1092 aOriginatorId, aOriginatorName); |
|
1093 /*Update level if resource client level is already present for this resource.*/ |
|
1094 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1095 pCL = ((DDynamicPowerResourceD*)pDepRes)->iResourceClientList; |
|
1096 else |
|
1097 pCL = ((DStaticPowerResourceD*)pDepRes)->iResourceClientList; |
|
1098 for(; pCL != NULL; pCL = pCL->iNextInList) |
|
1099 { |
|
1100 if(pCL->iClientId == pDR->iResourceId) |
|
1101 { |
|
1102 pCL->iLevel = depNode->iPropagatedLevel; |
|
1103 break; |
|
1104 } |
|
1105 } |
|
1106 if(!pCL) /*Create a new resource client level*/ |
|
1107 { |
|
1108 RemoveClientLevelFromPool(pCL); |
|
1109 pCL->iClientId = pDR->iResourceId; |
|
1110 pCL->iResourceId = pDepRes->iResourceId; |
|
1111 pCL->iLevel = depNode->iPropagatedLevel; |
|
1112 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1113 { |
|
1114 LIST_PUSH(((DDynamicPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); |
|
1115 } |
|
1116 else |
|
1117 { |
|
1118 LIST_PUSH(((DStaticPowerResourceD*)pDepRes)->iResourceClientList, pCL, iNextInList); |
|
1119 } |
|
1120 clientLevelCount--; |
|
1121 } |
|
1122 } |
|
1123 #ifdef PRM_INSTRUMENTATION_MACRO |
|
1124 if(aRequest.ClientId() & KIdMaskResourceWithDependencies) |
|
1125 { |
|
1126 SPowerResourceClient res; |
|
1127 SPowerResourceClient* pC = &res; |
|
1128 pC->iClientId = aRequest.ClientId(); |
|
1129 pC->iName = &KParentResource; |
|
1130 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; |
|
1131 TUint aResourceId = pDR->iResourceId; |
|
1132 TInt aNewState = aRequest.Level(); |
|
1133 PRM_CLIENT_CHANGE_STATE_START_TRACE |
|
1134 } |
|
1135 #endif |
|
1136 aResource->DoRequest(aRequest); |
937 #ifdef PRM_INSTRUMENTATION_MACRO |
1137 #ifdef PRM_INSTRUMENTATION_MACRO |
938 traceEnabled = ETrue; |
1138 if(aRequest.ClientId() & KIdMaskResourceWithDependencies) |
939 #endif |
1139 { |
940 HANDLE_CHANGE_PROPAGATION(PowerResourceController, DStaticPowerResourceD*, traceEnabled, aOriginatorId, aOriginatorName) |
1140 SPowerResourceClient res; |
941 } |
1141 SPowerResourceClient* pC = &res; |
942 |
1142 pC->iClientId = aRequest.ClientId(); |
943 |
1143 pC->iName = &KParentResource; |
|
1144 DStaticPowerResource*pR = (DStaticPowerResource*)pDR; |
|
1145 TUint aResourceId = pDR->iResourceId; |
|
1146 TInt aNewState = aRequest.Level(); |
|
1147 TInt r = KErrNone; |
|
1148 PRM_CLIENT_CHANGE_STATE_END_TRACE |
|
1149 } |
|
1150 #endif |
|
1151 pDR->iCachedLevel = aRequest.Level(); |
|
1152 pDR->iLevelOwnerId = aRequest.ClientId(); |
|
1153 if(pDR->iIdleListEntry) |
|
1154 { |
|
1155 pDR->iIdleListEntry->iCurrentLevel = aRequest.Level(); |
|
1156 pDR->iIdleListEntry->iLevelOwnerId = aRequest.ClientId(); |
|
1157 } |
|
1158 break; |
|
1159 } |
|
1160 case EIssueNotifications: |
|
1161 { |
|
1162 for(SNode* depNode = dependencyList; depNode != NULL; depNode = depNode->iNext) |
|
1163 { |
|
1164 pDepRes = depNode->iResource; |
|
1165 if((!depNode->iRequiresChange) || (pDepRes->iResourceId == (TUint)aRequest.ClientId())) |
|
1166 continue; |
|
1167 depRequest.ResourceId() = pDepRes->iResourceId; |
|
1168 depRequest.ClientId() = pDepRes->iLevelOwnerId; |
|
1169 depRequest.Level() = pDepRes->iCachedLevel; |
|
1170 depRequest.Resource() = pDepRes; |
|
1171 if(pDepRes->iResourceId & KIdMaskDynamic) |
|
1172 ((DDynamicPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, |
|
1173 aOriginatorId, aOriginatorName); |
|
1174 else |
|
1175 ((DStaticPowerResourceD*)pDepRes)->HandleChangePropagation(depRequest, EIssueNotifications, |
|
1176 aOriginatorId, aOriginatorName); |
|
1177 } |
|
1178 CompleteNotifications(aRequest.ClientId(), pDR, aRequest.Level(), KErrNone, |
|
1179 aRequest.ClientId()); |
|
1180 break; |
|
1181 } |
|
1182 default: |
|
1183 return KErrNotSupported; |
|
1184 } |
|
1185 return result; |
|
1186 } |
|
1187 |
|
1188 |