WM/WINCE代码研读系列之Power Management(6)

2019-07-14 00:17发布

下面在对UpdateDeviceState(pds)做具体说明
UpdateDeviceState
{
     //获取当前设备的电源级别最大值(ceilingDx)和最小值(floorDx)
     GetNewDeviceStateInfo
     {
          1.对于newCeilingDx
          //首先每个系统电源状态都对应一个默认的所有设备的最大电源级别
          newCeilingDx = psps->defaultCeilingDx;
 
         //在链表gpCeilingDx里查找特定的一类设备的最大电源级别
          devId.pGuid = pds->pListHead->pGuid;
          devId.pszName = NULL;
          if((pdpr = PowerRestrictionFindList(pCeilingDxList,&devId,NULL))!= NULL)
          {
                  newCeilingDx = pdpr->devDx;
          }
 
         //在链表gpCeilingDx里寻找特定的某个设备的最大电源级别
          devId.pszName = pds->pszName;
          if((pdpr = PowerRestrictionFindList(pCeilingDxList,&devId,NULL)) != NULL)
          {
                newCeilingDx = pdpr->devDx;
          }
 
          2.对于newFloorDx
          newFloorDx = D4;//先设置为最小电源级别D4
         //在链表gpFloorDx 里去查找某一类设备的最小电源级别
          devId.pszName = NULL;
          pdpr = pFloorDxList;
          while((pdpr = PowerRestrictionFindList(pdpr,&devId,NULL))!= NULL)
          {
               if(pdpr->devDx < newFloorDx) != 0))
                   newFloorDx = pdpr->devDx;
               pdpr = pdpr->pNext;
           }

         //在链表gpFloorDx里寻找在特定系统电源状态下的某一类设备的最小电源级别
          devId.pszName = NULL;
          pdpr = pFloorDxList;
          while((pdpr = PowerRestrictionFindList(pdpr,&devId,psps->pszName))!= NULL)
          {
               if(pdpr->devDx < newFloorDx)
                   newFloorDx = pdpr->devDx;
               pdpr = pdpr->pNext;
          }
 
         //在链表gpFloorDx 里去查找某个设备的最小电源级别
          devId.pszName = pds->pszName;
          pdpr = pFloorDxList;
          while((pdpr = PowerRestrictionFindList(pdpr,&devId,NULL))!= NULL)
          {
               if(pdpr->devDx < newFloorDx)
                    newFloorDx = pdpr->devDx;
               pdpr = pdpr->pNext;
          }

         //在链表gpFloorDx里寻找在特定系统电源状态下的某个设备的最小电源级别
          devId.pszName = pds->pszName;
          pdpr = pFloorDxList;
          while((pdpr = PowerRestrictionFindList(pdpr,&devId,psps->pszName)) != NULL) 
          {
               if(pdpr->devDx < newFloorDx)
                    newFloorDx = pdpr->devDx;
               pdpr = pdpr->pNext;
           }
      }
 
     //决定设备电源级别最终是什么
      GetNewDeviceDx
      {
          //如果setDx不是PwrDeviceUnspecified,则设备的最终电源级别就等于setDx。
           if(setDx != PwrDeviceUnspecified)
           {
                newDx = setDx;
           }
           else{
               //设备的最终电源级别由reqDx 来确定,但最终电源级别必须在最小值(floorDx)和最大值(ceilingDx)之间
                newDx = reqDx;
                if(newDx < ceilingDx)
                     newDx = ceilingDx;
                if(floorDx < newDx)
                     newDx = floorDx;
           }
 
           //如果电源级别没有改变或是无效
           if(curDx == newDx || ! VALID_DX(newDx))
           {
                 newDx = PwrDeviceUnspecified;
            }
      }
 
      //调用各个驱动的IOCTL_POWER_SET去设置电源级别
      SetDevicePower
      {
            //根据设备支持电源级别的情况来重影射一下电源级别
            reqDx = MapDevicePowerState(newDx,pds->caps.DeviceDx);
 
           //如果要设置的电源级别与当前级别不一样就设置
           if(reqDx != pds->actualDx || pds->dwNumPending != 0 || fForceSet)
                fDoSet = TRUE;
 
           //打开设备驱动并调用驱动的IOCTL_POWER_SET
           hDevice = pds->pInterface->pfnOpenDevice(pds);
           pds->pInterface->pfnRequestDevice(hDevice,IOCTL_POWER_SET,ppr,ppr == NULL?0:sizeof(*ppr),&reqDx,sizeof(reqDx),&dwBytesReturned);
 
          //如果Backlight 在D0和非D0状态下转换
           if(fOnToOther||fOtherToOn)
           {
                 if(!memcmp(pds->pszName,TEXT("bkl1"),sizeof(TCHAR)*4))
                 {
                       gBacklightMs = GetTickCount()-gBacklightMs;
                       if(fOnToOther)
                       {                            //在日志里记录Backlight 开启的时间
                            gBacklightMsTotal += gBacklightMs;
                            PMSQM_Set(PMSQM_DATAID_POWER_BKL_TOTAL,gBacklightMsTotal);
                            PMSQM_Set(PMSQM_DATAID_POWER_BKL_ON,gBacklightMs);
                       }
                       else if(fOtherToOn) {
                           //在日志里记录Backlight 关闭的时间
                            PMSQM_Set(PMSQM_DATAID_POWER_BKL_OFF,gBacklightMs);
                        }
                        gBacklightMs = GetTickCount();
                  }
            }
       }
}