universal7885: format code using clang-format-15

This commit is contained in:
roynatech2544 2022-04-12 17:26:15 +09:00
commit cb072badd5
No known key found for this signature in database
GPG key ID: 50ABF73F0D19445D
55 changed files with 3946 additions and 3783 deletions

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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,
}; };

View file

@ -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)

View file

@ -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 {
} else { service->setBatteryWritable(SysfsType::FASTCHARGE, Number::DISABLE);
service->setBatteryWritable(SysfsType::FASTCHARGE, Number::DISABLE); }
}
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_com_eurekateam_samsungextras_interfaces_Battery_getFastChargeSysfs(JNIEnv* env, Java_com_eurekateam_samsungextras_interfaces_Battery_getFastChargeSysfs(
__unused jclass obj) { JNIEnv *env, __unused jclass obj) {
int ret = service->getBatteryStats(SysfsType::FASTCHARGE); int ret = service->getBatteryStats(SysfsType::FASTCHARGE);
return ret; return ret;
} }
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(JNIEnv* env, Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(
__unused jobject obj, JNIEnv *env, __unused jobject obj, jint id) {
jint id) { /**
/** * id:
* id: * 1 = BATTERY_CAPACITY_MAX
* 1 = BATTERY_CAPACITY_MAX * 2 = BATTERY_CAPACITY_CURRENT (%)
* 2 = BATTERY_CAPACITY_CURRENT (%) * 3 = BATTERY_CAPACITY_CURRENT (mAh)
* 3 = BATTERY_CAPACITY_CURRENT (mAh) * 4 = CHARGING_STATE
* 4 = CHARGING_STATE * 5 = BATTERY_TEMP
* 5 = BATTERY_TEMP * 6 = BATTERY_CURRENT
* 6 = BATTERY_CURRENT */
*/
int ret; int ret;
switch (id) { switch (id) {
case 1: case 1:
ret = service->getBatteryStats(SysfsType::CAPACITY_MAX) / 1000; ret = service->getBatteryStats(SysfsType::CAPACITY_MAX) / 1000;
break; break;
case 2: case 2:
ret = service->getBatteryStats(SysfsType::CAPACITY_CURRENT); ret = service->getBatteryStats(SysfsType::CAPACITY_CURRENT);
break; break;
case 3: case 3:
ret = (float)service->getBatteryStats(SysfsType::CAPACITY_CURRENT) * ret = (float)service->getBatteryStats(SysfsType::CAPACITY_CURRENT) *
(float)service->getBatteryStats(SysfsType::CAPACITY_MAX) / 100000; (float)service->getBatteryStats(SysfsType::CAPACITY_MAX) / 100000;
break; break;
case 4: case 4:
if (service->getBatteryStats(SysfsType::CURRENT) > 0) { if (service->getBatteryStats(SysfsType::CURRENT) > 0) {
ret = 1; ret = 1;
} else { } else {
ret = 0; 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; break;
case 5:
ret = service->getBatteryStats(SysfsType::TEMP) / 10;
break;
case 6:
ret = service->getBatteryStats(SysfsType::CURRENT);
break;
default:
ret = -1;
break;
}
return ret;
} }

View file

@ -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);
}
} }

View file

@ -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;
} }

View file

@ -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()

View file

@ -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;
} }

View file

@ -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(){ Return<V1_2::Space> FMRadio::getChannelSpacing() {
switch (mChannelSpacing) { switch (mChannelSpacing) {
case 1: return V1_2::Space::CHANNEL_SPACING_10HZ; case 1:
case 2: return V1_2::Space::CHANNEL_SPACING_20HZ; return V1_2::Space::CHANNEL_SPACING_10HZ;
case 3: return V1_2::Space::CHANNEL_SPACING_30HZ; case 2:
case 4: return V1_2::Space::CHANNEL_SPACING_40HZ; return V1_2::Space::CHANNEL_SPACING_20HZ;
case 5: return V1_2::Space::CHANNEL_SPACING_50HZ; case 3:
default: return V1_2::Space::CHANNEL_SPACING_30HZ; 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) { IFMRadio *FMRadio::getInstance(void) { return new FMRadio(); }
return new FMRadio(); } // namespace vendor::eureka::hardware::fmradio::V1_2
}
} // namespace vendor::eureka::hardware::fmradio::V1_0

View file

@ -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

View file

@ -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
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
} }

View file

@ -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();
} }
} }

View file

@ -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_

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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

View file

@ -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

View file

@ -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
} }

View file

@ -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() {}

View file

@ -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

View file

@ -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;
} }

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -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_

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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 << "!";
} }
} }

View file

@ -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);
} }

View file

@ -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

View file

@ -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

View file

@ -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;
} }

View file

@ -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;
} }