143 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			143 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * 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) {
 | |
|         if (mOrientationSensor != nullptr) {
 | |
|             ASensorEventQueue_disableSensor(mQueue, mOrientationSensor);
 | |
|         }
 | |
|         ASensorManager_destroyEventQueue(mSensorManager, mQueue);
 | |
|     }
 | |
| }
 | |
| 
 | |
| }  // namespace pixel
 | |
| }  // namespace google
 | |
| }  // namespace hardware
 | |
| }  // namespace android
 |