searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

[IOKit]macOS系统电源管理技巧

2023-07-18 09:57:29
30
0

<IOKit>电源管理相关的接口主要通过头文件<IOKit/pwr_mgt/IOPMLib.h>提供,我们可以通过这个头文件实现:

  1. 获取电池信息;(Intel cpu不支持)
  2. 屏幕熄屏设置;
  3. 系统睡眠设置;
  4. 系统开关机设置;

为了实现以上功能,首先第一步需要初始化并获取电源管理接口连接:

// bootstrap_port是框架提供的常量,表征系统根端口
// 获取设备主端口
mach_port_t master_dev_port;
int ret = IOMasterPort(bootstrap_port, &master_dev_port);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: retrieve master_dev_port failed: %i", ret);
    return;
}
// 建立电源管理连接
io_connect_t power_mgt;
if (!(power_mgt = IOPMFindPowerManagement(master_dev_port))) {
    NSLog(@"Error: retrieve power_mgt failed");
    return;
}

 

1. 获取电池信息

原本的接口IOPMCopyBatteryInfo已经不支持Intel CPU了,如果需要获取电池信息要通过头文件<IOKit/ps/IOPowerSources.h>来实现,比如获取当前电池的剩余电量可以通过以下代码实现:

CFTypeRef blob = IOPSCopyPowerSourcesInfo(); 
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);  
 
CFDictionaryRef source;  
const void *value;  
int curCapacity, maxCapacity;  
double percent; 
int count = CFArrayGetCount(sources);  
for (int i = 0 ; i < count ; i++)  
{  
    source = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));  
    if (!source) {
        NSLog(@"Error in IOPSGetPowerSourceDescription"); 
        return -1.0f;
    }

    value = CFDictionaryGetValue(source, CFSTR(kIOPSCurrentCapacityKey));  
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &curCapacity);  
    value = CFDictionaryGetValue(source, CFSTR(kIOPSMaxCapacityKey));  
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &maxCapacity);  
 
    percent = ((double)curCapacity/(double)maxCapacity * 100.0f);  
    return percent;  
}

return -1.0f;

 

2. 屏幕熄屏设置

unsigned long dim_time = 10;
// kPMMinutesToDim是在头文件IOPM.h中定义的枚举值
int ret = IOPMSetAggressiveness(power_mgt,
                                kPMMinutesToDim,
                                dim_time);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: retrieve sleep settings failed: %i", ret);
}

 

3. 系统睡眠设置

unsigned long sleep_time = 10;
// kPMMinutesToSleep为IOPM.h头文件中定义的枚举值
int ret = IOPMSetAggressiveness(power_mgt,
                                kPMMinutesToSleep,
                                sleep_time);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: set sleep failed: %i", ret);
    return;
}

 

4. 系统开关机设置

// 设置定时启动
CFAbsoluteTime poweron_time = CFAbsoluteTimeGetCurrent() + 30; // 单位为秒
CFDateRef date = CFDateCreate(kCFAllocatorDefault, poweron_time);
// kIOPMAutoPowerOn为IOPMKeys.h头文件中定义的宏字符串
int ret = IOPMSchedulePowerEvent(date,
                                 CFSTR("com.pwr_mgt.test"),
                                 CFSTR(kIOPMAutoPowerOn));
if (ret != kIOReturnSuccess) {
        NSLog(@"Set auto power on failed: %d", ret);
}
CFRelease(date)

// 取消定时启动,注意date参数需要和设置的时候保持一致
CFDateRef date = CFDateCreate(kCFAllocatorDefault, poweron_time);
int ret = IOPMCancelScheduledPowerEvent(date,
                                        CFSTR("com.pwr_mgt.test"),
                                        CFSTR(kIOPMAutoPowerOn));
if (ret != kIOReturnSuccess) {
    NSLog(@"Cancel previous power event failed: %d", ret);
}
CFRelease(date);
0条评论
0 / 1000
l****n
14文章数
1粉丝数
l****n
14 文章 | 1 粉丝
原创

