blob: 2647a0671869c7ca72ca0475dd3d0cb1e02250df [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "pixelstats-orientation"
#include <android/sensor.h>
#include <log/log.h>
#include <pixelstats/OrientationCollector.h>
namespace android {
namespace hardware {
namespace google {
namespace pixel {
#define GET_EVENT_TIMEOUT_MILLIS 200
#define SENSOR_TYPE_DEVICE_ORIENTATION 27
#define ORIENTATION_UNKNOWN -1
sp<OrientationCollector> OrientationCollector::createOrientationCollector() {
sp<OrientationCollector> orientationCollector;
orientationCollector = new OrientationCollector();
if (orientationCollector != nullptr && orientationCollector->init() < 0) {
orientationCollector->disableOrientationSensor();
return nullptr;
}
return orientationCollector;
}
/* pollOrientation
* orientation: [out] orientation value from sensor Hal.
* Return: OK, or error code from sensor Hal
*/
int32_t OrientationCollector::pollOrientation(int *orientation) {
int err = OK;
int eventCount = 0;
ASensorEvent sensorEvent;
*orientation = ORIENTATION_UNKNOWN;
/* Get sensor events. */
/* Get sensor sample events. */
err = getEvents(&sensorEvent, 1, &eventCount);
if (eventCount > 0) {
ALOGV("%s: ##event data: %f,%f,%f", __func__, sensorEvent.data[0], sensorEvent.data[1],
sensorEvent.data[2]);
*orientation = sensorEvent.data[0];
}
return err;
}
/*
* Collects sensor samples and returns them in the sensor sample event list
* specified by event_list. Limits the number of returned sample events to the
* value specified by event_list_size. Returns the number of returned sample
* events in p_event_count.
*
* event_list List of collected sample events.
* event_list_size Size of sample event list.
* event_count Returned count of the number of collected sample
* events.
*/
int OrientationCollector::getEvents(ASensorEvent *event_list, size_t event_list_size,
int *event_count) {
int rv;
int err = OK;
/* Wait for a sensor event to be available */
/* The timeout is used to prevent blocking for long time, when sensor pool is
* empty, for example the device is put on a horizontal wireless charger.
*/
rv = ALooper_pollOnce(GET_EVENT_TIMEOUT_MILLIS, nullptr, nullptr, nullptr);
if (rv == ALOOPER_POLL_ERROR) {
ALOGI("Sensor event looper returned a poll error.\n");
err = UNKNOWN_ERROR;
goto out;
}
/* Get sensor events. */
*event_count = ASensorEventQueue_getEvents(mQueue, event_list, event_list_size);
out:
return err;
}
int32_t OrientationCollector::init() {
int err = OK;
ALooper *looper = nullptr;
// Get orientation sensor events from the NDK
mSensorManager = ASensorManager_getInstanceForPackage(nullptr);
if (mSensorManager == nullptr) {
ALOGE("%s: Unable to get sensorManager.\n", __func__);
return UNKNOWN_ERROR;
}
looper = ALooper_forThread();
if (looper == nullptr) {
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
}
if (looper == nullptr) {
ALOGE("%s: Failed to prepare an event looper.\n", __FUNCTION__);
return UNKNOWN_ERROR;
}
mQueue = ASensorManager_createEventQueue(mSensorManager, looper, 0, nullptr, nullptr);
mOrientationSensor =
ASensorManager_getDefaultSensor(mSensorManager, SENSOR_TYPE_DEVICE_ORIENTATION);
if (mOrientationSensor == nullptr) {
ALOGE("%s: Unable to get orientation sensor.\n", __func__);
return UNKNOWN_ERROR;
}
err = ASensorEventQueue_registerSensor(mQueue, mOrientationSensor,
ASensor_getMinDelay(mOrientationSensor), 0);
if (err < 0) {
ALOGE("%s: Unable to register for orientation sensor events\n", __func__);
}
return err;
}
void OrientationCollector::disableOrientationSensor() {
if (mSensorManager != nullptr && mQueue != nullptr) {
ASensorEventQueue_disableSensor(mQueue, mOrientationSensor);
ASensorManager_destroyEventQueue(mSensorManager, mQueue);
}
}
} // namespace pixel
} // namespace google
} // namespace hardware
} // namespace android