Changeset 27327 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Mar 12, 2010 1:16:28 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DrvACPI.cpp
r27326 r27327 235 235 */ 236 236 static DECLCALLBACK(int) drvACPIQueryBatteryStatus(PPDMIACPICONNECTOR pInterface, bool *pfPresent, 237 238 239 237 PPDMACPIBATCAPACITY penmRemainingCapacity, 238 PPDMACPIBATSTATE penmBatteryState, 239 uint32_t *pu32PresentRate) 240 240 { 241 241 /* default return values for all architectures */ … … 268 268 { 269 269 AssertMsgFailed(("Could not determine system power status, error: 0x%x\n", 270 270 GetLastError())); 271 271 } 272 272 … … 303 303 fResult = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSTransportTypeKey), &psValue); 304 304 if ( fResult 305 && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo)305 && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSInternalType), 0) == kCFCompareEqualTo) 306 306 { 307 307 PDMACPIPOWERSOURCE powerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; … … 309 309 fResult = CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSPowerSourceStateKey), &psValue); 310 310 if ( fResult 311 && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo)311 && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSACPowerValue), 0) == kCFCompareEqualTo) 312 312 powerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 313 313 else if ( fResult 314 314 && CFStringCompare((CFStringRef)psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) 315 315 powerSource = PDM_ACPI_POWER_SOURCE_BATTERY; 316 316 … … 352 352 353 353 if ( powerSource == PDM_ACPI_POWER_SOURCE_OUTLET 354 && CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue))354 && CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) 355 355 { 356 356 /* We are running on an AC power source, but we also have a … … 449 449 */ 450 450 *pu32PresentRate = (uint32_t)( ( ((float)BatteryIo.bst.volt/1000.0) 451 452 451 * ((float)BatteryIo.bst.rate/1000.0)) 452 * 1000.0); 453 453 } 454 454 } … … 525 525 ASMAtomicWriteBool(&pThis->fDontPokePoller, false); 526 526 527 /*528 * Read the status of the powerline-adapter.529 */530 531 527 PDMACPIPOWERSOURCE enmPowerSource = PDM_ACPI_POWER_SOURCE_UNKNOWN; 532 PRTSTREAM pStrmStatus; 533 PRTDIR pDir = NULL; 528 PRTSTREAM pStrmStatus; 529 PRTSTREAM pStrmType; 530 PRTDIR pDir = NULL; 534 531 RTDIRENTRY DirEntry; 535 char szLine[1024]; 536 int rc = RTDirOpen(&pDir, "/proc/acpi/ac_adapter/"); 532 char szLine[1024]; 533 bool fBatteryPresent = false; /* one or more batteries present */ 534 bool fCharging = false; /* one or more batteries charging */ 535 bool fDischarging = false; /* one or more batteries discharging */ 536 bool fCritical = false; /* one or more batteries in critical state */ 537 int32_t maxCapacityTotal = 0; /* total capacity of all batteries */ 538 int32_t currentCapacityTotal = 0; /* total current capacity of all batteries */ 539 int32_t presentRateTotal = 0; /* total present (dis)charging rate of all batts */ 540 541 int rc = RTDirOpen(&pDir, "/sys/class/power_supply/"); 537 542 if (RT_SUCCESS(rc)) 538 543 { 544 /* 545 * The new /sys interface introduced with Linux 2.6.25. 546 */ 539 547 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 540 548 { … … 545 553 || strcmp(DirEntry.szName, "..") == 0) 546 554 continue; 547 rc = RTStrmOpenF("r", &pStrmStatus, 548 "/proc/acpi/ac_adapter/%s/status", DirEntry.szName);555 #define POWER_OPEN(s, n) RTStrmOpenF("r", s, "/sys/class/power_supply/%s/" n, DirEntry.szName) 556 rc = POWER_OPEN(&pStrmType, "type"); 549 557 if (RT_FAILURE(rc)) 550 rc = RTStrmOpenF("r", &pStrmStatus,551 "/proc/acpi/ac_adapter/%s/state", DirEntry.szName);558 continue; 559 rc = RTStrmGetLine(pStrmType, szLine, sizeof(szLine)); 552 560 if (RT_SUCCESS(rc)) 553 561 { 554 while (pThread->enmState == PDMTHREADSTATE_RUNNING)562 if (strcmp(szLine, "Mains") == 0) 555 563 { 556 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 557 if (RT_FAILURE(rc)) 558 break; 559 if ( strstr(szLine, "Status:") != NULL 560 || strstr(szLine, "state:") != NULL) 564 /* AC adapter */ 565 rc = POWER_OPEN(&pStrmStatus, "online"); 566 if (RT_SUCCESS(rc)) 561 567 { 562 if (strstr(szLine, "on-line") != NULL) 568 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 569 if ( RT_SUCCESS(rc) 570 && strcmp(szLine, "1") == 0) 563 571 enmPowerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 564 572 else 565 573 enmPowerSource = PDM_ACPI_POWER_SOURCE_BATTERY; 566 break;574 RTStrmClose(pStrmStatus); 567 575 } 568 576 } 569 RTStrmClose(pStrmStatus); 570 break; 577 else if (strcmp(szLine, "Battery") == 0) 578 { 579 /* Battery */ 580 rc = POWER_OPEN(&pStrmStatus, "present"); 581 if (RT_SUCCESS(rc)) 582 { 583 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 584 RTStrmClose(pStrmStatus); 585 if ( RT_SUCCESS(rc) 586 && strcmp(szLine, "1") == 0) 587 { 588 fBatteryPresent = true; 589 rc = RTStrmOpenF("r", &pStrmStatus, 590 "/sys/class/power_supply/%s/status", DirEntry.szName); 591 if (RT_SUCCESS(rc)) 592 { 593 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 594 if (RT_SUCCESS(rc)) 595 { 596 if (strcmp(szLine, "Discharging") == 0) 597 fDischarging = true; 598 else if (strcmp(szLine, "Charging") == 0) 599 fCharging = true; 600 } 601 RTStrmClose(pStrmStatus); 602 } 603 rc = POWER_OPEN(&pStrmStatus, "capacity_level"); 604 if (RT_SUCCESS(rc)) 605 { 606 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 607 if ( RT_SUCCESS(rc) 608 && strcmp(szLine, "Critical") == 0) 609 fCritical = true; 610 RTStrmClose(pStrmStatus); 611 } 612 rc = POWER_OPEN(&pStrmStatus, "energy_full"); 613 if (RT_FAILURE(rc)) 614 rc = POWER_OPEN(&pStrmStatus, "charge_full"); 615 if (RT_SUCCESS(rc)) 616 { 617 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 618 if (RT_SUCCESS(rc)) 619 { 620 int32_t maxCapacity = 0; 621 rc = RTStrToInt32Full(szLine, 0, &maxCapacity); 622 if ( RT_SUCCESS(rc) 623 && maxCapacity > 0) 624 maxCapacityTotal += maxCapacity; 625 } 626 RTStrmClose(pStrmStatus); 627 } 628 rc = POWER_OPEN(&pStrmStatus, "energy_now"); 629 if (RT_FAILURE(rc)) 630 rc = POWER_OPEN(&pStrmStatus, "charge_now"); 631 if (RT_SUCCESS(rc)) 632 { 633 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 634 if (RT_SUCCESS(rc)) 635 { 636 int32_t currentCapacity = 0; 637 rc = RTStrToInt32Full(szLine, 0, ¤tCapacity); 638 if ( RT_SUCCESS(rc) 639 && currentCapacity > 0) 640 currentCapacityTotal += currentCapacity; 641 } 642 RTStrmClose(pStrmStatus); 643 } 644 rc = POWER_OPEN(&pStrmStatus, "current_now"); 645 if (RT_SUCCESS(rc)) 646 { 647 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 648 if (RT_SUCCESS(rc)) 649 { 650 int32_t presentRate = 0; 651 rc = RTStrToInt32Full(szLine, 0, &presentRate); 652 if ( RT_SUCCESS(rc) 653 && presentRate > 0) 654 { 655 if (fDischarging) 656 presentRateTotal -= presentRate; 657 else 658 presentRateTotal += presentRate; 659 } 660 } 661 RTStrmClose(pStrmStatus); 662 } 663 } 664 } 665 } 571 666 } 667 RTStrmClose(pStrmType); 668 #undef POWER_OPEN 572 669 } 573 670 RTDirClose(pDir); 574 671 } 575 576 /* 577 * Read the status of all batteries and collect it into one. 578 */ 579 580 int32_t maxCapacityTotal = INT32_MIN; /* the summed up maximum capacity */ 581 int32_t currentCapacityTotal = INT32_MIN; /* the summed up total capacity */ 582 int32_t presentRate = 0; 583 int32_t presentRateTotal = 0; 584 bool fBatteryPresent = false; 585 bool fCharging = false; 586 bool fDischarging = false; 587 bool fCritical = false; 588 589 rc = RTDirOpen(&pDir, "/proc/acpi/battery/"); 590 if (RT_SUCCESS(rc)) 672 else /* !/sys */ 591 673 { 592 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 674 /* 675 * The old /proc/acpi interface 676 */ 677 /* 678 * Read the status of the powerline-adapter. 679 */ 680 rc = RTDirOpen(&pDir, "/proc/acpi/ac_adapter/"); 681 if (RT_SUCCESS(rc)) 593 682 { 594 rc = RTDirRead(pDir, &DirEntry, NULL); 595 if (RT_FAILURE(rc)) 596 break; 597 if ( strcmp(DirEntry.szName, ".") == 0 598 || strcmp(DirEntry.szName, "..") == 0) 599 continue; 600 601 pStrmStatus; 602 rc = RTStrmOpenF("r", &pStrmStatus, 603 "/proc/acpi/battery/%s/status", DirEntry.szName); 604 /* there is a 2nd variant of that file */ 605 if (RT_FAILURE(rc)) 606 { 607 rc = RTStrmOpenF("r", &pStrmStatus, 608 "/proc/acpi/battery/%s/state", DirEntry.szName); 609 } 610 if (RT_FAILURE(rc)) 611 continue; 612 613 PRTSTREAM pStrmInfo; 614 rc = RTStrmOpenF("r", &pStrmInfo, 615 "/proc/acpi/battery/%s/info", DirEntry.szName); 616 if (RT_FAILURE(rc)) 617 { 618 RTStrmClose(pStrmStatus); 619 continue; 620 } 621 622 /* get 'present' status from the info file */ 683 #define POWER_OPEN(s, n) RTStrmOpenF("r", s, "/proc/acpi/ac_adapter/%s/" n, DirEntry.szName) 623 684 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 624 685 { 625 rc = RT StrmGetLine(pStrmInfo, szLine, sizeof(szLine));686 rc = RTDirRead(pDir, &DirEntry, NULL); 626 687 if (RT_FAILURE(rc)) 627 688 break; 628 if (strstr(szLine, "present:") != NULL) 689 if ( strcmp(DirEntry.szName, ".") == 0 690 || strcmp(DirEntry.szName, "..") == 0) 691 continue; 692 rc = POWER_OPEN(&pStrmStatus, "status"); 693 if (RT_FAILURE(rc)) 694 rc = POWER_OPEN(&pStrmStatus, "state"); 695 if (RT_SUCCESS(rc)) 629 696 { 630 if (strstr(szLine, "yes") != NULL)697 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 631 698 { 632 fBatteryPresent = true; 633 break; 699 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 700 if (RT_FAILURE(rc)) 701 break; 702 if ( strstr(szLine, "Status:") != NULL 703 || strstr(szLine, "state:") != NULL) 704 { 705 if (strstr(szLine, "on-line") != NULL) 706 enmPowerSource = PDM_ACPI_POWER_SOURCE_OUTLET; 707 else 708 enmPowerSource = PDM_ACPI_POWER_SOURCE_BATTERY; 709 break; 710 } 634 711 } 712 RTStrmClose(pStrmStatus); 713 break; 635 714 } 636 715 } 637 638 RTStrmRewind(pStrmInfo); 639 if (fBatteryPresent) 716 RTDirClose(pDir); 717 #undef POWER_OPEN 718 } 719 720 /* 721 * Read the status of all batteries and collect it into one. 722 */ 723 rc = RTDirOpen(&pDir, "/proc/acpi/battery/"); 724 if (RT_SUCCESS(rc)) 725 { 726 #define POWER_OPEN(s, n) RTStrmOpenF("r", s, "/proc/acpi/battery/%s/" n, DirEntry.szName) 727 bool fThisBatteryPresent = false; 728 bool fThisDischarging = false; 729 730 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 640 731 { 641 /* get the maximum capacity from the info file */ 732 rc = RTDirRead(pDir, &DirEntry, NULL); 733 if (RT_FAILURE(rc)) 734 break; 735 if ( strcmp(DirEntry.szName, ".") == 0 736 || strcmp(DirEntry.szName, "..") == 0) 737 continue; 738 739 rc = POWER_OPEN(&pStrmStatus, "status"); 740 /* there is a 2nd variant of that file */ 741 if (RT_FAILURE(rc)) 742 rc = POWER_OPEN(&pStrmStatus, "state"); 743 if (RT_FAILURE(rc)) 744 continue; 745 746 PRTSTREAM pStrmInfo; 747 rc = POWER_OPEN(&pStrmInfo, "info"); 748 if (RT_FAILURE(rc)) 749 { 750 RTStrmClose(pStrmStatus); 751 continue; 752 } 753 754 /* get 'present' status from the info file */ 642 755 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 643 756 { 644 int32_t maxCapacity = INT32_MIN;645 757 rc = RTStrmGetLine(pStrmInfo, szLine, sizeof(szLine)); 646 758 if (RT_FAILURE(rc)) 647 759 break; 648 if (strstr(szLine, " last full capacity:") != NULL)760 if (strstr(szLine, "present:") != NULL) 649 761 { 650 char *psz; 651 rc = RTStrToInt32Ex(RTStrStripL(&szLine[19]), &psz, 0, &maxCapacity); 652 if (RT_FAILURE(rc)) 653 maxCapacity = INT32_MIN; 654 655 /* did we get a valid capacity and it's the first value we got? */ 656 if (maxCapacityTotal < 0 && maxCapacity > 0) 762 if (strstr(szLine, "yes") != NULL) 657 763 { 658 /* take this as the maximum capacity */659 maxCapacityTotal = maxCapacity;764 fThisBatteryPresent = true; 765 break; 660 766 } 661 else662 {663 /* sum up the maximum capacity */664 if (maxCapacityTotal > 0 && maxCapacity > 0)665 maxCapacityTotal += maxCapacity;666 }667 /* we got all we need */668 break;669 767 } 670 768 } 671 769 672 /* get the current capacity/state from the status file */ 673 bool fGotRemainingCapacity = false; 674 bool fGotBatteryState = false; 675 bool fGotCapacityState = false; 676 bool fGotPresentRate = false; 677 while ( ( !fGotRemainingCapacity 678 || !fGotBatteryState 679 || !fGotCapacityState 680 || !fGotPresentRate) 681 && pThread->enmState == PDMTHREADSTATE_RUNNING) 770 if (fThisBatteryPresent) 682 771 { 683 int32_t currentCapacity = INT32_MIN;684 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine));685 if (RT_FAILURE(rc)) 686 break;687 if (strstr(szLine, "remaining capacity:") != NULL)772 fBatteryPresent = true; 773 RTStrmRewind(pStrmInfo); 774 775 /* get the maximum capacity from the info file */ 776 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 688 777 { 689 char *psz; 690 rc = RTStrToInt32Ex(RTStrStripL(&szLine[19]), &psz, 0, ¤tCapacity); 778 rc = RTStrmGetLine(pStrmInfo, szLine, sizeof(szLine)); 691 779 if (RT_FAILURE(rc)) 692 currentCapacity = INT32_MIN; 693 694 /* is this the first valid value we see? If so, take it! */ 695 if (currentCapacityTotal < 0 && currentCapacity >= 0) 780 break; 781 if (strstr(szLine, "last full capacity:") != NULL) 696 782 { 697 currentCapacityTotal = currentCapacity; 783 char *psz; 784 int32_t maxCapacity = 0; 785 rc = RTStrToInt32Ex(RTStrStripL(&szLine[19]), &psz, 0, &maxCapacity); 786 if (RT_FAILURE(rc)) 787 maxCapacity = 0; 788 maxCapacityTotal += maxCapacity; 789 break; 698 790 } 699 else 791 } 792 793 /* get the current capacity/state from the status file */ 794 int32_t presentRate = 0; 795 bool fGotRemainingCapacity = false; 796 bool fGotBatteryState = false; 797 bool fGotCapacityState = false; 798 bool fGotPresentRate = false; 799 while ( ( !fGotRemainingCapacity 800 || !fGotBatteryState 801 || !fGotCapacityState 802 || !fGotPresentRate) 803 && pThread->enmState == PDMTHREADSTATE_RUNNING) 804 { 805 rc = RTStrmGetLine(pStrmStatus, szLine, sizeof(szLine)); 806 if (RT_FAILURE(rc)) 807 break; 808 if (strstr(szLine, "remaining capacity:") != NULL) 700 809 { 701 /* just sum up the current value */ 702 if (currentCapacityTotal > 0 && currentCapacity > 0) 810 char *psz; 811 int32_t currentCapacity = 0; 812 rc = RTStrToInt32Ex(RTStrStripL(&szLine[19]), &psz, 0, ¤tCapacity); 813 if ( RT_SUCCESS(rc) 814 && currentCapacity > 0) 703 815 currentCapacityTotal += currentCapacity; 816 fGotRemainingCapacity = true; 704 817 } 705 fGotRemainingCapacity = true; 818 else if (strstr(szLine, "charging state:") != NULL) 819 { 820 if (strstr(szLine + 15, "discharging") != NULL) 821 { 822 fDischarging = true; 823 fThisDischarging = true; 824 } 825 else if (strstr(szLine + 15, "charging") != NULL) 826 fCharging = true; 827 fGotBatteryState = true; 828 } 829 else if (strstr(szLine, "capacity state:") != NULL) 830 { 831 if (strstr(szLine + 15, "critical") != NULL) 832 fCritical = true; 833 fGotCapacityState = true; 834 } 835 if (strstr(szLine, "present rate:") != NULL) 836 { 837 char *psz; 838 rc = RTStrToInt32Ex(RTStrStripL(&szLine[13]), &psz, 0, &presentRate); 839 if (RT_FAILURE(rc)) 840 presentRate = 0; 841 fGotPresentRate = true; 842 } 706 843 } 707 else if (strstr(szLine, "charging state:") != NULL) 708 { 709 if (strstr(szLine + 15, "discharging") != NULL) 710 fDischarging = true; 711 else if (strstr(szLine + 15, "charging") != NULL) 712 fCharging = true; 713 fGotBatteryState = true; 714 } 715 else if (strstr(szLine, "capacity state:") != NULL) 716 { 717 if (strstr(szLine + 15, "critical") != NULL) 718 fCritical = true; 719 fGotCapacityState = true; 720 } 721 if (strstr(szLine, "present rate:") != NULL) 722 { 723 char *psz; 724 rc = RTStrToInt32Ex(RTStrStripL(&szLine[13]), &psz, 0, &presentRate); 725 if (RT_FAILURE(rc)) 726 presentRate = 0; 727 fGotPresentRate = true; 728 } 844 if (fThisDischarging) 845 presentRateTotal -= presentRate; 846 else 847 presentRateTotal += presentRate; 729 848 } 849 RTStrmClose(pStrmStatus); 850 RTStrmClose(pStrmInfo); 730 851 } 731 732 if (presentRate) 733 { 734 if (fDischarging) 735 presentRateTotal -= presentRate; 736 else 737 presentRateTotal += presentRate; 738 } 739 740 RTStrmClose(pStrmStatus); 741 RTStrmClose(pStrmInfo); 852 RTDirClose(pDir); 853 #undef POWER_OPEN 742 854 } 743 RTDirClose(pDir); 744 } 855 } /* /proc/acpi */ 745 856 746 857 /* atomic update of the state */ … … 772 883 (uint32_t)(( (float)presentRateTotal 773 884 / (float)maxCapacityTotal) * 1000); 885 } 886 else 887 { 888 /* unknown capacity / state */ 889 pThis->enmBatteryRemainingCapacity = PDM_ACPI_BAT_CAPACITY_UNKNOWN; 890 pThis->u32BatteryPresentRate = ~0; 774 891 } 775 892 RTCritSectLeave(&pThis->CritSect);
Note:
See TracChangeset
for help on using the changeset viewer.