[IOKit]macOS系统电源管理技巧

2023-07-18 09:57:29
30
0

<IOKit>电源管理相关的接口主要通过头文件<IOKit/pwr_mgt/IOPMLib.h>提供,我们可以通过这个头文件实现:

  1. 获取电池信息;(Intel cpu不支持)
  2. 屏幕熄屏设置;
  3. 系统睡眠设置;
  4. 系统开关机设置;

为了实现以上功能,首先第一步需要初始化并获取电源管理接口连接:

// bootstrap_port是框架提供的常量,表征系统根端口
// 获取设备主端口
mach_port_t master_dev_port;
int ret = IOMasterPort(bootstrap_port, &master_dev_port);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: retrieve master_dev_port failed: %i", ret);
    return;
}
// 建立电源管理连接
io_connect_t power_mgt;
if (!(power_mgt = IOPMFindPowerManagement(master_dev_port))) {
    NSLog(@"Error: retrieve power_mgt failed");
    return;
}

 

1. 获取电池信息

原本的接口IOPMCopyBatteryInfo已经不支持Intel CPU了,如果需要获取电池信息要通过头文件<IOKit/ps/IOPowerSources.h>来实现,比如获取当前电池的剩余电量可以通过以下代码实现:

CFTypeRef blob = IOPSCopyPowerSourcesInfo(); 
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);  
 
CFDictionaryRef source;  
const void *value;  
int curCapacity, maxCapacity;  
double percent; 
int count = CFArrayGetCount(sources);  
for (int i = 0 ; i < count ; i++)  
{  
    source = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));  
    if (!source) {
        NSLog(@"Error in IOPSGetPowerSourceDescription"); 
        return -1.0f;
    }

    value = CFDictionaryGetValue(source, CFSTR(kIOPSCurrentCapacityKey));  
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &curCapacity);  
    value = CFDictionaryGetValue(source, CFSTR(kIOPSMaxCapacityKey));  
    CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &maxCapacity);  
 
    percent = ((double)curCapacity/(double)maxCapacity * 100.0f);  
    return percent;  
}

return -1.0f;

 

2. 屏幕熄屏设置

unsigned long dim_time = 10;
// kPMMinutesToDim是在头文件IOPM.h中定义的枚举值
int ret = IOPMSetAggressiveness(power_mgt,
                                kPMMinutesToDim,
                                dim_time);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: retrieve sleep settings failed: %i", ret);
}

 

3. 系统睡眠设置

unsigned long sleep_time = 10;
// kPMMinutesToSleep为IOPM.h头文件中定义的枚举值
int ret = IOPMSetAggressiveness(power_mgt,
                                kPMMinutesToSleep,
                                sleep_time);
if (ret != kIOReturnSuccess) {
    NSLog(@"Error: set sleep failed: %i", ret);
    return;
}

 

4. 系统开关机设置

// 设置定时启动
CFAbsoluteTime poweron_time = CFAbsoluteTimeGetCurrent() + 30; // 单位为秒
CFDateRef date = CFDateCreate(kCFAllocatorDefault, poweron_time);
// kIOPMAutoPowerOn为IOPMKeys.h头文件中定义的宏字符串
int ret = IOPMSchedulePowerEvent(date,
                                 CFSTR("com.pwr_mgt.test"),
                                 CFSTR(kIOPMAutoPowerOn));
if (ret != kIOReturnSuccess) {
        NSLog(@"Set auto power on failed: %d", ret);
}
CFRelease(date)

// 取消定时启动,注意date参数需要和设置的时候保持一致
CFDateRef date = CFDateCreate(kCFAllocatorDefault, poweron_time);
int ret = IOPMCancelScheduledPowerEvent(date,
                                        CFSTR("com.pwr_mgt.test"),
                                        CFSTR(kIOPMAutoPowerOn));
if (ret != kIOReturnSuccess) {
    NSLog(@"Cancel previous power event failed: %d", ret);
}
CFRelease(date);
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0