mirror of
https://github.com/chararomandroid/android_device_samsung_a20
synced 2026-08-22 20:15:32 -04:00
universal7885: format code using clang-format-15
This commit is contained in:
parent
bfcbd0d355
commit
cb072badd5
55 changed files with 3946 additions and 3783 deletions
|
|
@ -17,486 +17,481 @@
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
#include <vendor/eureka/hardware/fmradio/1.2/IFMRadio.h>
|
#include <vendor/eureka/hardware/fmradio/1.2/IFMRadio.h>
|
||||||
|
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
using vendor::eureka::hardware::fmradio::V1_2::IFMRadio;
|
|
||||||
using vendor::eureka::hardware::fmradio::V1_0::Direction;
|
using vendor::eureka::hardware::fmradio::V1_0::Direction;
|
||||||
using vendor::eureka::hardware::fmradio::V1_1::Status;
|
using vendor::eureka::hardware::fmradio::V1_1::Status;
|
||||||
|
using vendor::eureka::hardware::fmradio::V1_2::IFMRadio;
|
||||||
|
|
||||||
//#define DEBUG
|
// #define DEBUG
|
||||||
#define TRACK_SIZE 30
|
#define TRACK_SIZE 30
|
||||||
long tracks[TRACK_SIZE] = { 0 };
|
long tracks[TRACK_SIZE] = {0};
|
||||||
bool FMThread = false;
|
bool FMThread = false;
|
||||||
|
|
||||||
int open_fm_device(){
|
int open_fm_device() {
|
||||||
int fd;
|
int fd;
|
||||||
if ((fd = open("/dev/radio0", O_RDWR)) < 0){
|
if ((fd = open("/dev/radio0", O_RDWR)) < 0) {
|
||||||
printf("Cannot open /dev/radio0.\n");
|
printf("Cannot open /dev/radio0.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
static int fm_radio_get_frequency(int fd, long *channel)
|
static int fm_radio_get_frequency(int fd, long *channel) {
|
||||||
{
|
struct v4l2_frequency freq {};
|
||||||
struct v4l2_frequency freq{};
|
int ret;
|
||||||
int ret;
|
|
||||||
|
|
||||||
freq.tuner = 0;
|
freq.tuner = 0;
|
||||||
freq.type = V4L2_TUNER_RADIO;
|
freq.type = V4L2_TUNER_RADIO;
|
||||||
|
|
||||||
ret = ioctl(fd, VIDIOC_G_FREQUENCY, &freq);
|
ret = ioctl(fd, VIDIOC_G_FREQUENCY, &freq);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("FmRadioController: failed to get frequency\n");
|
printf("FmRadioController: failed to get frequency\n");
|
||||||
return FM_FAILURE;
|
return FM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
*channel = (long)freq.frequency/16000;
|
*channel = (long)freq.frequency / 16000;
|
||||||
|
|
||||||
return FM_SUCCESS;
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fm_radio_set_frequency(int fd, long channel)
|
static int fm_radio_set_frequency(int fd, long channel) {
|
||||||
{
|
struct v4l2_frequency freq {};
|
||||||
struct v4l2_frequency freq{};
|
int ret;
|
||||||
int ret;
|
|
||||||
|
|
||||||
freq.tuner = 0;
|
freq.tuner = 0;
|
||||||
freq.type = V4L2_TUNER_RADIO;
|
freq.type = V4L2_TUNER_RADIO;
|
||||||
freq.frequency = (unsigned int) channel * 16000;
|
freq.frequency = (unsigned int)channel * 16000;
|
||||||
|
|
||||||
ret = ioctl(fd, VIDIOC_S_FREQUENCY, &freq);
|
ret = ioctl(fd, VIDIOC_S_FREQUENCY, &freq);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("FmRadioController: failed to set frequency\n");
|
printf("FmRadioController: failed to set frequency\n");
|
||||||
return FM_FAILURE;
|
return FM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FM_SUCCESS;
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fm_radio_set_control(int fd, unsigned int id, long val)
|
static int fm_radio_set_control(int fd, unsigned int id, long val) {
|
||||||
{
|
struct v4l2_control ctrl {};
|
||||||
struct v4l2_control ctrl{};
|
int ret;
|
||||||
int ret;
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("FmRadioController:fm_radio_set_control: id(%d) val(%ld)\n", id, val);
|
printf("FmRadioController:fm_radio_set_control: id(%d) val(%ld)\n", id, val);
|
||||||
#endif
|
#endif
|
||||||
ctrl.id = id;
|
ctrl.id = id;
|
||||||
if (val)
|
if (val)
|
||||||
ctrl.value = (unsigned int)val;
|
ctrl.value = (unsigned int)val;
|
||||||
else
|
else
|
||||||
ctrl.value = 0;
|
ctrl.value = 0;
|
||||||
|
|
||||||
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
|
ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("FmRadioController: failed to set control\n");
|
printf("FmRadioController: failed to set control\n");
|
||||||
return FM_FAILURE;
|
return FM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FM_SUCCESS;
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fm_radio_seek_frequency(int fd, unsigned int upward, unsigned int wrap_around, unsigned int spacing)
|
static int fm_radio_seek_frequency(int fd, unsigned int upward,
|
||||||
{
|
unsigned int wrap_around,
|
||||||
struct v4l2_hw_freq_seek seek{};
|
unsigned int spacing) {
|
||||||
int ret;
|
struct v4l2_hw_freq_seek seek {};
|
||||||
|
int ret;
|
||||||
|
|
||||||
seek.tuner = 0;
|
seek.tuner = 0;
|
||||||
seek.type = V4L2_TUNER_RADIO;
|
seek.type = V4L2_TUNER_RADIO;
|
||||||
seek.seek_upward = upward;
|
seek.seek_upward = upward;
|
||||||
seek.wrap_around = wrap_around;
|
seek.wrap_around = wrap_around;
|
||||||
seek.spacing = spacing;
|
seek.spacing = spacing;
|
||||||
|
|
||||||
ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &seek);
|
ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &seek);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("FmRadioController: failed to seek frequency\n");
|
printf("FmRadioController: failed to seek frequency\n");
|
||||||
return FM_FAILURE;
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FM_SUCCESS;
|
||||||
|
}
|
||||||
|
static int fm_radio_channel_searching(int fd, unsigned int upward,
|
||||||
|
unsigned int wrap_around,
|
||||||
|
unsigned int spacing, long *channel) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = fm_radio_set_control(fd, V4L2_CID_S610_SEEK_MODE,
|
||||||
|
FM_TUNER_AUTONOMOUS_SEARCH_MODE);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = fm_radio_seek_frequency(fd, upward, wrap_around, spacing);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = fm_radio_get_frequency(fd, channel);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static int fm_radio_set_tuner(int fd, unsigned int mode) {
|
||||||
|
struct v4l2_tuner tuner {};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
tuner.index = 0;
|
||||||
|
tuner.audmode = mode;
|
||||||
|
tuner.type = 1;
|
||||||
|
|
||||||
|
ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("FmRadioController: failed to set tuner\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FM_SUCCESS;
|
||||||
|
}
|
||||||
|
static int fm_radio_get_tuner(int fd) {
|
||||||
|
struct v4l2_tuner tuner {};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
tuner.index = 0;
|
||||||
|
tuner.type = 1;
|
||||||
|
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("FmRadioController: failed to set tuner\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tuner.audmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fm_radio_set_mute(int fd, bool mute) {
|
||||||
|
int muteint = 1;
|
||||||
|
if (mute)
|
||||||
|
muteint = 0;
|
||||||
|
int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_MUTE, muteint);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("FmRadioController: failed to set mute\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fm_radio_set_volume(int fd, int volume /* 1 ~ 15 */) {
|
||||||
|
int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_VOLUME, volume);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("FmRadioController: failed to set volume\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class C, typename T> bool contains(C &&c, T e) {
|
||||||
|
return std::find(std::begin(c), std::end(c), e) != std::end(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static long fm_radio_get_freqs(int fd) {
|
||||||
|
long ret = 0;
|
||||||
|
fm_radio_set_mute(fd, true);
|
||||||
|
sp<IFMRadio> service = IFMRadio::getService();
|
||||||
|
bool mSysfs = service->isAvailable() == Status::YES;
|
||||||
|
for (long &track : tracks) {
|
||||||
|
if (mSysfs) {
|
||||||
|
service->adjustFreqByStep(Direction::UP);
|
||||||
|
ret = (long)service->getFreqFromSysfs();
|
||||||
|
} else {
|
||||||
|
fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_50KHZ, &ret);
|
||||||
|
}
|
||||||
|
if (contains(tracks, ret))
|
||||||
|
break;
|
||||||
|
track = ret;
|
||||||
|
printf("Found Freq %ld\n", ret);
|
||||||
|
}
|
||||||
|
fm_radio_set_mute(fd, false);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fm_radio_poll(int fd, struct pollfd *poll_fd) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
poll_fd->fd = fd;
|
||||||
|
poll_fd->events = POLLIN;
|
||||||
|
poll_fd->revents = 0;
|
||||||
|
|
||||||
|
ret = poll(poll_fd, 1, 360);
|
||||||
|
if (ret > 0) {
|
||||||
|
if (poll_fd->revents & POLLIN) {
|
||||||
|
printf("FmRadioController: ready to read\n");
|
||||||
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FM_SUCCESS;
|
printf("FmRadioController: cannot read yet\n");
|
||||||
}
|
return FM_FAILURE;
|
||||||
static int fm_radio_channel_searching(int fd, unsigned int upward, unsigned int wrap_around, unsigned int spacing, long *channel)
|
}
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = fm_radio_set_control(fd, V4L2_CID_S610_SEEK_MODE, FM_TUNER_AUTONOMOUS_SEARCH_MODE);
|
if (!ret) {
|
||||||
|
printf("FmRadioController: polling timeout\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("FmRadioController: pollig fail: %d\n", ret);
|
||||||
|
return FM_FAILURE - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fm_radio_read(int fd, unsigned char *buf) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = read(fd, buf, FM_RADIO_RDS_DATA_MAX);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("FmRadioController: failed to read\n");
|
||||||
|
return FM_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fm_radio_thread(int fd) {
|
||||||
|
struct pollfd radio_poll {};
|
||||||
|
unsigned char read_buf[FM_RADIO_RDS_DATA_MAX];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (FMThread) {
|
||||||
|
ret = fm_radio_poll(fd, &radio_poll);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (ret < FM_FAILURE)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fm_radio_read(fd, read_buf);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
break;
|
||||||
|
}
|
||||||
ret = fm_radio_seek_frequency(fd, upward, wrap_around, spacing);
|
return 0;
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = fm_radio_get_frequency(fd, channel);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
static int fm_radio_set_tuner(int fd, unsigned int mode)
|
static unsigned int fm_radio_get_upperband_limit(int fd) {
|
||||||
{
|
int ret;
|
||||||
struct v4l2_tuner tuner{};
|
struct v4l2_tuner tuner {};
|
||||||
int ret;
|
unsigned int freq;
|
||||||
|
tuner.index = 0;
|
||||||
tuner.index = 0;
|
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||||||
tuner.audmode = mode;
|
if (ret < 0) {
|
||||||
tuner.type = 1;
|
return FM_FAILURE;
|
||||||
|
} else {
|
||||||
ret = ioctl(fd, VIDIOC_S_TUNER, &tuner);
|
freq = (tuner.rangehigh / 16000);
|
||||||
if (ret < 0) {
|
|
||||||
printf("FmRadioController: failed to set tuner\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
|
||||||
static int fm_radio_get_tuner(int fd)
|
|
||||||
{
|
|
||||||
struct v4l2_tuner tuner{};
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
tuner.index = 0;
|
|
||||||
tuner.type = 1;
|
|
||||||
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("FmRadioController: failed to set tuner\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tuner.audmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fm_radio_set_mute(int fd, bool mute)
|
|
||||||
{
|
|
||||||
int muteint = 1;
|
|
||||||
if (mute) muteint = 0;
|
|
||||||
int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_MUTE, muteint);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("FmRadioController: failed to set mute\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fm_radio_set_volume(int fd, int volume /* 1 ~ 15 */)
|
|
||||||
{
|
|
||||||
int ret = fm_radio_set_control(fd, V4L2_CID_AUDIO_VOLUME, volume);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("FmRadioController: failed to set volume\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class C, typename T>
|
|
||||||
bool contains(C&& c, T e) { return std::find(std::begin(c), std::end(c), e) != std::end(c); }
|
|
||||||
|
|
||||||
static long fm_radio_get_freqs(int fd){
|
|
||||||
long ret = 0;
|
|
||||||
fm_radio_set_mute(fd, true);
|
|
||||||
sp<IFMRadio> service = IFMRadio::getService();
|
|
||||||
bool mSysfs = service->isAvailable() == Status::YES;
|
|
||||||
for (long & track : tracks){
|
|
||||||
if (mSysfs) {
|
|
||||||
service->adjustFreqByStep(Direction::UP);
|
|
||||||
ret = (long) service->getFreqFromSysfs();
|
|
||||||
} else {
|
|
||||||
fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_50KHZ, &ret);
|
|
||||||
}
|
|
||||||
if (contains(tracks, ret)) break;
|
|
||||||
track = ret;
|
|
||||||
printf("Found Freq %ld\n", ret);
|
|
||||||
}
|
|
||||||
fm_radio_set_mute(fd, false);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fm_radio_poll(int fd, struct pollfd *poll_fd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
poll_fd->fd = fd;
|
|
||||||
poll_fd->events = POLLIN;
|
|
||||||
poll_fd->revents = 0;
|
|
||||||
|
|
||||||
ret = poll(poll_fd, 1, 360);
|
|
||||||
if (ret > 0) {
|
|
||||||
if (poll_fd->revents & POLLIN) {
|
|
||||||
printf("FmRadioController: ready to read\n");
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("FmRadioController: cannot read yet\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret) {
|
|
||||||
printf("FmRadioController: polling timeout\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("FmRadioController: pollig fail: %d\n", ret);
|
|
||||||
return FM_FAILURE - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fm_radio_read(int fd, unsigned char *buf)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = read(fd, buf, FM_RADIO_RDS_DATA_MAX);
|
|
||||||
if (ret < 0) {
|
|
||||||
printf("FmRadioController: failed to read\n");
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fm_radio_thread(int fd)
|
|
||||||
{
|
|
||||||
struct pollfd radio_poll{};
|
|
||||||
unsigned char read_buf[FM_RADIO_RDS_DATA_MAX];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
while (FMThread) {
|
|
||||||
ret = fm_radio_poll(fd, &radio_poll);
|
|
||||||
if (ret < 0) {
|
|
||||||
if (ret < FM_FAILURE)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fm_radio_read(fd, read_buf);
|
|
||||||
if (ret < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static unsigned int fm_radio_get_upperband_limit(int fd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
struct v4l2_tuner tuner{};
|
|
||||||
unsigned int freq;
|
|
||||||
tuner.index = 0;
|
|
||||||
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
|
||||||
if(ret < 0) {
|
|
||||||
return FM_FAILURE;
|
|
||||||
}else {
|
|
||||||
freq = (tuner.rangehigh / 16000);
|
|
||||||
return freq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int fm_radio_get_lowerband_limit(int fd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
unsigned int freq;
|
|
||||||
struct v4l2_tuner tuner{};
|
|
||||||
|
|
||||||
tuner.index = 0;
|
|
||||||
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
|
||||||
if(ret < 0) {
|
|
||||||
return FM_FAILURE;
|
|
||||||
}else {
|
|
||||||
freq = (tuner.rangelow / 16000);
|
|
||||||
return freq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static long fm_radio_get_rmssi(int fd)
|
|
||||||
{
|
|
||||||
struct v4l2_tuner tuner{};
|
|
||||||
int ret;
|
|
||||||
long rmssi;
|
|
||||||
tuner.index = 0;
|
|
||||||
tuner.signal = 0;
|
|
||||||
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
|
||||||
if(ret < 0) {
|
|
||||||
ret = FM_FAILURE;
|
|
||||||
}else {
|
|
||||||
rmssi = tuner.signal;
|
|
||||||
ret = rmssi;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
static int fm_radio_set_rssi(int fd, long rssi){
|
|
||||||
int ret = fm_radio_set_control(fd, V4L2_CID_S610_RSSI_TH, rssi);
|
|
||||||
if (ret < 0){
|
|
||||||
return FM_FAILURE;
|
|
||||||
}
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_openFMDevice
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz) {
|
|
||||||
return open_fm_device();
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jlong JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getFMFreq
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
long freq;
|
|
||||||
fm_radio_get_frequency(fd, &freq);
|
|
||||||
return freq;
|
return freq;
|
||||||
}
|
}
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMFreq
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd, jint freq) {
|
|
||||||
return fm_radio_set_frequency(fd, freq);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMVolume
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd, jint volume) {
|
|
||||||
return fm_radio_set_volume(fd, volume);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMMute
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd, jboolean mute) {
|
|
||||||
return fm_radio_set_mute(fd, mute);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getFmUpper
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
return fm_radio_get_upperband_limit(fd);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getFMLower
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
return fm_radio_get_lowerband_limit(fd);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getRMSSI
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
return fm_radio_get_rmssi(fd);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jlongArray JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getFMTracks
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
fm_radio_get_freqs(fd);
|
|
||||||
jlongArray result;
|
|
||||||
result = (*env).NewLongArray(TRACK_SIZE);
|
|
||||||
if (result == nullptr) {
|
|
||||||
return nullptr; /* out of memory error thrown */
|
|
||||||
}
|
|
||||||
int i;
|
|
||||||
// fill a temp structure to use to populate the java int array
|
|
||||||
jlong fill[TRACK_SIZE];
|
|
||||||
for (i = 0; i < TRACK_SIZE; i++) {
|
|
||||||
fill[i] = tracks[i]; // put whatever logic you want to populate the values here.
|
|
||||||
}
|
|
||||||
// move from the temp structure to the java structure
|
|
||||||
(*env).SetLongArrayRegion(result, 0, TRACK_SIZE, fill);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMStereo
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
return fm_radio_set_tuner(fd, 1);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMMono
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
|
||||||
return fm_radio_set_tuner(fd, 0);
|
|
||||||
}
|
|
||||||
extern "C"
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMThread
|
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd, jboolean run) {
|
|
||||||
if (run){
|
|
||||||
FMThread = true;
|
|
||||||
fm_radio_thread(fd);
|
|
||||||
}else{
|
|
||||||
FMThread = false;
|
|
||||||
}
|
|
||||||
return FM_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
static unsigned int fm_radio_get_lowerband_limit(int fd) {
|
||||||
JNIEXPORT void JNICALL
|
int ret;
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMBoot
|
unsigned int freq;
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
struct v4l2_tuner tuner {};
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT1, 4800); // SetIFCount 1
|
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT2, 5600); // SetIFCount 2
|
tuner.index = 0;
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_SOFT_STEREO_BLEND, 3172); // Set Soft Stereo Blend
|
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_SOFT_MUTE_COEFF, 16); // SetSoftMuteCoeff
|
if (ret < 0) {
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_CH_BAND, S610_BAND_FM); // Set Band (To FM)
|
return FM_FAILURE;
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_CH_SPACING, FM_CHANNEL_SPACING_50KHZ); // Spacing 5kHz
|
} else {
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_RDS_ON, FM_RDS_ENABLE); // RDS on
|
freq = (tuner.rangelow / 16000);
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extern "C"
|
static long fm_radio_get_rmssi(int fd) {
|
||||||
JNIEXPORT jint JNICALL
|
struct v4l2_tuner tuner {};
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getNextChannel
|
int ret;
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
long rmssi;
|
||||||
long ret;
|
tuner.index = 0;
|
||||||
sp<IFMRadio> service = IFMRadio::getService();
|
tuner.signal = 0;
|
||||||
bool mSysfs = service->isAvailable() == Status::YES;
|
ret = ioctl(fd, VIDIOC_G_TUNER, &tuner);
|
||||||
if (!mSysfs){
|
if (ret < 0) {
|
||||||
fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_100KHZ, &ret);
|
ret = FM_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
service->adjustFreqByStep(Direction::UP);
|
rmssi = tuner.signal;
|
||||||
ret = service->getFreqFromSysfs();
|
ret = rmssi;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
extern "C"
|
static int fm_radio_set_rssi(int fd, long rssi) {
|
||||||
JNIEXPORT jint JNICALL
|
int ret = fm_radio_set_control(fd, V4L2_CID_S610_RSSI_TH, rssi);
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getBeforeChannel
|
if (ret < 0) {
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
return FM_FAILURE;
|
||||||
long ret;
|
}
|
||||||
sp<IFMRadio> service = IFMRadio::getService();
|
return FM_SUCCESS;
|
||||||
bool mSysfs = service->isAvailable() == Status::YES;
|
}
|
||||||
if (!mSysfs){
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
fm_radio_channel_searching(fd, 0, 0, FM_CHANNEL_SPACING_100KHZ, &ret);
|
Java_com_eurekateam_fmradio_NativeFMInterface_openFMDevice(
|
||||||
} else {
|
__unused JNIEnv *env, __unused jobject thiz) {
|
||||||
service->adjustFreqByStep(Direction::DOWN);
|
return open_fm_device();
|
||||||
ret = service->getFreqFromSysfs();
|
}
|
||||||
}
|
extern "C" JNIEXPORT jlong JNICALL
|
||||||
return ret;
|
Java_com_eurekateam_fmradio_NativeFMInterface_getFMFreq(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
long freq;
|
||||||
|
fm_radio_get_frequency(fd, &freq);
|
||||||
|
return freq;
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMFreq(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd, jint freq) {
|
||||||
|
return fm_radio_set_frequency(fd, freq);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMVolume(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd,
|
||||||
|
jint volume) {
|
||||||
|
return fm_radio_set_volume(fd, volume);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMMute(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd,
|
||||||
|
jboolean mute) {
|
||||||
|
return fm_radio_set_mute(fd, mute);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_getFmUpper(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
return fm_radio_get_upperband_limit(fd);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_getFMLower(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
return fm_radio_get_lowerband_limit(fd);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_getRMSSI(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
return fm_radio_get_rmssi(fd);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jlongArray JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_getFMTracks(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
fm_radio_get_freqs(fd);
|
||||||
|
jlongArray result;
|
||||||
|
result = (*env).NewLongArray(TRACK_SIZE);
|
||||||
|
if (result == nullptr) {
|
||||||
|
return nullptr; /* out of memory error thrown */
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
// fill a temp structure to use to populate the java int array
|
||||||
|
jlong fill[TRACK_SIZE];
|
||||||
|
for (i = 0; i < TRACK_SIZE; i++) {
|
||||||
|
fill[i] =
|
||||||
|
tracks[i]; // put whatever logic you want to populate the values here.
|
||||||
|
}
|
||||||
|
// move from the temp structure to the java structure
|
||||||
|
(*env).SetLongArrayRegion(result, 0, TRACK_SIZE, fill);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMStereo(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
return fm_radio_set_tuner(fd, 1);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMMono(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd) {
|
||||||
|
return fm_radio_set_tuner(fd, 0);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMThread(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd,
|
||||||
|
jboolean run) {
|
||||||
|
if (run) {
|
||||||
|
FMThread = true;
|
||||||
|
fm_radio_thread(fd);
|
||||||
|
} else {
|
||||||
|
FMThread = false;
|
||||||
|
}
|
||||||
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C" JNIEXPORT void JNICALL
|
||||||
JNIEXPORT jboolean JNICALL
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMBoot(__unused JNIEnv *env,
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getAudioChannel
|
__unused jobject thiz,
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
jint fd) {
|
||||||
int channel = fm_radio_get_tuner(fd);
|
fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT1, 4800); // SetIFCount 1
|
||||||
if (channel == V4L2_TUNER_MODE_STEREO){
|
fm_radio_set_control(fd, V4L2_CID_S610_IF_COUNT2, 5600); // SetIFCount 2
|
||||||
return true; // Is EarPhones
|
fm_radio_set_control(fd, V4L2_CID_S610_SOFT_STEREO_BLEND,
|
||||||
}else{
|
3172); // Set Soft Stereo Blend
|
||||||
return false; // Is Speaker
|
fm_radio_set_control(fd, V4L2_CID_S610_SOFT_MUTE_COEFF,
|
||||||
}
|
16); // SetSoftMuteCoeff
|
||||||
|
fm_radio_set_control(fd, V4L2_CID_S610_CH_BAND,
|
||||||
|
S610_BAND_FM); // Set Band (To FM)
|
||||||
|
fm_radio_set_control(fd, V4L2_CID_S610_CH_SPACING,
|
||||||
|
FM_CHANNEL_SPACING_50KHZ); // Spacing 5kHz
|
||||||
|
fm_radio_set_control(fd, V4L2_CID_S610_RDS_ON, FM_RDS_ENABLE); // RDS on
|
||||||
}
|
}
|
||||||
extern "C"
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNIEXPORT void JNICALL
|
Java_com_eurekateam_fmradio_NativeFMInterface_getNextChannel(
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_stopSearching
|
__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
long ret;
|
||||||
fm_radio_set_control(fd, V4L2_CID_S610_SEEK_CANCEL, 1);
|
sp<IFMRadio> service = IFMRadio::getService();
|
||||||
|
bool mSysfs = service->isAvailable() == Status::YES;
|
||||||
|
if (!mSysfs) {
|
||||||
|
fm_radio_channel_searching(fd, 1, 0, FM_CHANNEL_SPACING_100KHZ, &ret);
|
||||||
|
} else {
|
||||||
|
service->adjustFreqByStep(Direction::UP);
|
||||||
|
ret = service->getFreqFromSysfs();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
extern "C"
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNIEXPORT jint JNICALL
|
Java_com_eurekateam_fmradio_NativeFMInterface_getBeforeChannel(
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setFMRSSI
|
__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd, jlong rssi) {
|
long ret;
|
||||||
return fm_radio_set_rssi(fd, rssi);
|
sp<IFMRadio> service = IFMRadio::getService();
|
||||||
|
bool mSysfs = service->isAvailable() == Status::YES;
|
||||||
|
if (!mSysfs) {
|
||||||
|
fm_radio_channel_searching(fd, 0, 0, FM_CHANNEL_SPACING_100KHZ, &ret);
|
||||||
|
} else {
|
||||||
|
service->adjustFreqByStep(Direction::DOWN);
|
||||||
|
ret = service->getFreqFromSysfs();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
extern "C"
|
|
||||||
JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_closeFMDevice
|
Java_com_eurekateam_fmradio_NativeFMInterface_getAudioChannel(
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
||||||
close(fd);
|
int channel = fm_radio_get_tuner(fd);
|
||||||
|
if (channel == V4L2_TUNER_MODE_STEREO) {
|
||||||
|
return true; // Is EarPhones
|
||||||
|
} else {
|
||||||
|
return false; // Is Speaker
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extern "C"
|
extern "C" JNIEXPORT void JNICALL
|
||||||
JNIEXPORT jboolean JNICALL
|
Java_com_eurekateam_fmradio_NativeFMInterface_stopSearching(
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_getSysfsSupport
|
__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
||||||
(__unused JNIEnv *env, __unused jobject thiz) {
|
fm_radio_set_control(fd, V4L2_CID_S610_SEEK_CANCEL, 1);
|
||||||
sp<IFMRadio> service = IFMRadio::getService();
|
}
|
||||||
return service->isAvailable() == Status::YES;
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_setFMRSSI(__unused JNIEnv *env,
|
||||||
|
__unused jobject thiz,
|
||||||
|
jint fd, jlong rssi) {
|
||||||
|
return fm_radio_set_rssi(fd, rssi);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT void JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_closeFMDevice(
|
||||||
|
__unused JNIEnv *env, __unused jobject thiz, jint fd) {
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
|
Java_com_eurekateam_fmradio_NativeFMInterface_getSysfsSupport(
|
||||||
|
__unused JNIEnv *env, __unused jobject thiz) {
|
||||||
|
sp<IFMRadio> service = IFMRadio::getService();
|
||||||
|
return service->isAvailable() == Status::YES;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,24 +14,24 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <media/IAudioFlinger.h>
|
|
||||||
#include <media/AudioSystem.h>
|
#include <media/AudioSystem.h>
|
||||||
|
#include <media/IAudioFlinger.h>
|
||||||
|
|
||||||
#define FM_FAILURE -1
|
#define FM_FAILURE -1
|
||||||
#define FM_SUCCESS 0
|
#define FM_SUCCESS 0
|
||||||
#define IOHANDLE 13
|
#define IOHANDLE 13
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
extern "C"
|
extern "C" JNIEXPORT jboolean JNICALL
|
||||||
JNIEXPORT jboolean JNICALL
|
Java_com_eurekateam_fmradio_NativeFMInterface_setAudioRoute(
|
||||||
Java_com_eurekateam_fmradio_NativeFMInterface_setAudioRoute
|
__unused JNIEnv *env, __unused jobject thiz, jboolean speaker) {
|
||||||
(__unused JNIEnv *env, __unused jobject thiz, jboolean speaker) {
|
const sp<IAudioFlinger> &af = AudioSystem::get_audio_flinger();
|
||||||
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
|
if (af == 0)
|
||||||
if (af == 0) return PERMISSION_DENIED;
|
return PERMISSION_DENIED;
|
||||||
if (speaker){
|
if (speaker) {
|
||||||
af->setParameters(IOHANDLE, String8("routing=2"));
|
af->setParameters(IOHANDLE, String8("routing=2"));
|
||||||
}else{
|
} else {
|
||||||
af->setParameters(IOHANDLE, String8("routing=8"));
|
af->setParameters(IOHANDLE, String8("routing=8"));
|
||||||
}
|
}
|
||||||
return FM_SUCCESS;
|
return FM_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,56 @@
|
||||||
#define FM_FAILURE -1
|
#define FM_FAILURE -1
|
||||||
#define FM_SUCCESS 0
|
#define FM_SUCCESS 0
|
||||||
|
|
||||||
#define V4L2_CID_USER_S610_BASE (0x00980900 + 0x1070)
|
#define V4L2_CID_USER_S610_BASE (0x00980900 + 0x1070)
|
||||||
enum s610_ctrl_id {
|
enum s610_ctrl_id {
|
||||||
V4L2_CID_S610_CH_SPACING = (V4L2_CID_USER_S610_BASE + 0x01),
|
V4L2_CID_S610_CH_SPACING = (V4L2_CID_USER_S610_BASE + 0x01),
|
||||||
V4L2_CID_S610_CH_BAND = (V4L2_CID_USER_S610_BASE + 0x02),
|
V4L2_CID_S610_CH_BAND = (V4L2_CID_USER_S610_BASE + 0x02),
|
||||||
V4L2_CID_S610_SOFT_STEREO_BLEND = (V4L2_CID_USER_S610_BASE + 0x03),
|
V4L2_CID_S610_SOFT_STEREO_BLEND = (V4L2_CID_USER_S610_BASE + 0x03),
|
||||||
V4L2_CID_S610_SOFT_STEREO_BLEND_COEFF = (V4L2_CID_USER_S610_BASE+0x04),
|
V4L2_CID_S610_SOFT_STEREO_BLEND_COEFF = (V4L2_CID_USER_S610_BASE + 0x04),
|
||||||
V4L2_CID_S610_SOFT_MUTE_COEFF = (V4L2_CID_USER_S610_BASE + 0x5),
|
V4L2_CID_S610_SOFT_MUTE_COEFF = (V4L2_CID_USER_S610_BASE + 0x5),
|
||||||
V4L2_CID_S610_RSSI_CURR = (V4L2_CID_USER_S610_BASE + 0x06),
|
V4L2_CID_S610_RSSI_CURR = (V4L2_CID_USER_S610_BASE + 0x06),
|
||||||
V4L2_CID_S610_SNR_CURR = (V4L2_CID_USER_S610_BASE + 0x07),
|
V4L2_CID_S610_SNR_CURR = (V4L2_CID_USER_S610_BASE + 0x07),
|
||||||
V4L2_CID_S610_SEEK_CANCEL = (V4L2_CID_USER_S610_BASE + 0x08),
|
V4L2_CID_S610_SEEK_CANCEL = (V4L2_CID_USER_S610_BASE + 0x08),
|
||||||
V4L2_CID_S610_SEEK_MODE = (V4L2_CID_USER_S610_BASE + 0x09),
|
V4L2_CID_S610_SEEK_MODE = (V4L2_CID_USER_S610_BASE + 0x09),
|
||||||
V4L2_CID_S610_RDS_ON = (V4L2_CID_USER_S610_BASE + 0x0A),
|
V4L2_CID_S610_RDS_ON = (V4L2_CID_USER_S610_BASE + 0x0A),
|
||||||
V4L2_CID_S610_IF_COUNT1 = (V4L2_CID_USER_S610_BASE + 0x0B),
|
V4L2_CID_S610_IF_COUNT1 = (V4L2_CID_USER_S610_BASE + 0x0B),
|
||||||
V4L2_CID_S610_IF_COUNT2 = (V4L2_CID_USER_S610_BASE + 0x0C),
|
V4L2_CID_S610_IF_COUNT2 = (V4L2_CID_USER_S610_BASE + 0x0C),
|
||||||
V4L2_CID_S610_RSSI_TH = (V4L2_CID_USER_S610_BASE + 0x0D),
|
V4L2_CID_S610_RSSI_TH = (V4L2_CID_USER_S610_BASE + 0x0D),
|
||||||
V4L2_CID_S610_KERNEL_VER = (V4L2_CID_USER_S610_BASE + 0x0E),
|
V4L2_CID_S610_KERNEL_VER = (V4L2_CID_USER_S610_BASE + 0x0E),
|
||||||
V4L2_CID_S610_SOFT_STEREO_BLEND_REF = (V4L2_CID_USER_S610_BASE+0x0F),
|
V4L2_CID_S610_SOFT_STEREO_BLEND_REF = (V4L2_CID_USER_S610_BASE + 0x0F),
|
||||||
V4L2_CID_S610_REG_RW_ADDR = (V4L2_CID_USER_S610_BASE + 0x10),
|
V4L2_CID_S610_REG_RW_ADDR = (V4L2_CID_USER_S610_BASE + 0x10),
|
||||||
V4L2_CID_S610_REG_RW = (V4L2_CID_USER_S610_BASE + 0x11),
|
V4L2_CID_S610_REG_RW = (V4L2_CID_USER_S610_BASE + 0x11),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tunner modes */
|
/* Tunner modes */
|
||||||
enum fm_tuner_mode {
|
enum fm_tuner_mode {
|
||||||
FM_TUNER_STOP_SEARCH_MODE = 0,
|
FM_TUNER_STOP_SEARCH_MODE = 0,
|
||||||
FM_TUNER_PRESET_MODE = 1,
|
FM_TUNER_PRESET_MODE = 1,
|
||||||
FM_TUNER_AUTONOMOUS_SEARCH_MODE = 2,
|
FM_TUNER_AUTONOMOUS_SEARCH_MODE = 2,
|
||||||
FM_TUNER_AUTONOMOUS_SEARCH_MODE_NEXT = 10
|
FM_TUNER_AUTONOMOUS_SEARCH_MODE_NEXT = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
/* channel spacing */
|
/* channel spacing */
|
||||||
enum fm_channel_spacing {
|
enum fm_channel_spacing {
|
||||||
FM_CHANNEL_SPACING_50KHZ = 1,
|
FM_CHANNEL_SPACING_50KHZ = 1,
|
||||||
FM_CHANNEL_SPACING_100KHZ = 2,
|
FM_CHANNEL_SPACING_100KHZ = 2,
|
||||||
FM_CHANNEL_SPACING_200KHZ = 4
|
FM_CHANNEL_SPACING_200KHZ = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Mute modes */
|
/* Mute modes */
|
||||||
enum fm_mute_mode {
|
enum fm_mute_mode { FM_MUTE_ON = 0, FM_MUTE_OFF = 1, FM_MUTE_ATTENUATE = 2 };
|
||||||
FM_MUTE_ON = 0,
|
|
||||||
FM_MUTE_OFF = 1,
|
|
||||||
FM_MUTE_ATTENUATE = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/* FM RDS modes */
|
/* FM RDS modes */
|
||||||
enum fm_rds_mode {
|
enum fm_rds_mode { FM_RDS_DISABLE = 0, FM_RDS_ENABLE = 1 };
|
||||||
FM_RDS_DISABLE = 0,
|
|
||||||
FM_RDS_ENABLE = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
#define FM_RADIO_RDS_DATA_MAX 48
|
#define FM_RADIO_RDS_DATA_MAX 48
|
||||||
|
|
||||||
enum s610_freq_bands {
|
enum s610_freq_bands {
|
||||||
S610_BAND_FM = 0,
|
S610_BAND_FM = 0,
|
||||||
S610_BAND_AM = 1,
|
S610_BAND_AM = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum s610_aud_mode {
|
enum s610_aud_mode {
|
||||||
S610_AUD_ENABLE = 1,
|
S610_AUD_ENABLE = 1,
|
||||||
S610_AUD_DISABLE = 0,
|
S610_AUD_DISABLE = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,125 +1,123 @@
|
||||||
|
|
||||||
typedef u_int8_t __u8;
|
typedef u_int8_t __u8;
|
||||||
typedef int32_t __s32;
|
typedef int32_t __s32;
|
||||||
typedef u_int32_t __u32;
|
typedef u_int32_t __u32;
|
||||||
|
|
||||||
struct v4l2_tuner {
|
struct v4l2_tuner {
|
||||||
__u32 index;
|
__u32 index;
|
||||||
__u8 name[32];
|
__u8 name[32];
|
||||||
__u32 type; /* enum v4l2_tuner_type */
|
__u32 type; /* enum v4l2_tuner_type */
|
||||||
__u32 capability;
|
__u32 capability;
|
||||||
__u32 rangelow;
|
__u32 rangelow;
|
||||||
__u32 rangehigh;
|
__u32 rangehigh;
|
||||||
__u32 rxsubchans;
|
__u32 rxsubchans;
|
||||||
__u32 audmode;
|
__u32 audmode;
|
||||||
__s32 signal;
|
__s32 signal;
|
||||||
__s32 afc;
|
__s32 afc;
|
||||||
__u32 reserved[4];
|
__u32 reserved[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v4l2_frequency {
|
struct v4l2_frequency {
|
||||||
__u32 tuner;
|
__u32 tuner;
|
||||||
__u32 type; /* enum v4l2_tuner_type */
|
__u32 type; /* enum v4l2_tuner_type */
|
||||||
__u32 frequency;
|
__u32 frequency;
|
||||||
__u32 reserved[8];
|
__u32 reserved[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct v4l2_hw_freq_seek {
|
struct v4l2_hw_freq_seek {
|
||||||
__u32 tuner;
|
__u32 tuner;
|
||||||
__u32 type; /* enum v4l2_tuner_type */
|
__u32 type; /* enum v4l2_tuner_type */
|
||||||
__u32 seek_upward;
|
__u32 seek_upward;
|
||||||
__u32 wrap_around;
|
__u32 wrap_around;
|
||||||
__u32 spacing;
|
__u32 spacing;
|
||||||
__u32 rangelow;
|
__u32 rangelow;
|
||||||
__u32 rangehigh;
|
__u32 rangehigh;
|
||||||
__u32 reserved[5];
|
__u32 reserved[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum v4l2_tuner_type {
|
enum v4l2_tuner_type {
|
||||||
V4L2_TUNER_RADIO = 1,
|
V4L2_TUNER_RADIO = 1,
|
||||||
V4L2_TUNER_ANALOG_TV = 2,
|
V4L2_TUNER_ANALOG_TV = 2,
|
||||||
V4L2_TUNER_DIGITAL_TV = 3,
|
V4L2_TUNER_DIGITAL_TV = 3,
|
||||||
V4L2_TUNER_SDR = 4,
|
V4L2_TUNER_SDR = 4,
|
||||||
V4L2_TUNER_RF = 5,
|
V4L2_TUNER_RF = 5,
|
||||||
};
|
};
|
||||||
struct v4l2_control {
|
struct v4l2_control {
|
||||||
__u32 id;
|
__u32 id;
|
||||||
__s32 value;
|
__s32 value;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP
|
* struct v4l2_capability - Describes V4L2 device caps returned by
|
||||||
*
|
* VIDIOC_QUERYCAP
|
||||||
* @driver: name of the driver module (e.g. "bttv")
|
*
|
||||||
* @card: name of the card (e.g. "Hauppauge WinTV")
|
* @driver: name of the driver module (e.g. "bttv")
|
||||||
* @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
|
* @card: name of the card (e.g. "Hauppauge WinTV")
|
||||||
* @version: KERNEL_VERSION
|
* @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) )
|
||||||
* @capabilities: capabilities of the physical device as a whole
|
* @version: KERNEL_VERSION
|
||||||
* @device_caps: capabilities accessed via this particular device (node)
|
* @capabilities: capabilities of the physical device as a whole
|
||||||
* @reserved: reserved fields for future extensions
|
* @device_caps: capabilities accessed via this particular device (node)
|
||||||
*/
|
* @reserved: reserved fields for future extensions
|
||||||
|
*/
|
||||||
struct v4l2_capability {
|
struct v4l2_capability {
|
||||||
__u8 driver[16];
|
__u8 driver[16];
|
||||||
__u8 card[32];
|
__u8 card[32];
|
||||||
__u8 bus_info[32];
|
__u8 bus_info[32];
|
||||||
__u32 version;
|
__u32 version;
|
||||||
__u32 capabilities;
|
__u32 capabilities;
|
||||||
__u32 device_caps;
|
__u32 device_caps;
|
||||||
__u32 reserved[3];
|
__u32 reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* T I M E C O D E
|
* T I M E C O D E
|
||||||
*/
|
*/
|
||||||
struct v4l2_timecode {
|
struct v4l2_timecode {
|
||||||
__u32 type;
|
__u32 type;
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
__u8 frames;
|
__u8 frames;
|
||||||
__u8 seconds;
|
__u8 seconds;
|
||||||
__u8 minutes;
|
__u8 minutes;
|
||||||
__u8 hours;
|
__u8 hours;
|
||||||
__u8 userbits[4];
|
__u8 userbits[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct v4l2_buffer {
|
struct v4l2_buffer {
|
||||||
__u32 index;
|
__u32 index;
|
||||||
__u32 type;
|
__u32 type;
|
||||||
__u32 bytesused;
|
__u32 bytesused;
|
||||||
__u32 flags;
|
__u32 flags;
|
||||||
__u32 field;
|
__u32 field;
|
||||||
struct timeval timestamp;
|
struct timeval timestamp;
|
||||||
struct v4l2_timecode timecode;
|
struct v4l2_timecode timecode;
|
||||||
__u32 sequence;
|
__u32 sequence;
|
||||||
|
|
||||||
/* memory location */
|
/* memory location */
|
||||||
__u32 memory;
|
__u32 memory;
|
||||||
union {
|
union {
|
||||||
__u32 offset;
|
__u32 offset;
|
||||||
unsigned long userptr;
|
unsigned long userptr;
|
||||||
struct v4l2_plane *planes;
|
struct v4l2_plane *planes;
|
||||||
__s32 fd;
|
__s32 fd;
|
||||||
} m;
|
} m;
|
||||||
__u32 length;
|
__u32 length;
|
||||||
__u32 reserved2;
|
__u32 reserved2;
|
||||||
__u32 reserved;
|
__u32 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define V4L2_TUNER_MODE_MONO 0x0000
|
#define V4L2_TUNER_MODE_MONO 0x0000
|
||||||
#define V4L2_TUNER_MODE_STEREO 0x0001
|
#define V4L2_TUNER_MODE_STEREO 0x0001
|
||||||
|
|
||||||
// Ioctl
|
// Ioctl
|
||||||
#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
|
#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct v4l2_frequency)
|
||||||
#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
|
#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct v4l2_frequency)
|
||||||
#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
|
#define VIDIOC_G_TUNER _IOWR('V', 29, struct v4l2_tuner)
|
||||||
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
|
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
|
||||||
#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
|
#define VIDIOC_S_TUNER _IOW('V', 30, struct v4l2_tuner)
|
||||||
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
|
#define VIDIOC_S_CTRL _IOWR('V', 28, struct v4l2_control)
|
||||||
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
|
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
|
||||||
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
|
#define VIDIOC_G_CTRL _IOWR('V', 27, struct v4l2_control)
|
||||||
|
|
||||||
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
|
|
||||||
#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
|
|
||||||
#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
|
|
||||||
#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
|
|
||||||
|
|
||||||
|
|
||||||
|
#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
|
||||||
|
#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
|
||||||
|
#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE + 5)
|
||||||
|
#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE + 9)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
#include "jni.h"
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include <hidl/HidlSupport.h>
|
#include <hidl/HidlSupport.h>
|
||||||
#include <hidl/LegacySupport.h>
|
#include <hidl/LegacySupport.h>
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
||||||
#include "jni.h"
|
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
using vendor::eureka::hardware::parts::V1_0::IBatteryStats;
|
using vendor::eureka::hardware::parts::V1_0::IBatteryStats;
|
||||||
|
|
@ -12,81 +12,78 @@ using vendor::eureka::hardware::parts::V1_0::SysfsType;
|
||||||
|
|
||||||
static android::sp<IBatteryStats> service = IBatteryStats::getService();
|
static android::sp<IBatteryStats> service = IBatteryStats::getService();
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Battery_setChargeSysfs(JNIEnv* env,
|
Java_com_eurekateam_samsungextras_interfaces_Battery_setChargeSysfs(
|
||||||
__unused jclass obj,
|
JNIEnv *env, __unused jclass obj, jint enable) {
|
||||||
jint enable) {
|
if (enable == 1) {
|
||||||
if (enable == 1) {
|
service->setBatteryWritable(SysfsType::CHARGE, Number::ENABLE);
|
||||||
service->setBatteryWritable(SysfsType::CHARGE, Number::ENABLE);
|
} else {
|
||||||
} else {
|
service->setBatteryWritable(SysfsType::CHARGE, Number::DISABLE);
|
||||||
service->setBatteryWritable(SysfsType::CHARGE, Number::DISABLE);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Battery_getChargeSysfs(JNIEnv* env,
|
Java_com_eurekateam_samsungextras_interfaces_Battery_getChargeSysfs(
|
||||||
__unused jclass obj) {
|
JNIEnv *env, __unused jclass obj) {
|
||||||
int ret = service->getBatteryStats(SysfsType::CHARGE);
|
int ret = service->getBatteryStats(SysfsType::CHARGE);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Battery_setFastCharge(JNIEnv* env,
|
Java_com_eurekateam_samsungextras_interfaces_Battery_setFastCharge(
|
||||||
__unused jobject obj,
|
JNIEnv *env, __unused jobject obj, jint enable) {
|
||||||
jint enable) {
|
if (enable == 1) {
|
||||||
if (enable == 1) {
|
service->setBatteryWritable(SysfsType::FASTCHARGE, Number::ENABLE);
|
||||||
service->setBatteryWritable(SysfsType::FASTCHARGE, Number::ENABLE);
|
} else {
|
||||||
|
service->setBatteryWritable(SysfsType::FASTCHARGE, Number::DISABLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_samsungextras_interfaces_Battery_getFastChargeSysfs(
|
||||||
|
JNIEnv *env, __unused jclass obj) {
|
||||||
|
int ret = service->getBatteryStats(SysfsType::FASTCHARGE);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(
|
||||||
|
JNIEnv *env, __unused jobject obj, jint id) {
|
||||||
|
/**
|
||||||
|
* id:
|
||||||
|
* 1 = BATTERY_CAPACITY_MAX
|
||||||
|
* 2 = BATTERY_CAPACITY_CURRENT (%)
|
||||||
|
* 3 = BATTERY_CAPACITY_CURRENT (mAh)
|
||||||
|
* 4 = CHARGING_STATE
|
||||||
|
* 5 = BATTERY_TEMP
|
||||||
|
* 6 = BATTERY_CURRENT
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
switch (id) {
|
||||||
|
case 1:
|
||||||
|
ret = service->getBatteryStats(SysfsType::CAPACITY_MAX) / 1000;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
ret = service->getBatteryStats(SysfsType::CAPACITY_CURRENT);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
ret = (float)service->getBatteryStats(SysfsType::CAPACITY_CURRENT) *
|
||||||
|
(float)service->getBatteryStats(SysfsType::CAPACITY_MAX) / 100000;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (service->getBatteryStats(SysfsType::CURRENT) > 0) {
|
||||||
|
ret = 1;
|
||||||
} else {
|
} else {
|
||||||
service->setBatteryWritable(SysfsType::FASTCHARGE, Number::DISABLE);
|
ret = 0;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
case 5:
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Battery_getFastChargeSysfs(JNIEnv* env,
|
ret = service->getBatteryStats(SysfsType::TEMP) / 10;
|
||||||
__unused jclass obj) {
|
break;
|
||||||
int ret = service->getBatteryStats(SysfsType::FASTCHARGE);
|
case 6:
|
||||||
return ret;
|
ret = service->getBatteryStats(SysfsType::CURRENT);
|
||||||
}
|
break;
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
default:
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(JNIEnv* env,
|
ret = -1;
|
||||||
__unused jobject obj,
|
break;
|
||||||
jint id) {
|
}
|
||||||
/**
|
return ret;
|
||||||
* id:
|
|
||||||
* 1 = BATTERY_CAPACITY_MAX
|
|
||||||
* 2 = BATTERY_CAPACITY_CURRENT (%)
|
|
||||||
* 3 = BATTERY_CAPACITY_CURRENT (mAh)
|
|
||||||
* 4 = CHARGING_STATE
|
|
||||||
* 5 = BATTERY_TEMP
|
|
||||||
* 6 = BATTERY_CURRENT
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
switch (id) {
|
|
||||||
case 1:
|
|
||||||
ret = service->getBatteryStats(SysfsType::CAPACITY_MAX) / 1000;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ret = service->getBatteryStats(SysfsType::CAPACITY_CURRENT);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
ret = (float)service->getBatteryStats(SysfsType::CAPACITY_CURRENT) *
|
|
||||||
(float)service->getBatteryStats(SysfsType::CAPACITY_MAX) / 100000;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (service->getBatteryStats(SysfsType::CURRENT) > 0) {
|
|
||||||
ret = 1;
|
|
||||||
} else {
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
ret = service->getBatteryStats(SysfsType::TEMP) / 10;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
ret = service->getBatteryStats(SysfsType::CURRENT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,34 @@
|
||||||
|
#include "jni.h"
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include <hidl/HidlSupport.h>
|
#include <hidl/HidlSupport.h>
|
||||||
#include <hidl/LegacySupport.h>
|
#include <hidl/LegacySupport.h>
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
||||||
#include "jni.h"
|
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
using vendor::eureka::hardware::parts::V1_0::Number;
|
|
||||||
using vendor::eureka::hardware::parts::V1_0::Display;
|
using vendor::eureka::hardware::parts::V1_0::Display;
|
||||||
using vendor::eureka::hardware::parts::V1_0::IDisplayConfigs;
|
using vendor::eureka::hardware::parts::V1_0::IDisplayConfigs;
|
||||||
|
using vendor::eureka::hardware::parts::V1_0::Number;
|
||||||
|
|
||||||
static android::sp<IDisplayConfigs> service = IDisplayConfigs::getService();
|
static android::sp<IDisplayConfigs> service = IDisplayConfigs::getService();
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Display_setDT2W(JNIEnv* env, jclass clazz, jboolean enable) {
|
Java_com_eurekateam_samsungextras_interfaces_Display_setDT2W(JNIEnv *env,
|
||||||
if (enable) {
|
jclass clazz,
|
||||||
service->writeDisplay(Number::ENABLE,
|
jboolean enable) {
|
||||||
Display::DOUBLE_TAP);
|
if (enable) {
|
||||||
} else {
|
service->writeDisplay(Number::ENABLE, Display::DOUBLE_TAP);
|
||||||
service->writeDisplay(Number::DISABLE,
|
} else {
|
||||||
Display::DOUBLE_TAP);
|
service->writeDisplay(Number::DISABLE, Display::DOUBLE_TAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_com_eurekateam_samsungextras_interfaces_Display_setGloveMode(JNIEnv* env, jclass clazz, jboolean enable) {
|
Java_com_eurekateam_samsungextras_interfaces_Display_setGloveMode(
|
||||||
if (enable) {
|
JNIEnv *env, jclass clazz, jboolean enable) {
|
||||||
service->writeDisplay(Number::ENABLE, Display::GLOVE_MODE);
|
if (enable) {
|
||||||
} else {
|
service->writeDisplay(Number::ENABLE, Display::GLOVE_MODE);
|
||||||
service->writeDisplay(Number::DISABLE, Display::GLOVE_MODE);
|
} else {
|
||||||
}
|
service->writeDisplay(Number::DISABLE, Display::GLOVE_MODE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,63 +1,66 @@
|
||||||
|
#include "jni.h"
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include <hidl/HidlSupport.h>
|
#include <hidl/HidlSupport.h>
|
||||||
#include <hidl/LegacySupport.h>
|
#include <hidl/LegacySupport.h>
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
||||||
#include "jni.h"
|
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
using vendor::eureka::hardware::parts::V1_0::Device;
|
using vendor::eureka::hardware::parts::V1_0::Device;
|
||||||
using vendor::eureka::hardware::parts::V1_0::Value;
|
|
||||||
using vendor::eureka::hardware::parts::V1_0::IFlashBrightness;
|
using vendor::eureka::hardware::parts::V1_0::IFlashBrightness;
|
||||||
using vendor::eureka::hardware::parts::V1_0::Number;
|
using vendor::eureka::hardware::parts::V1_0::Number;
|
||||||
|
using vendor::eureka::hardware::parts::V1_0::Value;
|
||||||
|
|
||||||
static android::sp<IFlashBrightness> service = IFlashBrightness::getService();
|
static android::sp<IFlashBrightness> service = IFlashBrightness::getService();
|
||||||
|
|
||||||
extern "C" JNIEXPORT void JNICALL Java_com_eurekateam_samsungextras_interfaces_Flashlight_setFlash(
|
extern "C" JNIEXPORT void JNICALL
|
||||||
JNIEnv* env, __unused jobject obj, jint value) {
|
Java_com_eurekateam_samsungextras_interfaces_Flashlight_setFlash(
|
||||||
service->setFlashlightEnable(Number::ENABLE);
|
JNIEnv *env, __unused jobject obj, jint value) {
|
||||||
switch (value) {
|
service->setFlashlightEnable(Number::ENABLE);
|
||||||
case 1:
|
switch (value) {
|
||||||
service->setFlashlightWritable(Value::ONEUI);
|
case 1:
|
||||||
break;
|
service->setFlashlightWritable(Value::ONEUI);
|
||||||
case 2:
|
break;
|
||||||
service->setFlashlightWritable(Value::TWOUI);
|
case 2:
|
||||||
break;
|
service->setFlashlightWritable(Value::TWOUI);
|
||||||
case 3:
|
break;
|
||||||
service->setFlashlightWritable(Value::THREEUI);
|
case 3:
|
||||||
break;
|
service->setFlashlightWritable(Value::THREEUI);
|
||||||
case 4:
|
break;
|
||||||
service->setFlashlightWritable(Value::FOURUI);
|
case 4:
|
||||||
break;
|
service->setFlashlightWritable(Value::FOURUI);
|
||||||
case 5:
|
break;
|
||||||
service->setFlashlightWritable(Value::FIVEUI);
|
case 5:
|
||||||
break;
|
service->setFlashlightWritable(Value::FIVEUI);
|
||||||
case 6:
|
break;
|
||||||
service->setFlashlightWritable(Value::SIXUI);
|
case 6:
|
||||||
break;
|
service->setFlashlightWritable(Value::SIXUI);
|
||||||
case 7:
|
break;
|
||||||
service->setFlashlightWritable(Value::SEVENUI);
|
case 7:
|
||||||
break;
|
service->setFlashlightWritable(Value::SEVENUI);
|
||||||
case 8:
|
break;
|
||||||
service->setFlashlightWritable(Value::EIGHTUI);
|
case 8:
|
||||||
break;
|
service->setFlashlightWritable(Value::EIGHTUI);
|
||||||
case 9:
|
break;
|
||||||
service->setFlashlightWritable(Value::NINEUI);
|
case 9:
|
||||||
break;
|
service->setFlashlightWritable(Value::NINEUI);
|
||||||
case 10:
|
break;
|
||||||
service->setFlashlightWritable(Value::TENUI);
|
case 10:
|
||||||
break;
|
service->setFlashlightWritable(Value::TENUI);
|
||||||
default:
|
break;
|
||||||
break;
|
default:
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
extern "C" JNIEXPORT jint JNICALL Java_com_eurekateam_samsungextras_interfaces_Flashlight_getFlash(
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
JNIEnv* env, jobject clazz, jint isA10) {
|
Java_com_eurekateam_samsungextras_interfaces_Flashlight_getFlash(JNIEnv *env,
|
||||||
int ret;
|
jobject clazz,
|
||||||
if (isA10 == 1) {
|
jint isA10) {
|
||||||
ret = service->readFlashlightstats(Device::A10);
|
int ret;
|
||||||
} else {
|
if (isA10 == 1) {
|
||||||
ret = service->readFlashlightstats(Device::NOTA10);
|
ret = service->readFlashlightstats(Device::A10);
|
||||||
}
|
} else {
|
||||||
return ret;
|
ret = service->readFlashlightstats(Device::NOTA10);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,22 @@
|
||||||
#include <cutils/properties.h>
|
#include <cutils/properties.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static inline const char* BtmGetDefaultName() {
|
static inline const char *BtmGetDefaultName() {
|
||||||
char product_device[PROPERTY_VALUE_MAX];
|
char product_device[PROPERTY_VALUE_MAX];
|
||||||
property_get("ro.product.device", product_device, "");
|
property_get("ro.product.device", product_device, "");
|
||||||
|
|
||||||
if (strstr(product_device, "a10")) return "Galaxy A10";
|
if (strstr(product_device, "a10"))
|
||||||
if (strstr(product_device, "a20e")) return "Galaxy A20e";
|
return "Galaxy A10";
|
||||||
if (strstr(product_device, "a20")) return "Galaxy A20";
|
if (strstr(product_device, "a20e"))
|
||||||
if (strstr(product_device, "a30")) return "Galaxy A30";
|
return "Galaxy A20e";
|
||||||
if (strstr(product_device, "a40")) return "Galaxy A40";
|
if (strstr(product_device, "a20"))
|
||||||
// Fallback to Generic
|
return "Galaxy A20";
|
||||||
return "Samsung Galaxy";
|
if (strstr(product_device, "a30"))
|
||||||
|
return "Galaxy A30";
|
||||||
|
if (strstr(product_device, "a40"))
|
||||||
|
return "Galaxy A40";
|
||||||
|
// Fallback to Generic
|
||||||
|
return "Samsung Galaxy";
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BTM_DEF_LOCAL_NAME BtmGetDefaultName()
|
#define BTM_DEF_LOCAL_NAME BtmGetDefaultName()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#define KMSG_PATH "/proc/kmsg"
|
#define KMSG_PATH "/proc/kmsg"
|
||||||
|
|
@ -23,17 +23,17 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void copy_kmsg() {
|
void copy_kmsg() {
|
||||||
std::ifstream readfile(KMSG_PATH);
|
std::ifstream readfile(KMSG_PATH);
|
||||||
std::ofstream writefile(WRITE_KMSG);
|
std::ofstream writefile(WRITE_KMSG);
|
||||||
writefile << readfile.rdbuf();
|
writefile << readfile.rdbuf();
|
||||||
}
|
}
|
||||||
void copy_logcat() {
|
void copy_logcat() {
|
||||||
system("/system/bin/logcat -b all -f /data/debug/logcat.txt");
|
system("/system/bin/logcat -b all -f /data/debug/logcat.txt");
|
||||||
}
|
}
|
||||||
int main() {
|
int main() {
|
||||||
std::thread kmsg(copy_kmsg);
|
std::thread kmsg(copy_kmsg);
|
||||||
std::thread logcat(copy_logcat);
|
std::thread logcat(copy_logcat);
|
||||||
kmsg.join();
|
kmsg.join();
|
||||||
logcat.join();
|
logcat.join();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,65 +16,69 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
static int mChannelSpacing = 3;
|
static int mChannelSpacing = 3;
|
||||||
|
|
||||||
namespace vendor::eureka::hardware::fmradio::V1_2 {
|
namespace vendor::eureka::hardware::fmradio::V1_2 {
|
||||||
|
|
||||||
Return<void> FMRadio::setManualFreq(float freq) {
|
Return<void> FMRadio::setManualFreq(float freq) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
||||||
file << freq * 1000;
|
file << freq * 1000;
|
||||||
file.close();
|
file.close();
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> FMRadio::adjustFreqByStep(fmradio::V1_0::Direction dir) {
|
Return<void> FMRadio::adjustFreqByStep(fmradio::V1_0::Direction dir) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
std::string value = "";
|
std::string value = "";
|
||||||
if (dir == V1_0::Direction::UP){
|
if (dir == V1_0::Direction::UP) {
|
||||||
value = "1 " + std::to_string(mChannelSpacing * 10);
|
value = "1 " + std::to_string(mChannelSpacing * 10);
|
||||||
} else if (dir == V1_0::Direction::DOWN){
|
} else if (dir == V1_0::Direction::DOWN) {
|
||||||
value = "0 " + std::to_string(mChannelSpacing * 10);
|
value = "0 " + std::to_string(mChannelSpacing * 10);
|
||||||
}
|
}
|
||||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_seek");
|
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_seek");
|
||||||
file << value;
|
file << value;
|
||||||
file.close();
|
file.close();
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
Return<V1_1::Status> FMRadio::isAvailable(){
|
Return<V1_1::Status> FMRadio::isAvailable() {
|
||||||
struct stat info;
|
struct stat info;
|
||||||
if(stat("/sys/devices/virtual/s610_radio/s610_radio/", &info ) != 0) {
|
if (stat("/sys/devices/virtual/s610_radio/s610_radio/", &info) != 0) {
|
||||||
return V1_1::Status::NO;
|
return V1_1::Status::NO;
|
||||||
} else {
|
} else {
|
||||||
return V1_1::Status::YES;
|
return V1_1::Status::YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Return<void> FMRadio::setChannelSpacing(V1_2::Space space){
|
Return<void> FMRadio::setChannelSpacing(V1_2::Space space) {
|
||||||
mChannelSpacing = (int) space;
|
mChannelSpacing = (int)space;
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
Return<int32_t> FMRadio::getFreqFromSysfs(){
|
Return<int32_t> FMRadio::getFreqFromSysfs() {
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
std::string value;
|
std::string value;
|
||||||
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
file.open("/sys/devices/virtual/s610_radio/s610_radio/radio_freq_ctrl");
|
||||||
std::getline(file, value);
|
std::getline(file, value);
|
||||||
file.close();
|
file.close();
|
||||||
return std::stoi(value);
|
return std::stoi(value);
|
||||||
}
|
|
||||||
Return<V1_2::Space> FMRadio::getChannelSpacing(){
|
|
||||||
switch (mChannelSpacing) {
|
|
||||||
case 1: return V1_2::Space::CHANNEL_SPACING_10HZ;
|
|
||||||
case 2: return V1_2::Space::CHANNEL_SPACING_20HZ;
|
|
||||||
case 3: return V1_2::Space::CHANNEL_SPACING_30HZ;
|
|
||||||
case 4: return V1_2::Space::CHANNEL_SPACING_40HZ;
|
|
||||||
case 5: return V1_2::Space::CHANNEL_SPACING_50HZ;
|
|
||||||
default: return V1_2::Space::CHANNEL_SPACING_30HZ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
IFMRadio* FMRadio::getInstance(void) {
|
Return<V1_2::Space> FMRadio::getChannelSpacing() {
|
||||||
return new FMRadio();
|
switch (mChannelSpacing) {
|
||||||
|
case 1:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_10HZ;
|
||||||
|
case 2:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_20HZ;
|
||||||
|
case 3:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_30HZ;
|
||||||
|
case 4:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_40HZ;
|
||||||
|
case 5:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_50HZ;
|
||||||
|
default:
|
||||||
|
return V1_2::Space::CHANNEL_SPACING_30HZ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace vendor::eureka::hardware::fmradio::V1_0
|
IFMRadio *FMRadio::getInstance(void) { return new FMRadio(); }
|
||||||
|
} // namespace vendor::eureka::hardware::fmradio::V1_2
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,16 @@ using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
|
|
||||||
struct FMRadio : public IFMRadio {
|
struct FMRadio : public IFMRadio {
|
||||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_0::IFMRadio follow.
|
// Methods from ::vendor::eureka::hardware::fmradio::V1_0::IFMRadio follow.
|
||||||
Return<void> setManualFreq(float freq);
|
Return<void> setManualFreq(float freq);
|
||||||
Return<void> adjustFreqByStep(V1_0::Direction dir);
|
Return<void> adjustFreqByStep(V1_0::Direction dir);
|
||||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_1::IFMRadio follow.
|
// Methods from ::vendor::eureka::hardware::fmradio::V1_1::IFMRadio follow.
|
||||||
Return<V1_1::Status> isAvailable();
|
Return<V1_1::Status> isAvailable();
|
||||||
Return<int32_t> getFreqFromSysfs();
|
Return<int32_t> getFreqFromSysfs();
|
||||||
// Methods from ::vendor::eureka::hardware::fmradio::V1_2::IFMRadio follow.
|
// Methods from ::vendor::eureka::hardware::fmradio::V1_2::IFMRadio follow.
|
||||||
Return<void> setChannelSpacing(V1_2::Space space);
|
Return<void> setChannelSpacing(V1_2::Space space);
|
||||||
Return<V1_2::Space> getChannelSpacing();
|
Return<V1_2::Space> getChannelSpacing();
|
||||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||||
static IFMRadio* getInstance(void);
|
static IFMRadio *getInstance(void);
|
||||||
};
|
};
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::fmradio::V1_2
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,21 @@ using vendor::eureka::hardware::fmradio::V1_2::FMRadio;
|
||||||
using vendor::eureka::hardware::fmradio::V1_2::IFMRadio;
|
using vendor::eureka::hardware::fmradio::V1_2::IFMRadio;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int ret;
|
int ret;
|
||||||
android::sp<IFMRadio> mFMService = FMRadio::getInstance();
|
android::sp<IFMRadio> mFMService = FMRadio::getInstance();
|
||||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||||
|
|
||||||
if (mFMService != nullptr) {
|
if (mFMService != nullptr) {
|
||||||
ret = mFMService->registerAsService();
|
ret = mFMService->registerAsService();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ALOGE("Can't register instance of FMRadio HAL, nullptr");
|
ALOGE("Can't register instance of FMRadio HAL, nullptr");
|
||||||
} else {
|
|
||||||
ALOGI("registered FMRadio HAL");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ALOGE("Can't create instance of FMRadio HAL, nullptr");
|
ALOGI("registered FMRadio HAL");
|
||||||
}
|
}
|
||||||
joinRpcThreadpool();
|
} else {
|
||||||
|
ALOGE("Can't create instance of FMRadio HAL, nullptr");
|
||||||
|
}
|
||||||
|
joinRpcThreadpool();
|
||||||
|
|
||||||
return -1; // should never get here
|
return -1; // should never get here
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,97 +13,99 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "Battery.h"
|
#include "Battery.h"
|
||||||
#include <unistd.h>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||||
|
|
||||||
// Methods from ::android::hardware::battery::V1_0::IBattery follow.
|
// Methods from ::android::hardware::battery::V1_0::IBattery follow.
|
||||||
Return<int32_t> BatteryStats::getBatteryStats(parts::V1_0::SysfsType stats) {
|
Return<int32_t> BatteryStats::getBatteryStats(parts::V1_0::SysfsType stats) {
|
||||||
std::ifstream file;
|
std::ifstream file;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
switch (stats) {
|
switch (stats) {
|
||||||
case SysfsType::CAPACITY_MAX:
|
case SysfsType::CAPACITY_MAX:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
||||||
break;
|
break;
|
||||||
case SysfsType::TEMP:
|
case SysfsType::TEMP:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
||||||
break;
|
break;
|
||||||
case SysfsType::CAPACITY_CURRENT:
|
case SysfsType::CAPACITY_CURRENT:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
||||||
break;
|
break;
|
||||||
case SysfsType::CURRENT:
|
case SysfsType::CURRENT:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
||||||
break;
|
break;
|
||||||
case SysfsType::FASTCHARGE:
|
case SysfsType::FASTCHARGE:
|
||||||
filename = "/sys/class/sec/switch/afc_disable";
|
filename = "/sys/class/sec/switch/afc_disable";
|
||||||
break;
|
break;
|
||||||
case SysfsType::CHARGE:
|
case SysfsType::CHARGE:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
filename =
|
||||||
break;
|
"/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
||||||
default:
|
break;
|
||||||
filename = "";
|
default:
|
||||||
break;
|
filename = "";
|
||||||
}
|
break;
|
||||||
std::string value;
|
}
|
||||||
int32_t intvalue;
|
std::string value;
|
||||||
file.open(filename);
|
int32_t intvalue;
|
||||||
if (file.is_open()) {
|
file.open(filename);
|
||||||
getline(file, value);
|
if (file.is_open()) {
|
||||||
file.close();
|
getline(file, value);
|
||||||
std::stringstream val(value);
|
file.close();
|
||||||
val >> intvalue;
|
std::stringstream val(value);
|
||||||
return intvalue;
|
val >> intvalue;
|
||||||
}
|
return intvalue;
|
||||||
return -1;
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> BatteryStats::setBatteryWritable(parts::V1_0::SysfsType stats,
|
Return<void> BatteryStats::setBatteryWritable(parts::V1_0::SysfsType stats,
|
||||||
parts::V1_0::Number value) {
|
parts::V1_0::Number value) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
bool FastCharge = false;
|
bool FastCharge = false;
|
||||||
switch (stats) {
|
switch (stats) {
|
||||||
case SysfsType::CAPACITY_MAX:
|
case SysfsType::CAPACITY_MAX:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
filename = "/sys/devices/platform/battery/power_supply/battery/charge_full";
|
||||||
break;
|
break;
|
||||||
case SysfsType::TEMP:
|
case SysfsType::TEMP:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
filename = "/sys/devices/platform/battery/power_supply/battery/batt_temp";
|
||||||
break;
|
break;
|
||||||
case SysfsType::CAPACITY_CURRENT:
|
case SysfsType::CAPACITY_CURRENT:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
filename = "/sys/devices/platform/battery/power_supply/battery/capacity";
|
||||||
break;
|
break;
|
||||||
case SysfsType::CURRENT:
|
case SysfsType::CURRENT:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
filename = "/sys/devices/platform/battery/power_supply/battery/current_now";
|
||||||
break;
|
break;
|
||||||
case SysfsType::FASTCHARGE:
|
case SysfsType::FASTCHARGE:
|
||||||
filename = "/sys/class/sec/switch/afc_disable";
|
filename = "/sys/class/sec/switch/afc_disable";
|
||||||
FastCharge = true;
|
FastCharge = true;
|
||||||
break;
|
break;
|
||||||
case SysfsType::CHARGE:
|
case SysfsType::CHARGE:
|
||||||
filename = "/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
filename =
|
||||||
break;
|
"/sys/devices/platform/battery/power_supply/battery/batt_slate_mode";
|
||||||
default:
|
break;
|
||||||
filename = "";
|
default:
|
||||||
break;
|
filename = "";
|
||||||
}
|
break;
|
||||||
if (FastCharge) seteuid(ANDROID_SYSTEM_UID);
|
}
|
||||||
file.open(filename);
|
if (FastCharge)
|
||||||
int write;
|
seteuid(ANDROID_SYSTEM_UID);
|
||||||
if (value == Number::ENABLE) {
|
file.open(filename);
|
||||||
write = 1;
|
int write;
|
||||||
} else {
|
if (value == Number::ENABLE) {
|
||||||
write = 0;
|
write = 1;
|
||||||
}
|
} else {
|
||||||
file << write;
|
write = 0;
|
||||||
file.close();
|
}
|
||||||
if (FastCharge) seteuid(ANDROID_ROOT_UID);
|
file << write;
|
||||||
return Void();
|
file.close();
|
||||||
|
if (FastCharge)
|
||||||
|
seteuid(ANDROID_ROOT_UID);
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
IBatteryStats* BatteryStats::getInstance(void) {
|
IBatteryStats *BatteryStats::getInstance(void) { return new BatteryStats(); }
|
||||||
return new BatteryStats();
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
}
|
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
|
|
||||||
struct BatteryStats : public IBatteryStats {
|
struct BatteryStats : public IBatteryStats {
|
||||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IBatteryStats follow.
|
// Methods from ::vendor::eureka::hardware::parts::V1_0::IBatteryStats follow.
|
||||||
Return<int32_t> getBatteryStats(SysfsType stats) override;
|
Return<int32_t> getBatteryStats(SysfsType stats) override;
|
||||||
Return<void> setBatteryWritable(SysfsType stats, Number value) override;
|
Return<void> setBatteryWritable(SysfsType stats, Number value) override;
|
||||||
|
|
||||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||||
static IBatteryStats* getInstance(void);
|
static IBatteryStats *getInstance(void);
|
||||||
};
|
};
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
|
|
|
||||||
|
|
@ -18,27 +18,28 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
namespace vendor::eureka::hardware::parts::V1_0 {
|
namespace vendor::eureka::hardware::parts::V1_0 {
|
||||||
|
|
||||||
Return<void> DisplayConfigs::writeDisplay(parts::V1_0::Number enable, parts::V1_0::Display type) {
|
Return<void> DisplayConfigs::writeDisplay(parts::V1_0::Number enable,
|
||||||
std::ofstream file;
|
parts::V1_0::Display type) {
|
||||||
std::string writevalue;
|
std::ofstream file;
|
||||||
if (type == Display::DOUBLE_TAP){
|
std::string writevalue;
|
||||||
writevalue = "aot_enable";
|
if (type == Display::DOUBLE_TAP) {
|
||||||
} else if (type == Display::GLOVE_MODE){
|
writevalue = "aot_enable";
|
||||||
writevalue = "glove_mode";
|
} else if (type == Display::GLOVE_MODE) {
|
||||||
}
|
writevalue = "glove_mode";
|
||||||
|
}
|
||||||
|
|
||||||
if (enable == Number::ENABLE) {
|
if (enable == Number::ENABLE) {
|
||||||
writevalue += ",1";
|
writevalue += ",1";
|
||||||
} else {
|
} else {
|
||||||
writevalue += ",0";
|
writevalue += ",0";
|
||||||
}
|
}
|
||||||
file.open("/sys/class/sec/tsp/cmd");
|
file.open("/sys/class/sec/tsp/cmd");
|
||||||
file << writevalue;
|
file << writevalue;
|
||||||
file.close();
|
file.close();
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
IDisplayConfigs* DisplayConfigs::getInstance(void) {
|
IDisplayConfigs *DisplayConfigs::getInstance(void) {
|
||||||
return new DisplayConfigs();
|
return new DisplayConfigs();
|
||||||
}
|
}
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,10 @@ using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
|
|
||||||
struct DisplayConfigs : public IDisplayConfigs {
|
struct DisplayConfigs : public IDisplayConfigs {
|
||||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IDisplayConfigs follow.
|
// Methods from ::vendor::eureka::hardware::parts::V1_0::IDisplayConfigs
|
||||||
Return<void> writeDisplay(Number enable, Display type);
|
// follow.
|
||||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
Return<void> writeDisplay(Number enable, Display type);
|
||||||
static IDisplayConfigs* getInstance(void);
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||||
|
static IDisplayConfigs *getInstance(void);
|
||||||
};
|
};
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
|
|
|
||||||
|
|
@ -20,91 +20,92 @@ namespace vendor::eureka::hardware::parts::V1_0 {
|
||||||
|
|
||||||
// Methods from ::android::hardware::parts::V1_0::IFlashLight follow.
|
// Methods from ::android::hardware::parts::V1_0::IFlashLight follow.
|
||||||
Return<void> FlashBrightness::setFlashlightEnable(parts::V1_0::Number enable) {
|
Return<void> FlashBrightness::setFlashlightEnable(parts::V1_0::Number enable) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
std::string writevalue;
|
std::string writevalue;
|
||||||
switch (enable) {
|
switch (enable) {
|
||||||
case Number::ENABLE:
|
case Number::ENABLE:
|
||||||
writevalue = "1";
|
writevalue = "1";
|
||||||
break;
|
break;
|
||||||
case Number::DISABLE:
|
case Number::DISABLE:
|
||||||
writevalue = "0";
|
writevalue = "0";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
writevalue = "";
|
writevalue = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file.open("/sys/class/camera/flash/torch_brightness_lvl_enable");
|
file.open("/sys/class/camera/flash/torch_brightness_lvl_enable");
|
||||||
file << writevalue;
|
file << writevalue;
|
||||||
file.close();
|
file.close();
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> FlashBrightness::setFlashlightWritable(parts::V1_0::Value value) {
|
Return<void> FlashBrightness::setFlashlightWritable(parts::V1_0::Value value) {
|
||||||
std::ofstream file;
|
std::ofstream file;
|
||||||
std::string writevalue;
|
std::string writevalue;
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case Value::ONEUI:
|
case Value::ONEUI:
|
||||||
writevalue = "1";
|
writevalue = "1";
|
||||||
break;
|
break;
|
||||||
case Value::TWOUI:
|
case Value::TWOUI:
|
||||||
writevalue = "2";
|
writevalue = "2";
|
||||||
break;
|
break;
|
||||||
case Value::THREEUI:
|
case Value::THREEUI:
|
||||||
writevalue = "3";
|
writevalue = "3";
|
||||||
break;
|
break;
|
||||||
case Value::FOURUI:
|
case Value::FOURUI:
|
||||||
writevalue = "4";
|
writevalue = "4";
|
||||||
break;
|
break;
|
||||||
case Value::FIVEUI:
|
case Value::FIVEUI:
|
||||||
writevalue = "5";
|
writevalue = "5";
|
||||||
break;
|
break;
|
||||||
case Value::SIXUI:
|
case Value::SIXUI:
|
||||||
writevalue = "6";
|
writevalue = "6";
|
||||||
break;
|
break;
|
||||||
case Value::SEVENUI:
|
case Value::SEVENUI:
|
||||||
writevalue = "7";
|
writevalue = "7";
|
||||||
break;
|
break;
|
||||||
case Value::EIGHTUI:
|
case Value::EIGHTUI:
|
||||||
writevalue = "8";
|
writevalue = "8";
|
||||||
break;
|
break;
|
||||||
case Value::NINEUI:
|
case Value::NINEUI:
|
||||||
writevalue = "9";
|
writevalue = "9";
|
||||||
break;
|
break;
|
||||||
case Value::TENUI:
|
case Value::TENUI:
|
||||||
writevalue = "10";
|
writevalue = "10";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
writevalue = "";
|
writevalue = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
||||||
file << writevalue;
|
file << writevalue;
|
||||||
|
file.close();
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<int32_t>
|
||||||
|
FlashBrightness::readFlashlightstats(parts::V1_0::Device device) {
|
||||||
|
std::ifstream file;
|
||||||
|
std::string value;
|
||||||
|
int32_t intvalue;
|
||||||
|
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
||||||
|
if (file.is_open()) {
|
||||||
|
getline(file, value);
|
||||||
file.close();
|
file.close();
|
||||||
return Void();
|
std::stringstream val(value);
|
||||||
}
|
val >> intvalue;
|
||||||
|
if (device == Device::A10) {
|
||||||
Return<int32_t> FlashBrightness::readFlashlightstats(parts::V1_0::Device device) {
|
return intvalue;
|
||||||
std::ifstream file;
|
} else if (device == Device::NOTA10) {
|
||||||
std::string value;
|
return intvalue / 21;
|
||||||
int32_t intvalue;
|
|
||||||
file.open("/sys/class/camera/flash/torch_brightness_lvl");
|
|
||||||
if (file.is_open()) {
|
|
||||||
getline(file, value);
|
|
||||||
file.close();
|
|
||||||
std::stringstream val(value);
|
|
||||||
val >> intvalue;
|
|
||||||
if (device == Device::A10) {
|
|
||||||
return intvalue;
|
|
||||||
} else if (device == Device::NOTA10) {
|
|
||||||
return intvalue / 21;
|
|
||||||
}
|
|
||||||
// Never Here
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
// Never Here
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFlashBrightness* FlashBrightness::getInstance(void) {
|
IFlashBrightness *FlashBrightness::getInstance(void) {
|
||||||
return new FlashBrightness();
|
return new FlashBrightness();
|
||||||
}
|
}
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
|
|
|
||||||
|
|
@ -29,11 +29,12 @@ using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
|
|
||||||
struct FlashBrightness : public IFlashBrightness {
|
struct FlashBrightness : public IFlashBrightness {
|
||||||
// Methods from ::vendor::eureka::hardware::parts::V1_0::IFlashBrightness follow.
|
// Methods from ::vendor::eureka::hardware::parts::V1_0::IFlashBrightness
|
||||||
Return<void> setFlashlightEnable(Number enable);
|
// follow.
|
||||||
Return<void> setFlashlightWritable(Value value);
|
Return<void> setFlashlightEnable(Number enable);
|
||||||
Return<int32_t> readFlashlightstats(Device device);
|
Return<void> setFlashlightWritable(Value value);
|
||||||
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
Return<int32_t> readFlashlightstats(Device device);
|
||||||
static IFlashBrightness* getInstance(void);
|
// Methods from ::android::hidl::base::V1_0::IBase follow.
|
||||||
|
static IFlashBrightness *getInstance(void);
|
||||||
};
|
};
|
||||||
} // namespace vendor::eureka::hardware::parts::V1_0
|
} // namespace vendor::eureka::hardware::parts::V1_0
|
||||||
|
|
|
||||||
|
|
@ -14,63 +14,64 @@
|
||||||
|
|
||||||
#define LOG_TAG "vendor.eureka.hardware.parts@1.0-service"
|
#define LOG_TAG "vendor.eureka.hardware.parts@1.0-service"
|
||||||
|
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
|
||||||
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
|
||||||
#include <hidl/LegacySupport.h>
|
#include <hidl/LegacySupport.h>
|
||||||
|
#include <vendor/eureka/hardware/parts/1.0/IBatteryStats.h>
|
||||||
|
#include <vendor/eureka/hardware/parts/1.0/IDisplayConfigs.h>
|
||||||
|
#include <vendor/eureka/hardware/parts/1.0/IFlashBrightness.h>
|
||||||
|
|
||||||
#include "Battery.h"
|
#include "Battery.h"
|
||||||
#include "FlashLight.h"
|
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
#include "FlashLight.h"
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
using android::hardware::configureRpcThreadpool;
|
using android::hardware::configureRpcThreadpool;
|
||||||
using android::hardware::joinRpcThreadpool;
|
using android::hardware::joinRpcThreadpool;
|
||||||
using vendor::eureka::hardware::parts::V1_0::BatteryStats;
|
using vendor::eureka::hardware::parts::V1_0::BatteryStats;
|
||||||
using vendor::eureka::hardware::parts::V1_0::IBatteryStats;
|
|
||||||
using vendor::eureka::hardware::parts::V1_0::FlashBrightness;
|
|
||||||
using vendor::eureka::hardware::parts::V1_0::IFlashBrightness;
|
|
||||||
using vendor::eureka::hardware::parts::V1_0::DisplayConfigs;
|
using vendor::eureka::hardware::parts::V1_0::DisplayConfigs;
|
||||||
|
using vendor::eureka::hardware::parts::V1_0::FlashBrightness;
|
||||||
|
using vendor::eureka::hardware::parts::V1_0::IBatteryStats;
|
||||||
using vendor::eureka::hardware::parts::V1_0::IDisplayConfigs;
|
using vendor::eureka::hardware::parts::V1_0::IDisplayConfigs;
|
||||||
|
using vendor::eureka::hardware::parts::V1_0::IFlashBrightness;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int ret;
|
int ret;
|
||||||
android::sp<IBatteryStats> mBatteryService = BatteryStats::getInstance();
|
android::sp<IBatteryStats> mBatteryService = BatteryStats::getInstance();
|
||||||
android::sp<IFlashBrightness> mFlashLightService = FlashBrightness::getInstance();
|
android::sp<IFlashBrightness> mFlashLightService =
|
||||||
android::sp<IDisplayConfigs> mDisplayService = DisplayConfigs::getInstance();
|
FlashBrightness::getInstance();
|
||||||
configureRpcThreadpool(4, true /*callerWillJoin*/);
|
android::sp<IDisplayConfigs> mDisplayService = DisplayConfigs::getInstance();
|
||||||
|
configureRpcThreadpool(4, true /*callerWillJoin*/);
|
||||||
|
|
||||||
if (mBatteryService != nullptr) {
|
if (mBatteryService != nullptr) {
|
||||||
ret = mBatteryService->registerAsService();
|
ret = mBatteryService->registerAsService();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
ALOGE("Can't register instance of Battery HAL, nullptr");
|
ALOGE("Can't register instance of Battery HAL, nullptr");
|
||||||
} else {
|
|
||||||
ALOGI("registered Battery HAL");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ALOGE("Can't create instance of Battery HAL, nullptr");
|
ALOGI("registered Battery HAL");
|
||||||
}
|
}
|
||||||
if (mFlashLightService != nullptr) {
|
} else {
|
||||||
ret = mFlashLightService->registerAsService();
|
ALOGE("Can't create instance of Battery HAL, nullptr");
|
||||||
if (ret != 0) {
|
}
|
||||||
ALOGE("Can't register instance of FlashLight HAL, nullptr");
|
if (mFlashLightService != nullptr) {
|
||||||
} else {
|
ret = mFlashLightService->registerAsService();
|
||||||
ALOGI("registered FlashLight HAL");
|
if (ret != 0) {
|
||||||
}
|
ALOGE("Can't register instance of FlashLight HAL, nullptr");
|
||||||
} else {
|
} else {
|
||||||
ALOGE("Can't create instance of FlashLight HAL, nullptr");
|
ALOGI("registered FlashLight HAL");
|
||||||
}
|
}
|
||||||
if (mDisplayService != nullptr) {
|
} else {
|
||||||
ret = mDisplayService->registerAsService();
|
ALOGE("Can't create instance of FlashLight HAL, nullptr");
|
||||||
if (ret != 0) {
|
}
|
||||||
ALOGE("Can't register instance of Display HAL, nullptr");
|
if (mDisplayService != nullptr) {
|
||||||
} else {
|
ret = mDisplayService->registerAsService();
|
||||||
ALOGI("registered Display HAL");
|
if (ret != 0) {
|
||||||
}
|
ALOGE("Can't register instance of Display HAL, nullptr");
|
||||||
} else {
|
} else {
|
||||||
ALOGE("Can't create instance of Display HAL, nullptr");
|
ALOGI("registered Display HAL");
|
||||||
}
|
}
|
||||||
joinRpcThreadpool();
|
} else {
|
||||||
|
ALOGE("Can't create instance of Display HAL, nullptr");
|
||||||
|
}
|
||||||
|
joinRpcThreadpool();
|
||||||
|
|
||||||
return -1; // should never get here
|
return -1; // should never get here
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,172 +22,175 @@ namespace light {
|
||||||
/*
|
/*
|
||||||
* Write value to path and close file.
|
* Write value to path and close file.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T> static void set(const std::string &path, const T &value) {
|
||||||
static void set(const std::string& path, const T& value) {
|
std::ofstream file(path);
|
||||||
std::ofstream file(path);
|
file << value << std::endl;
|
||||||
file << value << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T> static T get(const std::string &path, const T &def) {
|
||||||
static T get(const std::string& path, const T& def) {
|
std::ifstream file(path);
|
||||||
std::ifstream file(path);
|
T result;
|
||||||
T result;
|
|
||||||
|
|
||||||
file >> result;
|
file >> result;
|
||||||
return file.fail() ? def : result;
|
return file.fail() ? def : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lights::Lights() {
|
Lights::Lights() {
|
||||||
mLights.emplace(LightType::BACKLIGHT,
|
mLights.emplace(LightType::BACKLIGHT, std::bind(&Lights::handleBacklight,
|
||||||
std::bind(&Lights::handleBacklight, this, std::placeholders::_1));
|
this, std::placeholders::_1));
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||||
mLights.emplace(LightType::BUTTONS,
|
mLights.emplace(LightType::BUTTONS, std::bind(&Lights::handleButtons, this,
|
||||||
std::bind(&Lights::handleButtons, this, std::placeholders::_1));
|
std::placeholders::_1));
|
||||||
#endif /* BUTTON_BRIGHTNESS_NODE */
|
#endif /* BUTTON_BRIGHTNESS_NODE */
|
||||||
#ifdef LED_BLINK_NODE
|
#ifdef LED_BLINK_NODE
|
||||||
mLights.emplace(LightType::BATTERY,
|
mLights.emplace(LightType::BATTERY, std::bind(&Lights::handleBattery, this,
|
||||||
std::bind(&Lights::handleBattery, this, std::placeholders::_1));
|
std::placeholders::_1));
|
||||||
mLights.emplace(LightType::NOTIFICATIONS,
|
mLights.emplace(
|
||||||
std::bind(&Lights::handleNotifications, this, std::placeholders::_1));
|
LightType::NOTIFICATIONS,
|
||||||
mLights.emplace(LightType::ATTENTION,
|
std::bind(&Lights::handleNotifications, this, std::placeholders::_1));
|
||||||
std::bind(&Lights::handleAttention, this, std::placeholders::_1));
|
mLights.emplace(LightType::ATTENTION, std::bind(&Lights::handleAttention,
|
||||||
|
this, std::placeholders::_1));
|
||||||
#endif /* LED_BLINK_NODE */
|
#endif /* LED_BLINK_NODE */
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) {
|
ndk::ScopedAStatus Lights::setLightState(int32_t id,
|
||||||
LightType type = static_cast<LightType>(id);
|
const HwLightState &state) {
|
||||||
auto it = mLights.find(type);
|
LightType type = static_cast<LightType>(id);
|
||||||
|
auto it = mLights.find(type);
|
||||||
|
|
||||||
if (it == mLights.end()) {
|
if (it == mLights.end()) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock global mutex until light state is updated.
|
* Lock global mutex until light state is updated.
|
||||||
*/
|
*/
|
||||||
std::lock_guard<std::mutex> lock(mLock);
|
std::lock_guard<std::mutex> lock(mLock);
|
||||||
|
|
||||||
it->second(state);
|
it->second(state);
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lights::handleBacklight(const HwLightState& state) {
|
void Lights::handleBacklight(const HwLightState &state) {
|
||||||
uint32_t max_brightness = get(PANEL_MAX_BRIGHTNESS_NODE, MAX_INPUT_BRIGHTNESS);
|
uint32_t max_brightness =
|
||||||
uint32_t brightness = rgbToBrightness(state);
|
get(PANEL_MAX_BRIGHTNESS_NODE, MAX_INPUT_BRIGHTNESS);
|
||||||
|
uint32_t brightness = rgbToBrightness(state);
|
||||||
|
|
||||||
if (max_brightness != MAX_INPUT_BRIGHTNESS) {
|
if (max_brightness != MAX_INPUT_BRIGHTNESS) {
|
||||||
brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS;
|
brightness = brightness * max_brightness / MAX_INPUT_BRIGHTNESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(PANEL_BRIGHTNESS_NODE, brightness);
|
set(PANEL_BRIGHTNESS_NODE, brightness);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||||
void Lights::handleButtons(const HwLightState& state) {
|
void Lights::handleButtons(const HwLightState &state) {
|
||||||
#ifdef VAR_BUTTON_BRIGHTNESS
|
#ifdef VAR_BUTTON_BRIGHTNESS
|
||||||
uint32_t brightness = rgbToBrightness(state);
|
uint32_t brightness = rgbToBrightness(state);
|
||||||
#else
|
#else
|
||||||
uint32_t brightness = (state.color & COLOR_MASK) ? 1 : 0;
|
uint32_t brightness = (state.color & COLOR_MASK) ? 1 : 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set(BUTTON_BRIGHTNESS_NODE, brightness);
|
set(BUTTON_BRIGHTNESS_NODE, brightness);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LED_BLINK_NODE
|
#ifdef LED_BLINK_NODE
|
||||||
void Lights::handleBattery(const HwLightState& state) {
|
void Lights::handleBattery(const HwLightState &state) {
|
||||||
mBatteryState = state;
|
mBatteryState = state;
|
||||||
setNotificationLED();
|
setNotificationLED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lights::handleNotifications(const HwLightState& state) {
|
void Lights::handleNotifications(const HwLightState &state) {
|
||||||
mNotificationState = state;
|
mNotificationState = state;
|
||||||
setNotificationLED();
|
setNotificationLED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lights::handleAttention(const HwLightState& state) {
|
void Lights::handleAttention(const HwLightState &state) {
|
||||||
mAttentionState = state;
|
mAttentionState = state;
|
||||||
setNotificationLED();
|
setNotificationLED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lights::setNotificationLED() {
|
void Lights::setNotificationLED() {
|
||||||
int32_t adjusted_brightness = MAX_INPUT_BRIGHTNESS;
|
int32_t adjusted_brightness = MAX_INPUT_BRIGHTNESS;
|
||||||
HwLightState state;
|
HwLightState state;
|
||||||
#ifdef LED_BLN_NODE
|
#ifdef LED_BLN_NODE
|
||||||
bool bln = false;
|
bool bln = false;
|
||||||
#endif /* LED_BLN_NODE */
|
#endif /* LED_BLN_NODE */
|
||||||
|
|
||||||
if (mNotificationState.color & COLOR_MASK) {
|
if (mNotificationState.color & COLOR_MASK) {
|
||||||
adjusted_brightness = LED_BRIGHTNESS_NOTIFICATION;
|
adjusted_brightness = LED_BRIGHTNESS_NOTIFICATION;
|
||||||
state = mNotificationState;
|
state = mNotificationState;
|
||||||
#ifdef LED_BLN_NODE
|
#ifdef LED_BLN_NODE
|
||||||
bln = true;
|
bln = true;
|
||||||
#endif /* LED_BLN_NODE */
|
#endif /* LED_BLN_NODE */
|
||||||
} else if (mAttentionState.color & COLOR_MASK) {
|
} else if (mAttentionState.color & COLOR_MASK) {
|
||||||
adjusted_brightness = LED_BRIGHTNESS_ATTENTION;
|
adjusted_brightness = LED_BRIGHTNESS_ATTENTION;
|
||||||
state = mAttentionState;
|
state = mAttentionState;
|
||||||
if (state.flashMode == FlashMode::HARDWARE) {
|
if (state.flashMode == FlashMode::HARDWARE) {
|
||||||
if (state.flashOnMs > 0 && state.flashOffMs == 0) state.flashMode = FlashMode::NONE;
|
if (state.flashOnMs > 0 && state.flashOffMs == 0)
|
||||||
state.color = 0x000000ff;
|
state.flashMode = FlashMode::NONE;
|
||||||
}
|
state.color = 0x000000ff;
|
||||||
if (state.flashMode == FlashMode::NONE) {
|
|
||||||
state.color = 0;
|
|
||||||
}
|
|
||||||
} else if (mBatteryState.color & COLOR_MASK) {
|
|
||||||
adjusted_brightness = LED_BRIGHTNESS_BATTERY;
|
|
||||||
state = mBatteryState;
|
|
||||||
} else {
|
|
||||||
set(LED_BLINK_NODE, "0x00000000 0 0");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.flashMode == FlashMode::NONE) {
|
if (state.flashMode == FlashMode::NONE) {
|
||||||
state.flashOnMs = 0;
|
state.color = 0;
|
||||||
state.flashOffMs = 0;
|
|
||||||
}
|
}
|
||||||
|
} else if (mBatteryState.color & COLOR_MASK) {
|
||||||
|
adjusted_brightness = LED_BRIGHTNESS_BATTERY;
|
||||||
|
state = mBatteryState;
|
||||||
|
} else {
|
||||||
|
set(LED_BLINK_NODE, "0x00000000 0 0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
state.color = calibrateColor(state.color & COLOR_MASK, adjusted_brightness);
|
if (state.flashMode == FlashMode::NONE) {
|
||||||
set(LED_BLINK_NODE, ::android::base::StringPrintf("0x%08x %d %d", state.color, state.flashOnMs,
|
state.flashOnMs = 0;
|
||||||
state.flashOffMs));
|
state.flashOffMs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.color = calibrateColor(state.color & COLOR_MASK, adjusted_brightness);
|
||||||
|
set(LED_BLINK_NODE,
|
||||||
|
::android::base::StringPrintf("0x%08x %d %d", state.color,
|
||||||
|
state.flashOnMs, state.flashOffMs));
|
||||||
|
|
||||||
#ifdef LED_BLN_NODE
|
#ifdef LED_BLN_NODE
|
||||||
if (bln) {
|
if (bln) {
|
||||||
set(LED_BLN_NODE, (state.color & COLOR_MASK) ? 1 : 0);
|
set(LED_BLN_NODE, (state.color & COLOR_MASK) ? 1 : 0);
|
||||||
}
|
}
|
||||||
#endif /* LED_BLN_NODE */
|
#endif /* LED_BLN_NODE */
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Lights::calibrateColor(uint32_t color, int32_t brightness) {
|
uint32_t Lights::calibrateColor(uint32_t color, int32_t brightness) {
|
||||||
uint32_t red = ((color >> 16) & 0xFF) * LED_ADJUSTMENT_R;
|
uint32_t red = ((color >> 16) & 0xFF) * LED_ADJUSTMENT_R;
|
||||||
uint32_t green = ((color >> 8) & 0xFF) * LED_ADJUSTMENT_G;
|
uint32_t green = ((color >> 8) & 0xFF) * LED_ADJUSTMENT_G;
|
||||||
uint32_t blue = (color & 0xFF) * LED_ADJUSTMENT_B;
|
uint32_t blue = (color & 0xFF) * LED_ADJUSTMENT_B;
|
||||||
|
|
||||||
return (((red * brightness) / 255) << 16) + (((green * brightness) / 255) << 8) +
|
return (((red * brightness) / 255) << 16) +
|
||||||
((blue * brightness) / 255);
|
(((green * brightness) / 255) << 8) + ((blue * brightness) / 255);
|
||||||
}
|
}
|
||||||
#endif /* LED_BLINK_NODE */
|
#endif /* LED_BLINK_NODE */
|
||||||
|
|
||||||
#define AutoHwLight(light) \
|
#define AutoHwLight(light) \
|
||||||
{ .id = (int32_t)light, .type = light, .ordinal = 0 }
|
{ .id = (int32_t)light, .type = light, .ordinal = 0 }
|
||||||
|
|
||||||
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight>* _aidl_return) {
|
ndk::ScopedAStatus Lights::getLights(std::vector<HwLight> *_aidl_return) {
|
||||||
for (auto const& light : mLights) {
|
for (auto const &light : mLights) {
|
||||||
_aidl_return->push_back(AutoHwLight(light.first));
|
_aidl_return->push_back(AutoHwLight(light.first));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Lights::rgbToBrightness(const HwLightState& state) {
|
uint32_t Lights::rgbToBrightness(const HwLightState &state) {
|
||||||
uint32_t color = state.color & COLOR_MASK;
|
uint32_t color = state.color & COLOR_MASK;
|
||||||
|
|
||||||
return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) +
|
return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) +
|
||||||
(29 * (color & 0xff))) >>
|
(29 * (color & 0xff))) >>
|
||||||
8;
|
8;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace light
|
} // namespace light
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
} // namespace aidl
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "samsung_lights.h"
|
||||||
#include <aidl/android/hardware/light/BnLights.h>
|
#include <aidl/android/hardware/light/BnLights.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "samsung_lights.h"
|
|
||||||
|
|
||||||
using ::aidl::android::hardware::light::HwLight;
|
using ::aidl::android::hardware::light::HwLight;
|
||||||
using ::aidl::android::hardware::light::HwLightState;
|
using ::aidl::android::hardware::light::HwLightState;
|
||||||
|
|
@ -19,36 +19,38 @@ namespace hardware {
|
||||||
namespace light {
|
namespace light {
|
||||||
|
|
||||||
class Lights : public BnLights {
|
class Lights : public BnLights {
|
||||||
public:
|
public:
|
||||||
Lights();
|
Lights();
|
||||||
|
|
||||||
ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override;
|
ndk::ScopedAStatus setLightState(int32_t id,
|
||||||
ndk::ScopedAStatus getLights(std::vector<HwLight>* _aidl_return) override;
|
const HwLightState &state) override;
|
||||||
|
ndk::ScopedAStatus getLights(std::vector<HwLight> *_aidl_return) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleBacklight(const HwLightState& state);
|
void handleBacklight(const HwLightState &state);
|
||||||
#ifdef BUTTON_BRIGHTNESS_NODE
|
#ifdef BUTTON_BRIGHTNESS_NODE
|
||||||
void handleButtons(const HwLightState& state);
|
void handleButtons(const HwLightState &state);
|
||||||
#endif /* BUTTON_BRIGHTNESS_NODE */
|
#endif /* BUTTON_BRIGHTNESS_NODE */
|
||||||
#ifdef LED_BLINK_NODE
|
#ifdef LED_BLINK_NODE
|
||||||
void handleBattery(const HwLightState& state);
|
void handleBattery(const HwLightState &state);
|
||||||
void handleNotifications(const HwLightState& state);
|
void handleNotifications(const HwLightState &state);
|
||||||
void handleAttention(const HwLightState& state);
|
void handleAttention(const HwLightState &state);
|
||||||
void setNotificationLED();
|
void setNotificationLED();
|
||||||
uint32_t calibrateColor(uint32_t color, int32_t brightness);
|
uint32_t calibrateColor(uint32_t color, int32_t brightness);
|
||||||
|
|
||||||
HwLightState mAttentionState;
|
HwLightState mAttentionState;
|
||||||
HwLightState mBatteryState;
|
HwLightState mBatteryState;
|
||||||
HwLightState mNotificationState;
|
HwLightState mNotificationState;
|
||||||
#endif /* LED_BLINK_NODE */
|
#endif /* LED_BLINK_NODE */
|
||||||
|
|
||||||
uint32_t rgbToBrightness(const HwLightState& state);
|
uint32_t rgbToBrightness(const HwLightState &state);
|
||||||
|
|
||||||
std::mutex mLock;
|
std::mutex mLock;
|
||||||
std::unordered_map<LightType, std::function<void(const HwLightState&)>> mLights;
|
std::unordered_map<LightType, std::function<void(const HwLightState &)>>
|
||||||
|
mLights;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace light
|
} // namespace light
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
} // namespace aidl
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
#define LED_BLN_NODE "/sys/class/misc/backlightnotification/notification_led"
|
#define LED_BLN_NODE "/sys/class/misc/backlightnotification/notification_led"
|
||||||
|
|
||||||
// Uncomment to enable variable button brightness
|
// Uncomment to enable variable button brightness
|
||||||
//#define VAR_BUTTON_BRIGHTNESS 1
|
// #define VAR_BUTTON_BRIGHTNESS 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Brightness adjustment factors
|
* Brightness adjustment factors
|
||||||
|
|
@ -55,4 +55,4 @@
|
||||||
#define LED_BRIGHTNESS_NOTIFICATION 255
|
#define LED_BRIGHTNESS_NOTIFICATION 255
|
||||||
#define LED_BRIGHTNESS_ATTENTION 255
|
#define LED_BRIGHTNESS_ATTENTION 255
|
||||||
|
|
||||||
#endif // SAMSUNG_LIGHTS_H
|
#endif // SAMSUNG_LIGHTS_H
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,14 @@
|
||||||
using ::aidl::android::hardware::light::Lights;
|
using ::aidl::android::hardware::light::Lights;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||||
std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();
|
std::shared_ptr<Lights> lights = ndk::SharedRefBase::make<Lights>();
|
||||||
|
|
||||||
const std::string instance = std::string() + Lights::descriptor + "/default";
|
const std::string instance = std::string() + Lights::descriptor + "/default";
|
||||||
binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str());
|
binder_status_t status =
|
||||||
CHECK(status == STATUS_OK);
|
AServiceManager_addService(lights->asBinder().get(), instance.c_str());
|
||||||
|
CHECK(status == STATUS_OK);
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool();
|
ABinderProcess_joinThreadPool();
|
||||||
return EXIT_FAILURE; // should not reach
|
return EXIT_FAILURE; // should not reach
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@
|
||||||
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <memory>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <sys/eventfd.h>
|
#include <sys/eventfd.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
#include <utils/Trace.h>
|
#include <utils/Trace.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "InteractionHandler.h"
|
#include "InteractionHandler.h"
|
||||||
|
|
||||||
|
|
@ -33,227 +33,233 @@
|
||||||
#define MSINSEC 1000L
|
#define MSINSEC 1000L
|
||||||
#define USINMS 1000000L
|
#define USINMS 1000000L
|
||||||
|
|
||||||
static const std::vector<std::string> fb_idle_patch = {"/sys/class/drm/card0/device/idle_state",
|
static const std::vector<std::string> fb_idle_patch = {
|
||||||
"/sys/class/graphics/fb0/idle_state"};
|
"/sys/class/drm/card0/device/idle_state",
|
||||||
|
"/sys/class/graphics/fb0/idle_state"};
|
||||||
|
|
||||||
InteractionHandler::InteractionHandler(std::shared_ptr<HintManager> const& hint_manager)
|
InteractionHandler::InteractionHandler(
|
||||||
: mState(INTERACTION_STATE_UNINITIALIZED),
|
std::shared_ptr<HintManager> const &hint_manager)
|
||||||
mWaitMs(100),
|
: mState(INTERACTION_STATE_UNINITIALIZED), mWaitMs(100),
|
||||||
mMinDurationMs(1400),
|
mMinDurationMs(1400), mMaxDurationMs(5650), mDurationMs(0),
|
||||||
mMaxDurationMs(5650),
|
|
||||||
mDurationMs(0),
|
|
||||||
mHintManager(hint_manager) {}
|
mHintManager(hint_manager) {}
|
||||||
|
|
||||||
InteractionHandler::~InteractionHandler() {
|
InteractionHandler::~InteractionHandler() { Exit(); }
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fb_idle_open(void) {
|
static int fb_idle_open(void) {
|
||||||
int fd;
|
int fd;
|
||||||
for (auto& path : fb_idle_patch) {
|
for (auto &path : fb_idle_patch) {
|
||||||
fd = open(path.c_str(), O_RDONLY);
|
fd = open(path.c_str(), O_RDONLY);
|
||||||
if (fd >= 0) return fd;
|
if (fd >= 0)
|
||||||
}
|
return fd;
|
||||||
ALOGE("Unable to open fb idle state path (%d)", errno);
|
}
|
||||||
return -1;
|
ALOGE("Unable to open fb idle state path (%d)", errno);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InteractionHandler::Init() {
|
bool InteractionHandler::Init() {
|
||||||
std::lock_guard<std::mutex> lk(mLock);
|
std::lock_guard<std::mutex> lk(mLock);
|
||||||
|
|
||||||
if (mState != INTERACTION_STATE_UNINITIALIZED) return true;
|
|
||||||
|
|
||||||
mIdleFd = fb_idle_open();
|
|
||||||
|
|
||||||
mEventFd = eventfd(0, EFD_NONBLOCK);
|
|
||||||
if (mEventFd < 0) {
|
|
||||||
ALOGE("Unable to create event fd (%d)", errno);
|
|
||||||
if (mIdleFd >= 0) {
|
|
||||||
close(mIdleFd);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mState = INTERACTION_STATE_IDLE;
|
|
||||||
mThread = std::unique_ptr<std::thread>(new std::thread(&InteractionHandler::Routine, this));
|
|
||||||
|
|
||||||
|
if (mState != INTERACTION_STATE_UNINITIALIZED)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
mIdleFd = fb_idle_open();
|
||||||
|
|
||||||
|
mEventFd = eventfd(0, EFD_NONBLOCK);
|
||||||
|
if (mEventFd < 0) {
|
||||||
|
ALOGE("Unable to create event fd (%d)", errno);
|
||||||
|
if (mIdleFd >= 0) {
|
||||||
|
close(mIdleFd);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mState = INTERACTION_STATE_IDLE;
|
||||||
|
mThread = std::unique_ptr<std::thread>(
|
||||||
|
new std::thread(&InteractionHandler::Routine, this));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::Exit() {
|
void InteractionHandler::Exit() {
|
||||||
std::unique_lock<std::mutex> lk(mLock);
|
std::unique_lock<std::mutex> lk(mLock);
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) return;
|
if (mState == INTERACTION_STATE_UNINITIALIZED)
|
||||||
|
return;
|
||||||
|
|
||||||
AbortWaitLocked();
|
AbortWaitLocked();
|
||||||
mState = INTERACTION_STATE_UNINITIALIZED;
|
mState = INTERACTION_STATE_UNINITIALIZED;
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
|
|
||||||
mCond.notify_all();
|
mCond.notify_all();
|
||||||
mThread->join();
|
mThread->join();
|
||||||
|
|
||||||
close(mEventFd);
|
close(mEventFd);
|
||||||
if (mIdleFd >= 0) {
|
if (mIdleFd >= 0) {
|
||||||
close(mIdleFd);
|
close(mIdleFd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::PerfLock() {
|
void InteractionHandler::PerfLock() {
|
||||||
ALOGV("%s: acquiring perf lock", __func__);
|
ALOGV("%s: acquiring perf lock", __func__);
|
||||||
if (!mHintManager->DoHint("INTERACTION")) {
|
if (!mHintManager->DoHint("INTERACTION")) {
|
||||||
ALOGE("%s: do hint INTERACTION failed", __func__);
|
ALOGE("%s: do hint INTERACTION failed", __func__);
|
||||||
}
|
}
|
||||||
ATRACE_INT("interaction_lock", 1);
|
ATRACE_INT("interaction_lock", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::PerfRel() {
|
void InteractionHandler::PerfRel() {
|
||||||
ALOGV("%s: releasing perf lock", __func__);
|
ALOGV("%s: releasing perf lock", __func__);
|
||||||
if (!mHintManager->EndHint("INTERACTION")) {
|
if (!mHintManager->EndHint("INTERACTION")) {
|
||||||
ALOGE("%s: end hint INTERACTION failed", __func__);
|
ALOGE("%s: end hint INTERACTION failed", __func__);
|
||||||
}
|
}
|
||||||
ATRACE_INT("interaction_lock", 0);
|
ATRACE_INT("interaction_lock", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start, struct timespec end) {
|
size_t InteractionHandler::CalcTimespecDiffMs(struct timespec start,
|
||||||
size_t diff_in_us = 0;
|
struct timespec end) {
|
||||||
diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
|
size_t diff_in_us = 0;
|
||||||
diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
|
diff_in_us += (end.tv_sec - start.tv_sec) * MSINSEC;
|
||||||
return diff_in_us;
|
diff_in_us += (end.tv_nsec - start.tv_nsec) / USINMS;
|
||||||
|
return diff_in_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::Acquire(int32_t duration) {
|
void InteractionHandler::Acquire(int32_t duration) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(mLock);
|
std::lock_guard<std::mutex> lk(mLock);
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) {
|
if (mState == INTERACTION_STATE_UNINITIALIZED) {
|
||||||
ALOGW("%s: called while uninitialized", __func__);
|
ALOGW("%s: called while uninitialized", __func__);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int inputDuration = duration + 650;
|
||||||
|
int finalDuration;
|
||||||
|
if (inputDuration > mMaxDurationMs)
|
||||||
|
finalDuration = mMaxDurationMs;
|
||||||
|
else if (inputDuration > mMinDurationMs)
|
||||||
|
finalDuration = inputDuration;
|
||||||
|
else
|
||||||
|
finalDuration = mMinDurationMs;
|
||||||
|
|
||||||
|
struct timespec cur_timespec;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
||||||
|
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
|
||||||
|
size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec);
|
||||||
|
// don't hint if previous hint's duration covers this hint's duration
|
||||||
|
if (elapsed_time <= (mDurationMs - finalDuration)) {
|
||||||
|
ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld",
|
||||||
|
__func__, static_cast<int>(mDurationMs),
|
||||||
|
static_cast<int>(finalDuration),
|
||||||
|
static_cast<long long>(elapsed_time));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
mLastTimespec = cur_timespec;
|
||||||
|
mDurationMs = finalDuration;
|
||||||
|
|
||||||
int inputDuration = duration + 650;
|
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);
|
||||||
int finalDuration;
|
|
||||||
if (inputDuration > mMaxDurationMs)
|
|
||||||
finalDuration = mMaxDurationMs;
|
|
||||||
else if (inputDuration > mMinDurationMs)
|
|
||||||
finalDuration = inputDuration;
|
|
||||||
else
|
|
||||||
finalDuration = mMinDurationMs;
|
|
||||||
|
|
||||||
struct timespec cur_timespec;
|
if (mState == INTERACTION_STATE_WAITING)
|
||||||
clock_gettime(CLOCK_MONOTONIC, &cur_timespec);
|
AbortWaitLocked();
|
||||||
if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) {
|
else if (mState == INTERACTION_STATE_IDLE)
|
||||||
size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec);
|
PerfLock();
|
||||||
// don't hint if previous hint's duration covers this hint's duration
|
|
||||||
if (elapsed_time <= (mDurationMs - finalDuration)) {
|
|
||||||
ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__,
|
|
||||||
static_cast<int>(mDurationMs), static_cast<int>(finalDuration),
|
|
||||||
static_cast<long long>(elapsed_time));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mLastTimespec = cur_timespec;
|
|
||||||
mDurationMs = finalDuration;
|
|
||||||
|
|
||||||
ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration);
|
mState = INTERACTION_STATE_INTERACTION;
|
||||||
|
mCond.notify_one();
|
||||||
if (mState == INTERACTION_STATE_WAITING)
|
|
||||||
AbortWaitLocked();
|
|
||||||
else if (mState == INTERACTION_STATE_IDLE)
|
|
||||||
PerfLock();
|
|
||||||
|
|
||||||
mState = INTERACTION_STATE_INTERACTION;
|
|
||||||
mCond.notify_one();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::Release() {
|
void InteractionHandler::Release() {
|
||||||
std::lock_guard<std::mutex> lk(mLock);
|
std::lock_guard<std::mutex> lk(mLock);
|
||||||
if (mState == INTERACTION_STATE_WAITING) {
|
if (mState == INTERACTION_STATE_WAITING) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
PerfRel();
|
PerfRel();
|
||||||
mState = INTERACTION_STATE_IDLE;
|
mState = INTERACTION_STATE_IDLE;
|
||||||
} else {
|
} else {
|
||||||
// clear any wait aborts pending in event fd
|
// clear any wait aborts pending in event fd
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
ssize_t ret = read(mEventFd, &val, sizeof(val));
|
ssize_t ret = read(mEventFd, &val, sizeof(val));
|
||||||
|
|
||||||
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno);
|
ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret,
|
||||||
}
|
errno);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// should be called while locked
|
// should be called while locked
|
||||||
void InteractionHandler::AbortWaitLocked() {
|
void InteractionHandler::AbortWaitLocked() {
|
||||||
uint64_t val = 1;
|
uint64_t val = 1;
|
||||||
ssize_t ret = write(mEventFd, &val, sizeof(val));
|
ssize_t ret = write(mEventFd, &val, sizeof(val));
|
||||||
if (ret != sizeof(val)) ALOGW("Unable to write to event fd (%zd)", ret);
|
if (ret != sizeof(val))
|
||||||
|
ALOGW("Unable to write to event fd (%zd)", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) {
|
||||||
char data[MAX_LENGTH];
|
char data[MAX_LENGTH];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
struct pollfd pfd[2];
|
struct pollfd pfd[2];
|
||||||
|
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
|
|
||||||
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms);
|
ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms);
|
||||||
|
|
||||||
pfd[0].fd = mEventFd;
|
pfd[0].fd = mEventFd;
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
pfd[1].fd = mIdleFd;
|
pfd[1].fd = mIdleFd;
|
||||||
pfd[1].events = POLLPRI | POLLERR;
|
pfd[1].events = POLLPRI | POLLERR;
|
||||||
|
|
||||||
ret = poll(pfd, 1, wait_ms);
|
ret = poll(pfd, 1, wait_ms);
|
||||||
|
if (ret > 0) {
|
||||||
|
ALOGV("%s: wait aborted", __func__);
|
||||||
|
return;
|
||||||
|
} else if (ret < 0) {
|
||||||
|
ALOGE("%s: error in poll while waiting", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mIdleFd < 0) {
|
||||||
|
ret = poll(pfd, 1, timeout_ms);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
ALOGV("%s: wait aborted", __func__);
|
ALOGV("%s: wait for duration aborted", __func__);
|
||||||
return;
|
return;
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
ALOGE("%s: error in poll while waiting", __func__);
|
ALOGE("%s: Error on waiting for duration (%zd)", __func__, ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mIdleFd < 0) {
|
ret = pread(mIdleFd, data, sizeof(data), 0);
|
||||||
ret = poll(pfd, 1, timeout_ms);
|
if (!ret) {
|
||||||
if (ret > 0) {
|
ALOGE("%s: Unexpected EOF!", __func__);
|
||||||
ALOGV("%s: wait for duration aborted", __func__);
|
return;
|
||||||
return;
|
}
|
||||||
} else if (ret < 0) {
|
|
||||||
ALOGE("%s: Error on waiting for duration (%zd)", __func__, ret);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = pread(mIdleFd, data, sizeof(data), 0);
|
if (!strncmp(data, "idle", 4)) {
|
||||||
if (!ret) {
|
ALOGV("%s: already idle", __func__);
|
||||||
ALOGE("%s: Unexpected EOF!", __func__);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!strncmp(data, "idle", 4)) {
|
ret = poll(pfd, 2, timeout_ms);
|
||||||
ALOGV("%s: already idle", __func__);
|
if (ret < 0)
|
||||||
return;
|
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret);
|
||||||
}
|
else if (ret == 0)
|
||||||
|
ALOGV("%s: timed out waiting for idle", __func__);
|
||||||
ret = poll(pfd, 2, timeout_ms);
|
else if (pfd[0].revents)
|
||||||
if (ret < 0)
|
ALOGV("%s: wait for idle aborted", __func__);
|
||||||
ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret);
|
else if (pfd[1].revents)
|
||||||
else if (ret == 0)
|
ALOGV("%s: idle detected", __func__);
|
||||||
ALOGV("%s: timed out waiting for idle", __func__);
|
|
||||||
else if (pfd[0].revents)
|
|
||||||
ALOGV("%s: wait for idle aborted", __func__);
|
|
||||||
else if (pfd[1].revents)
|
|
||||||
ALOGV("%s: idle detected", __func__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InteractionHandler::Routine() {
|
void InteractionHandler::Routine() {
|
||||||
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
std::unique_lock<std::mutex> lk(mLock, std::defer_lock);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
lk.lock();
|
lk.lock();
|
||||||
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; });
|
mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; });
|
||||||
if (mState == INTERACTION_STATE_UNINITIALIZED) return;
|
if (mState == INTERACTION_STATE_UNINITIALIZED)
|
||||||
mState = INTERACTION_STATE_WAITING;
|
return;
|
||||||
lk.unlock();
|
mState = INTERACTION_STATE_WAITING;
|
||||||
|
lk.unlock();
|
||||||
|
|
||||||
WaitForIdle(mWaitMs, mDurationMs);
|
WaitForIdle(mWaitMs, mDurationMs);
|
||||||
Release();
|
Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,47 +28,47 @@
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
|
||||||
enum interaction_state {
|
enum interaction_state {
|
||||||
INTERACTION_STATE_UNINITIALIZED,
|
INTERACTION_STATE_UNINITIALIZED,
|
||||||
INTERACTION_STATE_IDLE,
|
INTERACTION_STATE_IDLE,
|
||||||
INTERACTION_STATE_INTERACTION,
|
INTERACTION_STATE_INTERACTION,
|
||||||
INTERACTION_STATE_WAITING,
|
INTERACTION_STATE_WAITING,
|
||||||
};
|
};
|
||||||
|
|
||||||
class InteractionHandler {
|
class InteractionHandler {
|
||||||
public:
|
public:
|
||||||
InteractionHandler(std::shared_ptr<HintManager> const& hint_manager);
|
InteractionHandler(std::shared_ptr<HintManager> const &hint_manager);
|
||||||
~InteractionHandler();
|
~InteractionHandler();
|
||||||
bool Init();
|
bool Init();
|
||||||
void Exit();
|
void Exit();
|
||||||
void Acquire(int32_t duration);
|
void Acquire(int32_t duration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Release();
|
void Release();
|
||||||
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms);
|
void WaitForIdle(int32_t wait_ms, int32_t timeout_ms);
|
||||||
void AbortWaitLocked();
|
void AbortWaitLocked();
|
||||||
void Routine();
|
void Routine();
|
||||||
|
|
||||||
void PerfLock();
|
void PerfLock();
|
||||||
void PerfRel();
|
void PerfRel();
|
||||||
|
|
||||||
size_t CalcTimespecDiffMs(struct timespec start, struct timespec end);
|
size_t CalcTimespecDiffMs(struct timespec start, struct timespec end);
|
||||||
|
|
||||||
enum interaction_state mState;
|
enum interaction_state mState;
|
||||||
|
|
||||||
int mIdleFd;
|
int mIdleFd;
|
||||||
int mEventFd;
|
int mEventFd;
|
||||||
|
|
||||||
int32_t mWaitMs;
|
int32_t mWaitMs;
|
||||||
int32_t mMinDurationMs;
|
int32_t mMinDurationMs;
|
||||||
int32_t mMaxDurationMs;
|
int32_t mMaxDurationMs;
|
||||||
int32_t mDurationMs;
|
int32_t mDurationMs;
|
||||||
|
|
||||||
struct timespec mLastTimespec;
|
struct timespec mLastTimespec;
|
||||||
|
|
||||||
std::unique_ptr<std::thread> mThread;
|
std::unique_ptr<std::thread> mThread;
|
||||||
std::mutex mLock;
|
std::mutex mLock;
|
||||||
std::condition_variable mCond;
|
std::condition_variable mCond;
|
||||||
std::shared_ptr<HintManager> mHintManager;
|
std::shared_ptr<HintManager> mHintManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
#endif // POWER_LIBPERFMGR_INTERACTIONHANDLER_H_
|
||||||
|
|
|
||||||
|
|
@ -42,221 +42,221 @@ constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio";
|
||||||
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
|
constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering";
|
||||||
|
|
||||||
Power::Power(std::shared_ptr<HintManager> hm)
|
Power::Power(std::shared_ptr<HintManager> hm)
|
||||||
: mHintManager(hm),
|
: mHintManager(hm), mInteractionHandler(nullptr), mVRModeOn(false),
|
||||||
mInteractionHandler(nullptr),
|
|
||||||
mVRModeOn(false),
|
|
||||||
mSustainedPerfModeOn(false) {
|
mSustainedPerfModeOn(false) {
|
||||||
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
|
mInteractionHandler = std::make_unique<InteractionHandler>(mHintManager);
|
||||||
mInteractionHandler->Init();
|
mInteractionHandler->Init();
|
||||||
|
|
||||||
std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
|
std::string state = ::android::base::GetProperty(kPowerHalStateProp, "");
|
||||||
if (state == "SUSTAINED_PERFORMANCE") {
|
if (state == "SUSTAINED_PERFORMANCE") {
|
||||||
ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
|
ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||||
mSustainedPerfModeOn = true;
|
mSustainedPerfModeOn = true;
|
||||||
} else if (state == "VR") {
|
} else if (state == "VR") {
|
||||||
ALOGI("Initialize with VR on");
|
ALOGI("Initialize with VR on");
|
||||||
mHintManager->DoHint(state);
|
mHintManager->DoHint(state);
|
||||||
mVRModeOn = true;
|
mVRModeOn = true;
|
||||||
} else if (state == "VR_SUSTAINED_PERFORMANCE") {
|
} else if (state == "VR_SUSTAINED_PERFORMANCE") {
|
||||||
ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
|
ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR on");
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||||
mSustainedPerfModeOn = true;
|
mSustainedPerfModeOn = true;
|
||||||
mVRModeOn = true;
|
mVRModeOn = true;
|
||||||
} else {
|
} else {
|
||||||
ALOGI("Initialize PowerHAL");
|
ALOGI("Initialize PowerHAL");
|
||||||
}
|
}
|
||||||
|
|
||||||
state = ::android::base::GetProperty(kPowerHalAudioProp, "");
|
state = ::android::base::GetProperty(kPowerHalAudioProp, "");
|
||||||
if (state == "AUDIO_STREAMING_LOW_LATENCY") {
|
if (state == "AUDIO_STREAMING_LOW_LATENCY") {
|
||||||
ALOGI("Initialize with AUDIO_LOW_LATENCY on");
|
ALOGI("Initialize with AUDIO_LOW_LATENCY on");
|
||||||
mHintManager->DoHint(state);
|
mHintManager->DoHint(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
|
state = ::android::base::GetProperty(kPowerHalRenderingProp, "");
|
||||||
if (state == "EXPENSIVE_RENDERING") {
|
if (state == "EXPENSIVE_RENDERING") {
|
||||||
ALOGI("Initialize with EXPENSIVE_RENDERING on");
|
ALOGI("Initialize with EXPENSIVE_RENDERING on");
|
||||||
mHintManager->DoHint("EXPENSIVE_RENDERING");
|
mHintManager->DoHint("EXPENSIVE_RENDERING");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now start to take powerhint
|
// Now start to take powerhint
|
||||||
ALOGI("PowerHAL ready to process hints");
|
ALOGI("PowerHAL ready to process hints");
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) {
|
||||||
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
|
LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled;
|
||||||
ATRACE_INT(toString(type).c_str(), enabled);
|
ATRACE_INT(toString(type).c_str(), enabled);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Mode::LOW_POWER:
|
case Mode::LOW_POWER:
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
mHintManager->DoHint(toString(type));
|
mHintManager->DoHint(toString(type));
|
||||||
} else {
|
} else {
|
||||||
mHintManager->EndHint(toString(type));
|
mHintManager->EndHint(toString(type));
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Mode::SUSTAINED_PERFORMANCE:
|
|
||||||
if (enabled && !mSustainedPerfModeOn) {
|
|
||||||
if (!mVRModeOn) { // Sustained mode only.
|
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
|
||||||
} else { // Sustained + VR mode.
|
|
||||||
mHintManager->EndHint("VR");
|
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
|
||||||
}
|
|
||||||
mSustainedPerfModeOn = true;
|
|
||||||
} else if (!enabled && mSustainedPerfModeOn) {
|
|
||||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
|
||||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
|
||||||
if (mVRModeOn) { // Switch back to VR Mode.
|
|
||||||
mHintManager->DoHint("VR");
|
|
||||||
}
|
|
||||||
mSustainedPerfModeOn = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Mode::VR:
|
|
||||||
if (enabled && !mVRModeOn) {
|
|
||||||
if (!mSustainedPerfModeOn) { // VR mode only.
|
|
||||||
mHintManager->DoHint("VR");
|
|
||||||
} else { // Sustained + VR mode.
|
|
||||||
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
|
||||||
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
|
||||||
}
|
|
||||||
mVRModeOn = true;
|
|
||||||
} else if (!enabled && mVRModeOn) {
|
|
||||||
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
|
||||||
mHintManager->EndHint("VR");
|
|
||||||
if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
|
|
||||||
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
|
||||||
}
|
|
||||||
mVRModeOn = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Mode::LAUNCH:
|
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::FIXED_PERFORMANCE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::EXPENSIVE_RENDERING:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::INTERACTIVE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::DEVICE_IDLE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::DISPLAY_INACTIVE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::AUDIO_STREAMING_LOW_LATENCY:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::CAMERA_STREAMING_SECURE:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::CAMERA_STREAMING_LOW:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::CAMERA_STREAMING_MID:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Mode::CAMERA_STREAMING_HIGH:
|
|
||||||
[[fallthrough]];
|
|
||||||
default:
|
|
||||||
if (enabled) {
|
|
||||||
mHintManager->DoHint(toString(type));
|
|
||||||
} else {
|
|
||||||
mHintManager->EndHint(toString(type));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case Mode::SUSTAINED_PERFORMANCE:
|
||||||
|
if (enabled && !mSustainedPerfModeOn) {
|
||||||
|
if (!mVRModeOn) { // Sustained mode only.
|
||||||
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||||
|
} else { // Sustained + VR mode.
|
||||||
|
mHintManager->EndHint("VR");
|
||||||
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||||
|
}
|
||||||
|
mSustainedPerfModeOn = true;
|
||||||
|
} else if (!enabled && mSustainedPerfModeOn) {
|
||||||
|
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
||||||
|
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
||||||
|
if (mVRModeOn) { // Switch back to VR Mode.
|
||||||
|
mHintManager->DoHint("VR");
|
||||||
|
}
|
||||||
|
mSustainedPerfModeOn = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Mode::VR:
|
||||||
|
if (enabled && !mVRModeOn) {
|
||||||
|
if (!mSustainedPerfModeOn) { // VR mode only.
|
||||||
|
mHintManager->DoHint("VR");
|
||||||
|
} else { // Sustained + VR mode.
|
||||||
|
mHintManager->EndHint("SUSTAINED_PERFORMANCE");
|
||||||
|
mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
|
||||||
|
}
|
||||||
|
mVRModeOn = true;
|
||||||
|
} else if (!enabled && mVRModeOn) {
|
||||||
|
mHintManager->EndHint("VR_SUSTAINED_PERFORMANCE");
|
||||||
|
mHintManager->EndHint("VR");
|
||||||
|
if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
|
||||||
|
mHintManager->DoHint("SUSTAINED_PERFORMANCE");
|
||||||
|
}
|
||||||
|
mVRModeOn = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Mode::LAUNCH:
|
||||||
|
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::FIXED_PERFORMANCE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::EXPENSIVE_RENDERING:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::INTERACTIVE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::DEVICE_IDLE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::DISPLAY_INACTIVE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::AUDIO_STREAMING_LOW_LATENCY:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::CAMERA_STREAMING_SECURE:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::CAMERA_STREAMING_LOW:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::CAMERA_STREAMING_MID:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Mode::CAMERA_STREAMING_HIGH:
|
||||||
|
[[fallthrough]];
|
||||||
|
default:
|
||||||
|
if (enabled) {
|
||||||
|
mHintManager->DoHint(toString(type));
|
||||||
|
} else {
|
||||||
|
mHintManager->EndHint(toString(type));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) {
|
ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) {
|
||||||
bool supported = mHintManager->IsHintSupported(toString(type));
|
bool supported = mHintManager->IsHintSupported(toString(type));
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Mode::LOW_POWER: // LOW_POWER handled insides PowerHAL specifically
|
case Mode::LOW_POWER: // LOW_POWER handled insides PowerHAL specifically
|
||||||
supported = true;
|
supported = true;
|
||||||
break;
|
break;
|
||||||
case Mode::DOUBLE_TAP_TO_WAKE:
|
case Mode::DOUBLE_TAP_TO_WAKE:
|
||||||
supported = true;
|
supported = true;
|
||||||
break;
|
break;
|
||||||
case Mode::INTERACTIVE:
|
case Mode::INTERACTIVE:
|
||||||
supported = true;
|
supported = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Power mode " << toString(type) << " isModeSupported: " << supported;
|
LOG(INFO) << "Power mode " << toString(type)
|
||||||
*_aidl_return = supported;
|
<< " isModeSupported: " << supported;
|
||||||
return ndk::ScopedAStatus::ok();
|
*_aidl_return = supported;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) {
|
||||||
LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs;
|
LOG(DEBUG) << "Power setBoost: " << toString(type)
|
||||||
ATRACE_INT(toString(type).c_str(), durationMs);
|
<< " duration: " << durationMs;
|
||||||
switch (type) {
|
ATRACE_INT(toString(type).c_str(), durationMs);
|
||||||
case Boost::INTERACTION:
|
switch (type) {
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
case Boost::INTERACTION:
|
||||||
break;
|
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||||
}
|
break;
|
||||||
mInteractionHandler->Acquire(durationMs);
|
|
||||||
break;
|
|
||||||
case Boost::DISPLAY_UPDATE_IMMINENT:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Boost::ML_ACC:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Boost::AUDIO_LAUNCH:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Boost::CAMERA_LAUNCH:
|
|
||||||
[[fallthrough]];
|
|
||||||
case Boost::CAMERA_SHOT:
|
|
||||||
[[fallthrough]];
|
|
||||||
default:
|
|
||||||
if (mVRModeOn || mSustainedPerfModeOn) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (durationMs > 0) {
|
|
||||||
mHintManager->DoHint(toString(type), std::chrono::milliseconds(durationMs));
|
|
||||||
} else if (durationMs == 0) {
|
|
||||||
mHintManager->DoHint(toString(type));
|
|
||||||
} else {
|
|
||||||
mHintManager->EndHint(toString(type));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
mInteractionHandler->Acquire(durationMs);
|
||||||
return ndk::ScopedAStatus::ok();
|
break;
|
||||||
}
|
case Boost::DISPLAY_UPDATE_IMMINENT:
|
||||||
|
[[fallthrough]];
|
||||||
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool* _aidl_return) {
|
case Boost::ML_ACC:
|
||||||
bool supported = mHintManager->IsHintSupported(toString(type));
|
[[fallthrough]];
|
||||||
LOG(INFO) << "Power boost " << toString(type) << " isBoostSupported: " << supported;
|
case Boost::AUDIO_LAUNCH:
|
||||||
*_aidl_return = supported;
|
[[fallthrough]];
|
||||||
return ndk::ScopedAStatus::ok();
|
case Boost::CAMERA_LAUNCH:
|
||||||
}
|
[[fallthrough]];
|
||||||
|
case Boost::CAMERA_SHOT:
|
||||||
constexpr const char* boolToString(bool b) {
|
[[fallthrough]];
|
||||||
return b ? "true" : "false";
|
default:
|
||||||
}
|
if (mVRModeOn || mSustainedPerfModeOn) {
|
||||||
|
break;
|
||||||
binder_status_t Power::dump(int fd, const char**, uint32_t) {
|
|
||||||
std::string buf(::android::base::StringPrintf(
|
|
||||||
"HintManager Running: %s\n"
|
|
||||||
"VRMode: %s\n"
|
|
||||||
"SustainedPerformanceMode: %s\n",
|
|
||||||
boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
|
|
||||||
boolToString(mSustainedPerfModeOn)));
|
|
||||||
// Dump nodes through libperfmgr
|
|
||||||
mHintManager->DumpToFd(fd);
|
|
||||||
if (!::android::base::WriteStringToFd(buf, fd)) {
|
|
||||||
PLOG(ERROR) << "Failed to dump state to fd";
|
|
||||||
}
|
}
|
||||||
fsync(fd);
|
if (durationMs > 0) {
|
||||||
return STATUS_OK;
|
mHintManager->DoHint(toString(type),
|
||||||
|
std::chrono::milliseconds(durationMs));
|
||||||
|
} else if (durationMs == 0) {
|
||||||
|
mHintManager->DoHint(toString(type));
|
||||||
|
} else {
|
||||||
|
mHintManager->EndHint(toString(type));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pixel
|
ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) {
|
||||||
} // namespace impl
|
bool supported = mHintManager->IsHintSupported(toString(type));
|
||||||
} // namespace power
|
LOG(INFO) << "Power boost " << toString(type)
|
||||||
} // namespace hardware
|
<< " isBoostSupported: " << supported;
|
||||||
} // namespace google
|
*_aidl_return = supported;
|
||||||
} // namespace aidl
|
return ndk::ScopedAStatus::ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const char *boolToString(bool b) { return b ? "true" : "false"; }
|
||||||
|
|
||||||
|
binder_status_t Power::dump(int fd, const char **, uint32_t) {
|
||||||
|
std::string buf(::android::base::StringPrintf(
|
||||||
|
"HintManager Running: %s\n"
|
||||||
|
"VRMode: %s\n"
|
||||||
|
"SustainedPerformanceMode: %s\n",
|
||||||
|
boolToString(mHintManager->IsRunning()), boolToString(mVRModeOn),
|
||||||
|
boolToString(mSustainedPerfModeOn)));
|
||||||
|
// Dump nodes through libperfmgr
|
||||||
|
mHintManager->DumpToFd(fd);
|
||||||
|
if (!::android::base::WriteStringToFd(buf, fd)) {
|
||||||
|
PLOG(ERROR) << "Failed to dump state to fd";
|
||||||
|
}
|
||||||
|
fsync(fd);
|
||||||
|
return STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace pixel
|
||||||
|
} // namespace impl
|
||||||
|
} // namespace power
|
||||||
|
} // namespace hardware
|
||||||
|
} // namespace google
|
||||||
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -38,24 +38,24 @@ using ::aidl::android::hardware::power::Mode;
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
|
||||||
class Power : public ::aidl::android::hardware::power::BnPower {
|
class Power : public ::aidl::android::hardware::power::BnPower {
|
||||||
public:
|
public:
|
||||||
Power(std::shared_ptr<HintManager> hm);
|
Power(std::shared_ptr<HintManager> hm);
|
||||||
ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
|
ndk::ScopedAStatus setMode(Mode type, bool enabled) override;
|
||||||
ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override;
|
ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override;
|
||||||
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
|
ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override;
|
||||||
ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override;
|
ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override;
|
||||||
binder_status_t dump(int fd, const char** args, uint32_t numArgs) override;
|
binder_status_t dump(int fd, const char **args, uint32_t numArgs) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<HintManager> mHintManager;
|
std::shared_ptr<HintManager> mHintManager;
|
||||||
std::unique_ptr<InteractionHandler> mInteractionHandler;
|
std::unique_ptr<InteractionHandler> mInteractionHandler;
|
||||||
std::atomic<bool> mVRModeOn;
|
std::atomic<bool> mVRModeOn;
|
||||||
std::atomic<bool> mSustainedPerfModeOn;
|
std::atomic<bool> mSustainedPerfModeOn;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pixel
|
} // namespace pixel
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
} // namespace power
|
} // namespace power
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace google
|
} // namespace google
|
||||||
} // namespace aidl
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -37,51 +37,54 @@ namespace power {
|
||||||
namespace impl {
|
namespace impl {
|
||||||
namespace pixel {
|
namespace pixel {
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::setMode(const std::string& mode, bool enabled) {
|
ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) {
|
||||||
LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled;
|
LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled;
|
||||||
ATRACE_INT(mode.c_str(), enabled);
|
ATRACE_INT(mode.c_str(), enabled);
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
mHintManager->DoHint(mode);
|
mHintManager->DoHint(mode);
|
||||||
} else {
|
} else {
|
||||||
mHintManager->EndHint(mode);
|
mHintManager->EndHint(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::isModeSupported(const std::string& mode, bool* _aidl_return) {
|
ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode,
|
||||||
bool supported = mHintManager->IsHintSupported(mode);
|
bool *_aidl_return) {
|
||||||
LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported;
|
bool supported = mHintManager->IsHintSupported(mode);
|
||||||
*_aidl_return = supported;
|
LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported;
|
||||||
return ndk::ScopedAStatus::ok();
|
*_aidl_return = supported;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::setBoost(const std::string& boost, int32_t durationMs) {
|
ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost,
|
||||||
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
int32_t durationMs) {
|
||||||
ATRACE_INT(boost.c_str(), durationMs);
|
LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs;
|
||||||
|
ATRACE_INT(boost.c_str(), durationMs);
|
||||||
|
|
||||||
if (durationMs > 0) {
|
if (durationMs > 0) {
|
||||||
mHintManager->DoHint(boost, std::chrono::milliseconds(durationMs));
|
mHintManager->DoHint(boost, std::chrono::milliseconds(durationMs));
|
||||||
} else if (durationMs == 0) {
|
} else if (durationMs == 0) {
|
||||||
mHintManager->DoHint(boost);
|
mHintManager->DoHint(boost);
|
||||||
} else {
|
} else {
|
||||||
mHintManager->EndHint(boost);
|
mHintManager->EndHint(boost);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string& boost, bool* _aidl_return) {
|
ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost,
|
||||||
bool supported = mHintManager->IsHintSupported(boost);
|
bool *_aidl_return) {
|
||||||
LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported;
|
bool supported = mHintManager->IsHintSupported(boost);
|
||||||
*_aidl_return = supported;
|
LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported;
|
||||||
return ndk::ScopedAStatus::ok();
|
*_aidl_return = supported;
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pixel
|
} // namespace pixel
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
} // namespace power
|
} // namespace power
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace google
|
} // namespace google
|
||||||
} // namespace aidl
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -32,21 +32,25 @@ namespace pixel {
|
||||||
|
|
||||||
using ::android::perfmgr::HintManager;
|
using ::android::perfmgr::HintManager;
|
||||||
|
|
||||||
class PowerExt : public ::aidl::google::hardware::power::extension::pixel::BnPowerExt {
|
class PowerExt
|
||||||
public:
|
: public ::aidl::google::hardware::power::extension::pixel::BnPowerExt {
|
||||||
PowerExt(std::shared_ptr<HintManager> hm) : mHintManager(hm) {}
|
public:
|
||||||
ndk::ScopedAStatus setMode(const std::string& mode, bool enabled) override;
|
PowerExt(std::shared_ptr<HintManager> hm) : mHintManager(hm) {}
|
||||||
ndk::ScopedAStatus isModeSupported(const std::string& mode, bool* _aidl_return) override;
|
ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override;
|
||||||
ndk::ScopedAStatus setBoost(const std::string& boost, int32_t durationMs) override;
|
ndk::ScopedAStatus isModeSupported(const std::string &mode,
|
||||||
ndk::ScopedAStatus isBoostSupported(const std::string& boost, bool* _aidl_return) override;
|
bool *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus setBoost(const std::string &boost,
|
||||||
|
int32_t durationMs) override;
|
||||||
|
ndk::ScopedAStatus isBoostSupported(const std::string &boost,
|
||||||
|
bool *_aidl_return) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<HintManager> mHintManager;
|
std::shared_ptr<HintManager> mHintManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pixel
|
} // namespace pixel
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
} // namespace power
|
} // namespace power
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace google
|
} // namespace google
|
||||||
} // namespace aidl
|
} // namespace aidl
|
||||||
|
|
|
||||||
|
|
@ -34,41 +34,44 @@ constexpr char kPowerHalConfigPath[] = "/vendor/etc/powerhint.json";
|
||||||
constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
|
constexpr char kPowerHalInitProp[] = "vendor.powerhal.init";
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting.";
|
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is starting.";
|
||||||
|
|
||||||
// Parse config but do not start the looper
|
// Parse config but do not start the looper
|
||||||
std::shared_ptr<HintManager> hm = HintManager::GetFromJSON(kPowerHalConfigPath, false);
|
std::shared_ptr<HintManager> hm =
|
||||||
if (!hm) {
|
HintManager::GetFromJSON(kPowerHalConfigPath, false);
|
||||||
LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
|
if (!hm) {
|
||||||
}
|
LOG(FATAL) << "Invalid config: " << kPowerHalConfigPath;
|
||||||
|
}
|
||||||
|
|
||||||
// single thread
|
// single thread
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||||
|
|
||||||
// core service
|
// core service
|
||||||
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(hm);
|
std::shared_ptr<Power> pw = ndk::SharedRefBase::make<Power>(hm);
|
||||||
ndk::SpAIBinder pwBinder = pw->asBinder();
|
ndk::SpAIBinder pwBinder = pw->asBinder();
|
||||||
|
|
||||||
// extension service
|
// extension service
|
||||||
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(hm);
|
std::shared_ptr<PowerExt> pwExt = ndk::SharedRefBase::make<PowerExt>(hm);
|
||||||
|
|
||||||
// attach the extension to the same binder we will be registering
|
// attach the extension to the same binder we will be registering
|
||||||
CHECK(STATUS_OK == AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get()));
|
CHECK(STATUS_OK ==
|
||||||
|
AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get()));
|
||||||
|
|
||||||
const std::string instance = std::string() + Power::descriptor + "/default";
|
const std::string instance = std::string() + Power::descriptor + "/default";
|
||||||
binder_status_t status = AServiceManager_addService(pw->asBinder().get(), instance.c_str());
|
binder_status_t status =
|
||||||
CHECK(status == STATUS_OK);
|
AServiceManager_addService(pw->asBinder().get(), instance.c_str());
|
||||||
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
|
CHECK(status == STATUS_OK);
|
||||||
|
LOG(INFO) << "Pixel Power HAL AIDL Service with Extension is started.";
|
||||||
|
|
||||||
std::thread initThread([&]() {
|
std::thread initThread([&]() {
|
||||||
::android::base::WaitForProperty(kPowerHalInitProp, "1");
|
::android::base::WaitForProperty(kPowerHalInitProp, "1");
|
||||||
hm->Start();
|
hm->Start();
|
||||||
});
|
});
|
||||||
initThread.detach();
|
initThread.detach();
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool();
|
ABinderProcess_joinThreadPool();
|
||||||
|
|
||||||
// should not reach
|
// should not reach
|
||||||
LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died.";
|
LOG(ERROR) << "Pixel Power HAL AIDL Service with Extension just died.";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,296 +19,317 @@ namespace android {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
namespace vibrator {
|
namespace vibrator {
|
||||||
|
|
||||||
static std::map<Effect, int> CP_TRIGGER_EFFECTS {
|
static std::map<Effect, int> CP_TRIGGER_EFFECTS{{Effect::CLICK, 10},
|
||||||
{ Effect::CLICK, 10 },
|
{Effect::DOUBLE_CLICK, 14},
|
||||||
{ Effect::DOUBLE_CLICK, 14 },
|
{Effect::HEAVY_CLICK, 23},
|
||||||
{ Effect::HEAVY_CLICK, 23 },
|
{Effect::TEXTURE_TICK, 50},
|
||||||
{ Effect::TEXTURE_TICK, 50 },
|
{Effect::TICK, 50}};
|
||||||
{ Effect::TICK, 50 }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write value to path and close file.
|
* Write value to path and close file.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static ndk::ScopedAStatus writeNode(const std::string& path, const T& value) {
|
static ndk::ScopedAStatus writeNode(const std::string &path, const T &value) {
|
||||||
std::ofstream node(path);
|
std::ofstream node(path);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
LOG(ERROR) << "Failed to open: " << path;
|
LOG(ERROR) << "Failed to open: " << path;
|
||||||
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << "writeNode node: " << path << " value: " << value;
|
LOG(DEBUG) << "writeNode node: " << path << " value: " << value;
|
||||||
|
|
||||||
node << value << std::endl;
|
node << value << std::endl;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
LOG(ERROR) << "Failed to write: " << value;
|
LOG(ERROR) << "Failed to write: " << value;
|
||||||
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool nodeExists(const std::string& path) {
|
static bool nodeExists(const std::string &path) {
|
||||||
std::ofstream f(path.c_str());
|
std::ofstream f(path.c_str());
|
||||||
return f.good();
|
return f.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vibrator::Vibrator() {
|
Vibrator::Vibrator() {
|
||||||
mIsTimedOutVibrator = nodeExists(VIBRATOR_TIMEOUT_PATH);
|
mIsTimedOutVibrator = nodeExists(VIBRATOR_TIMEOUT_PATH);
|
||||||
mHasTimedOutIntensity = nodeExists(VIBRATOR_INTENSITY_PATH);
|
mHasTimedOutIntensity = nodeExists(VIBRATOR_INTENSITY_PATH);
|
||||||
mHasTimedOutEffect = nodeExists(VIBRATOR_CP_TRIGGER_PATH);
|
mHasTimedOutEffect = nodeExists(VIBRATOR_CP_TRIGGER_PATH);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t* _aidl_return) {
|
ndk::ScopedAStatus Vibrator::getCapabilities(int32_t *_aidl_return) {
|
||||||
*_aidl_return = IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
*_aidl_return =
|
||||||
IVibrator::CAP_EXTERNAL_CONTROL /*| IVibrator::CAP_COMPOSE_EFFECTS |
|
IVibrator::CAP_ON_CALLBACK | IVibrator::CAP_PERFORM_CALLBACK |
|
||||||
IVibrator::CAP_ALWAYS_ON_CONTROL*/;
|
IVibrator::CAP_EXTERNAL_CONTROL /*| IVibrator::CAP_COMPOSE_EFFECTS |
|
||||||
|
IVibrator::CAP_ALWAYS_ON_CONTROL*/
|
||||||
|
;
|
||||||
|
|
||||||
if (mHasTimedOutIntensity) {
|
if (mHasTimedOutIntensity) {
|
||||||
*_aidl_return = *_aidl_return | IVibrator::CAP_AMPLITUDE_CONTROL |
|
*_aidl_return = *_aidl_return | IVibrator::CAP_AMPLITUDE_CONTROL |
|
||||||
IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
|
IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::off() {
|
ndk::ScopedAStatus Vibrator::off() { return activate(0); }
|
||||||
return activate(0);
|
|
||||||
|
ndk::ScopedAStatus
|
||||||
|
Vibrator::on(int32_t timeoutMs,
|
||||||
|
const std::shared_ptr<IVibratorCallback> &callback) {
|
||||||
|
ndk::ScopedAStatus status;
|
||||||
|
|
||||||
|
if (mHasTimedOutEffect)
|
||||||
|
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear all effects
|
||||||
|
|
||||||
|
status = activate(timeoutMs);
|
||||||
|
|
||||||
|
if (callback != nullptr) {
|
||||||
|
std::thread([=] {
|
||||||
|
LOG(DEBUG) << "Starting on on another thread";
|
||||||
|
usleep(timeoutMs * 1000);
|
||||||
|
LOG(DEBUG) << "Notifying on complete";
|
||||||
|
if (!callback->onComplete().isOk()) {
|
||||||
|
LOG(ERROR) << "Failed to call onComplete";
|
||||||
|
}
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::on(int32_t timeoutMs, const std::shared_ptr<IVibratorCallback>& callback) {
|
ndk::ScopedAStatus
|
||||||
ndk::ScopedAStatus status;
|
Vibrator::perform(Effect effect, EffectStrength strength,
|
||||||
|
const std::shared_ptr<IVibratorCallback> &callback,
|
||||||
if (mHasTimedOutEffect)
|
int32_t *_aidl_return) {
|
||||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear all effects
|
ndk::ScopedAStatus status;
|
||||||
|
uint32_t amplitude = strengthToAmplitude(strength, &status);
|
||||||
status = activate(timeoutMs);
|
uint32_t ms = 1000;
|
||||||
|
|
||||||
if (callback != nullptr) {
|
|
||||||
std::thread([=] {
|
|
||||||
LOG(DEBUG) << "Starting on on another thread";
|
|
||||||
usleep(timeoutMs * 1000);
|
|
||||||
LOG(DEBUG) << "Notifying on complete";
|
|
||||||
if (!callback->onComplete().isOk()) {
|
|
||||||
LOG(ERROR) << "Failed to call onComplete";
|
|
||||||
}
|
|
||||||
}).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!status.isOk())
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::perform(Effect effect, EffectStrength strength, const std::shared_ptr<IVibratorCallback>& callback, int32_t* _aidl_return) {
|
activate(0);
|
||||||
ndk::ScopedAStatus status;
|
setAmplitude(amplitude);
|
||||||
uint32_t amplitude = strengthToAmplitude(strength, &status);
|
|
||||||
uint32_t ms = 1000;
|
if (mHasTimedOutEffect &&
|
||||||
|
CP_TRIGGER_EFFECTS.find(effect) != CP_TRIGGER_EFFECTS.end()) {
|
||||||
|
writeNode(VIBRATOR_CP_TRIGGER_PATH, CP_TRIGGER_EFFECTS[effect]);
|
||||||
|
} else {
|
||||||
|
if (mHasTimedOutEffect)
|
||||||
|
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear previous effect
|
||||||
|
|
||||||
|
ms = effectToMs(effect, &status);
|
||||||
|
|
||||||
if (!status.isOk())
|
if (!status.isOk())
|
||||||
return status;
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
activate(0);
|
status = activate(ms);
|
||||||
setAmplitude(amplitude);
|
|
||||||
|
|
||||||
if (mHasTimedOutEffect && CP_TRIGGER_EFFECTS.find(effect) != CP_TRIGGER_EFFECTS.end()) {
|
if (callback != nullptr) {
|
||||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, CP_TRIGGER_EFFECTS[effect]);
|
std::thread([=] {
|
||||||
} else {
|
LOG(DEBUG) << "Starting perform on another thread";
|
||||||
if (mHasTimedOutEffect)
|
usleep(ms * 1000);
|
||||||
writeNode(VIBRATOR_CP_TRIGGER_PATH, 0); // Clear previous effect
|
LOG(DEBUG) << "Notifying perform complete";
|
||||||
|
callback->onComplete();
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
ms = effectToMs(effect, &status);
|
*_aidl_return = ms;
|
||||||
|
return status;
|
||||||
if (!status.isOk())
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = activate(ms);
|
|
||||||
|
|
||||||
if (callback != nullptr) {
|
|
||||||
std::thread([=] {
|
|
||||||
LOG(DEBUG) << "Starting perform on another thread";
|
|
||||||
usleep(ms * 1000);
|
|
||||||
LOG(DEBUG) << "Notifying perform complete";
|
|
||||||
callback->onComplete();
|
|
||||||
}).detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
*_aidl_return = ms;
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getSupportedEffects(std::vector<Effect>* _aidl_return) {
|
ndk::ScopedAStatus
|
||||||
*_aidl_return = {Effect::CLICK, Effect::DOUBLE_CLICK, Effect::HEAVY_CLICK,
|
Vibrator::getSupportedEffects(std::vector<Effect> *_aidl_return) {
|
||||||
Effect::TICK, Effect::TEXTURE_TICK, Effect::THUD, Effect::POP,
|
*_aidl_return = {
|
||||||
Effect::RINGTONE_1, Effect::RINGTONE_2, Effect::RINGTONE_3,
|
Effect::CLICK, Effect::DOUBLE_CLICK, Effect::HEAVY_CLICK,
|
||||||
Effect::RINGTONE_4, Effect::RINGTONE_5, Effect::RINGTONE_6,
|
Effect::TICK, Effect::TEXTURE_TICK, Effect::THUD,
|
||||||
Effect::RINGTONE_7, Effect::RINGTONE_7, Effect::RINGTONE_8,
|
Effect::POP, Effect::RINGTONE_1, Effect::RINGTONE_2,
|
||||||
Effect::RINGTONE_9, Effect::RINGTONE_10, Effect::RINGTONE_11,
|
Effect::RINGTONE_3, Effect::RINGTONE_4, Effect::RINGTONE_5,
|
||||||
Effect::RINGTONE_12, Effect::RINGTONE_13, Effect::RINGTONE_14,
|
Effect::RINGTONE_6, Effect::RINGTONE_7, Effect::RINGTONE_7,
|
||||||
Effect::RINGTONE_15};
|
Effect::RINGTONE_8, Effect::RINGTONE_9, Effect::RINGTONE_10,
|
||||||
return ndk::ScopedAStatus::ok();
|
Effect::RINGTONE_11, Effect::RINGTONE_12, Effect::RINGTONE_13,
|
||||||
|
Effect::RINGTONE_14, Effect::RINGTONE_15};
|
||||||
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
ndk::ScopedAStatus Vibrator::setAmplitude(float amplitude) {
|
||||||
uint32_t intensity;
|
uint32_t intensity;
|
||||||
|
|
||||||
if (amplitude == 0) {
|
if (amplitude == 0) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(DEBUG) << "Setting amplitude: " << (uint32_t)amplitude;
|
LOG(DEBUG) << "Setting amplitude: " << (uint32_t)amplitude;
|
||||||
|
|
||||||
intensity = std::lround((amplitude - 1) * INTENSITY_MAX / 254.0);
|
intensity = std::lround((amplitude - 1) * INTENSITY_MAX / 254.0);
|
||||||
if (intensity > INTENSITY_MAX) {
|
if (intensity > INTENSITY_MAX) {
|
||||||
intensity = INTENSITY_MAX;
|
intensity = INTENSITY_MAX;
|
||||||
}
|
}
|
||||||
LOG(DEBUG) << "Setting intensity: " << intensity;
|
LOG(DEBUG) << "Setting intensity: " << intensity;
|
||||||
|
|
||||||
if (mHasTimedOutIntensity) {
|
if (mHasTimedOutIntensity) {
|
||||||
return writeNode(VIBRATOR_INTENSITY_PATH, intensity);
|
return writeNode(VIBRATOR_INTENSITY_PATH, intensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
ndk::ScopedAStatus Vibrator::setExternalControl(bool enabled) {
|
||||||
if (mEnabled) {
|
if (mEnabled) {
|
||||||
LOG(WARNING) << "Setting external control while the vibrator is enabled is "
|
LOG(WARNING) << "Setting external control while the vibrator is enabled is "
|
||||||
"unsupported!";
|
"unsupported!";
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "ExternalControl: " << mExternalControl << " -> " << enabled;
|
LOG(INFO) << "ExternalControl: " << mExternalControl << " -> " << enabled;
|
||||||
mExternalControl = enabled;
|
mExternalControl = enabled;
|
||||||
return ndk::ScopedAStatus::ok();
|
return ndk::ScopedAStatus::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getCompositionDelayMax(int32_t* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getCompositionDelayMax(int32_t * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getCompositionSizeMax(int32_t * /*_aidl_return*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(std::vector<CompositePrimitive>* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getSupportedPrimitives(
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
std::vector<CompositePrimitive> * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getPrimitiveDuration(CompositePrimitive /*primitive*/, int32_t* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getPrimitiveDuration(CompositePrimitive /*primitive*/,
|
||||||
|
int32_t * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::compose(const std::vector<CompositeEffect>& /*composite*/, const std::shared_ptr<IVibratorCallback>& /*callback*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::compose(const std::vector<CompositeEffect> & /*composite*/,
|
||||||
|
const std::shared_ptr<IVibratorCallback> & /*callback*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect>* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getSupportedAlwaysOnEffects(std::vector<Effect> * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/, EffectStrength /*strength*/) {
|
ndk::ScopedAStatus Vibrator::alwaysOnEnable(int32_t /*id*/, Effect /*effect*/,
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
EffectStrength /*strength*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
|
ndk::ScopedAStatus Vibrator::alwaysOnDisable(int32_t /*id*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getResonantFrequency(float* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getResonantFrequency(float * /*_aidl_return*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getQFactor(float* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getQFactor(float * /*_aidl_return*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getFrequencyResolution(float* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getFrequencyResolution(float * /*_aidl_return*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float* /*_aidl_return*/) {
|
ndk::ScopedAStatus Vibrator::getFrequencyMinimum(float * /*_aidl_return*/) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getBandwidthAmplitudeMap(std::vector<float>* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getBandwidthAmplitudeMap(std::vector<float> * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getPwlePrimitiveDurationMax(int32_t* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getPwlePrimitiveDurationMax(int32_t * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getPwleCompositionSizeMax(int32_t* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getPwleCompositionSizeMax(int32_t * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::getSupportedBraking(std::vector<Braking>* /*_aidl_return*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::getSupportedBraking(std::vector<Braking> * /*_aidl_return*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::composePwle(const std::vector<PrimitivePwle>& /*composite*/, const std::shared_ptr<IVibratorCallback>& /*callback*/) {
|
ndk::ScopedAStatus
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
Vibrator::composePwle(const std::vector<PrimitivePwle> & /*composite*/,
|
||||||
|
const std::shared_ptr<IVibratorCallback> & /*callback*/) {
|
||||||
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndk::ScopedAStatus Vibrator::activate(uint32_t timeoutMs) {
|
ndk::ScopedAStatus Vibrator::activate(uint32_t timeoutMs) {
|
||||||
std::lock_guard<std::mutex> lock{mMutex};
|
std::lock_guard<std::mutex> lock{mMutex};
|
||||||
if (!mIsTimedOutVibrator) {
|
if (!mIsTimedOutVibrator) {
|
||||||
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
return writeNode(VIBRATOR_TIMEOUT_PATH, timeoutMs);
|
return writeNode(VIBRATOR_TIMEOUT_PATH, timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Vibrator::strengthToAmplitude(EffectStrength strength, ndk::ScopedAStatus* status) {
|
uint8_t Vibrator::strengthToAmplitude(EffectStrength strength,
|
||||||
*status = ndk::ScopedAStatus::ok();
|
ndk::ScopedAStatus *status) {
|
||||||
|
*status = ndk::ScopedAStatus::ok();
|
||||||
|
|
||||||
switch (strength) {
|
switch (strength) {
|
||||||
case EffectStrength::LIGHT:
|
case EffectStrength::LIGHT:
|
||||||
return 64;
|
return 64;
|
||||||
case EffectStrength::MEDIUM:
|
case EffectStrength::MEDIUM:
|
||||||
return 128;
|
return 128;
|
||||||
case EffectStrength::STRONG:
|
case EffectStrength::STRONG:
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Vibrator::effectToMs(Effect effect, ndk::ScopedAStatus* status) {
|
uint32_t Vibrator::effectToMs(Effect effect, ndk::ScopedAStatus *status) {
|
||||||
*status = ndk::ScopedAStatus::ok();
|
*status = ndk::ScopedAStatus::ok();
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case Effect::CLICK:
|
case Effect::CLICK:
|
||||||
return 10;
|
return 10;
|
||||||
case Effect::DOUBLE_CLICK:
|
case Effect::DOUBLE_CLICK:
|
||||||
return 15;
|
return 15;
|
||||||
case Effect::TICK:
|
case Effect::TICK:
|
||||||
case Effect::TEXTURE_TICK:
|
case Effect::TEXTURE_TICK:
|
||||||
case Effect::THUD:
|
case Effect::THUD:
|
||||||
case Effect::POP:
|
case Effect::POP:
|
||||||
return 5;
|
return 5;
|
||||||
case Effect::HEAVY_CLICK:
|
case Effect::HEAVY_CLICK:
|
||||||
return 10;
|
return 10;
|
||||||
case Effect::RINGTONE_1:
|
case Effect::RINGTONE_1:
|
||||||
case Effect::RINGTONE_2:
|
case Effect::RINGTONE_2:
|
||||||
case Effect::RINGTONE_3:
|
case Effect::RINGTONE_3:
|
||||||
case Effect::RINGTONE_4:
|
case Effect::RINGTONE_4:
|
||||||
case Effect::RINGTONE_5:
|
case Effect::RINGTONE_5:
|
||||||
case Effect::RINGTONE_6:
|
case Effect::RINGTONE_6:
|
||||||
case Effect::RINGTONE_7:
|
case Effect::RINGTONE_7:
|
||||||
case Effect::RINGTONE_8:
|
case Effect::RINGTONE_8:
|
||||||
case Effect::RINGTONE_9:
|
case Effect::RINGTONE_9:
|
||||||
case Effect::RINGTONE_10:
|
case Effect::RINGTONE_10:
|
||||||
case Effect::RINGTONE_11:
|
case Effect::RINGTONE_11:
|
||||||
case Effect::RINGTONE_12:
|
case Effect::RINGTONE_12:
|
||||||
case Effect::RINGTONE_13:
|
case Effect::RINGTONE_13:
|
||||||
case Effect::RINGTONE_14:
|
case Effect::RINGTONE_14:
|
||||||
case Effect::RINGTONE_15:
|
case Effect::RINGTONE_15:
|
||||||
return 30000;
|
return 30000;
|
||||||
}
|
}
|
||||||
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
*status = ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace vibrator
|
} // namespace vibrator
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,15 @@
|
||||||
|
|
||||||
#define VIBRATOR_TIMEOUT_PATH "/sys/class/timed_output/vibrator/enable"
|
#define VIBRATOR_TIMEOUT_PATH "/sys/class/timed_output/vibrator/enable"
|
||||||
#define VIBRATOR_INTENSITY_PATH "/sys/class/timed_output/vibrator/intensity"
|
#define VIBRATOR_INTENSITY_PATH "/sys/class/timed_output/vibrator/intensity"
|
||||||
#define VIBRATOR_CP_TRIGGER_PATH "/sys/class/timed_output/vibrator/cp_trigger_index"
|
#define VIBRATOR_CP_TRIGGER_PATH \
|
||||||
|
"/sys/class/timed_output/vibrator/cp_trigger_index"
|
||||||
|
|
||||||
using ::aidl::android::hardware::vibrator::IVibratorCallback;
|
|
||||||
using ::aidl::android::hardware::vibrator::Braking;
|
using ::aidl::android::hardware::vibrator::Braking;
|
||||||
using ::aidl::android::hardware::vibrator::Effect;
|
|
||||||
using ::aidl::android::hardware::vibrator::EffectStrength;
|
|
||||||
using ::aidl::android::hardware::vibrator::CompositeEffect;
|
using ::aidl::android::hardware::vibrator::CompositeEffect;
|
||||||
using ::aidl::android::hardware::vibrator::CompositePrimitive;
|
using ::aidl::android::hardware::vibrator::CompositePrimitive;
|
||||||
|
using ::aidl::android::hardware::vibrator::Effect;
|
||||||
|
using ::aidl::android::hardware::vibrator::EffectStrength;
|
||||||
|
using ::aidl::android::hardware::vibrator::IVibratorCallback;
|
||||||
using ::aidl::android::hardware::vibrator::PrimitivePwle;
|
using ::aidl::android::hardware::vibrator::PrimitivePwle;
|
||||||
|
|
||||||
namespace aidl {
|
namespace aidl {
|
||||||
|
|
@ -31,44 +32,61 @@ namespace vibrator {
|
||||||
|
|
||||||
class Vibrator : public BnVibrator {
|
class Vibrator : public BnVibrator {
|
||||||
public:
|
public:
|
||||||
Vibrator();
|
Vibrator();
|
||||||
ndk::ScopedAStatus getCapabilities(int32_t* _aidl_return) override;
|
ndk::ScopedAStatus getCapabilities(int32_t *_aidl_return) override;
|
||||||
ndk::ScopedAStatus off() override;
|
ndk::ScopedAStatus off() override;
|
||||||
ndk::ScopedAStatus on(int32_t timeoutMs, const std::shared_ptr<IVibratorCallback>& callback) override;
|
ndk::ScopedAStatus
|
||||||
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength, const std::shared_ptr<IVibratorCallback>& callback, int32_t* _aidl_return) override;
|
on(int32_t timeoutMs,
|
||||||
ndk::ScopedAStatus getSupportedEffects(std::vector<Effect>* _aidl_return) override;
|
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||||
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
ndk::ScopedAStatus perform(Effect effect, EffectStrength strength,
|
||||||
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
const std::shared_ptr<IVibratorCallback> &callback,
|
||||||
ndk::ScopedAStatus getCompositionDelayMax(int32_t* _aidl_return) override;
|
int32_t *_aidl_return) override;
|
||||||
ndk::ScopedAStatus getCompositionSizeMax(int32_t* _aidl_return) override;
|
ndk::ScopedAStatus
|
||||||
ndk::ScopedAStatus getSupportedPrimitives(std::vector<CompositePrimitive>* _aidl_return) override;
|
getSupportedEffects(std::vector<Effect> *_aidl_return) override;
|
||||||
ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive, int32_t* _aidl_return) override;
|
ndk::ScopedAStatus setAmplitude(float amplitude) override;
|
||||||
ndk::ScopedAStatus compose(const std::vector<CompositeEffect>& composite, const std::shared_ptr<IVibratorCallback>& callback) override;
|
ndk::ScopedAStatus setExternalControl(bool enabled) override;
|
||||||
ndk::ScopedAStatus getSupportedAlwaysOnEffects(std::vector<Effect>* _aidl_return) override;
|
ndk::ScopedAStatus getCompositionDelayMax(int32_t *_aidl_return) override;
|
||||||
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect, EffectStrength strength) override;
|
ndk::ScopedAStatus getCompositionSizeMax(int32_t *_aidl_return) override;
|
||||||
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
|
ndk::ScopedAStatus getSupportedPrimitives(
|
||||||
ndk::ScopedAStatus getResonantFrequency(float* _aidl_return) override;
|
std::vector<CompositePrimitive> *_aidl_return) override;
|
||||||
ndk::ScopedAStatus getQFactor(float* _aidl_return) override;
|
ndk::ScopedAStatus getPrimitiveDuration(CompositePrimitive primitive,
|
||||||
ndk::ScopedAStatus getFrequencyResolution(float* _aidl_return) override;
|
int32_t *_aidl_return) override;
|
||||||
ndk::ScopedAStatus getFrequencyMinimum(float* _aidl_return) override;
|
ndk::ScopedAStatus
|
||||||
ndk::ScopedAStatus getBandwidthAmplitudeMap(std::vector<float>* _aidl_return) override;
|
compose(const std::vector<CompositeEffect> &composite,
|
||||||
ndk::ScopedAStatus getPwlePrimitiveDurationMax(int32_t* _aidl_return) override;
|
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||||
ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t* _aidl_return) override;
|
ndk::ScopedAStatus
|
||||||
ndk::ScopedAStatus getSupportedBraking(std::vector<Braking>* _aidl_return) override;
|
getSupportedAlwaysOnEffects(std::vector<Effect> *_aidl_return) override;
|
||||||
ndk::ScopedAStatus composePwle(const std::vector<PrimitivePwle>& composite, const std::shared_ptr<IVibratorCallback>& callback) override;
|
ndk::ScopedAStatus alwaysOnEnable(int32_t id, Effect effect,
|
||||||
|
EffectStrength strength) override;
|
||||||
|
ndk::ScopedAStatus alwaysOnDisable(int32_t id) override;
|
||||||
|
ndk::ScopedAStatus getResonantFrequency(float *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus getQFactor(float *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus getFrequencyResolution(float *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus getFrequencyMinimum(float *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus
|
||||||
|
getBandwidthAmplitudeMap(std::vector<float> *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus
|
||||||
|
getPwlePrimitiveDurationMax(int32_t *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus getPwleCompositionSizeMax(int32_t *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus
|
||||||
|
getSupportedBraking(std::vector<Braking> *_aidl_return) override;
|
||||||
|
ndk::ScopedAStatus
|
||||||
|
composePwle(const std::vector<PrimitivePwle> &composite,
|
||||||
|
const std::shared_ptr<IVibratorCallback> &callback) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ndk::ScopedAStatus activate(uint32_t ms);
|
ndk::ScopedAStatus activate(uint32_t ms);
|
||||||
static uint32_t effectToMs(Effect effect, ndk::ScopedAStatus* status);
|
static uint32_t effectToMs(Effect effect, ndk::ScopedAStatus *status);
|
||||||
static uint8_t strengthToAmplitude(EffectStrength strength, ndk::ScopedAStatus* status);
|
static uint8_t strengthToAmplitude(EffectStrength strength,
|
||||||
|
ndk::ScopedAStatus *status);
|
||||||
|
|
||||||
bool mEnabled{false};
|
bool mEnabled{false};
|
||||||
bool mExternalControl{false};
|
bool mExternalControl{false};
|
||||||
std::mutex mMutex;
|
std::mutex mMutex;
|
||||||
|
|
||||||
bool mIsTimedOutVibrator;
|
bool mIsTimedOutVibrator;
|
||||||
bool mHasTimedOutIntensity;
|
bool mHasTimedOutIntensity;
|
||||||
bool mHasTimedOutEffect;
|
bool mHasTimedOutEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace vibrator
|
} // namespace vibrator
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,22 @@
|
||||||
|
|
||||||
#include "Vibrator.h"
|
#include "Vibrator.h"
|
||||||
|
|
||||||
|
#include <android-base/logging.h>
|
||||||
#include <android/binder_manager.h>
|
#include <android/binder_manager.h>
|
||||||
#include <android/binder_process.h>
|
#include <android/binder_process.h>
|
||||||
#include <android-base/logging.h>
|
|
||||||
|
|
||||||
using ::aidl::android::hardware::vibrator::Vibrator;
|
using ::aidl::android::hardware::vibrator::Vibrator;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||||
std::shared_ptr<Vibrator> vibrator = ndk::SharedRefBase::make<Vibrator>();
|
std::shared_ptr<Vibrator> vibrator = ndk::SharedRefBase::make<Vibrator>();
|
||||||
|
|
||||||
const std::string instance = std::string() + Vibrator::descriptor + "/default";
|
const std::string instance =
|
||||||
binder_status_t status = AServiceManager_addService(vibrator->asBinder().get(), instance.c_str());
|
std::string() + Vibrator::descriptor + "/default";
|
||||||
CHECK(status == STATUS_OK);
|
binder_status_t status =
|
||||||
|
AServiceManager_addService(vibrator->asBinder().get(), instance.c_str());
|
||||||
|
CHECK(status == STATUS_OK);
|
||||||
|
|
||||||
ABinderProcess_joinThreadPool();
|
ABinderProcess_joinThreadPool();
|
||||||
return EXIT_FAILURE; // should not reach
|
return EXIT_FAILURE; // should not reach
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,64 +23,69 @@
|
||||||
using ::android::NO_ERROR;
|
using ::android::NO_ERROR;
|
||||||
using ::android::OK;
|
using ::android::OK;
|
||||||
|
|
||||||
using ::android::hardware::Void;
|
|
||||||
using ::android::hardware::hidl_vec;
|
|
||||||
using ::android::hardware::hidl_string;
|
using ::android::hardware::hidl_string;
|
||||||
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::Void;
|
||||||
|
|
||||||
const int kMaxCameraIdLen = 16;
|
const int kMaxCameraIdLen = 16;
|
||||||
|
|
||||||
SamsungCameraProvider::SamsungCameraProvider() : LegacyCameraProviderImpl_2_5() {
|
SamsungCameraProvider::SamsungCameraProvider()
|
||||||
mExtraIDs.push_back(50);
|
: LegacyCameraProviderImpl_2_5() {
|
||||||
mDisabledIDs.push_back(2);
|
mExtraIDs.push_back(50);
|
||||||
if (!mInitFailed) {
|
mDisabledIDs.push_back(2);
|
||||||
for (int i : mExtraIDs) {
|
if (!mInitFailed) {
|
||||||
struct camera_info info;
|
for (int i : mExtraIDs) {
|
||||||
auto rc = mModule->getCameraInfo(i, &info);
|
struct camera_info info;
|
||||||
|
auto rc = mModule->getCameraInfo(i, &info);
|
||||||
|
|
||||||
if (rc != NO_ERROR) {
|
if (rc != NO_ERROR) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkCameraVersion(i, info) != OK) {
|
if (checkCameraVersion(i, info) != OK) {
|
||||||
ALOGE("Camera version check failed!");
|
ALOGE("Camera version check failed!");
|
||||||
mModule.clear();
|
mModule.clear();
|
||||||
mInitFailed = true;
|
mInitFailed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SAMSUNG_CAMERA_DEBUG
|
#ifdef SAMSUNG_CAMERA_DEBUG
|
||||||
ALOGI("ID=%d is at index %d", i, mNumberOfLegacyCameras);
|
ALOGI("ID=%d is at index %d", i, mNumberOfLegacyCameras);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char cameraId[kMaxCameraIdLen];
|
char cameraId[kMaxCameraIdLen];
|
||||||
snprintf(cameraId, sizeof(cameraId), "%d", i);
|
snprintf(cameraId, sizeof(cameraId), "%d", i);
|
||||||
std::string cameraIdStr(cameraId);
|
std::string cameraIdStr(cameraId);
|
||||||
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
|
mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
|
||||||
|
|
||||||
addDeviceNames(i);
|
addDeviceNames(i);
|
||||||
mNumberOfLegacyCameras++;
|
mNumberOfLegacyCameras++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> SamsungCameraProvider::getCameraIdList(
|
Return<void> SamsungCameraProvider::getCameraIdList(
|
||||||
ICameraProvider::getCameraIdList_cb _hidl_cb) {
|
ICameraProvider::getCameraIdList_cb _hidl_cb) {
|
||||||
std::vector<hidl_string> deviceNameList;
|
std::vector<hidl_string> deviceNameList;
|
||||||
for (auto const& deviceNamePair : mCameraDeviceNames) {
|
for (auto const &deviceNamePair : mCameraDeviceNames) {
|
||||||
int id = std::stoi(deviceNamePair.first);
|
int id = std::stoi(deviceNamePair.first);
|
||||||
if (id >= mNumberOfLegacyCameras || std::find(mDisabledIDs.begin(), mDisabledIDs.end(), id) != mDisabledIDs.end()) {
|
if (id >= mNumberOfLegacyCameras ||
|
||||||
// External camera devices must be reported through the device status change callback,
|
std::find(mDisabledIDs.begin(), mDisabledIDs.end(), id) !=
|
||||||
// not in this list.
|
mDisabledIDs.end()) {
|
||||||
// Linux4: Also skip disabled camera IDs.
|
// External camera devices must be reported through the device status
|
||||||
continue;
|
// change callback, not in this list. Linux4: Also skip disabled camera
|
||||||
}
|
// IDs.
|
||||||
if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
|
continue;
|
||||||
deviceNameList.push_back(deviceNamePair.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
|
if (mCameraStatusMap[deviceNamePair.first] ==
|
||||||
_hidl_cb(::android::hardware::camera::common::V1_0::Status::OK, hidlDeviceNameList);
|
CAMERA_DEVICE_STATUS_PRESENT) {
|
||||||
return Void();
|
deviceNameList.push_back(deviceNamePair.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
|
||||||
|
_hidl_cb(::android::hardware::camera::common::V1_0::Status::OK,
|
||||||
|
hidlDeviceNameList);
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
SamsungCameraProvider::~SamsungCameraProvider() {}
|
SamsungCameraProvider::~SamsungCameraProvider() {}
|
||||||
|
|
|
||||||
|
|
@ -20,19 +20,21 @@
|
||||||
|
|
||||||
#define SAMSUNG_CAMERA_DEBUG
|
#define SAMSUNG_CAMERA_DEBUG
|
||||||
|
|
||||||
using ::android::hardware::camera::provider::V2_5::ICameraProvider;
|
|
||||||
using ::android::hardware::camera::provider::V2_5::implementation::LegacyCameraProviderImpl_2_5;
|
|
||||||
using ::android::hardware::Return;
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::camera::provider::V2_5::ICameraProvider;
|
||||||
|
using ::android::hardware::camera::provider::V2_5::implementation::
|
||||||
|
LegacyCameraProviderImpl_2_5;
|
||||||
|
|
||||||
class SamsungCameraProvider : public LegacyCameraProviderImpl_2_5 {
|
class SamsungCameraProvider : public LegacyCameraProviderImpl_2_5 {
|
||||||
public:
|
public:
|
||||||
SamsungCameraProvider();
|
SamsungCameraProvider();
|
||||||
~SamsungCameraProvider();
|
~SamsungCameraProvider();
|
||||||
|
|
||||||
|
Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
|
||||||
|
|
||||||
Return<void> getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb);
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> mExtraIDs;
|
std::vector<int> mExtraIDs;
|
||||||
std::vector<int> mDisabledIDs;
|
std::vector<int> mDisabledIDs;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SAMSUNG_CAMERA_PROVIDER_H
|
#endif // SAMSUNG_CAMERA_PROVIDER_H
|
||||||
|
|
|
||||||
|
|
@ -28,21 +28,22 @@
|
||||||
using android::status_t;
|
using android::status_t;
|
||||||
using android::hardware::camera::provider::V2_5::ICameraProvider;
|
using android::hardware::camera::provider::V2_5::ICameraProvider;
|
||||||
|
|
||||||
int main()
|
int main() {
|
||||||
{
|
using namespace android::hardware::camera::provider::V2_5::implementation;
|
||||||
using namespace android::hardware::camera::provider::V2_5::implementation;
|
|
||||||
|
|
||||||
ALOGI("CameraProvider@2.5 legacy service is starting.");
|
ALOGI("CameraProvider@2.5 legacy service is starting.");
|
||||||
|
|
||||||
::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT, /*willJoin*/ true);
|
::android::hardware::configureRpcThreadpool(/*threads*/ HWBINDER_THREAD_COUNT,
|
||||||
|
/*willJoin*/ true);
|
||||||
|
|
||||||
::android::sp<ICameraProvider> provider = new CameraProvider<SamsungCameraProvider>();
|
::android::sp<ICameraProvider> provider =
|
||||||
|
new CameraProvider<SamsungCameraProvider>();
|
||||||
|
|
||||||
status_t status = provider->registerAsService("legacy/0");
|
status_t status = provider->registerAsService("legacy/0");
|
||||||
LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering provider service: %d",
|
LOG_ALWAYS_FATAL_IF(status != android::OK,
|
||||||
status);
|
"Error while registering provider service: %d", status);
|
||||||
|
|
||||||
::android::hardware::joinRpcThreadpool();
|
::android::hardware::joinRpcThreadpool();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@
|
||||||
|
|
||||||
#include <hardware/hw_auth_token.h>
|
#include <hardware/hw_auth_token.h>
|
||||||
|
|
||||||
|
#include "BiometricsFingerprint.h"
|
||||||
#include <hardware/fingerprint.h>
|
#include <hardware/fingerprint.h>
|
||||||
#include <hardware/hardware.h>
|
#include <hardware/hardware.h>
|
||||||
#include "BiometricsFingerprint.h"
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <fstream>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#ifdef HAS_FINGERPRINT_GESTURES
|
#ifdef HAS_FINGERPRINT_GESTURES
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
@ -39,481 +39,501 @@ namespace fingerprint {
|
||||||
namespace V2_3 {
|
namespace V2_3 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
using RequestStatus =
|
||||||
|
android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
||||||
|
|
||||||
BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr;
|
BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr;
|
||||||
|
|
||||||
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) {
|
BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr) {
|
||||||
sInstance = this; // keep track of the most recent instance
|
sInstance = this; // keep track of the most recent instance
|
||||||
if (!openHal()) {
|
if (!openHal()) {
|
||||||
LOG(ERROR) << "Can't open HAL module";
|
LOG(ERROR) << "Can't open HAL module";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_FINGERPRINT_GESTURES
|
#ifdef HAS_FINGERPRINT_GESTURES
|
||||||
request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1);
|
request(FINGERPRINT_REQUEST_NAVIGATION_MODE_START, 1);
|
||||||
|
|
||||||
uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
uinputFd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||||
if (uinputFd < 0) {
|
if (uinputFd < 0) {
|
||||||
LOG(ERROR) << "Unable to open uinput node";
|
LOG(ERROR) << "Unable to open uinput node";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) | ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) |
|
int err = ioctl(uinputFd, UI_SET_EVBIT, EV_KEY) |
|
||||||
ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN);
|
ioctl(uinputFd, UI_SET_KEYBIT, KEY_UP) |
|
||||||
if (err != 0) {
|
ioctl(uinputFd, UI_SET_KEYBIT, KEY_DOWN);
|
||||||
LOG(ERROR) << "Unable to enable key events";
|
if (err != 0) {
|
||||||
return;
|
LOG(ERROR) << "Unable to enable key events";
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(uidev.name, "uinput-sec-fp");
|
sprintf(uidev.name, "uinput-sec-fp");
|
||||||
uidev.id.bustype = BUS_VIRTUAL;
|
uidev.id.bustype = BUS_VIRTUAL;
|
||||||
|
|
||||||
err = write(uinputFd, &uidev, sizeof(uidev));
|
err = write(uinputFd, &uidev, sizeof(uidev));
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
LOG(ERROR) << "Write user device to uinput node failed";
|
LOG(ERROR) << "Write user device to uinput node failed";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioctl(uinputFd, UI_DEV_CREATE);
|
err = ioctl(uinputFd, UI_DEV_CREATE);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
LOG(ERROR) << "Unable to create uinput device";
|
LOG(ERROR) << "Unable to create uinput device";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures";
|
LOG(INFO) << "Successfully registered uinput-sec-fp for fingerprint gestures";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
BiometricsFingerprint::~BiometricsFingerprint() {
|
BiometricsFingerprint::~BiometricsFingerprint() {
|
||||||
if (ss_fingerprint_close() != 0) {
|
if (ss_fingerprint_close() != 0) {
|
||||||
LOG(ERROR) << "Can't close HAL module";
|
LOG(ERROR) << "Can't close HAL module";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
|
Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
|
||||||
std::ifstream in("/sys/devices/virtual/fingerprint/fingerprint/position");
|
std::ifstream in("/sys/devices/virtual/fingerprint/fingerprint/position");
|
||||||
if (in) {
|
if (in) {
|
||||||
in.close();
|
in.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) {
|
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float,
|
||||||
return Void();
|
float) {
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> BiometricsFingerprint::onFingerUp() {
|
Return<void> BiometricsFingerprint::onFingerUp() { return Void(); }
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
|
Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case 0:
|
case 0:
|
||||||
return RequestStatus::SYS_OK;
|
return RequestStatus::SYS_OK;
|
||||||
case -2:
|
case -2:
|
||||||
return RequestStatus::SYS_ENOENT;
|
return RequestStatus::SYS_ENOENT;
|
||||||
case -4:
|
case -4:
|
||||||
return RequestStatus::SYS_EINTR;
|
return RequestStatus::SYS_EINTR;
|
||||||
case -5:
|
case -5:
|
||||||
return RequestStatus::SYS_EIO;
|
return RequestStatus::SYS_EIO;
|
||||||
case -11:
|
case -11:
|
||||||
return RequestStatus::SYS_EAGAIN;
|
return RequestStatus::SYS_EAGAIN;
|
||||||
case -12:
|
case -12:
|
||||||
return RequestStatus::SYS_ENOMEM;
|
return RequestStatus::SYS_ENOMEM;
|
||||||
case -13:
|
case -13:
|
||||||
return RequestStatus::SYS_EACCES;
|
return RequestStatus::SYS_EACCES;
|
||||||
case -14:
|
case -14:
|
||||||
return RequestStatus::SYS_EFAULT;
|
return RequestStatus::SYS_EFAULT;
|
||||||
case -16:
|
case -16:
|
||||||
return RequestStatus::SYS_EBUSY;
|
return RequestStatus::SYS_EBUSY;
|
||||||
case -22:
|
case -22:
|
||||||
return RequestStatus::SYS_EINVAL;
|
return RequestStatus::SYS_EINVAL;
|
||||||
case -28:
|
case -28:
|
||||||
return RequestStatus::SYS_ENOSPC;
|
return RequestStatus::SYS_ENOSPC;
|
||||||
case -110:
|
case -110:
|
||||||
return RequestStatus::SYS_ETIMEDOUT;
|
return RequestStatus::SYS_ETIMEDOUT;
|
||||||
default:
|
default:
|
||||||
LOG(ERROR) << "An unknown error returned from fingerprint vendor library: " << error;
|
LOG(ERROR) << "An unknown error returned from fingerprint vendor library: "
|
||||||
return RequestStatus::SYS_UNKNOWN;
|
<< error;
|
||||||
}
|
return RequestStatus::SYS_UNKNOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate from errors returned by traditional HAL (see fingerprint.h) to
|
// Translate from errors returned by traditional HAL (see fingerprint.h) to
|
||||||
// HIDL-compliant FingerprintError.
|
// HIDL-compliant FingerprintError.
|
||||||
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) {
|
FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error,
|
||||||
*vendorCode = 0;
|
int32_t *vendorCode) {
|
||||||
switch (error) {
|
*vendorCode = 0;
|
||||||
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
|
switch (error) {
|
||||||
return FingerprintError::ERROR_HW_UNAVAILABLE;
|
case FINGERPRINT_ERROR_HW_UNAVAILABLE:
|
||||||
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
|
return FingerprintError::ERROR_HW_UNAVAILABLE;
|
||||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
|
||||||
case FINGERPRINT_ERROR_TIMEOUT:
|
|
||||||
return FingerprintError::ERROR_TIMEOUT;
|
|
||||||
case FINGERPRINT_ERROR_NO_SPACE:
|
|
||||||
return FingerprintError::ERROR_NO_SPACE;
|
|
||||||
case FINGERPRINT_ERROR_CANCELED:
|
|
||||||
return FingerprintError::ERROR_CANCELED;
|
|
||||||
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
|
|
||||||
return FingerprintError::ERROR_UNABLE_TO_REMOVE;
|
|
||||||
case FINGERPRINT_ERROR_LOCKOUT:
|
|
||||||
return FingerprintError::ERROR_LOCKOUT;
|
|
||||||
default:
|
|
||||||
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
|
|
||||||
// vendor specific code.
|
|
||||||
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
|
|
||||||
return FingerprintError::ERROR_VENDOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error;
|
|
||||||
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
||||||
|
case FINGERPRINT_ERROR_TIMEOUT:
|
||||||
|
return FingerprintError::ERROR_TIMEOUT;
|
||||||
|
case FINGERPRINT_ERROR_NO_SPACE:
|
||||||
|
return FingerprintError::ERROR_NO_SPACE;
|
||||||
|
case FINGERPRINT_ERROR_CANCELED:
|
||||||
|
return FingerprintError::ERROR_CANCELED;
|
||||||
|
case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
|
||||||
|
return FingerprintError::ERROR_UNABLE_TO_REMOVE;
|
||||||
|
case FINGERPRINT_ERROR_LOCKOUT:
|
||||||
|
return FingerprintError::ERROR_LOCKOUT;
|
||||||
|
default:
|
||||||
|
if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
|
||||||
|
// vendor specific code.
|
||||||
|
*vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
|
||||||
|
return FingerprintError::ERROR_VENDOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(ERROR) << "Unknown error from fingerprint vendor library: " << error;
|
||||||
|
return FingerprintError::ERROR_UNABLE_TO_PROCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
|
// Translate acquired messages returned by traditional HAL (see fingerprint.h)
|
||||||
// to HIDL-compliant FingerprintAcquiredInfo.
|
// to HIDL-compliant FingerprintAcquiredInfo.
|
||||||
FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(int32_t info,
|
FingerprintAcquiredInfo
|
||||||
int32_t* vendorCode) {
|
BiometricsFingerprint::VendorAcquiredFilter(int32_t info, int32_t *vendorCode) {
|
||||||
*vendorCode = 0;
|
*vendorCode = 0;
|
||||||
switch (info) {
|
switch (info) {
|
||||||
case FINGERPRINT_ACQUIRED_GOOD:
|
case FINGERPRINT_ACQUIRED_GOOD:
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_GOOD;
|
return FingerprintAcquiredInfo::ACQUIRED_GOOD;
|
||||||
case FINGERPRINT_ACQUIRED_PARTIAL:
|
case FINGERPRINT_ACQUIRED_PARTIAL:
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
|
return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
|
||||||
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
case FINGERPRINT_ACQUIRED_INSUFFICIENT:
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
|
||||||
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
|
|
||||||
case FINGERPRINT_ACQUIRED_TOO_SLOW:
|
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
|
|
||||||
case FINGERPRINT_ACQUIRED_TOO_FAST:
|
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
|
|
||||||
default:
|
|
||||||
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
|
|
||||||
// vendor specific code.
|
|
||||||
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
|
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
|
|
||||||
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
||||||
|
case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
|
||||||
|
return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
|
||||||
|
case FINGERPRINT_ACQUIRED_TOO_SLOW:
|
||||||
|
return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
|
||||||
|
case FINGERPRINT_ACQUIRED_TOO_FAST:
|
||||||
|
return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
|
||||||
|
default:
|
||||||
|
if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
|
||||||
|
// vendor specific code.
|
||||||
|
*vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
|
||||||
|
return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(ERROR) << "Unknown acquiredmsg from fingerprint vendor library: " << info;
|
||||||
|
return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<uint64_t> BiometricsFingerprint::setNotify(
|
Return<uint64_t> BiometricsFingerprint::setNotify(
|
||||||
const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
|
const sp<IBiometricsFingerprintClientCallback> &clientCallback) {
|
||||||
std::lock_guard<std::mutex> lock(mClientCallbackMutex);
|
std::lock_guard<std::mutex> lock(mClientCallbackMutex);
|
||||||
mClientCallback = clientCallback;
|
mClientCallback = clientCallback;
|
||||||
// This is here because HAL 2.3 doesn't have a way to propagate a
|
// This is here because HAL 2.3 doesn't have a way to propagate a
|
||||||
// unique token for its driver. Subsequent versions should send a unique
|
// unique token for its driver. Subsequent versions should send a unique
|
||||||
// token for each call to setNotify(). This is fine as long as there's only
|
// token for each call to setNotify(). This is fine as long as there's only
|
||||||
// one fingerprint device on the platform.
|
// one fingerprint device on the platform.
|
||||||
return reinterpret_cast<uint64_t>(this);
|
return reinterpret_cast<uint64_t>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<uint64_t> BiometricsFingerprint::preEnroll() {
|
Return<uint64_t> BiometricsFingerprint::preEnroll() {
|
||||||
return ss_fingerprint_pre_enroll();
|
return ss_fingerprint_pre_enroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
|
Return<RequestStatus>
|
||||||
uint32_t gid, uint32_t timeoutSec) {
|
BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69> &hat, uint32_t gid,
|
||||||
const hw_auth_token_t* authToken = reinterpret_cast<const hw_auth_token_t*>(hat.data());
|
uint32_t timeoutSec) {
|
||||||
|
const hw_auth_token_t *authToken =
|
||||||
|
reinterpret_cast<const hw_auth_token_t *>(hat.data());
|
||||||
|
|
||||||
return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec));
|
return ErrorFilter(ss_fingerprint_enroll(authToken, gid, timeoutSec));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::postEnroll() {
|
Return<RequestStatus> BiometricsFingerprint::postEnroll() {
|
||||||
return ErrorFilter(ss_fingerprint_post_enroll());
|
return ErrorFilter(ss_fingerprint_post_enroll());
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
|
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
|
||||||
return ss_fingerprint_get_auth_id();
|
return ss_fingerprint_get_auth_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::cancel() {
|
Return<RequestStatus> BiometricsFingerprint::cancel() {
|
||||||
int32_t ret = ss_fingerprint_cancel();
|
int32_t ret = ss_fingerprint_cancel();
|
||||||
|
|
||||||
#ifdef CALL_NOTIFY_ON_CANCEL
|
#ifdef CALL_NOTIFY_ON_CANCEL
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
fingerprint_msg_t msg{};
|
fingerprint_msg_t msg{};
|
||||||
msg.type = FINGERPRINT_ERROR;
|
msg.type = FINGERPRINT_ERROR;
|
||||||
msg.data.error = FINGERPRINT_ERROR_CANCELED;
|
msg.data.error = FINGERPRINT_ERROR_CANCELED;
|
||||||
notify(&msg);
|
notify(&msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ErrorFilter(ret);
|
return ErrorFilter(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::enumerate() {
|
Return<RequestStatus> BiometricsFingerprint::enumerate() {
|
||||||
if (ss_fingerprint_enumerate != nullptr) {
|
if (ss_fingerprint_enumerate != nullptr) {
|
||||||
return ErrorFilter(ss_fingerprint_enumerate());
|
return ErrorFilter(ss_fingerprint_enumerate());
|
||||||
}
|
}
|
||||||
|
|
||||||
return RequestStatus::SYS_UNKNOWN;
|
return RequestStatus::SYS_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
|
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid,
|
||||||
return ErrorFilter(ss_fingerprint_remove(gid, fid));
|
uint32_t fid) {
|
||||||
|
return ErrorFilter(ss_fingerprint_remove(gid, fid));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
|
Return<RequestStatus>
|
||||||
const hidl_string& storePath) {
|
BiometricsFingerprint::setActiveGroup(uint32_t gid,
|
||||||
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
|
const hidl_string &storePath) {
|
||||||
LOG(ERROR) << "Bad path length: " << storePath.size();
|
if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
|
||||||
return RequestStatus::SYS_EINVAL;
|
LOG(ERROR) << "Bad path length: " << storePath.size();
|
||||||
}
|
return RequestStatus::SYS_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (access(storePath.c_str(), W_OK)) {
|
if (access(storePath.c_str(), W_OK)) {
|
||||||
return RequestStatus::SYS_EINVAL;
|
return RequestStatus::SYS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str()));
|
return ErrorFilter(ss_fingerprint_set_active_group(gid, storePath.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
|
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
|
||||||
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid));
|
uint32_t gid) {
|
||||||
|
return ErrorFilter(ss_fingerprint_authenticate(operationId, gid));
|
||||||
}
|
}
|
||||||
|
|
||||||
IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
|
IBiometricsFingerprint *BiometricsFingerprint::getInstance() {
|
||||||
if (!sInstance) {
|
if (!sInstance) {
|
||||||
sInstance = new BiometricsFingerprint();
|
sInstance = new BiometricsFingerprint();
|
||||||
}
|
}
|
||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BiometricsFingerprint::openHal() {
|
bool BiometricsFingerprint::openHal() {
|
||||||
void* handle = dlopen("libbauthserver.so", RTLD_NOW);
|
void *handle = dlopen("libbauthserver.so", RTLD_NOW);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
ss_fingerprint_close = reinterpret_cast<typeof(ss_fingerprint_close)>(
|
ss_fingerprint_close = reinterpret_cast<typeof(ss_fingerprint_close)>(
|
||||||
dlsym(handle, "ss_fingerprint_close"));
|
dlsym(handle, "ss_fingerprint_close"));
|
||||||
ss_fingerprint_open =
|
ss_fingerprint_open = reinterpret_cast<typeof(ss_fingerprint_open)>(
|
||||||
reinterpret_cast<typeof(ss_fingerprint_open)>(dlsym(handle, "ss_fingerprint_open"));
|
dlsym(handle, "ss_fingerprint_open"));
|
||||||
|
|
||||||
ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
|
ss_set_notify_callback = reinterpret_cast<typeof(ss_set_notify_callback)>(
|
||||||
dlsym(handle, "ss_set_notify_callback"));
|
dlsym(handle, "ss_set_notify_callback"));
|
||||||
ss_fingerprint_pre_enroll = reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
|
ss_fingerprint_pre_enroll =
|
||||||
dlsym(handle, "ss_fingerprint_pre_enroll"));
|
reinterpret_cast<typeof(ss_fingerprint_pre_enroll)>(
|
||||||
ss_fingerprint_enroll = reinterpret_cast<typeof(ss_fingerprint_enroll)>(
|
dlsym(handle, "ss_fingerprint_pre_enroll"));
|
||||||
dlsym(handle, "ss_fingerprint_enroll"));
|
ss_fingerprint_enroll = reinterpret_cast<typeof(ss_fingerprint_enroll)>(
|
||||||
ss_fingerprint_post_enroll = reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
|
dlsym(handle, "ss_fingerprint_enroll"));
|
||||||
dlsym(handle, "ss_fingerprint_post_enroll"));
|
ss_fingerprint_post_enroll =
|
||||||
ss_fingerprint_get_auth_id = reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
|
reinterpret_cast<typeof(ss_fingerprint_post_enroll)>(
|
||||||
dlsym(handle, "ss_fingerprint_get_auth_id"));
|
dlsym(handle, "ss_fingerprint_post_enroll"));
|
||||||
ss_fingerprint_cancel = reinterpret_cast<typeof(ss_fingerprint_cancel)>(
|
ss_fingerprint_get_auth_id =
|
||||||
dlsym(handle, "ss_fingerprint_cancel"));
|
reinterpret_cast<typeof(ss_fingerprint_get_auth_id)>(
|
||||||
ss_fingerprint_enumerate = reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
|
dlsym(handle, "ss_fingerprint_get_auth_id"));
|
||||||
dlsym(handle, "ss_fingerprint_enumerate"));
|
ss_fingerprint_cancel = reinterpret_cast<typeof(ss_fingerprint_cancel)>(
|
||||||
ss_fingerprint_remove = reinterpret_cast<typeof(ss_fingerprint_remove)>(
|
dlsym(handle, "ss_fingerprint_cancel"));
|
||||||
dlsym(handle, "ss_fingerprint_remove"));
|
ss_fingerprint_enumerate =
|
||||||
ss_fingerprint_set_active_group = reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
|
reinterpret_cast<typeof(ss_fingerprint_enumerate)>(
|
||||||
dlsym(handle, "ss_fingerprint_set_active_group"));
|
dlsym(handle, "ss_fingerprint_enumerate"));
|
||||||
ss_fingerprint_authenticate = reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
|
ss_fingerprint_remove = reinterpret_cast<typeof(ss_fingerprint_remove)>(
|
||||||
dlsym(handle, "ss_fingerprint_authenticate"));
|
dlsym(handle, "ss_fingerprint_remove"));
|
||||||
ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>(
|
ss_fingerprint_set_active_group =
|
||||||
dlsym(handle, "ss_fingerprint_request"));
|
reinterpret_cast<typeof(ss_fingerprint_set_active_group)>(
|
||||||
|
dlsym(handle, "ss_fingerprint_set_active_group"));
|
||||||
|
ss_fingerprint_authenticate =
|
||||||
|
reinterpret_cast<typeof(ss_fingerprint_authenticate)>(
|
||||||
|
dlsym(handle, "ss_fingerprint_authenticate"));
|
||||||
|
ss_fingerprint_request = reinterpret_cast<typeof(ss_fingerprint_request)>(
|
||||||
|
dlsym(handle, "ss_fingerprint_request"));
|
||||||
|
|
||||||
if ((err = ss_fingerprint_open(nullptr)) != 0) {
|
if ((err = ss_fingerprint_open(nullptr)) != 0) {
|
||||||
LOG(ERROR) << "Can't open fingerprint, error: " << err;
|
LOG(ERROR) << "Can't open fingerprint, error: " << err;
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) {
|
|
||||||
LOG(ERROR) << "Can't register fingerprint module callback, error: " << err;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if ((err = ss_set_notify_callback(BiometricsFingerprint::notify)) != 0) {
|
||||||
|
LOG(ERROR) << "Can't register fingerprint module callback, error: "
|
||||||
|
<< err;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) {
|
void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
|
||||||
BiometricsFingerprint* thisPtr =
|
BiometricsFingerprint *thisPtr = static_cast<BiometricsFingerprint *>(
|
||||||
static_cast<BiometricsFingerprint*>(BiometricsFingerprint::getInstance());
|
BiometricsFingerprint::getInstance());
|
||||||
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
|
std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
|
||||||
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
|
if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
|
||||||
LOG(ERROR) << "Receiving callbacks before the client callback is registered.";
|
LOG(ERROR)
|
||||||
return;
|
<< "Receiving callbacks before the client callback is registered.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const uint64_t devId = 1;
|
||||||
|
switch (msg->type) {
|
||||||
|
case FINGERPRINT_ERROR: {
|
||||||
|
int32_t vendorCode = 0;
|
||||||
|
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
|
||||||
|
LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
|
||||||
|
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onError callback";
|
||||||
}
|
}
|
||||||
const uint64_t devId = 1;
|
} break;
|
||||||
switch (msg->type) {
|
case FINGERPRINT_ACQUIRED: {
|
||||||
case FINGERPRINT_ERROR: {
|
if (msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) {
|
||||||
int32_t vendorCode = 0;
|
thisPtr->handleEvent(msg->data.acquired.acquired_info);
|
||||||
FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
|
return;
|
||||||
LOG(DEBUG) << "onError(" << static_cast<int>(result) << ")";
|
}
|
||||||
if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
|
int32_t vendorCode = 0;
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onError callback";
|
FingerprintAcquiredInfo result =
|
||||||
}
|
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
|
||||||
} break;
|
LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
|
||||||
case FINGERPRINT_ACQUIRED: {
|
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode)
|
||||||
if (msg->data.acquired.acquired_info > SEM_FINGERPRINT_EVENT_BASE) {
|
.isOk()) {
|
||||||
thisPtr->handleEvent(msg->data.acquired.acquired_info);
|
LOG(ERROR) << "failed to invoke fingerprint onAcquired callback";
|
||||||
return;
|
}
|
||||||
}
|
} break;
|
||||||
int32_t vendorCode = 0;
|
case FINGERPRINT_TEMPLATE_ENROLLING:
|
||||||
FingerprintAcquiredInfo result =
|
|
||||||
VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
|
|
||||||
LOG(DEBUG) << "onAcquired(" << static_cast<int>(result) << ")";
|
|
||||||
if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onAcquired callback";
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case FINGERPRINT_TEMPLATE_ENROLLING:
|
|
||||||
#ifdef USES_PERCENTAGE_SAMPLES
|
#ifdef USES_PERCENTAGE_SAMPLES
|
||||||
const_cast<fingerprint_msg_t*>(msg)->data.enroll.samples_remaining =
|
const_cast<fingerprint_msg_t *>(msg)->data.enroll.samples_remaining =
|
||||||
100 - msg->data.enroll.samples_remaining;
|
100 - msg->data.enroll.samples_remaining;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION
|
#ifdef CALL_CANCEL_ON_ENROLL_COMPLETION
|
||||||
if (msg->data.enroll.samples_remaining == 0) {
|
if (msg->data.enroll.samples_remaining == 0) {
|
||||||
thisPtr->ss_fingerprint_cancel();
|
thisPtr->ss_fingerprint_cancel();
|
||||||
}
|
|
||||||
#endif
|
|
||||||
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
|
|
||||||
<< ", gid=" << msg->data.enroll.finger.gid
|
|
||||||
<< ", rem=" << msg->data.enroll.samples_remaining << ")";
|
|
||||||
if (!thisPtr->mClientCallback
|
|
||||||
->onEnrollResult(devId, msg->data.enroll.finger.fid,
|
|
||||||
msg->data.enroll.finger.gid,
|
|
||||||
msg->data.enroll.samples_remaining)
|
|
||||||
.isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FINGERPRINT_TEMPLATE_REMOVED:
|
|
||||||
LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
|
|
||||||
<< ", gid=" << msg->data.removed.finger.gid
|
|
||||||
<< ", rem=" << msg->data.removed.remaining_templates << ")";
|
|
||||||
if (!thisPtr->mClientCallback
|
|
||||||
->onRemoved(devId, msg->data.removed.finger.fid,
|
|
||||||
msg->data.removed.finger.gid,
|
|
||||||
msg->data.removed.remaining_templates)
|
|
||||||
.isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onRemoved callback";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FINGERPRINT_AUTHENTICATED:
|
|
||||||
LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
|
|
||||||
<< ", gid=" << msg->data.authenticated.finger.gid << ")";
|
|
||||||
if (msg->data.authenticated.finger.fid != 0) {
|
|
||||||
const uint8_t* hat = reinterpret_cast<const uint8_t*>(&msg->data.authenticated.hat);
|
|
||||||
const hidl_vec<uint8_t> token(
|
|
||||||
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
|
|
||||||
if (!thisPtr->mClientCallback
|
|
||||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
|
||||||
msg->data.authenticated.finger.gid, token)
|
|
||||||
.isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not a recognized fingerprint
|
|
||||||
if (!thisPtr->mClientCallback
|
|
||||||
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
|
||||||
msg->data.authenticated.finger.gid,
|
|
||||||
hidl_vec<uint8_t>())
|
|
||||||
.isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FINGERPRINT_TEMPLATE_ENUMERATING:
|
|
||||||
LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
|
|
||||||
<< ", gid=" << msg->data.enumerated.finger.gid
|
|
||||||
<< ", rem=" << msg->data.enumerated.remaining_templates << ")";
|
|
||||||
if (!thisPtr->mClientCallback
|
|
||||||
->onEnumerate(devId, msg->data.enumerated.finger.fid,
|
|
||||||
msg->data.enumerated.finger.gid,
|
|
||||||
msg->data.enumerated.remaining_templates)
|
|
||||||
.isOk()) {
|
|
||||||
LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
LOG(DEBUG) << "onEnrollResult(fid=" << msg->data.enroll.finger.fid
|
||||||
|
<< ", gid=" << msg->data.enroll.finger.gid
|
||||||
|
<< ", rem=" << msg->data.enroll.samples_remaining << ")";
|
||||||
|
if (!thisPtr->mClientCallback
|
||||||
|
->onEnrollResult(devId, msg->data.enroll.finger.fid,
|
||||||
|
msg->data.enroll.finger.gid,
|
||||||
|
msg->data.enroll.samples_remaining)
|
||||||
|
.isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onEnrollResult callback";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FINGERPRINT_TEMPLATE_REMOVED:
|
||||||
|
LOG(DEBUG) << "onRemove(fid=" << msg->data.removed.finger.fid
|
||||||
|
<< ", gid=" << msg->data.removed.finger.gid
|
||||||
|
<< ", rem=" << msg->data.removed.remaining_templates << ")";
|
||||||
|
if (!thisPtr->mClientCallback
|
||||||
|
->onRemoved(devId, msg->data.removed.finger.fid,
|
||||||
|
msg->data.removed.finger.gid,
|
||||||
|
msg->data.removed.remaining_templates)
|
||||||
|
.isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onRemoved callback";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FINGERPRINT_AUTHENTICATED:
|
||||||
|
LOG(DEBUG) << "onAuthenticated(fid=" << msg->data.authenticated.finger.fid
|
||||||
|
<< ", gid=" << msg->data.authenticated.finger.gid << ")";
|
||||||
|
if (msg->data.authenticated.finger.fid != 0) {
|
||||||
|
const uint8_t *hat =
|
||||||
|
reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
|
||||||
|
const hidl_vec<uint8_t> token(
|
||||||
|
std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
|
||||||
|
if (!thisPtr->mClientCallback
|
||||||
|
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
||||||
|
msg->data.authenticated.finger.gid, token)
|
||||||
|
.isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not a recognized fingerprint
|
||||||
|
if (!thisPtr->mClientCallback
|
||||||
|
->onAuthenticated(devId, msg->data.authenticated.finger.fid,
|
||||||
|
msg->data.authenticated.finger.gid,
|
||||||
|
hidl_vec<uint8_t>())
|
||||||
|
.isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onAuthenticated callback";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FINGERPRINT_TEMPLATE_ENUMERATING:
|
||||||
|
LOG(DEBUG) << "onEnumerate(fid=" << msg->data.enumerated.finger.fid
|
||||||
|
<< ", gid=" << msg->data.enumerated.finger.gid
|
||||||
|
<< ", rem=" << msg->data.enumerated.remaining_templates << ")";
|
||||||
|
if (!thisPtr->mClientCallback
|
||||||
|
->onEnumerate(devId, msg->data.enumerated.finger.fid,
|
||||||
|
msg->data.enumerated.finger.gid,
|
||||||
|
msg->data.enumerated.remaining_templates)
|
||||||
|
.isOk()) {
|
||||||
|
LOG(ERROR) << "failed to invoke fingerprint onEnumerate callback";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiometricsFingerprint::handleEvent(int eventCode) {
|
void BiometricsFingerprint::handleEvent(int eventCode) {
|
||||||
switch (eventCode) {
|
switch (eventCode) {
|
||||||
#ifdef HAS_FINGERPRINT_GESTURES
|
#ifdef HAS_FINGERPRINT_GESTURES
|
||||||
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN:
|
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_DOWN:
|
||||||
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP:
|
case SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP:
|
||||||
struct input_event event {};
|
struct input_event event {};
|
||||||
int keycode = eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ? KEY_UP : KEY_DOWN;
|
int keycode =
|
||||||
int err;
|
eventCode == SEM_FINGERPRINT_EVENT_GESTURE_SWIPE_UP ? KEY_UP : KEY_DOWN;
|
||||||
|
int err;
|
||||||
|
|
||||||
// Report the key
|
// Report the key
|
||||||
event.type = EV_KEY;
|
event.type = EV_KEY;
|
||||||
event.code = keycode;
|
event.code = keycode;
|
||||||
event.value = 1;
|
event.value = 1;
|
||||||
err = write(uinputFd, &event, sizeof(event));
|
err = write(uinputFd, &event, sizeof(event));
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Force a flush with an EV_SYN
|
|
||||||
event.type = EV_SYN;
|
|
||||||
event.code = SYN_REPORT;
|
|
||||||
event.value = 0;
|
|
||||||
err = write(uinputFd, &event, sizeof(event));
|
|
||||||
if (err < 0) {
|
|
||||||
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Report the key
|
|
||||||
event.type = EV_KEY;
|
|
||||||
event.code = keycode;
|
|
||||||
event.value = 0;
|
|
||||||
err = write(uinputFd, &event, sizeof(event));
|
|
||||||
if (err < 0) {
|
|
||||||
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force a flush with an EV_SYN
|
|
||||||
event.type = EV_SYN;
|
|
||||||
event.code = SYN_REPORT;
|
|
||||||
event.value = 0;
|
|
||||||
err = write(uinputFd, &event, sizeof(event));
|
|
||||||
if (err < 0) {
|
|
||||||
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Force a flush with an EV_SYN
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
event.value = 0;
|
||||||
|
err = write(uinputFd, &event, sizeof(event));
|
||||||
|
if (err < 0) {
|
||||||
|
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report the key
|
||||||
|
event.type = EV_KEY;
|
||||||
|
event.code = keycode;
|
||||||
|
event.value = 0;
|
||||||
|
err = write(uinputFd, &event, sizeof(event));
|
||||||
|
if (err < 0) {
|
||||||
|
LOG(ERROR) << "Write EV_KEY to uinput node failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a flush with an EV_SYN
|
||||||
|
event.type = EV_SYN;
|
||||||
|
event.code = SYN_REPORT;
|
||||||
|
event.value = 0;
|
||||||
|
err = write(uinputFd, &event, sizeof(event));
|
||||||
|
if (err < 0) {
|
||||||
|
LOG(ERROR) << "Write EV_SYN to uinput node failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int BiometricsFingerprint::request(int cmd, int param) {
|
int BiometricsFingerprint::request(int cmd, int param) {
|
||||||
// TO-DO: input, output handling not implemented
|
// TO-DO: input, output handling not implemented
|
||||||
int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param);
|
int result = ss_fingerprint_request(cmd, nullptr, 0, nullptr, 0, param);
|
||||||
LOG(INFO) << "request(cmd=" << cmd << ", param=" << param << ", result=" << result << ")";
|
LOG(INFO) << "request(cmd=" << cmd << ", param=" << param
|
||||||
return result;
|
<< ", result=" << result << ")";
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BiometricsFingerprint::waitForSensor(std::chrono::milliseconds pollWait,
|
int BiometricsFingerprint::waitForSensor(std::chrono::milliseconds pollWait,
|
||||||
std::chrono::milliseconds timeOut) {
|
std::chrono::milliseconds timeOut) {
|
||||||
int sensorStatus = SEM_SENSOR_STATUS_WORKING;
|
int sensorStatus = SEM_SENSOR_STATUS_WORKING;
|
||||||
std::chrono::milliseconds timeWaited = 0ms;
|
std::chrono::milliseconds timeWaited = 0ms;
|
||||||
while (sensorStatus != SEM_SENSOR_STATUS_OK) {
|
while (sensorStatus != SEM_SENSOR_STATUS_OK) {
|
||||||
if (sensorStatus == SEM_SENSOR_STATUS_CALIBRATION_ERROR ||
|
if (sensorStatus == SEM_SENSOR_STATUS_CALIBRATION_ERROR ||
|
||||||
sensorStatus == SEM_SENSOR_STATUS_ERROR) {
|
sensorStatus == SEM_SENSOR_STATUS_ERROR) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if (timeWaited >= timeOut) {
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
sensorStatus = request(FINGERPRINT_REQUEST_GET_SENSOR_STATUS, 0);
|
|
||||||
std::this_thread::sleep_for(pollWait);
|
|
||||||
timeWaited += pollWait;
|
|
||||||
}
|
}
|
||||||
return 0;
|
if (timeWaited >= timeOut) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
sensorStatus = request(FINGERPRINT_REQUEST_GET_SENSOR_STATUS, 0);
|
||||||
|
std::this_thread::sleep_for(pollWait);
|
||||||
|
timeWaited += pollWait;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V2_3
|
} // namespace V2_3
|
||||||
} // namespace fingerprint
|
} // namespace fingerprint
|
||||||
} // namespace biometrics
|
} // namespace biometrics
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -47,80 +47,92 @@ using ::android::hardware::hidl_string;
|
||||||
using ::android::hardware::hidl_vec;
|
using ::android::hardware::hidl_vec;
|
||||||
using ::android::hardware::Return;
|
using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintAcquiredInfo;
|
using ::android::hardware::biometrics::fingerprint::V2_1::
|
||||||
|
FingerprintAcquiredInfo;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError;
|
using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
|
using ::android::hardware::biometrics::fingerprint::V2_1::
|
||||||
|
IBiometricsFingerprintClientCallback;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint;
|
using ::android::hardware::biometrics::fingerprint::V2_3::
|
||||||
|
IBiometricsFingerprint;
|
||||||
|
|
||||||
struct BiometricsFingerprint : public IBiometricsFingerprint {
|
struct BiometricsFingerprint : public IBiometricsFingerprint {
|
||||||
BiometricsFingerprint();
|
BiometricsFingerprint();
|
||||||
~BiometricsFingerprint();
|
~BiometricsFingerprint();
|
||||||
|
|
||||||
// Method to wrap legacy HAL with BiometricsFingerprint class
|
// Method to wrap legacy HAL with BiometricsFingerprint class
|
||||||
static IBiometricsFingerprint* getInstance();
|
static IBiometricsFingerprint *getInstance();
|
||||||
|
|
||||||
// Methods from ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint
|
// Methods from
|
||||||
// follow.
|
// ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint
|
||||||
Return<uint64_t> setNotify(
|
// follow.
|
||||||
const sp<IBiometricsFingerprintClientCallback>& clientCallback) override;
|
Return<uint64_t> setNotify(
|
||||||
Return<uint64_t> preEnroll() override;
|
const sp<IBiometricsFingerprintClientCallback> &clientCallback) override;
|
||||||
Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid,
|
Return<uint64_t> preEnroll() override;
|
||||||
uint32_t timeoutSec) override;
|
Return<RequestStatus> enroll(const hidl_array<uint8_t, 69> &hat, uint32_t gid,
|
||||||
Return<RequestStatus> postEnroll() override;
|
uint32_t timeoutSec) override;
|
||||||
Return<uint64_t> getAuthenticatorId() override;
|
Return<RequestStatus> postEnroll() override;
|
||||||
Return<RequestStatus> cancel() override;
|
Return<uint64_t> getAuthenticatorId() override;
|
||||||
Return<RequestStatus> enumerate() override;
|
Return<RequestStatus> cancel() override;
|
||||||
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
|
Return<RequestStatus> enumerate() override;
|
||||||
Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
|
Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
|
||||||
Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
|
Return<RequestStatus> setActiveGroup(uint32_t gid,
|
||||||
Return<bool> isUdfps(uint32_t sensorID) override;
|
const hidl_string &storePath) override;
|
||||||
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor, float major) override;
|
Return<RequestStatus> authenticate(uint64_t operationId,
|
||||||
Return<void> onFingerUp() override;
|
uint32_t gid) override;
|
||||||
Return<void> onShowUdfpsOverlay() { return Void(); }
|
Return<bool> isUdfps(uint32_t sensorID) override;
|
||||||
Return<void> onHideUdfpsOverlay() { return Void(); }
|
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor,
|
||||||
|
float major) override;
|
||||||
|
Return<void> onFingerUp() override;
|
||||||
|
Return<void> onShowUdfpsOverlay() { return Void(); }
|
||||||
|
Return<void> onHideUdfpsOverlay() { return Void(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool openHal();
|
bool openHal();
|
||||||
int request(int cmd, int param);
|
int request(int cmd, int param);
|
||||||
int waitForSensor(std::chrono::milliseconds pollWait, std::chrono::milliseconds timeOut);
|
int waitForSensor(std::chrono::milliseconds pollWait,
|
||||||
static void notify(
|
std::chrono::milliseconds timeOut);
|
||||||
const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */
|
static void
|
||||||
void handleEvent(int eventCode);
|
notify(const fingerprint_msg_t
|
||||||
static Return<RequestStatus> ErrorFilter(int32_t error);
|
*msg); /* Static callback for legacy HAL implementation */
|
||||||
static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode);
|
void handleEvent(int eventCode);
|
||||||
static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode);
|
static Return<RequestStatus> ErrorFilter(int32_t error);
|
||||||
static BiometricsFingerprint* sInstance;
|
static FingerprintError VendorErrorFilter(int32_t error, int32_t *vendorCode);
|
||||||
|
static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error,
|
||||||
|
int32_t *vendorCode);
|
||||||
|
static BiometricsFingerprint *sInstance;
|
||||||
|
|
||||||
std::mutex mClientCallbackMutex;
|
std::mutex mClientCallbackMutex;
|
||||||
sp<IBiometricsFingerprintClientCallback> mClientCallback;
|
sp<IBiometricsFingerprintClientCallback> mClientCallback;
|
||||||
#ifdef HAS_FINGERPRINT_GESTURES
|
#ifdef HAS_FINGERPRINT_GESTURES
|
||||||
int uinputFd;
|
int uinputFd;
|
||||||
struct uinput_user_dev uidev {};
|
struct uinput_user_dev uidev {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int (*ss_fingerprint_close)();
|
int (*ss_fingerprint_close)();
|
||||||
int (*ss_fingerprint_open)(const char* id);
|
int (*ss_fingerprint_open)(const char *id);
|
||||||
|
|
||||||
int (*ss_set_notify_callback)(fingerprint_notify_t notify);
|
int (*ss_set_notify_callback)(fingerprint_notify_t notify);
|
||||||
uint64_t (*ss_fingerprint_pre_enroll)();
|
uint64_t (*ss_fingerprint_pre_enroll)();
|
||||||
int (*ss_fingerprint_enroll)(const hw_auth_token_t* hat, uint32_t gid, uint32_t timeout_sec);
|
int (*ss_fingerprint_enroll)(const hw_auth_token_t *hat, uint32_t gid,
|
||||||
int (*ss_fingerprint_post_enroll)();
|
uint32_t timeout_sec);
|
||||||
uint64_t (*ss_fingerprint_get_auth_id)();
|
int (*ss_fingerprint_post_enroll)();
|
||||||
int (*ss_fingerprint_cancel)();
|
uint64_t (*ss_fingerprint_get_auth_id)();
|
||||||
int (*ss_fingerprint_enumerate)();
|
int (*ss_fingerprint_cancel)();
|
||||||
int (*ss_fingerprint_remove)(uint32_t gid, uint32_t fid);
|
int (*ss_fingerprint_enumerate)();
|
||||||
int (*ss_fingerprint_set_active_group)(uint32_t gid, const char* store_path);
|
int (*ss_fingerprint_remove)(uint32_t gid, uint32_t fid);
|
||||||
int (*ss_fingerprint_authenticate)(uint64_t operation_id, uint32_t gid);
|
int (*ss_fingerprint_set_active_group)(uint32_t gid, const char *store_path);
|
||||||
int (*ss_fingerprint_request)(uint32_t cmd, char* inBuf, uint32_t inBuf_length, char* outBuf,
|
int (*ss_fingerprint_authenticate)(uint64_t operation_id, uint32_t gid);
|
||||||
uint32_t outBuf_length, uint32_t param);
|
int (*ss_fingerprint_request)(uint32_t cmd, char *inBuf,
|
||||||
|
uint32_t inBuf_length, char *outBuf,
|
||||||
|
uint32_t outBuf_length, uint32_t param);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V2_3
|
} // namespace V2_3
|
||||||
} // namespace fingerprint
|
} // namespace fingerprint
|
||||||
} // namespace biometrics
|
} // namespace biometrics
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
#endif // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
||||||
|
|
|
||||||
|
|
@ -101,4 +101,4 @@
|
||||||
#define SEM_SENSOR_STATUS_OK 100040
|
#define SEM_SENSOR_STATUS_OK 100040
|
||||||
#define SEM_SENSOR_STATUS_WORKING 100041
|
#define SEM_SENSOR_STATUS_WORKING 100041
|
||||||
|
|
||||||
#endif // SAMSUNG_FINGERPRINT_CONSTANTS_H
|
#endif // SAMSUNG_FINGERPRINT_CONSTANTS_H
|
||||||
|
|
|
||||||
|
|
@ -26,26 +26,28 @@ using android::hardware::configureRpcThreadpool;
|
||||||
using android::hardware::joinRpcThreadpool;
|
using android::hardware::joinRpcThreadpool;
|
||||||
|
|
||||||
using android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint;
|
using android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint;
|
||||||
using android::hardware::biometrics::fingerprint::V2_3::implementation::BiometricsFingerprint;
|
using android::hardware::biometrics::fingerprint::V2_3::implementation::
|
||||||
|
BiometricsFingerprint;
|
||||||
|
|
||||||
using android::OK;
|
using android::OK;
|
||||||
using android::sp;
|
using android::sp;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
android::sp<IBiometricsFingerprint> bio = BiometricsFingerprint::getInstance();
|
android::sp<IBiometricsFingerprint> bio =
|
||||||
|
BiometricsFingerprint::getInstance();
|
||||||
|
|
||||||
configureRpcThreadpool(1, true);
|
configureRpcThreadpool(1, true);
|
||||||
|
|
||||||
if (bio == nullptr || bio->registerAsService() != OK) {
|
if (bio == nullptr || bio->registerAsService() != OK) {
|
||||||
LOG(ERROR) << "Could not register service for Fingerprint HAL";
|
LOG(ERROR) << "Could not register service for Fingerprint HAL";
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Fingerprint HAL service is Ready.";
|
LOG(INFO) << "Fingerprint HAL service is Ready.";
|
||||||
joinRpcThreadpool();
|
joinRpcThreadpool();
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
// In normal operation, we don't expect the thread pool to shutdown
|
// In normal operation, we don't expect the thread pool to shutdown
|
||||||
LOG(ERROR) << "Fingerprint HAL failed to join thread pool.";
|
LOG(ERROR) << "Fingerprint HAL failed to join thread pool.";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,27 +32,27 @@ using android::OK;
|
||||||
using android::status_t;
|
using android::status_t;
|
||||||
|
|
||||||
namespace skeymaster {
|
namespace skeymaster {
|
||||||
IKeymasterDevice* CreateSKeymasterDevice(SecurityLevel securityLevel);
|
IKeymasterDevice *CreateSKeymasterDevice(SecurityLevel securityLevel);
|
||||||
} // namespace skeymaster
|
} // namespace skeymaster
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
IKeymasterDevice* keymaster =
|
IKeymasterDevice *keymaster =
|
||||||
skeymaster::CreateSKeymasterDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
|
skeymaster::CreateSKeymasterDevice(SecurityLevel::TRUSTED_ENVIRONMENT);
|
||||||
|
|
||||||
configureRpcThreadpool(1, true);
|
configureRpcThreadpool(1, true);
|
||||||
|
|
||||||
status_t status = keymaster->registerAsService();
|
status_t status = keymaster->registerAsService();
|
||||||
|
|
||||||
if (status != OK) {
|
if (status != OK) {
|
||||||
LOG(ERROR) << "Could not register service for Keymaster HAL";
|
LOG(ERROR) << "Could not register service for Keymaster HAL";
|
||||||
goto shutdown;
|
goto shutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Keymaster HAL service is Ready.";
|
LOG(INFO) << "Keymaster HAL service is Ready.";
|
||||||
joinRpcThreadpool();
|
joinRpcThreadpool();
|
||||||
|
|
||||||
shutdown:
|
shutdown:
|
||||||
// In normal operation, we don't expect the thread pool to shutdown
|
// In normal operation, we don't expect the thread pool to shutdown
|
||||||
LOG(ERROR) << "Keymaster HAL failed to join thread pool.";
|
LOG(ERROR) << "Keymaster HAL failed to join thread pool.";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,11 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define VERBOSE
|
// #define VERBOSE
|
||||||
|
|
||||||
#include "Sensors.h"
|
#include "Sensors.h"
|
||||||
#include <sensors/convert.h>
|
|
||||||
#include "multihal.h"
|
#include "multihal.h"
|
||||||
|
#include <sensors/convert.h>
|
||||||
|
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
|
||||||
|
|
@ -35,320 +35,332 @@ namespace implementation {
|
||||||
* return true indicating we need to use multi-hal functionality.
|
* return true indicating we need to use multi-hal functionality.
|
||||||
*/
|
*/
|
||||||
static bool UseMultiHal() {
|
static bool UseMultiHal() {
|
||||||
const std::string& name = MULTI_HAL_CONFIG_FILE_PATH;
|
const std::string &name = MULTI_HAL_CONFIG_FILE_PATH;
|
||||||
struct stat buffer;
|
struct stat buffer;
|
||||||
return (stat(name.c_str(), &buffer) == 0);
|
return (stat(name.c_str(), &buffer) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result ResultFromStatus(status_t err) {
|
static Result ResultFromStatus(status_t err) {
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case OK:
|
case OK:
|
||||||
return Result::OK;
|
return Result::OK;
|
||||||
case PERMISSION_DENIED:
|
case PERMISSION_DENIED:
|
||||||
return Result::PERMISSION_DENIED;
|
return Result::PERMISSION_DENIED;
|
||||||
case NO_MEMORY:
|
case NO_MEMORY:
|
||||||
return Result::NO_MEMORY;
|
return Result::NO_MEMORY;
|
||||||
case BAD_VALUE:
|
case BAD_VALUE:
|
||||||
return Result::BAD_VALUE;
|
return Result::BAD_VALUE;
|
||||||
default:
|
default:
|
||||||
return Result::INVALID_OPERATION;
|
return Result::INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Sensors::Sensors() : mInitCheck(NO_INIT), mSensorModule(nullptr), mSensorDevice(nullptr) {
|
Sensors::Sensors()
|
||||||
status_t err = OK;
|
: mInitCheck(NO_INIT), mSensorModule(nullptr), mSensorDevice(nullptr) {
|
||||||
if (UseMultiHal()) {
|
status_t err = OK;
|
||||||
mSensorModule = ::get_multi_hal_module_info();
|
if (UseMultiHal()) {
|
||||||
} else {
|
mSensorModule = ::get_multi_hal_module_info();
|
||||||
err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule);
|
} else {
|
||||||
|
err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
|
||||||
|
(hw_module_t const **)&mSensorModule);
|
||||||
|
}
|
||||||
|
if (mSensorModule == NULL) {
|
||||||
|
err = UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != OK) {
|
||||||
|
LOG(ERROR) << "Couldn't load " << SENSORS_HARDWARE_MODULE_ID << " module ("
|
||||||
|
<< strerror(-err) << ")";
|
||||||
|
|
||||||
|
mInitCheck = err;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
|
||||||
|
|
||||||
|
if (err != OK) {
|
||||||
|
LOG(ERROR) << "Couldn't open device for module "
|
||||||
|
<< SENSORS_HARDWARE_MODULE_ID << " (" << strerror(-err) << ")";
|
||||||
|
|
||||||
|
mInitCheck = err;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Require all the old HAL APIs to be present except for injection, which
|
||||||
|
// is considered optional.
|
||||||
|
CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
|
||||||
|
|
||||||
|
if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
|
||||||
|
if (mSensorDevice->inject_sensor_data == nullptr) {
|
||||||
|
LOG(ERROR) << "HAL specifies version 1.4, but does not implement "
|
||||||
|
"inject_sensor_data()";
|
||||||
}
|
}
|
||||||
if (mSensorModule == NULL) {
|
if (mSensorModule->set_operation_mode == nullptr) {
|
||||||
err = UNKNOWN_ERROR;
|
LOG(ERROR) << "HAL specifies version 1.4, but does not implement "
|
||||||
|
"set_operation_mode()";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (err != OK) {
|
/* Get us all sensors */
|
||||||
LOG(ERROR) << "Couldn't load " << SENSORS_HARDWARE_MODULE_ID << " module ("
|
setOperationMode(static_cast<hardware::sensors::V1_0::OperationMode>(5555));
|
||||||
<< strerror(-err) << ")";
|
|
||||||
|
|
||||||
mInitCheck = err;
|
mInitCheck = OK;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sensors_open_1(&mSensorModule->common, &mSensorDevice);
|
|
||||||
|
|
||||||
if (err != OK) {
|
|
||||||
LOG(ERROR) << "Couldn't open device for module " << SENSORS_HARDWARE_MODULE_ID << " ("
|
|
||||||
<< strerror(-err) << ")";
|
|
||||||
|
|
||||||
mInitCheck = err;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Require all the old HAL APIs to be present except for injection, which
|
|
||||||
// is considered optional.
|
|
||||||
CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
|
|
||||||
|
|
||||||
if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
|
|
||||||
if (mSensorDevice->inject_sensor_data == nullptr) {
|
|
||||||
LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()";
|
|
||||||
}
|
|
||||||
if (mSensorModule->set_operation_mode == nullptr) {
|
|
||||||
LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get us all sensors */
|
|
||||||
setOperationMode(static_cast<hardware::sensors::V1_0::OperationMode>(5555));
|
|
||||||
|
|
||||||
mInitCheck = OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Sensors::initCheck() const {
|
status_t Sensors::initCheck() const { return mInitCheck; }
|
||||||
return mInitCheck;
|
|
||||||
}
|
|
||||||
|
|
||||||
Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) {
|
Return<void> Sensors::getSensorsList(getSensorsList_cb _hidl_cb) {
|
||||||
sensor_t const* list;
|
sensor_t const *list;
|
||||||
size_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
|
size_t count = mSensorModule->get_sensors_list(mSensorModule, &list);
|
||||||
|
|
||||||
hidl_vec<SensorInfo> out;
|
hidl_vec<SensorInfo> out;
|
||||||
out.resize(count);
|
out.resize(count);
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
const sensor_t* src = &list[i];
|
const sensor_t *src = &list[i];
|
||||||
SensorInfo* dst = &out[i];
|
SensorInfo *dst = &out[i];
|
||||||
|
|
||||||
convertFromSensor(*src, dst);
|
convertFromSensor(*src, dst);
|
||||||
|
|
||||||
if (dst->requiredPermission == "com.samsung.permission.SSENSOR") {
|
if (dst->requiredPermission == "com.samsung.permission.SSENSOR") {
|
||||||
dst->requiredPermission = "";
|
dst->requiredPermission = "";
|
||||||
}
|
|
||||||
|
|
||||||
if (dst->typeAsString == "com.samsung.sensor.physical_proximity") {
|
|
||||||
LOG(INFO) << "Fixing com.samsung.sensor.physical_proximity";
|
|
||||||
dst->type = SensorType::PROXIMITY;
|
|
||||||
dst->typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
|
|
||||||
dst->maxRange = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VERBOSE
|
|
||||||
LOG(INFO) << "SENSOR NAME: " << dst->name;
|
|
||||||
LOG(INFO) << " VENDOR: " << dst->name;
|
|
||||||
LOG(INFO) << " TYPE: " << (uint32_t)dst->type;
|
|
||||||
LOG(INFO) << " TYPE_AS_STRING: " << dst->typeAsString;
|
|
||||||
LOG(INFO) << " FLAGS: " << std::hex << dst->flags;
|
|
||||||
LOG(INFO) << "";
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_hidl_cb(out);
|
if (dst->typeAsString == "com.samsung.sensor.physical_proximity") {
|
||||||
|
LOG(INFO) << "Fixing com.samsung.sensor.physical_proximity";
|
||||||
|
dst->type = SensorType::PROXIMITY;
|
||||||
|
dst->typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
|
||||||
|
dst->maxRange = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return Void();
|
#ifdef VERBOSE
|
||||||
|
LOG(INFO) << "SENSOR NAME: " << dst->name;
|
||||||
|
LOG(INFO) << " VENDOR: " << dst->name;
|
||||||
|
LOG(INFO) << " TYPE: " << (uint32_t)dst->type;
|
||||||
|
LOG(INFO) << " TYPE_AS_STRING: " << dst->typeAsString;
|
||||||
|
LOG(INFO) << " FLAGS: " << std::hex << dst->flags;
|
||||||
|
LOG(INFO) << "";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
_hidl_cb(out);
|
||||||
|
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Sensors::getHalDeviceVersion() const {
|
int Sensors::getHalDeviceVersion() const {
|
||||||
if (!mSensorDevice) {
|
if (!mSensorDevice) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mSensorDevice->common.version;
|
return mSensorDevice->common.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::setOperationMode(OperationMode mode) {
|
Return<Result> Sensors::setOperationMode(OperationMode mode) {
|
||||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
||||||
mSensorModule->set_operation_mode == nullptr) {
|
mSensorModule->set_operation_mode == nullptr) {
|
||||||
return Result::INVALID_OPERATION;
|
return Result::INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
|
return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::activate(int32_t sensor_handle, bool enabled) {
|
Return<Result> Sensors::activate(int32_t sensor_handle, bool enabled) {
|
||||||
return ResultFromStatus(mSensorDevice->activate(
|
return ResultFromStatus(mSensorDevice->activate(
|
||||||
reinterpret_cast<sensors_poll_device_t*>(mSensorDevice), sensor_handle, enabled));
|
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice), sensor_handle,
|
||||||
|
enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) {
|
Return<void> Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) {
|
||||||
hidl_vec<Event> out;
|
hidl_vec<Event> out;
|
||||||
hidl_vec<SensorInfo> dynamicSensorsAdded;
|
hidl_vec<SensorInfo> dynamicSensorsAdded;
|
||||||
|
|
||||||
std::unique_ptr<sensors_event_t[]> data;
|
std::unique_ptr<sensors_event_t[]> data;
|
||||||
int err = android::NO_ERROR;
|
int err = android::NO_ERROR;
|
||||||
|
|
||||||
{ // scope of reentry lock
|
{ // scope of reentry lock
|
||||||
|
|
||||||
// This enforces a single client, meaning that a maximum of one client can call poll().
|
// This enforces a single client, meaning that a maximum of one client can
|
||||||
// If this function is re-entred, it means that we are stuck in a state that may prevent
|
// call poll(). If this function is re-entred, it means that we are stuck in
|
||||||
// the system from proceeding normally.
|
// a state that may prevent the system from proceeding normally.
|
||||||
//
|
//
|
||||||
// Exit and let the system restart the sensor-hal-implementation hidl service.
|
// Exit and let the system restart the sensor-hal-implementation hidl
|
||||||
//
|
// service.
|
||||||
// This function must not call _hidl_cb(...) or return until there is no risk of blocking.
|
//
|
||||||
std::unique_lock<std::mutex> lock(mPollLock, std::try_to_lock);
|
// This function must not call _hidl_cb(...) or return until there is no
|
||||||
if (!lock.owns_lock()) {
|
// risk of blocking.
|
||||||
// cannot get the lock, hidl service will go into deadlock if it is not restarted.
|
std::unique_lock<std::mutex> lock(mPollLock, std::try_to_lock);
|
||||||
// This is guaranteed to not trigger in passthrough mode.
|
if (!lock.owns_lock()) {
|
||||||
LOG(ERROR)
|
// cannot get the lock, hidl service will go into deadlock if it is not
|
||||||
<< "ISensors::poll() re-entry. I do not know what to do except killing myself.";
|
// restarted. This is guaranteed to not trigger in passthrough mode.
|
||||||
::exit(-1);
|
LOG(ERROR) << "ISensors::poll() re-entry. I do not know what to do "
|
||||||
}
|
"except killing myself.";
|
||||||
|
::exit(-1);
|
||||||
if (maxCount <= 0) {
|
|
||||||
err = android::BAD_VALUE;
|
|
||||||
} else {
|
|
||||||
int bufferSize = maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize;
|
|
||||||
data.reset(new sensors_event_t[bufferSize]);
|
|
||||||
err = mSensorDevice->poll(reinterpret_cast<sensors_poll_device_t*>(mSensorDevice),
|
|
||||||
data.get(), bufferSize);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err < 0) {
|
if (maxCount <= 0) {
|
||||||
_hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded);
|
err = android::BAD_VALUE;
|
||||||
return Void();
|
} else {
|
||||||
|
int bufferSize =
|
||||||
|
maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize;
|
||||||
|
data.reset(new sensors_event_t[bufferSize]);
|
||||||
|
err = mSensorDevice->poll(
|
||||||
|
reinterpret_cast<sensors_poll_device_t *>(mSensorDevice), data.get(),
|
||||||
|
bufferSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const size_t count = (size_t)err;
|
if (err < 0) {
|
||||||
|
_hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded);
|
||||||
for (size_t i = 0; i < count; ++i) {
|
|
||||||
if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dynamic_sensor_meta_event_t* dyn = &data[i].dynamic_sensor_meta;
|
|
||||||
|
|
||||||
if (!dyn->connected) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK(dyn->sensor != nullptr);
|
|
||||||
CHECK_EQ(dyn->sensor->handle, dyn->handle);
|
|
||||||
|
|
||||||
SensorInfo info;
|
|
||||||
convertFromSensor(*dyn->sensor, &info);
|
|
||||||
|
|
||||||
size_t numDynamicSensors = dynamicSensorsAdded.size();
|
|
||||||
dynamicSensorsAdded.resize(numDynamicSensors + 1);
|
|
||||||
dynamicSensorsAdded[numDynamicSensors] = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
out.resize(count);
|
|
||||||
convertFromSensorEvents(err, data.get(), &out);
|
|
||||||
|
|
||||||
_hidl_cb(Result::OK, out, dynamicSensorsAdded);
|
|
||||||
|
|
||||||
return Void();
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t count = (size_t)err;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dynamic_sensor_meta_event_t *dyn = &data[i].dynamic_sensor_meta;
|
||||||
|
|
||||||
|
if (!dyn->connected) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(dyn->sensor != nullptr);
|
||||||
|
CHECK_EQ(dyn->sensor->handle, dyn->handle);
|
||||||
|
|
||||||
|
SensorInfo info;
|
||||||
|
convertFromSensor(*dyn->sensor, &info);
|
||||||
|
|
||||||
|
size_t numDynamicSensors = dynamicSensorsAdded.size();
|
||||||
|
dynamicSensorsAdded.resize(numDynamicSensors + 1);
|
||||||
|
dynamicSensorsAdded[numDynamicSensors] = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.resize(count);
|
||||||
|
convertFromSensorEvents(err, data.get(), &out);
|
||||||
|
|
||||||
|
_hidl_cb(Result::OK, out, dynamicSensorsAdded);
|
||||||
|
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
Return<Result> Sensors::batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
||||||
int64_t max_report_latency_ns) {
|
int64_t max_report_latency_ns) {
|
||||||
return ResultFromStatus(mSensorDevice->batch(mSensorDevice, sensor_handle, 0, /*flags*/
|
return ResultFromStatus(
|
||||||
sampling_period_ns, max_report_latency_ns));
|
mSensorDevice->batch(mSensorDevice, sensor_handle, 0, /*flags*/
|
||||||
|
sampling_period_ns, max_report_latency_ns));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::flush(int32_t sensor_handle) {
|
Return<Result> Sensors::flush(int32_t sensor_handle) {
|
||||||
return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle));
|
return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::injectSensorData(const Event& event) {
|
Return<Result> Sensors::injectSensorData(const Event &event) {
|
||||||
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 ||
|
||||||
mSensorDevice->inject_sensor_data == nullptr) {
|
mSensorDevice->inject_sensor_data == nullptr) {
|
||||||
return Result::INVALID_OPERATION;
|
return Result::INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
sensors_event_t out;
|
sensors_event_t out;
|
||||||
convertToSensorEvent(event, &out);
|
convertToSensorEvent(event, &out);
|
||||||
|
|
||||||
return ResultFromStatus(mSensorDevice->inject_sensor_data(mSensorDevice, &out));
|
return ResultFromStatus(
|
||||||
|
mSensorDevice->inject_sensor_data(mSensorDevice, &out));
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Sensors::registerDirectChannel(const SharedMemInfo& mem,
|
Return<void> Sensors::registerDirectChannel(const SharedMemInfo &mem,
|
||||||
registerDirectChannel_cb _hidl_cb) {
|
registerDirectChannel_cb _hidl_cb) {
|
||||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||||
mSensorDevice->config_direct_report == nullptr) {
|
mSensorDevice->config_direct_report == nullptr) {
|
||||||
// HAL does not support
|
// HAL does not support
|
||||||
_hidl_cb(Result::INVALID_OPERATION, -1);
|
_hidl_cb(Result::INVALID_OPERATION, -1);
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
sensors_direct_mem_t m;
|
|
||||||
if (!convertFromSharedMemInfo(mem, &m)) {
|
|
||||||
_hidl_cb(Result::BAD_VALUE, -1);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = mSensorDevice->register_direct_channel(mSensorDevice, &m, -1);
|
|
||||||
|
|
||||||
if (err < 0) {
|
|
||||||
_hidl_cb(ResultFromStatus(err), -1);
|
|
||||||
} else {
|
|
||||||
int32_t channelHandle = static_cast<int32_t>(err);
|
|
||||||
_hidl_cb(Result::OK, channelHandle);
|
|
||||||
}
|
|
||||||
return Void();
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
sensors_direct_mem_t m;
|
||||||
|
if (!convertFromSharedMemInfo(mem, &m)) {
|
||||||
|
_hidl_cb(Result::BAD_VALUE, -1);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = mSensorDevice->register_direct_channel(mSensorDevice, &m, -1);
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
_hidl_cb(ResultFromStatus(err), -1);
|
||||||
|
} else {
|
||||||
|
int32_t channelHandle = static_cast<int32_t>(err);
|
||||||
|
_hidl_cb(Result::OK, channelHandle);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<Result> Sensors::unregisterDirectChannel(int32_t channelHandle) {
|
Return<Result> Sensors::unregisterDirectChannel(int32_t channelHandle) {
|
||||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||||
mSensorDevice->config_direct_report == nullptr) {
|
mSensorDevice->config_direct_report == nullptr) {
|
||||||
// HAL does not support
|
// HAL does not support
|
||||||
return Result::INVALID_OPERATION;
|
return Result::INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle);
|
mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle);
|
||||||
|
|
||||||
return Result::OK;
|
return Result::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Sensors::configDirectReport(int32_t sensorHandle, int32_t channelHandle,
|
Return<void> Sensors::configDirectReport(int32_t sensorHandle,
|
||||||
RateLevel rate, configDirectReport_cb _hidl_cb) {
|
int32_t channelHandle, RateLevel rate,
|
||||||
if (mSensorDevice->register_direct_channel == nullptr ||
|
configDirectReport_cb _hidl_cb) {
|
||||||
mSensorDevice->config_direct_report == nullptr) {
|
if (mSensorDevice->register_direct_channel == nullptr ||
|
||||||
// HAL does not support
|
mSensorDevice->config_direct_report == nullptr) {
|
||||||
_hidl_cb(Result::INVALID_OPERATION, -1);
|
// HAL does not support
|
||||||
return Void();
|
_hidl_cb(Result::INVALID_OPERATION, -1);
|
||||||
}
|
|
||||||
|
|
||||||
sensors_direct_cfg_t cfg = {.rate_level = convertFromRateLevel(rate)};
|
|
||||||
if (cfg.rate_level < 0) {
|
|
||||||
_hidl_cb(Result::BAD_VALUE, -1);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = mSensorDevice->config_direct_report(mSensorDevice, sensorHandle, channelHandle, &cfg);
|
|
||||||
|
|
||||||
if (rate == RateLevel::STOP) {
|
|
||||||
_hidl_cb(ResultFromStatus(err), -1);
|
|
||||||
} else {
|
|
||||||
_hidl_cb(err > 0 ? Result::OK : ResultFromStatus(err), err);
|
|
||||||
}
|
|
||||||
return Void();
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
sensors_direct_cfg_t cfg = {.rate_level = convertFromRateLevel(rate)};
|
||||||
|
if (cfg.rate_level < 0) {
|
||||||
|
_hidl_cb(Result::BAD_VALUE, -1);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = mSensorDevice->config_direct_report(mSensorDevice, sensorHandle,
|
||||||
|
channelHandle, &cfg);
|
||||||
|
|
||||||
|
if (rate == RateLevel::STOP) {
|
||||||
|
_hidl_cb(ResultFromStatus(err), -1);
|
||||||
|
} else {
|
||||||
|
_hidl_cb(err > 0 ? Result::OK : ResultFromStatus(err), err);
|
||||||
|
}
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
void Sensors::convertFromSensorEvents(size_t count, const sensors_event_t* srcArray,
|
void Sensors::convertFromSensorEvents(size_t count,
|
||||||
hidl_vec<Event>* dstVec) {
|
const sensors_event_t *srcArray,
|
||||||
for (size_t i = 0; i < count; ++i) {
|
hidl_vec<Event> *dstVec) {
|
||||||
const sensors_event_t& src = srcArray[i];
|
for (size_t i = 0; i < count; ++i) {
|
||||||
Event* dst = &(*dstVec)[i];
|
const sensors_event_t &src = srcArray[i];
|
||||||
|
Event *dst = &(*dstVec)[i];
|
||||||
|
|
||||||
convertFromSensorEvent(src, dst);
|
convertFromSensorEvent(src, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ISensors* HIDL_FETCH_ISensors(const char* /* hal */) {
|
ISensors *HIDL_FETCH_ISensors(const char * /* hal */) {
|
||||||
Sensors* sensors = new Sensors;
|
Sensors *sensors = new Sensors;
|
||||||
if (sensors->initCheck() != OK) {
|
if (sensors->initCheck() != OK) {
|
||||||
delete sensors;
|
delete sensors;
|
||||||
sensors = nullptr;
|
sensors = nullptr;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sensors;
|
return sensors;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V1_0
|
} // namespace V1_0
|
||||||
} // namespace sensors
|
} // namespace sensors
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -30,54 +30,56 @@ namespace V1_0 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
struct Sensors : public ::android::hardware::sensors::V1_0::ISensors {
|
struct Sensors : public ::android::hardware::sensors::V1_0::ISensors {
|
||||||
Sensors();
|
Sensors();
|
||||||
|
|
||||||
status_t initCheck() const;
|
status_t initCheck() const;
|
||||||
|
|
||||||
Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
|
Return<void> getSensorsList(getSensorsList_cb _hidl_cb) override;
|
||||||
|
|
||||||
Return<Result> setOperationMode(OperationMode mode) override;
|
Return<Result> setOperationMode(OperationMode mode) override;
|
||||||
|
|
||||||
Return<Result> activate(int32_t sensor_handle, bool enabled) override;
|
Return<Result> activate(int32_t sensor_handle, bool enabled) override;
|
||||||
|
|
||||||
Return<void> poll(int32_t maxCount, poll_cb _hidl_cb) override;
|
Return<void> poll(int32_t maxCount, poll_cb _hidl_cb) override;
|
||||||
|
|
||||||
Return<Result> batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
Return<Result> batch(int32_t sensor_handle, int64_t sampling_period_ns,
|
||||||
int64_t max_report_latency_ns) override;
|
int64_t max_report_latency_ns) override;
|
||||||
|
|
||||||
Return<Result> flush(int32_t sensor_handle) override;
|
Return<Result> flush(int32_t sensor_handle) override;
|
||||||
|
|
||||||
Return<Result> injectSensorData(const Event& event) override;
|
Return<Result> injectSensorData(const Event &event) override;
|
||||||
|
|
||||||
Return<void> registerDirectChannel(const SharedMemInfo& mem,
|
Return<void>
|
||||||
registerDirectChannel_cb _hidl_cb) override;
|
registerDirectChannel(const SharedMemInfo &mem,
|
||||||
|
registerDirectChannel_cb _hidl_cb) override;
|
||||||
|
|
||||||
Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
|
Return<Result> unregisterDirectChannel(int32_t channelHandle) override;
|
||||||
|
|
||||||
Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate,
|
Return<void> configDirectReport(int32_t sensorHandle, int32_t channelHandle,
|
||||||
configDirectReport_cb _hidl_cb) override;
|
RateLevel rate,
|
||||||
|
configDirectReport_cb _hidl_cb) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int32_t kPollMaxBufferSize = 128;
|
static constexpr int32_t kPollMaxBufferSize = 128;
|
||||||
status_t mInitCheck;
|
status_t mInitCheck;
|
||||||
sensors_module_t* mSensorModule;
|
sensors_module_t *mSensorModule;
|
||||||
sensors_poll_device_1_t* mSensorDevice;
|
sensors_poll_device_1_t *mSensorDevice;
|
||||||
std::mutex mPollLock;
|
std::mutex mPollLock;
|
||||||
|
|
||||||
int getHalDeviceVersion() const;
|
int getHalDeviceVersion() const;
|
||||||
|
|
||||||
static void convertFromSensorEvents(size_t count, const sensors_event_t* src,
|
static void convertFromSensorEvents(size_t count, const sensors_event_t *src,
|
||||||
hidl_vec<Event>* dst);
|
hidl_vec<Event> *dst);
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Sensors);
|
DISALLOW_COPY_AND_ASSIGN(Sensors);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" ISensors* HIDL_FETCH_ISensors(const char* name);
|
extern "C" ISensors *HIDL_FETCH_ISensors(const char *name);
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V1_0
|
} // namespace V1_0
|
||||||
} // namespace sensors
|
} // namespace sensors
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
#endif // HARDWARE_INTERFACES_SENSORS_V1_0_SAMSUNG_SENSORS_H_
|
#endif // HARDWARE_INTERFACES_SENSORS_V1_0_SAMSUNG_SENSORS_H_
|
||||||
|
|
|
||||||
|
|
@ -30,51 +30,52 @@ namespace usb {
|
||||||
namespace V1_0 {
|
namespace V1_0 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
Return<void> Usb::switchRole(const hidl_string& portName __unused,
|
Return<void> Usb::switchRole(const hidl_string &portName __unused,
|
||||||
const PortRole& newRole __unused) {
|
const PortRole &newRole __unused) {
|
||||||
LOG(ERROR) << __func__ << ": Not supported";
|
LOG(ERROR) << __func__ << ": Not supported";
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Usb::queryPortStatus() {
|
Return<void> Usb::queryPortStatus() {
|
||||||
hidl_vec<PortStatus> currentPortStatus;
|
hidl_vec<PortStatus> currentPortStatus;
|
||||||
currentPortStatus.resize(1);
|
currentPortStatus.resize(1);
|
||||||
|
|
||||||
currentPortStatus[0].portName = "otg_default";
|
currentPortStatus[0].portName = "otg_default";
|
||||||
currentPortStatus[0].currentDataRole = PortDataRole::DEVICE;
|
currentPortStatus[0].currentDataRole = PortDataRole::DEVICE;
|
||||||
currentPortStatus[0].currentPowerRole = PortPowerRole::SINK;
|
currentPortStatus[0].currentPowerRole = PortPowerRole::SINK;
|
||||||
currentPortStatus[0].currentMode = PortMode::UFP;
|
currentPortStatus[0].currentMode = PortMode::UFP;
|
||||||
currentPortStatus[0].canChangeMode = false;
|
currentPortStatus[0].canChangeMode = false;
|
||||||
currentPortStatus[0].canChangeDataRole = false;
|
currentPortStatus[0].canChangeDataRole = false;
|
||||||
currentPortStatus[0].canChangePowerRole = false;
|
currentPortStatus[0].canChangePowerRole = false;
|
||||||
currentPortStatus[0].supportedModes = PortMode::UFP;
|
currentPortStatus[0].supportedModes = PortMode::UFP;
|
||||||
|
|
||||||
pthread_mutex_lock(&mLock);
|
pthread_mutex_lock(&mLock);
|
||||||
if (mCallback != NULL) {
|
if (mCallback != NULL) {
|
||||||
Return<void> ret = mCallback->notifyPortStatusChange(currentPortStatus, Status::SUCCESS);
|
Return<void> ret =
|
||||||
if (!ret.isOk()) {
|
mCallback->notifyPortStatusChange(currentPortStatus, Status::SUCCESS);
|
||||||
LOG(ERROR) << "queryPortStatus error " << ret.description();
|
if (!ret.isOk()) {
|
||||||
}
|
LOG(ERROR) << "queryPortStatus error " << ret.description();
|
||||||
} else {
|
|
||||||
LOG(INFO) << "Notifying userspace skipped. Callback is NULL";
|
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&mLock);
|
} else {
|
||||||
|
LOG(INFO) << "Notifying userspace skipped. Callback is NULL";
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&mLock);
|
||||||
|
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {
|
Return<void> Usb::setCallback(const sp<IUsbCallback> &callback) {
|
||||||
pthread_mutex_lock(&mLock);
|
pthread_mutex_lock(&mLock);
|
||||||
|
|
||||||
mCallback = callback;
|
mCallback = callback;
|
||||||
LOG(INFO) << "registering callback";
|
LOG(INFO) << "registering callback";
|
||||||
|
|
||||||
pthread_mutex_unlock(&mLock);
|
pthread_mutex_unlock(&mLock);
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V1_0
|
} // namespace V1_0
|
||||||
} // namespace usb
|
} // namespace usb
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -48,18 +48,19 @@ using ::android::hardware::usb::V1_0::PortRole;
|
||||||
using ::android::hidl::base::V1_0::IBase;
|
using ::android::hidl::base::V1_0::IBase;
|
||||||
|
|
||||||
struct Usb : public IUsb {
|
struct Usb : public IUsb {
|
||||||
Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
|
Return<void> switchRole(const hidl_string &portName,
|
||||||
Return<void> setCallback(const sp<IUsbCallback>& callback) override;
|
const PortRole &role) override;
|
||||||
Return<void> queryPortStatus() override;
|
Return<void> setCallback(const sp<IUsbCallback> &callback) override;
|
||||||
|
Return<void> queryPortStatus() override;
|
||||||
|
|
||||||
sp<IUsbCallback> mCallback;
|
sp<IUsbCallback> mCallback;
|
||||||
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V1_0
|
} // namespace V1_0
|
||||||
} // namespace usb
|
} // namespace usb
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
#endif // ANDROID_HARDWARE_USB_V1_0_USB_H
|
#endif // ANDROID_HARDWARE_USB_V1_0_USB_H
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Usb.h"
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
#include <hidl/HidlTransportSupport.h>
|
#include <hidl/HidlTransportSupport.h>
|
||||||
#include "Usb.h"
|
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
|
|
||||||
|
|
@ -29,19 +29,19 @@ using android::hardware::usb::V1_0::IUsb;
|
||||||
using android::hardware::usb::V1_0::implementation::Usb;
|
using android::hardware::usb::V1_0::implementation::Usb;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
android::sp<IUsb> service = new Usb();
|
android::sp<IUsb> service = new Usb();
|
||||||
|
|
||||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||||
android::status_t status = service->registerAsService();
|
android::status_t status = service->registerAsService();
|
||||||
|
|
||||||
if (status != android::OK) {
|
if (status != android::OK) {
|
||||||
LOG(ERROR) << "Cannot register USB HAL service";
|
LOG(ERROR) << "Cannot register USB HAL service";
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG(INFO) << "USB HAL Ready.";
|
|
||||||
joinRpcThreadpool();
|
|
||||||
// Under normal cases, execution will not reach this line.
|
|
||||||
LOG(ERROR) << "USB HAL failed to join thread pool.";
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "USB HAL Ready.";
|
||||||
|
joinRpcThreadpool();
|
||||||
|
// Under normal cases, execution will not reach this line.
|
||||||
|
LOG(ERROR) << "USB HAL failed to join thread pool.";
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -17,9 +17,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
#include <android/hardware/usb/1.3/IUsb.h>
|
|
||||||
#include <android/hardware/usb/1.2/types.h>
|
|
||||||
#include <android/hardware/usb/1.2/IUsbCallback.h>
|
#include <android/hardware/usb/1.2/IUsbCallback.h>
|
||||||
|
#include <android/hardware/usb/1.2/types.h>
|
||||||
|
#include <android/hardware/usb/1.3/IUsb.h>
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
|
|
||||||
|
|
@ -36,67 +36,64 @@ namespace usb {
|
||||||
namespace V1_3 {
|
namespace V1_3 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
using ::android::base::WriteStringToFile;
|
using ::android::sp;
|
||||||
using ::android::base::ReadFileToString;
|
using ::android::base::ReadFileToString;
|
||||||
|
using ::android::base::WriteStringToFile;
|
||||||
using ::android::hardware::hidl_array;
|
using ::android::hardware::hidl_array;
|
||||||
using ::android::hardware::hidl_memory;
|
using ::android::hardware::hidl_memory;
|
||||||
using ::android::hardware::hidl_string;
|
using ::android::hardware::hidl_string;
|
||||||
using ::android::hardware::hidl_vec;
|
using ::android::hardware::hidl_vec;
|
||||||
using ::android::hardware::Return;
|
using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
using ::android::hardware::usb::V1_0::PortRole;
|
|
||||||
using ::android::hardware::usb::V1_0::PortRoleType;
|
|
||||||
using ::android::hardware::usb::V1_0::PortDataRole;
|
using ::android::hardware::usb::V1_0::PortDataRole;
|
||||||
using ::android::hardware::usb::V1_0::PortPowerRole;
|
using ::android::hardware::usb::V1_0::PortPowerRole;
|
||||||
using ::android::hardware::usb::V1_0::PortRole;
|
using ::android::hardware::usb::V1_0::PortRole;
|
||||||
using ::android::hardware::usb::V1_0::PortRoleType;
|
using ::android::hardware::usb::V1_0::PortRoleType;
|
||||||
using ::android::hardware::usb::V1_0::Status;
|
using ::android::hardware::usb::V1_0::Status;
|
||||||
using ::android::hardware::usb::V1_3::IUsb;
|
|
||||||
using ::android::hardware::usb::V1_2::IUsbCallback;
|
|
||||||
using ::android::hardware::usb::V1_2::PortStatus;
|
|
||||||
using ::android::hardware::usb::V1_1::PortMode_1_1;
|
using ::android::hardware::usb::V1_1::PortMode_1_1;
|
||||||
using ::android::hardware::usb::V1_1::PortStatus_1_1;
|
using ::android::hardware::usb::V1_1::PortStatus_1_1;
|
||||||
|
using ::android::hardware::usb::V1_2::IUsbCallback;
|
||||||
|
using ::android::hardware::usb::V1_2::PortStatus;
|
||||||
|
using ::android::hardware::usb::V1_3::IUsb;
|
||||||
using ::android::hidl::base::V1_0::DebugInfo;
|
using ::android::hidl::base::V1_0::DebugInfo;
|
||||||
using ::android::hidl::base::V1_0::IBase;
|
using ::android::hidl::base::V1_0::IBase;
|
||||||
using ::android::sp;
|
|
||||||
|
|
||||||
enum class HALVersion{
|
enum class HALVersion { V1_0, V1_1, V1_2, V1_3 };
|
||||||
V1_0,
|
|
||||||
V1_1,
|
|
||||||
V1_2,
|
|
||||||
V1_3
|
|
||||||
};
|
|
||||||
|
|
||||||
#define USB_DATA_PATH "/sys/devices/virtual/usb_notify/usb_control/usb_data_enabled"
|
#define USB_DATA_PATH \
|
||||||
|
"/sys/devices/virtual/usb_notify/usb_control/usb_data_enabled"
|
||||||
|
|
||||||
struct Usb : public IUsb {
|
struct Usb : public IUsb {
|
||||||
Usb();
|
Usb();
|
||||||
|
|
||||||
Return<void> switchRole(const hidl_string &portName, const PortRole &role) override;
|
Return<void> switchRole(const hidl_string &portName,
|
||||||
Return<void> setCallback(const sp<V1_0::IUsbCallback>& callback) override;
|
const PortRole &role) override;
|
||||||
Return<void> queryPortStatus() override;
|
Return<void> setCallback(const sp<V1_0::IUsbCallback> &callback) override;
|
||||||
Return<void> enableContaminantPresenceDetection(const hidl_string &portName, bool enable);
|
Return<void> queryPortStatus() override;
|
||||||
Return<void> enableContaminantPresenceProtection(const hidl_string &portName, bool enable);
|
Return<void> enableContaminantPresenceDetection(const hidl_string &portName,
|
||||||
Return<bool> enableUsbDataSignal(bool enable) override;
|
bool enable);
|
||||||
|
Return<void> enableContaminantPresenceProtection(const hidl_string &portName,
|
||||||
|
bool enable);
|
||||||
|
Return<bool> enableUsbDataSignal(bool enable) override;
|
||||||
|
|
||||||
sp<V1_0::IUsbCallback> mCallback_1_0;
|
sp<V1_0::IUsbCallback> mCallback_1_0;
|
||||||
// Protects mCallback variable
|
// Protects mCallback variable
|
||||||
pthread_mutex_t mLock;
|
pthread_mutex_t mLock;
|
||||||
// Protects roleSwitch operation
|
// Protects roleSwitch operation
|
||||||
pthread_mutex_t mRoleSwitchLock;
|
pthread_mutex_t mRoleSwitchLock;
|
||||||
// Threads waiting for the partner to come back wait here
|
// Threads waiting for the partner to come back wait here
|
||||||
pthread_cond_t mPartnerCV;
|
pthread_cond_t mPartnerCV;
|
||||||
// lock protecting mPartnerCV
|
// lock protecting mPartnerCV
|
||||||
pthread_mutex_t mPartnerLock;
|
pthread_mutex_t mPartnerLock;
|
||||||
// Variable to signal partner coming back online after type switch
|
// Variable to signal partner coming back online after type switch
|
||||||
bool mPartnerUp;
|
bool mPartnerUp;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
pthread_t mPoll;
|
pthread_t mPoll;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V1_3
|
} // namespace V1_3
|
||||||
} // namespace usb
|
} // namespace usb
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
|
|
||||||
#define LOG_TAG "android.hardware.usb@1.3-service.samsung"
|
#define LOG_TAG "android.hardware.usb@1.3-service.samsung"
|
||||||
|
|
||||||
#include <hidl/HidlTransportSupport.h>
|
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
|
#include <hidl/HidlTransportSupport.h>
|
||||||
|
|
||||||
using android::sp;
|
using android::sp;
|
||||||
|
|
||||||
|
|
@ -34,19 +34,19 @@ using android::OK;
|
||||||
using android::status_t;
|
using android::status_t;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
android::sp<IUsb> service = new Usb();
|
android::sp<IUsb> service = new Usb();
|
||||||
|
|
||||||
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
configureRpcThreadpool(1, true /*callerWillJoin*/);
|
||||||
status_t status = service->registerAsService();
|
status_t status = service->registerAsService();
|
||||||
|
|
||||||
if (status != OK) {
|
if (status != OK) {
|
||||||
ALOGE("Cannot register USB HAL service");
|
ALOGE("Cannot register USB HAL service");
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALOGI("USB HAL Ready.");
|
|
||||||
joinRpcThreadpool();
|
|
||||||
// Under noraml cases, execution will not reach this line.
|
|
||||||
ALOGI("USB HAL failed to join thread pool.");
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ALOGI("USB HAL Ready.");
|
||||||
|
joinRpcThreadpool();
|
||||||
|
// Under noraml cases, execution will not reach this line.
|
||||||
|
ALOGI("USB HAL failed to join thread pool.");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,41 +29,43 @@
|
||||||
#define TELEPHONY_PROP "telephony.prop"
|
#define TELEPHONY_PROP "telephony.prop"
|
||||||
|
|
||||||
void LoadProperties(std::string data) {
|
void LoadProperties(std::string data) {
|
||||||
for (std::string line : android::base::Split(data, "\n")) {
|
for (std::string line : android::base::Split(data, "\n")) {
|
||||||
if (line == "\0") break;
|
if (line == "\0")
|
||||||
|
break;
|
||||||
|
|
||||||
std::vector<std::string> parts = android::base::Split(line, "=");
|
std::vector<std::string> parts = android::base::Split(line, "=");
|
||||||
if (parts.size() == 2) {
|
if (parts.size() == 2) {
|
||||||
LOG(INFO) << "Setting property: " << line;
|
LOG(INFO) << "Setting property: " << line;
|
||||||
android::base::SetProperty(parts.at(0), parts.at(1));
|
android::base::SetProperty(parts.at(0), parts.at(1));
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Invalid data: " << line;
|
LOG(ERROR) << "Invalid data: " << line;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
std::string prop = FACTORY_PROP;
|
std::string prop = FACTORY_PROP;
|
||||||
|
|
||||||
if (argc > 1 && std::string(argv[1]) == "NetworkConfig") prop = TELEPHONY_PROP;
|
if (argc > 1 && std::string(argv[1]) == "NetworkConfig")
|
||||||
|
prop = TELEPHONY_PROP;
|
||||||
|
|
||||||
std::ifstream in(EFS_NEW + prop);
|
std::ifstream in(EFS_NEW + prop);
|
||||||
if (in.good()) {
|
if (in.good()) {
|
||||||
in.close();
|
in.close();
|
||||||
prop = EFS_NEW + prop;
|
prop = EFS_NEW + prop;
|
||||||
} else {
|
} else {
|
||||||
prop = EFS_OLD + prop;
|
prop = EFS_OLD + prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Loading properties from " << prop;
|
LOG(INFO) << "Loading properties from " << prop;
|
||||||
|
|
||||||
std::string content;
|
std::string content;
|
||||||
if (android::base::ReadFileToString(prop, &content)) {
|
if (android::base::ReadFileToString(prop, &content)) {
|
||||||
LoadProperties(content.c_str());
|
LoadProperties(content.c_str());
|
||||||
} else if (prop == FACTORY_PROP) {
|
} else if (prop == FACTORY_PROP) {
|
||||||
LOG(WARNING) << "Could not read " << prop << ", setting defaults!";
|
LOG(WARNING) << "Could not read " << prop << ", setting defaults!";
|
||||||
LoadProperties("ro.vendor.multisim.simslotcount=1");
|
LoadProperties("ro.vendor.multisim.simslotcount=1");
|
||||||
} else {
|
} else {
|
||||||
LOG(WARNING) << "Could not read " << prop << "!";
|
LOG(WARNING) << "Could not read " << prop << "!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,54 +40,55 @@ using android::base::GetProperty;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
std::vector<std::string> ro_props_default_source_order = {
|
std::vector<std::string> ro_props_default_source_order = {
|
||||||
"", "odm.", "product.", "system.", "system_ext.", "vendor.",
|
"", "odm.", "product.", "system.", "system_ext.", "vendor.",
|
||||||
};
|
};
|
||||||
|
|
||||||
void property_override(char const prop[], char const value[], bool add = true) {
|
void property_override(char const prop[], char const value[], bool add = true) {
|
||||||
prop_info* pi;
|
prop_info *pi;
|
||||||
|
|
||||||
pi = (prop_info*)__system_property_find(prop);
|
pi = (prop_info *)__system_property_find(prop);
|
||||||
if (pi)
|
if (pi)
|
||||||
__system_property_update(pi, value, strlen(value));
|
__system_property_update(pi, value, strlen(value));
|
||||||
else if (add)
|
else if (add)
|
||||||
__system_property_add(prop, strlen(prop), value, strlen(value));
|
__system_property_add(prop, strlen(prop), value, strlen(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_ro_build_prop(const std::string& prop, const std::string& value, bool product = true) {
|
void set_ro_build_prop(const std::string &prop, const std::string &value,
|
||||||
string prop_name;
|
bool product = true) {
|
||||||
|
string prop_name;
|
||||||
|
|
||||||
for (const auto& source : ro_props_default_source_order) {
|
for (const auto &source : ro_props_default_source_order) {
|
||||||
if (product)
|
if (product)
|
||||||
prop_name = "ro.product." + source + prop;
|
prop_name = "ro.product." + source + prop;
|
||||||
else
|
else
|
||||||
prop_name = "ro." + source + "build." + prop;
|
prop_name = "ro." + source + "build." + prop;
|
||||||
|
|
||||||
property_override(prop_name.c_str(), value.c_str());
|
property_override(prop_name.c_str(), value.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasEnding(std::string const& fullString, std::string const& ending) {
|
bool hasEnding(std::string const &fullString, std::string const &ending) {
|
||||||
if (fullString.length() >= ending.length()) {
|
if (fullString.length() >= ending.length()) {
|
||||||
return (0 ==
|
return (0 == fullString.compare(fullString.length() - ending.length(),
|
||||||
fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
|
ending.length(), ending));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vendor_load_properties() {
|
void vendor_load_properties() {
|
||||||
string model;
|
string model;
|
||||||
|
|
||||||
model = GetProperty("ro.boot.product.model", "");
|
model = GetProperty("ro.boot.product.model", "");
|
||||||
if (model.empty()) {
|
if (model.empty()) {
|
||||||
model = GetProperty("ro.boot.em.model", "");
|
model = GetProperty("ro.boot.em.model", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasEnding(model, "N") || hasEnding(model, "S") || hasEnding(model, "K") ||
|
if (hasEnding(model, "N") || hasEnding(model, "S") || hasEnding(model, "K") ||
|
||||||
model == "SM-A202F") {
|
model == "SM-A202F") {
|
||||||
property_override("ro.boot.product.hardware.sku", "NFC");
|
property_override("ro.boot.product.hardware.sku", "NFC");
|
||||||
}
|
}
|
||||||
|
|
||||||
set_ro_build_prop("model", model);
|
set_ro_build_prop("model", model);
|
||||||
set_ro_build_prop("product", model, false);
|
set_ro_build_prop("product", model, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,14 +17,14 @@
|
||||||
#ifndef ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
#ifndef ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||||
#define ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
#define ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||||
|
|
||||||
#include "utils/Mutex.h"
|
|
||||||
#include "CameraModule.h"
|
|
||||||
#include "CameraMetadata.h"
|
|
||||||
#include "CameraDeviceSession.h"
|
#include "CameraDeviceSession.h"
|
||||||
|
#include "CameraMetadata.h"
|
||||||
|
#include "CameraModule.h"
|
||||||
|
#include "utils/Mutex.h"
|
||||||
|
|
||||||
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
|
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
|
||||||
#include <hidl/Status.h>
|
|
||||||
#include <hidl/MQDescriptor.h>
|
#include <hidl/MQDescriptor.h>
|
||||||
|
#include <hidl/Status.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
|
|
@ -33,127 +33,132 @@ namespace device {
|
||||||
namespace V3_2 {
|
namespace V3_2 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
using ::android::hardware::camera::device::V3_2::RequestTemplate;
|
using ::android::Mutex;
|
||||||
using ::android::hardware::camera::device::V3_2::ICameraDevice;
|
using ::android::sp;
|
||||||
using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
|
using ::android::hardware::hidl_string;
|
||||||
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
|
using ::android::hardware::hidl_vec;
|
||||||
|
using ::android::hardware::Return;
|
||||||
|
using ::android::hardware::Void;
|
||||||
using ::android::hardware::camera::common::V1_0::CameraResourceCost;
|
using ::android::hardware::camera::common::V1_0::CameraResourceCost;
|
||||||
using ::android::hardware::camera::common::V1_0::Status;
|
using ::android::hardware::camera::common::V1_0::Status;
|
||||||
using ::android::hardware::camera::common::V1_0::TorchMode;
|
using ::android::hardware::camera::common::V1_0::TorchMode;
|
||||||
using ::android::hardware::camera::common::V1_0::helper::CameraModule;
|
using ::android::hardware::camera::common::V1_0::helper::CameraModule;
|
||||||
using ::android::hardware::Return;
|
using ::android::hardware::camera::device::V3_2::ICameraDevice;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
|
||||||
using ::android::hardware::hidl_vec;
|
using ::android::hardware::camera::device::V3_2::ICameraDeviceSession;
|
||||||
using ::android::hardware::hidl_string;
|
using ::android::hardware::camera::device::V3_2::RequestTemplate;
|
||||||
using ::android::sp;
|
|
||||||
using ::android::Mutex;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The camera device HAL implementation is opened lazily (via the open call)
|
* The camera device HAL implementation is opened lazily (via the open call)
|
||||||
*/
|
*/
|
||||||
struct CameraDevice : public virtual RefBase {
|
struct CameraDevice : public virtual RefBase {
|
||||||
// Called by provider HAL. Provider HAL must ensure the uniqueness of
|
// Called by provider HAL. Provider HAL must ensure the uniqueness of
|
||||||
// CameraDevice object per cameraId, or there could be multiple CameraDevice
|
// CameraDevice object per cameraId, or there could be multiple CameraDevice
|
||||||
// trying to access the same physical camera.
|
// trying to access the same physical camera.
|
||||||
// Also, provider will have to keep track of all CameraDevice objects in
|
// Also, provider will have to keep track of all CameraDevice objects in
|
||||||
// order to notify CameraDevice when the underlying camera is detached
|
// order to notify CameraDevice when the underlying camera is detached
|
||||||
CameraDevice(sp<CameraModule> module,
|
CameraDevice(sp<CameraModule> module, const std::string &cameraId,
|
||||||
const std::string& cameraId,
|
const SortedVector<std::pair<std::string, std::string>>
|
||||||
const SortedVector<std::pair<std::string, std::string>>& cameraDeviceNames);
|
&cameraDeviceNames);
|
||||||
virtual ~CameraDevice();
|
virtual ~CameraDevice();
|
||||||
|
|
||||||
// Retrieve the HIDL interface, split into its own class to avoid inheritance issues when
|
// Retrieve the HIDL interface, split into its own class to avoid inheritance
|
||||||
// dealing with minor version revs and simultaneous implementation and interface inheritance
|
// issues when dealing with minor version revs and simultaneous implementation
|
||||||
virtual sp<ICameraDevice> getInterface() {
|
// and interface inheritance
|
||||||
return new TrampolineDeviceInterface_3_2(this);
|
virtual sp<ICameraDevice> getInterface() {
|
||||||
}
|
return new TrampolineDeviceInterface_3_2(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Caller must use this method to check if CameraDevice ctor failed
|
// Caller must use this method to check if CameraDevice ctor failed
|
||||||
bool isInitFailed() { return mInitFail; }
|
bool isInitFailed() { return mInitFail; }
|
||||||
// Used by provider HAL to signal external camera disconnected
|
// Used by provider HAL to signal external camera disconnected
|
||||||
void setConnectionStatus(bool connected);
|
void setConnectionStatus(bool connected);
|
||||||
|
|
||||||
/* Methods from ::android::hardware::camera::device::V3_2::ICameraDevice follow. */
|
/* Methods from ::android::hardware::camera::device::V3_2::ICameraDevice
|
||||||
// The following method can be called without opening the actual camera device
|
* follow. */
|
||||||
Return<void> getResourceCost(ICameraDevice::getResourceCost_cb _hidl_cb);
|
// The following method can be called without opening the actual camera device
|
||||||
Return<void> getCameraCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
Return<void> getResourceCost(ICameraDevice::getResourceCost_cb _hidl_cb);
|
||||||
Return<void> getEurekaCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
Return<void>
|
||||||
Return<Status> setTorchMode(TorchMode mode);
|
getCameraCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
||||||
|
Return<void>
|
||||||
|
getEurekaCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb);
|
||||||
|
Return<Status> setTorchMode(TorchMode mode);
|
||||||
|
|
||||||
// Open the device HAL and also return a default capture session
|
// Open the device HAL and also return a default capture session
|
||||||
Return<void> open(const sp<ICameraDeviceCallback>& callback, ICameraDevice::open_cb _hidl_cb);
|
Return<void> open(const sp<ICameraDeviceCallback> &callback,
|
||||||
Return<void> nuke(const sp<ICameraDeviceCallback>& callback, ICameraDevice::open_cb _hidl_cb);
|
ICameraDevice::open_cb _hidl_cb);
|
||||||
|
Return<void> nuke(const sp<ICameraDeviceCallback> &callback,
|
||||||
|
ICameraDevice::open_cb _hidl_cb);
|
||||||
|
|
||||||
// Forward the dump call to the opened session, or do nothing
|
// Forward the dump call to the opened session, or do nothing
|
||||||
Return<void> dumpState(const ::android::hardware::hidl_handle& fd);
|
Return<void> dumpState(const ::android::hardware::hidl_handle &fd);
|
||||||
/* End of Methods from ::android::hardware::camera::device::V3_2::ICameraDevice */
|
/* End of Methods from
|
||||||
|
* ::android::hardware::camera::device::V3_2::ICameraDevice */
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Overridden by child implementations for returning different versions of
|
||||||
|
// CameraDeviceSession
|
||||||
|
virtual sp<CameraDeviceSession>
|
||||||
|
createSession(camera3_device_t *, const camera_metadata_t *deviceInfo,
|
||||||
|
const sp<ICameraDeviceCallback> &);
|
||||||
|
|
||||||
// Overridden by child implementations for returning different versions of CameraDeviceSession
|
const sp<CameraModule> mModule;
|
||||||
virtual sp<CameraDeviceSession> createSession(camera3_device_t*,
|
const std::string mCameraId;
|
||||||
const camera_metadata_t* deviceInfo,
|
// const after ctor
|
||||||
const sp<ICameraDeviceCallback>&);
|
int mCameraIdInt;
|
||||||
|
int mDeviceVersion;
|
||||||
|
bool mInitFail = false;
|
||||||
|
// Set by provider (when external camera is connected/disconnected)
|
||||||
|
bool mDisconnected;
|
||||||
|
wp<CameraDeviceSession> mSession = nullptr;
|
||||||
|
|
||||||
const sp<CameraModule> mModule;
|
const SortedVector<std::pair<std::string, std::string>> &mCameraDeviceNames;
|
||||||
const std::string mCameraId;
|
|
||||||
// const after ctor
|
|
||||||
int mCameraIdInt;
|
|
||||||
int mDeviceVersion;
|
|
||||||
bool mInitFail = false;
|
|
||||||
// Set by provider (when external camera is connected/disconnected)
|
|
||||||
bool mDisconnected;
|
|
||||||
wp<CameraDeviceSession> mSession = nullptr;
|
|
||||||
|
|
||||||
const SortedVector<std::pair<std::string, std::string>>& mCameraDeviceNames;
|
// gating access to mSession and mDisconnected
|
||||||
|
mutable Mutex mLock;
|
||||||
|
|
||||||
// gating access to mSession and mDisconnected
|
// convert conventional HAL status to HIDL Status
|
||||||
mutable Mutex mLock;
|
static Status getHidlStatus(int);
|
||||||
|
|
||||||
// convert conventional HAL status to HIDL Status
|
Status initStatus() const;
|
||||||
static Status getHidlStatus(int);
|
|
||||||
|
|
||||||
Status initStatus() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TrampolineDeviceInterface_3_2 : public ICameraDevice {
|
struct TrampolineDeviceInterface_3_2 : public ICameraDevice {
|
||||||
TrampolineDeviceInterface_3_2(sp<CameraDevice> parent) :
|
TrampolineDeviceInterface_3_2(sp<CameraDevice> parent) : mParent(parent) {}
|
||||||
mParent(parent) {}
|
|
||||||
|
|
||||||
virtual Return<void> getResourceCost(V3_2::ICameraDevice::getResourceCost_cb _hidl_cb)
|
virtual Return<void>
|
||||||
override {
|
getResourceCost(V3_2::ICameraDevice::getResourceCost_cb _hidl_cb) override {
|
||||||
return mParent->getResourceCost(_hidl_cb);
|
return mParent->getResourceCost(_hidl_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Return<void> getCameraCharacteristics(
|
virtual Return<void> getCameraCharacteristics(
|
||||||
V3_2::ICameraDevice::getCameraCharacteristics_cb _hidl_cb) override {
|
V3_2::ICameraDevice::getCameraCharacteristics_cb _hidl_cb) override {
|
||||||
return mParent->getCameraCharacteristics(_hidl_cb);
|
return mParent->getCameraCharacteristics(_hidl_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Return<Status> setTorchMode(TorchMode mode) override {
|
virtual Return<Status> setTorchMode(TorchMode mode) override {
|
||||||
return mParent->setTorchMode(mode);
|
return mParent->setTorchMode(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Return<void> open(const sp<V3_2::ICameraDeviceCallback>& callback,
|
virtual Return<void> open(const sp<V3_2::ICameraDeviceCallback> &callback,
|
||||||
V3_2::ICameraDevice::open_cb _hidl_cb) override {
|
V3_2::ICameraDevice::open_cb _hidl_cb) override {
|
||||||
return mParent->open(callback, _hidl_cb);
|
return mParent->open(callback, _hidl_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Return<void> dumpState(const hidl_handle& fd) override {
|
virtual Return<void> dumpState(const hidl_handle &fd) override {
|
||||||
return mParent->dumpState(fd);
|
return mParent->dumpState(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
sp<CameraDevice> mParent;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
sp<CameraDevice> mParent;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V3_2
|
} // namespace V3_2
|
||||||
} // namespace device
|
} // namespace device
|
||||||
} // namespace camera
|
} // namespace camera
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
#endif // ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
#endif // ANDROID_HARDWARE_CAM_DEVICE_V3_2_CAMERADEVICE_H
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Eureka Team.
|
* Copyright (c) 2022 Eureka Team.
|
||||||
* https://github.com/eurekadevelopment
|
* https://github.com/eurekadevelopment
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CamDevice_3_2.h"
|
#include "CamDevice_3_2.h"
|
||||||
#include <include/convert.h>
|
#include <include/convert.h>
|
||||||
|
|
@ -21,139 +21,143 @@ namespace implementation {
|
||||||
|
|
||||||
using ::android::hardware::camera::common::V1_0::Status;
|
using ::android::hardware::camera::common::V1_0::Status;
|
||||||
|
|
||||||
Return<void> CameraDevice::getCameraCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
Return<void> CameraDevice::getCameraCharacteristics(
|
||||||
Status status = initStatus();
|
ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
||||||
CameraMetadata cameraCharacteristics;
|
Status status = initStatus();
|
||||||
if (status == Status::OK) {
|
CameraMetadata cameraCharacteristics;
|
||||||
//Module 2.1+ codepath.
|
if (status == Status::OK) {
|
||||||
struct camera_info info;
|
// Module 2.1+ codepath.
|
||||||
if (mCameraIdInt == 1) mCameraIdInt = 2;
|
struct camera_info info;
|
||||||
int ret = mModule->getCameraInfo(mCameraIdInt, &info);
|
if (mCameraIdInt == 1)
|
||||||
if (ret == OK) {
|
mCameraIdInt = 2;
|
||||||
convertToHidl(info.static_camera_characteristics, &cameraCharacteristics);
|
int ret = mModule->getCameraInfo(mCameraIdInt, &info);
|
||||||
} else {
|
if (ret == OK) {
|
||||||
ALOGE("%s: get camera info failed!", __FUNCTION__);
|
convertToHidl(info.static_camera_characteristics, &cameraCharacteristics);
|
||||||
status = Status::INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_hidl_cb(status, cameraCharacteristics);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
Return<void> CameraDevice::getEurekaCharacteristics(ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
|
||||||
return CameraDevice::getCameraCharacteristics(_hidl_cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback,
|
|
||||||
ICameraDevice::open_cb _hidl_cb) {
|
|
||||||
Status status = initStatus();
|
|
||||||
sp<CameraDeviceSession> session = nullptr;
|
|
||||||
|
|
||||||
if (callback == nullptr) {
|
|
||||||
ALOGE("%s: cannot open camera %s. callback is null!",
|
|
||||||
__FUNCTION__, mCameraId.c_str());
|
|
||||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != Status::OK) {
|
|
||||||
// Provider will never pass initFailed device to client, so
|
|
||||||
// this must be a disconnected camera
|
|
||||||
ALOGE("%s: cannot open camera %s. camera is disconnected!",
|
|
||||||
__FUNCTION__, mCameraId.c_str());
|
|
||||||
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
|
|
||||||
return Void();
|
|
||||||
} else {
|
} else {
|
||||||
mLock.lock();
|
ALOGE("%s: get camera info failed!", __FUNCTION__);
|
||||||
|
status = Status::INTERNAL_ERROR;
|
||||||
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
|
|
||||||
session = mSession.promote();
|
|
||||||
if (session != nullptr && !session->isClosed()) {
|
|
||||||
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Open HAL device */
|
|
||||||
status_t res;
|
|
||||||
camera3_device_t *device;
|
|
||||||
|
|
||||||
std::string mCameraID = mCameraId;
|
|
||||||
if (mCameraIdInt == 1) mCameraIdInt = 2;
|
|
||||||
if (mCameraID == "1") mCameraID = "2";
|
|
||||||
|
|
||||||
res = mModule->open(mCameraID.c_str(),
|
|
||||||
reinterpret_cast<hw_device_t**>(&device));
|
|
||||||
if (res != OK) {
|
|
||||||
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraID.c_str());
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(getHidlStatus(res), nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cross-check device version */
|
|
||||||
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
|
|
||||||
ALOGE("%s: Could not open camera: "
|
|
||||||
"Camera device should be at least %x, reports %x instead",
|
|
||||||
__FUNCTION__,
|
|
||||||
CAMERA_DEVICE_API_VERSION_3_2,
|
|
||||||
device->common.version);
|
|
||||||
device->common.close(&device->common);
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct camera_info info;
|
|
||||||
res = mModule->getCameraInfo(mCameraIdInt, &info);
|
|
||||||
if (res != OK) {
|
|
||||||
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
|
|
||||||
device->common.close(&device->common);
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
|
|
||||||
session = createSession(
|
|
||||||
device, info.static_camera_characteristics, callback);
|
|
||||||
if (session == nullptr) {
|
|
||||||
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
if (session->isInitFailed()) {
|
|
||||||
ALOGE("%s: camera device session init failed", __FUNCTION__);
|
|
||||||
session = nullptr;
|
|
||||||
mLock.unlock();
|
|
||||||
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
|
||||||
return Void();
|
|
||||||
}
|
|
||||||
mSession = session;
|
|
||||||
|
|
||||||
IF_ALOGV() {
|
|
||||||
session->getInterface()->interfaceChain([](
|
|
||||||
::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
|
|
||||||
ALOGV("Session interface chain:");
|
|
||||||
for (const auto& iface : interfaceChain) {
|
|
||||||
ALOGV(" %s", iface.c_str());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
mLock.unlock();
|
|
||||||
}
|
}
|
||||||
_hidl_cb(status, session->getInterface());
|
}
|
||||||
return Void();
|
_hidl_cb(status, cameraCharacteristics);
|
||||||
|
return Void();
|
||||||
}
|
}
|
||||||
Return<void> CameraDevice::nuke(const sp<ICameraDeviceCallback>& callback,
|
|
||||||
ICameraDevice::open_cb _hidl_cb) {
|
Return<void> CameraDevice::getEurekaCharacteristics(
|
||||||
return CameraDevice::open(callback, _hidl_cb);
|
ICameraDevice::getCameraCharacteristics_cb _hidl_cb) {
|
||||||
|
return CameraDevice::getCameraCharacteristics(_hidl_cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback> &callback,
|
||||||
|
ICameraDevice::open_cb _hidl_cb) {
|
||||||
|
Status status = initStatus();
|
||||||
|
sp<CameraDeviceSession> session = nullptr;
|
||||||
|
|
||||||
|
if (callback == nullptr) {
|
||||||
|
ALOGE("%s: cannot open camera %s. callback is null!", __FUNCTION__,
|
||||||
|
mCameraId.c_str());
|
||||||
|
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != Status::OK) {
|
||||||
|
// Provider will never pass initFailed device to client, so
|
||||||
|
// this must be a disconnected camera
|
||||||
|
ALOGE("%s: cannot open camera %s. camera is disconnected!", __FUNCTION__,
|
||||||
|
mCameraId.c_str());
|
||||||
|
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
|
||||||
|
return Void();
|
||||||
|
} else {
|
||||||
|
mLock.lock();
|
||||||
|
|
||||||
|
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
|
||||||
|
session = mSession.promote();
|
||||||
|
if (session != nullptr && !session->isClosed()) {
|
||||||
|
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Open HAL device */
|
||||||
|
status_t res;
|
||||||
|
camera3_device_t *device;
|
||||||
|
|
||||||
|
std::string mCameraID = mCameraId;
|
||||||
|
if (mCameraIdInt == 1)
|
||||||
|
mCameraIdInt = 2;
|
||||||
|
if (mCameraID == "1")
|
||||||
|
mCameraID = "2";
|
||||||
|
|
||||||
|
res = mModule->open(mCameraID.c_str(),
|
||||||
|
reinterpret_cast<hw_device_t **>(&device));
|
||||||
|
if (res != OK) {
|
||||||
|
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraID.c_str());
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(getHidlStatus(res), nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cross-check device version */
|
||||||
|
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
|
||||||
|
ALOGE("%s: Could not open camera: "
|
||||||
|
"Camera device should be at least %x, reports %x instead",
|
||||||
|
__FUNCTION__, CAMERA_DEVICE_API_VERSION_3_2,
|
||||||
|
device->common.version);
|
||||||
|
device->common.close(&device->common);
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct camera_info info;
|
||||||
|
res = mModule->getCameraInfo(mCameraIdInt, &info);
|
||||||
|
if (res != OK) {
|
||||||
|
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
|
||||||
|
device->common.close(&device->common);
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
session =
|
||||||
|
createSession(device, info.static_camera_characteristics, callback);
|
||||||
|
if (session == nullptr) {
|
||||||
|
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
if (session->isInitFailed()) {
|
||||||
|
ALOGE("%s: camera device session init failed", __FUNCTION__);
|
||||||
|
session = nullptr;
|
||||||
|
mLock.unlock();
|
||||||
|
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
mSession = session;
|
||||||
|
|
||||||
|
IF_ALOGV() {
|
||||||
|
session->getInterface()->interfaceChain(
|
||||||
|
[](::android::hardware::hidl_vec<::android::hardware::hidl_string>
|
||||||
|
interfaceChain) {
|
||||||
|
ALOGV("Session interface chain:");
|
||||||
|
for (const auto &iface : interfaceChain) {
|
||||||
|
ALOGV(" %s", iface.c_str());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mLock.unlock();
|
||||||
|
}
|
||||||
|
_hidl_cb(status, session->getInterface());
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
Return<void> CameraDevice::nuke(const sp<ICameraDeviceCallback> &callback,
|
||||||
|
ICameraDevice::open_cb _hidl_cb) {
|
||||||
|
return CameraDevice::open(callback, _hidl_cb);
|
||||||
}
|
}
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
} // namespace V3_2
|
} // namespace V3_2
|
||||||
} // namespace device
|
} // namespace device
|
||||||
} // namespace camera
|
} // namespace camera
|
||||||
} // namespace hardware
|
} // namespace hardware
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
|
|
||||||
int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
|
int __android_log_print(int prio, const char *tag, const char *fmt, ...) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,28 +23,29 @@ using android::Mutex;
|
||||||
|
|
||||||
static Mutex gLock;
|
static Mutex gLock;
|
||||||
|
|
||||||
extern "C" ALooper* ALooper_forCamera() {
|
extern "C" ALooper *ALooper_forCamera() {
|
||||||
LOG(VERBOSE) << "ALooper_forCamera";
|
LOG(VERBOSE) << "ALooper_forCamera";
|
||||||
ALooper* sLooper = NULL;
|
ALooper *sLooper = NULL;
|
||||||
|
|
||||||
|
Mutex::Autolock autoLock(gLock);
|
||||||
|
sLooper = new ALooper;
|
||||||
|
|
||||||
|
return sLooper;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int ALooper_release_forCamera(ALooper *sLooper) {
|
||||||
|
if (sLooper != nullptr) {
|
||||||
Mutex::Autolock autoLock(gLock);
|
Mutex::Autolock autoLock(gLock);
|
||||||
sLooper = new ALooper;
|
delete sLooper;
|
||||||
|
}
|
||||||
|
|
||||||
return sLooper;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int ALooper_release_forCamera(ALooper* sLooper) {
|
extern "C" int ALooper_pollOnce_camera(ALooper *sLooper, int timeoutMillis,
|
||||||
if (sLooper != nullptr) {
|
int *outFd, int *outEvents,
|
||||||
Mutex::Autolock autoLock(gLock);
|
void **outData) {
|
||||||
delete sLooper;
|
int res = sLooper->pollOnce(timeoutMillis, outFd, outEvents, outData);
|
||||||
}
|
LOG(VERBOSE) << "ALooper_pollOnce_camera => " << res;
|
||||||
|
return res;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int ALooper_pollOnce_camera(ALooper* sLooper, int timeoutMillis, int* outFd,
|
|
||||||
int* outEvents, void** outData) {
|
|
||||||
int res = sLooper->pollOnce(timeoutMillis, outFd, outEvents, outData);
|
|
||||||
LOG(VERBOSE) << "ALooper_pollOnce_camera => " << res;
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue