Skip to content

Commit

Permalink
Add CallNTPowerInformation
Browse files Browse the repository at this point in the history
  • Loading branch information
dbwiddis committed Feb 5, 2019
1 parent 07f3ce0 commit b5b0873
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Features
* [#1058](https://github.com/java-native-access/jna/pull/1058): Add selectable timeout to stopService() and improve timeout handling - [@keithharp](https://github.com/keithharp).
* [#1050](https://github.com/java-native-access/jna/pull/1050): Add `c.s.j.p.win32.VersionHelpers` and supporting functions - [@dbwiddis](https://github.com/dbwiddis).
* [#1061](https://github.com/java-native-access/jna/pull/1061): replace toArray(new T[size]) with toArray(new T[0]) for better performance - [@hc-codersatlas](https://github.com/hc-codersatlas).
* [#1065](https://github.com/java-native-access/jna/pull/1065): Add `c.s.j.p.win32.PowrProf#CallNTPowerInformation` and some supporting structures - [@dbwiddis](https://github.com/dbwiddis).

Bug Fixes
---------
Expand Down
9 changes: 9 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/NTStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,14 @@ public interface NTStatus {
// Indicates a particular Security ID may not be assigned as the owner of an object.
//
int STATUS_INVALID_OWNER = 0xC000005A;

// MessageId: STATUS_ACCESS_DENIED
//
// MessageText:
//
// A process has requested access to an object, but has not been granted
// those access rights.
//
int STATUS_ACCESS_DENIED = 0xC0000022;
}

161 changes: 161 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/PowrProf.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/* Copyright (c) 2019 Daniel Widdis, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.win32;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;

/**
* Functions used with power management.
*/
public interface PowrProf extends Library {
PowrProf INSTANCE = Native.load("PowrProf", PowrProf.class);

/**
* Indicates power level information.
*/
public interface POWER_INFORMATION_LEVEL {
int LAST_SLEEP_TIME = 15;
int LAST_WAKE_TIME = 14;
int PROCESSOR_INFORMATION = 11;
int SYSTEM_BATTERY_STATE = 5;
int SYSTEM_EXECUTION_STATE = 16;
int SYSTEM_POWER_CAPABILITIES = 4;
int SYSTEM_POWER_INFORMATION = 12;
int SYSTEM_POWER_POLICY_AC = 0;
int SYSTEM_POWER_POLICY_CURRENT = 8;
int SYSTEM_POWER_POLICY_DC = 1;
int SYSTEM_RESERVE_HIBER_FILE = 10;
}

/**
* Contains information about the current state of the system battery.
*/
@FieldOrder({ "acOnLine", "batteryPresent", "charging", "discharging", "spare1", "tag", "maxCapacity",
"remainingCapacity", "rate", "estimatedTime", "defaultAlert1", "defaultAlert2" })
class SystemBatteryState extends Structure {
public byte acOnLine;
public byte batteryPresent;
public byte charging;
public byte discharging;
public byte[] spare1 = new byte[3];
public byte tag;
public int maxCapacity;
public int remainingCapacity;
public int rate;
public int estimatedTime;
public int defaultAlert1;
public int defaultAlert2;

public SystemBatteryState(Pointer p) {
super(p);
read();
}

public SystemBatteryState() {
super();
}
}

/**
* Contains information about a processor.
*/
@FieldOrder({ "number", "maxMhz", "currentMhz", "mhzLimit", "maxIdleState", "currentIdleState" })
class ProcessorPowerInformation extends Structure {
public int number;
public int maxMhz;
public int currentMhz;
public int mhzLimit;
public int maxIdleState;
public int currentIdleState;

public ProcessorPowerInformation(Pointer p) {
super(p);
read();
}

public ProcessorPowerInformation() {
super();
}
}

/**
* Sets or retrieves power information.
* <p>
* Changes made to the current system power policy using
* {@link #CallNtPowerInformation()} are immediate, but they are not
* persistent; that is, the changes are not stored as part of a power
* scheme. Any changes to system power policy made with
* {@link #CallNtPowerInformation()} may be overwritten by changes to a
* policy scheme made by the user in the Power Options control panel
* program, or by subsequent calls to {@code WritePwrScheme},
* {@code SetActivePwrScheme}, or other power scheme functions.
*
* @param informationLevel
* The information level requested. This value indicates the
* specific power information to be set or retrieved. This
* parameter must be one of the following
* {@link POWER_INFORMATION_LEVEL} enumeration type values:
* {@link POWER_INFORMATION_LEVEL#LAST_SLEEP_TIME},
* {@link POWER_INFORMATION_LEVEL#LAST_WAKE_TIME},
* {@link POWER_INFORMATION_LEVEL#PROCESSOR_INFORMATION},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_BATTERY_STATE},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_EXECUTION_STATE},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_POWER_CAPABILITIES},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_POWER_INFORMATION},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_POWER_POLICY_AC},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_POWER_POLICY_CURRENT},
* {@link POWER_INFORMATION_LEVEL#SYSTEM_POWER_POLICY_DC}, or
* {@link POWER_INFORMATION_LEVEL#SYSTEM_RESERVE_HIBER_FILE}.
* @param lpInputBuffer
* A pointer to an optional input buffer. The data type of this
* buffer depends on the information level requested in the
* {@code informationLevel} parameter.
* @param nInputBufferSize
* The size of the input buffer, in bytes.
* @param lpOutputBuffer
* A pointer to an optional output buffer. The data type of this
* buffer depends on the information level requested in the
* {@code informationLevel} parameter. If the buffer is too small
* to contain the information, the function returns
* {@link NTStatus#STATUS_BUFFER_TOO_SMALL}.
* @param nOutputBufferSize
* The size of the output buffer, in bytes. Depending on the
* information level requested, this may be a variably sized
* buffer.
* @return If the function succeeds, the return value is
* {@link NTStatus#STATUS_SUCCESS}. If the function fails, the
* return value can be one the following status codes:
* {@link NTStatus#STATUS_BUFFER_TOO_SMALL} if the output buffer is
* of insufficient size to contain the data to be returned.
* {@link NTStatus#STATUS_ACCESS_DENIED} if the caller had
* insufficient access rights to perform the requested action.
*/
int CallNtPowerInformation(int informationLevel, Pointer lpInputBuffer, int nInputBufferSize,
Pointer lpOutputBuffer, int nOutputBufferSize);
}

67 changes: 67 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/PowrProfTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Copyright (c) 2019 Daniel Widdis, All Rights Reserved
*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.win32;

import com.sun.jna.Memory;
import com.sun.jna.platform.win32.PowrProf.POWER_INFORMATION_LEVEL;
import com.sun.jna.platform.win32.PowrProf.ProcessorPowerInformation;
import com.sun.jna.platform.win32.PowrProf.SystemBatteryState;
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;

import junit.framework.TestCase;

public class PowrProfTest extends TestCase {

public void testProcessorPowerInformation() {
SYSTEM_INFO info = new SYSTEM_INFO();
Kernel32.INSTANCE.GetSystemInfo(info);
int numProcs = info.dwNumberOfProcessors.intValue();

ProcessorPowerInformation ppi = new ProcessorPowerInformation();
long[] freqs = new long[numProcs];
int bufferSize = ppi.size() * numProcs;
Memory mem = new Memory(bufferSize);
assertEquals(NTStatus.STATUS_SUCCESS, PowrProf.INSTANCE
.CallNtPowerInformation(POWER_INFORMATION_LEVEL.PROCESSOR_INFORMATION, null, 0,
mem, bufferSize));
for (int i = 0; i < freqs.length; i++) {
ppi = new ProcessorPowerInformation(mem.share(i * (long) ppi.size()));
assertTrue(ppi.currentMhz <= ppi.maxMhz);
}
}

public void testSystemBatteryState() {
int size = new SystemBatteryState().size();
Memory mem = new Memory(size);
assertEquals(NTStatus.STATUS_SUCCESS,
PowrProf.INSTANCE.CallNtPowerInformation(POWER_INFORMATION_LEVEL.SYSTEM_BATTERY_STATE, null, 0, mem, size));
SystemBatteryState batteryState = new SystemBatteryState(mem);
if (batteryState.batteryPresent > 0) {
if (batteryState.acOnLine == 0 && batteryState.charging == 0 && batteryState.discharging > 0) {
assertTrue(batteryState.estimatedTime >= 0);
}
assertTrue(batteryState.remainingCapacity <= batteryState.maxCapacity);
}
}
}

0 comments on commit b5b0873

Please sign in to comment.